Assignment 12, Solutions
Part of
the homework for 22C:112, Spring 2009
|
See man 2 dup for mechanisms permitting open files to be moved to a different descriptor number, and note that if an open file is visible from two descriptor numbers, close() applied to one of its numbers does not close access to the file through the other number.
A problem: Give a fragment of C code that launches two applications using execve(), call them "app1" and "app2", where standard output of "app1" is piped into standard input of "app2", while both applications remain able to read and write the other files that were open prior to your code fragment. Your fragment should wait for both child processes to terminate before it exits. (1.0 points)
{ int fd[2]; const int readend = 0; /* the two ends of the pipe in fd */ const int writeend = 1; const int standardin = 0; /* the files we really want to change */ const int standardout = 1; pipe( fd ); if (fork() == 0) { /* child 1 */ dup2( fd[writeend], standardout ); close( fd[readend] ); close( fd[writeend] ); execve( "app1" ); /* standard output to the pipe */ } else if (fork() == 0) { /* child 2 */ close( standardin ); dup( fd[readend] ); /* guaranteed to return standardin */ close( fd[readend] ); close( fd[writeend] ); execve( "app2" ); /* standard input from the pipe */ } else { /* parent */ close( fd[readend] ); close( fd[writeend] ); wait(); wait(); /* we wait for both, not knowing which ends first */ } }
A problem: Write the code for a server that implements a single semaphore, with initial (abstract) value zero and client-to-server messages "P" and "V" corresponding to the wait and signal operations (names chosen in part because they are of length 1). You may assume pre-existing library implementations of such things as stacks and queues with the usual operations. (1.0 points)
{ int count = 0; queue myqueue; initialize_queue( &myqueue ); for (;;) { /* an infinite loop */ char operation = " "; ID client = server_receive( &operation, 1 ); if (operation == "P") { if (count > 0) { count = count - 1; /* send prompt reply to P */ server_send( client, NULL, 0 ); } else { /* remember client for delayed reply to P */ enqueue( &myqueue, client ); } } else if (operation == "V") { /* always send prompt reply to V */ server_send( client, NULL, 0 ); if (is_empty( &myqueue )) { count = count + 1; } else { /* send delayed reply to P */ client = dequeue( &myqueue ); server_send( client, NULL, 0 ); } } else { /* ignore illegal operations */ } } }
In Amoeba and Demos, many resources that are statically accessible in systems modeled on Unix are, instead, passed in what can be thought of as analogous to the environment in Unix. Among the most important of these is the file system.
a) What system data structure holds the envoronment of a Demos process? (0.5 points)
The link table.
b) What system data structure in Unix (or Linux) is analogous to the data structure you identified in part a. Note that this Unix data structure has a far narrower use than the use it has in Demos. (0.5 points)
The open file table.