When I am writing my own interpreter...


 
Thread Tools Search this Thread
Top Forums Programming When I am writing my own interpreter...
# 22  
Old 10-25-2007
Hmm... I seem to be doing something wrong. Here's what I've been doing...

Code:
I'm creating a filedescriptor fd[2]
fork child1
if(pid1 == 0) {
        close(fd[1]); 
        setting fd[0] to STDIN_FILENO using dup2
         close(fd[0]);
        }
        execlp("wc","wc",(char *) 0);
    }
    else {
        fork child 2
        if(pid2 == 0) {
               close(fd[1]);  
               set fd[0] to STDIN_FILENO using dup2
               close(fd[0]);
               set fd[1] to STDOUT_FILENO using dup2
               close(fd[1]);
               execlp("wc","wc", (char *) 0);
        }
        else {
            //parent continues
            fork child 3
            if(pid3 == 0) {
                    close(fd[0]);
                    set fd[1] to STDOUT_FILENO using dup2
                    close(fd[1])
                    execlp("ls","-la", (char *) 0);
            }
        }

What I'm trying to do here is creating a two level pipe for the command: ls -la | wc | wc

It works upto one level but after that I'm getting an "dup2: Bad File Descriptor" error maybe because of the child 2... I'm not sure what mistake I'm doing... Any suggestions on how to get around this one?

Last edited by Legend986; 10-25-2007 at 12:08 AM..
# 23  
Old 10-25-2007
I was actually thiniking about one silly thing: when I'm creating multiple pipes, I need to create multiple file descriptors right? How would I do that? Just define a pool of unused file descriptors and use them only when I need them or is there any other way?

I tried defining using
int fd[4][2];

to get four pipes but it isn't working due to some obvious reason I guess... Any advice please?
# 24  
Old 10-25-2007
I personally would associate the file descriptors with the struct that describes each process, so each struct may look like

Code:
struct shell_proc
{
   struct shell_proc *next;
   int fd_stdin,fd_stdout,fd_stderr;
   int argc;
   char **argv;
   char **environ;
   pid_t pid;
   int exit_code;
};

# 25  
Old 10-25-2007
Quote:
Originally Posted by Legend986
I was actually thiniking about one silly thing: when I'm creating multiple pipes, I need to create multiple file descriptors right? How would I do that? Just define a pool of unused file descriptors and use them only when I need them or is there any other way?

I tried defining using
int fd[4][2];

to get four pipes but it isn't working due to some obvious reason I guess... Any advice please?
This is a great attempt ! Smilie Smilie

If the file descriptors data type is defined as
int fd[4][2]; again you are imposing the limit on the number of processes that could be piped to each other.

( Or is that you are trying first with 'n' number of processes for piping where n <= 4 and then moving on to a more generic attempt )


##############

When replying to this thread I got this doubt, may be worth asking this along with this thread.

So basically pipe is a KDS - kernel data structure with its own memory capacity, therefore number of bytes that it can hold.

Take an example piping process like this

Code:
ls | wc -l

( assume ls runs over a million files and definitely has to take some 'n' number of seconds to complete that )

case 1 : Should wc process need to wait till lc flushes all the filenames to the ' | ' ?
case 2: Or as and when ' ls ' lists the filenames to the kernel data structure ' wc ' process would start using that information to count on the number of files.

What would be scenario if the information from process 1 ' ls ' overruns the capacity of the pipe data structure? Will the process 1 be signalled by the kernel to stop flushing data to pipe and at the same time process 2 signalled by the kernel to start using the data from the KDS so that process 1 can push in more information to the pipe data structure.

Is this how pumping information in to the pipe by process 1 and using the information by process 2 happens ?

Keep this thread alive, it is becoming more interesting Smilie
# 26  
Old 10-25-2007
pipes are implemented in the kernel and can be efficiently implemented as a ring buffer of say 512 to 4096 bytes. A write adds to the buffer, but if it attempts to write more, it blocks until the buffer has had some data read out. Similarly a read will block until more data is available.

Normally a pipe() is unidirectional but on some platforms a pipe() is actually implemented using socketpair(AF_UNIX,SOCK_STREAM,0);
# 27  
Old 10-25-2007
It may not directly help you, but this is the document inventing the pipes, i just stumbled across it on the net: pipes invented

The best information about recursively parsing and techniques of lexical analysis is still the "Dragon book" (real Name: Compilers: Principles, Techniques, and Tools) by Aho, Sethi and Ullmann (depending on you level of you pre-education, but you come across like you should be able to understand it). The authors offer better advice in this regard than perhaps any of us could provide.

bakunin
# 28  
Old 10-26-2007
Thanks I'll try to get that book... Actually I'm considering of rewriting a few parts because I see that I'm not able to achieve what I need. However I was curious about one thing:

Code:
int status;
	pid_t pid;
	pipe(pipe_a);
        pipe(pipe_b);

        if (!fork())
        {
                dup2(pipe_a[1], 1);
                closeall();
                execlp(argv[0], argv[0], argv[1], (char *)0);
        }
        else {
		if (!fork())
		{
		        dup2(pipe_a[0], 0);
		        dup2(pipe_b[1], 1);
		        closeall();
		        execlp(argv[3], argv[3], (char *)0);
		}
		else {
			if (!(pid=fork()))
			{
			        dup2(pipe_b[0], 0);
			        closeall();
			        execlp(argv[5], argv[5], (char *)0);
			}
			else {
				wait(NULL);
				return 1;
			}
		}
		
	}

argv[0] = "ls"
argv[1] = "-la"
argv[2] = "|"
argv[3] = "wc"
argv[4] = "|"
argv[5] = "wc"

When I'm running this, what surprised me is that it isn't displaying the output but when I type quit(which exits my shell), it is displaying the output and then exiting... Why isn't it going back I mean returning back?

Also when I'm using ps in my shell to see what are the processes running, ls is not there but there are two wc's.... and when I compiled the program without that wait(NULL), it still runs but when I run ps, it shows ls with a <defunct> besides it... It still shows the output when I type quit...
Login or Register to Ask a Question

Previous Thread | Next Thread

7 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Dynamically choosing the interpreter

Hi, Is it possible to choose the inerpreter conditionally. For example, if whereis bash returns /usr/bin/bash then i need to choose #!/usr/bin/bash else i need to use #!/usr/bin/sh. Is it possible to achieve in a shell script? Thanks (1 Reply)
Discussion started by: pandeesh
1 Replies

2. Linux

interpreter files

Can you explain me what is ment by interpreter files ?? Why and how they are used?? (1 Reply)
Discussion started by: kkalyan
1 Replies

3. Shell Programming and Scripting

Bad Interpreter

Hi. My name is Caleb (a.k.a RagingNinja) form the whited00r forums. (Whited00r makes custom firmware for iOS devices). I have been learning and creating simple shells scripts. I have been recently using VIM for Windows or using VirtualBox to run the UBUNTU OS within VirtualBox to create my shell... (2 Replies)
Discussion started by: RagingNinja
2 Replies

4. Shell Programming and Scripting

Multiple interpreter declarations

Hi, I am writing a shell script that connects to a remote server and performs some tasks on the server and exits. Since i am using a ssh connection, i am using a "expect" utility to supply the password automatically (which is present within the script). In order to use this utility, i need to... (3 Replies)
Discussion started by: sunrexstar
3 Replies

5. Programming

Java Interpreter

Hello guys - do you have any sample program implementing UNIX commands in an interpreter with Java? I can look up the simple ones such "ls" etc and then write my own commands. I would appreciate it. (2 Replies)
Discussion started by: cmontr
2 Replies

6. UNIX for Dummies Questions & Answers

m4 as script interpreter

#!/usr/bin/m4 when running m4 scripts with "#!/usr/bin/m4" they are executed properly, but "#!/usr/bin/m4" is printed out - how to avoid it? Thanks in advance. (5 Replies)
Discussion started by: Action
5 Replies

7. UNIX for Dummies Questions & Answers

an command interpreter

if somebody can help me pls. i need the source code for a shell which compiles C or java programs. i need a very short and simple one, just for the compiling part, in UNIX Respect (4 Replies)
Discussion started by: zlatan005
4 Replies
Login or Register to Ask a Question