Click to See Complete Forum and Search --> : Multiple command pipes


gautamshetty
November 29th, 2004, 11:17 AM
I am implementing a mini command line interpretter on linux.I have imlemented 1st and 2nd level of piping i.e ls|wc and ls|wc|more.Cant figure out how to implement n level piping(n is arbitrary).Please advise.

Latem
November 29th, 2004, 08:23 PM
I think it can be implemented using pipes. You have to use either normal pipes (with pipe() system call), or named pipes (with mknod() system call).

Lets say you have p1 | p2 | p3

Lets say u were to use normal pipes with pipe(). I am not 100% sure if normal pipes will work for this, but named pipes should work for sure. I am using pipe() for simplicity. It shouldnt be too different w/ named pipes. I think normal pipes should be ok. havent thought everything 100% out, so just not sure.

So with pipe() you will get two file descriptors (fd for short), one for read and one for write. Then you change p1's fd "1" (the file descriptor for stdout) to point to your write pipe fd. Similarly you change p2's fd "0" (the fd for stdin) to point to the read pipe. and that should do it. There is a system call for changing a process' default fd's 0 (stdin) 1 (stdout) and 2 (stderr), which I cant remember right now. Ill look into it. I am pretty sure you have to be the parent of the process you are trying to change. But that will be the case since (I am assuming) your program will launch p1, p2, and p3 (with some combination of fork() and exec()), and therefore will be the parent and have full control of the child processes.

For n level piping you just do this for every pair of processes.



Ok found my notes on I/O readirection:

#include <unistd.h>
int dup(int oldfd);
int dup2(int oldfd, int newfd);

Dup and Dup2 both make copies of a
file descriptor.

Dup make a copy and uses the lowest
numbered unused file descriptor.

Dup2 copies oldfd to newfd. Newfd
will be closed if necessary.

When a process forks, the child
inherits all of open files from the
parents.

We can open a file, duplicate it's file
descriptor to STD OUT/IN/ERR.
Then when we exec another program
we've effective changed it's STD
OUT/IN/ERR to the file we opened.

This exactly how the shell itself does
it.

/* simple example of redirection */
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
int fd;
fd=open("junk",
O_WRONLY|O_CREAT|O_TRUNC,
S_IRUSR|S_IWUSR); /* open output file */
dup2(fd, 1); /* set standard output to write to file */
close(fd); /* close unneeded file descriptor */
execlp("ls", "ls", "-l", 0); /* go do "ls -l" */
perror("redirect exec failed"); /* exec failed */
return 0;
}



Hope this helps. I am pretty sure that it in fact is implemented in something like this.

Latem