shell (addendum). example r what if we want to support something like this: m ps –le | sort r one...
TRANSCRIPT
Shell (Addendum)
Example What if we want to support something like
this: ps –le | sort
One process should execute ps –le and another should execute sort
By default a command like ps requires that its output goes to standard output i.e., the terminal
The sort command requires that a file be provided as a command line argument (standard input)
First Attempt
pid = fork(); if (pid<0) {
perror("Problem forking");exit(1);
} else if (pid>0) {/* parent process */ execlp("ps","ps","-le", NULL);perror("exec problem");exit(1);
} else {/* child process */}
execlp("sort","sort",NULL);perror("exec problem");exit(1);
}
return(0);}
Example
Why doesn’t this work? The output of the ps -le goes to the terminal
We want it to be the input to the sort The diagram on the next page shows
the status of the file descriptor tables after the fork No changes are made in the code related to
“First attempt”
Fork and Files
Parent File Descriptor table
01234
stdinstdoutstderr
System file table
Terminal info
01234
stdinstdoutstderr
Child File Descriptor table
Terminal info
Terminal info
Example First let us
Create shared memory that is to be used by the parent and child processes
This is done using the pipe function The pipe function is executed before the
fork function The results of ps –le should be put into the
shared memory to be used by child for sort See next slide for code The slide after code slide depicts the file
descriptor table and System File table
Example
int main(int argc, char **argv) { int fds[2]; pid_t pid;
/* attempt to create a pipe */ if (pipe(fds)<0) {
perror("Fatal Error");exit(1);
}
Example
Parent File Desc. table
01234
fds[0] fds[1]
stdinstdoutstderr
System file table
Terminal info
Terminal info
Terminal info
Shared mem. info: read Shared mem. Info:write
Example
Each entry in the system file table has information about the “file” which could be the terminal, disk file or pipe (shared memory)
Example
System file table
Terminal info
Terminal info
Terminal info
Shared mem. Info: read
Shared mem. Info:write
Shared Memory
Example
Let us now add the code for the fork See next slide for the code
Example
/* create another process */ pid = fork(); if (pid<0) {
perror("Problem forking");exit(1);
}
……………..
What is the status of the file descriptor table
Example
Parent File Desc. table
01234
fds[0] fds[1]
stdinstdoutstderr
System file table
01234
fds[0] fds[1]
stdinstdoutstderr
Child File Desc.table
Terminal info
Terminal info
Terminal info
Shared mem. Info: read
Shared mem. Info:write
Example
We want the output of the ps –le to be put into the shared memory
The sort command should read from the shared memory
How do we get there?
Example Let us start with the parent We should close the read end of the
pipe since the parent will only write to shared memory. This is done using the following command:
close(fds[0]); What does the parent file descriptor
table look like? See next slideFor now we will ignore the child process
Example
Parent File Desc. table
01234
fds[0]=NULL
fds[1]
stdinstdoutstderr
System file table
01234
fds[0] fds[1]
stdinstdoutstderr
Child File Desc.table
Terminal info
Terminal info
Terminal info
Shared mem. info: read
Shared mem. info:write
Example Now we want what would normally go to
the standard output to go to the shared memory
This is done with the following code:if ( dup2(fds[1],STDOUT_FILENO)<0) {
perror("can't dup"); exit(1);}
The new parent file descriptor table is on the next page
Example
Parent File Desc. table
01234
fds[0]=NULL
fds[1]
stdinstdoutstderr
System file table
01234
fds[0] fds[1]
stdinstdoutstderr
Child File Desc.table
Terminal info
Terminal info
Terminal info
Shared mem. info: read
Shared mem. info:write
Example
Now let us look at the child We should close the write end of the
pipe since the child will only read from shared memory. This is done using the following command:
close(fds[1]); What does the child file descriptor table
look like? See next slide
Example
Parent File Desc. table
01234
fds[0]=NULL
fds[1]
stdinstdoutstderr
System file table
01234
fds[0] fds[1]=NULL
stdinstdoutstderr
Child File Desc.table
Terminal info
Terminal info
Terminal info
Shared mem. info: read
Shared mem. info:write
Example Now want to set it up so that the child
reads from the shared memory This is done with the following code:
if ( dup2(fds[0],STDIN_FILENO)<0) { perror("can't dup"); exit(1);}
The new child file descriptor is on the next page
Example
Parent File Desc. table
01234
fds[0]=NULL
fds[1]
stdinstdoutstderr
System file table
01234
fds[0] fds[1]=NULL
stdinstdoutstderr
Child File Desc.table
Terminal info
Terminal info
Terminal info
Shared mem. info: read
Shared mem. info:write
Example
Let us now put it together
Example/* create another process */ pid = fork(); if (pid<0) {
perror("Problem forking");exit(1);
} else if (pid>0) {/* parent process */close(fds[0]);
/* close stdout, reconnect to the writing end of the pipe */if ( dup2(fds[1],STDOUT_FILENO)<0) { perror("can't dup"); exit(1);}
execlp("ps","ps","-le", NULL);perror("exec problem");exit(1);
Example
} else {/* child process */
close(fds[1]);if (dup2(fds[0],STDIN_FILENO) < 0) { perror("can't dup"); exit(1);}execlp("sort","sort",NULL);perror("exec problem");exit(1);
}
return(0);}