shell (addendum). example r what if we want to support something like this: m ps –le | sort r one...

25
Shell (Addendum)

Upload: calvin-bridges

Post on 04-Jan-2016

213 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Shell (Addendum). Example r What if we want to support something like this: m ps –le | sort r One process should execute ps –le and another should execute

Shell (Addendum)

Page 2: Shell (Addendum). Example r What if we want to support something like this: m ps –le | sort r One process should execute ps –le and another should execute

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)

Page 3: Shell (Addendum). Example r What if we want to support something like this: m ps –le | sort r One process should execute ps –le and another should execute

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);}

Page 4: Shell (Addendum). Example r What if we want to support something like this: m ps –le | sort r One process should execute ps –le and another should execute

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”

Page 5: Shell (Addendum). Example r What if we want to support something like this: m ps –le | sort r One process should execute ps –le and another should execute

Fork and Files

Parent File Descriptor table

01234

stdinstdoutstderr

System file table

Terminal info

01234

stdinstdoutstderr

Child File Descriptor table

Terminal info

Terminal info

Page 6: Shell (Addendum). Example r What if we want to support something like this: m ps –le | sort r One process should execute ps –le and another should execute

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

Page 7: Shell (Addendum). Example r What if we want to support something like this: m ps –le | sort r One process should execute ps –le and another should execute

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);

}

Page 8: Shell (Addendum). Example r What if we want to support something like this: m ps –le | sort r One process should execute ps –le and another should execute

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

Page 9: Shell (Addendum). Example r What if we want to support something like this: m ps –le | sort r One process should execute ps –le and another should execute

Example

Each entry in the system file table has information about the “file” which could be the terminal, disk file or pipe (shared memory)

Page 10: Shell (Addendum). Example r What if we want to support something like this: m ps –le | sort r One process should execute ps –le and another should execute

Example

System file table

Terminal info

Terminal info

Terminal info

Shared mem. Info: read

Shared mem. Info:write

Shared Memory

Page 11: Shell (Addendum). Example r What if we want to support something like this: m ps –le | sort r One process should execute ps –le and another should execute

Example

Let us now add the code for the fork See next slide for the code

Page 12: Shell (Addendum). Example r What if we want to support something like this: m ps –le | sort r One process should execute ps –le and another should execute

Example

/* create another process */ pid = fork(); if (pid<0) {

perror("Problem forking");exit(1);

}

……………..

What is the status of the file descriptor table

Page 13: Shell (Addendum). Example r What if we want to support something like this: m ps –le | sort r One process should execute ps –le and another should execute

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

Page 14: Shell (Addendum). Example r What if we want to support something like this: m ps –le | sort r One process should execute ps –le and another should execute

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?

Page 15: Shell (Addendum). Example r What if we want to support something like this: m ps –le | sort r One process should execute ps –le and another should execute

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

Page 16: Shell (Addendum). Example r What if we want to support something like this: m ps –le | sort r One process should execute ps –le and another should execute

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

Page 17: Shell (Addendum). Example r What if we want to support something like this: m ps –le | sort r One process should execute ps –le and another should execute

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

Page 18: Shell (Addendum). Example r What if we want to support something like this: m ps –le | sort r One process should execute ps –le and another should execute

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

Page 19: Shell (Addendum). Example r What if we want to support something like this: m ps –le | sort r One process should execute ps –le and another should execute

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

Page 20: Shell (Addendum). Example r What if we want to support something like this: m ps –le | sort r One process should execute ps –le and another should execute

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

Page 21: Shell (Addendum). Example r What if we want to support something like this: m ps –le | sort r One process should execute ps –le and another should execute

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

Page 22: Shell (Addendum). Example r What if we want to support something like this: m ps –le | sort r One process should execute ps –le and another should execute

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

Page 23: Shell (Addendum). Example r What if we want to support something like this: m ps –le | sort r One process should execute ps –le and another should execute

Example

Let us now put it together

Page 24: Shell (Addendum). Example r What if we want to support something like this: m ps –le | sort r One process should execute ps –le and another should execute

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);

Page 25: Shell (Addendum). Example r What if we want to support something like this: m ps –le | sort r One process should execute ps –le and another should execute

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);}