Tues, Sept. 26

 Note: part of warmup for hw2: sign up for forum and post a test message in hw2test thread.

Back to Tanenbaum to finish Chap 1.

 

UNIX system calls—we looked at write and exit earlier, now look at

fork(), the amazing parameterless UNIX process-creation system call.

 

Here is a trivial fork program, using the return value from fork to tell the parent and child apart:  The parent gets the child pid (always !=0) from fork, while the child gets back 0.

 

int main()

{

     if (fork())

printf(“hello from parent\n”);

     else printf(“hello from child\n”);

}

When you run this program, you will see one message and then the other, in either order.  Each terminates

by executing the exit syscall in the startup module.

 

After fork, while both processes exist, there is a parent-child relationship between them.  If the parent exits first, the child is an orphan, and gets assigned to process 1 as a child.  Being an orphan doesn’t affect how it runs, only how it gets cleaned up at the end.

 

Fork clones the whole process image, even the stack, so we can put in local variables and they will be copied:

 

int x_ext = 2;  /* external var, in data segment */

int main()

{

      int x_loc=6;  /* local (automatic) var, on stack */

 

      if (fork()) {

       x_loc++;

       x_ext++;

 printf(“hello from parent, x_loc=%d, x_ext = %d\n”, x_loc, x_ext);

}

else printf(“hello from child, x_loc=%d, x_ext = %d\n”, x_loc, x_ext); 

}

 

Here x_loc, a local or automatic variable, will be on the stack, = 6 in the original program image, and thus =6 in the copied image as well.  In the parent, x_loc will be incremented to 7, but this has no effect on the child. 

 

Similarly, x_ext is an external variable = 2 at the fork, so still 2 in the child’s report.

 So you will see “hello from parent, x_loc=7, x_ext=3\n” and “hello from child, x_loc=6, x_ext=2\n” output, in either order.

Question: can UNIX processes ever share memory?

Answer: yes, via special “shared memory” system calls, considered advanced programming.  The memory involved would be in that big area above the heap and below the stack, where the DLLs hang out.

 

Question: fork() produces another process, what about threads?

Answer: threads share the same process image, so thread programming is very tricky—it’s easy for one thread to damage data needed by another thread.  The processes are “bottled up” from one another each in their own address space.

 

Exec system call

 

Execve, or exec for short, replaces the current process image with one constructed from the contents of an executable file, i.e. it runs a program in the current process.  A simple (UNIX) program would be:

 

int main(int argc, char *argv[])

{

    int status;

 

    if (fork()) {

        waitpid(-1, &status, 0);  /* parent waits for child */

        printf("status=%d\n",status);

    } else {  /* run date in the child */

        execve("/usr/bin/date", argv, 0);

        /* never get here, unless execve fails */

    }

}

Here we are passing argv along from our old process to be the argv of the new image, since execve wants a non-trivial argv.  Waitpid(-1, ...) waits for any child to terminate, so the parent waits for date to run, print out the date, and exit, and then prints out “status = 0”, the success status.  Note that the stdout, stdin, and stderr fd’s pass live through the exec, so date has a good stdout to use and we see the output of date on the screen.

 

Stripped-down shell: look at code in Tan., pg. 49.  Similar to above with loop around it and general command instead of just “date.”

 

We have covered UNIX process management system calls: fork, exec, waitpid, exit.  Win2K has no fork or exec system calls, only the combination CreateProcess system call that takes the executable file as one of many parameters, and creates a new process running that program.  We could write a “wshell”, something like the UNIX shell with CreateProcess instead of fork and exec, and WaitForSingleObject (using the process handle returned by CreateProcess) after the CreateProcess to make the parent wait for termination of the program, itself done by ExitProcess.

 

NOTE: Correction to Tan., pg. 50, Fig. 1-20: change FFFF to FFFFFFFF for a 32-bit address space.

 

Look at the system call conversion table, pg. 55:

 

Refs on Win2k and UNIX/Win2K porting issues: Microsoft Windows Internels, by Russinovich and Solomon, also MSDN knowledge base (www.msdn.microsoft.com, and with MS Visual Studio).   Also see  WIndows System Programming, by Johnson Hart.  This has UNIX vs Windows coverage too.

 

Summary of First Part of Course

 

Def:  OS provides virtual machine for programs

UNIX and Win2K have similar virtual machine setups—

 

Also, don’t forget 2 ways to look at system call—function prototype, single instruction in user program image.

 

Idea of starting new job, finding out they are using a special OS, say for embedded programming.  What do you ask?  Does it provide a flat address space?  timesharing? automatic stack? (Windows 95 doesn’t), and what are the system calls?