• web pages for usp and its programs
  • GNU make document
  • exercise 1: Compiling C programs
    • Your have to write four files, a makefile, two c programs and a c header file. (Refer to A.3)
    • The mylib.c should implement a function named sum() which sums the numbers from a to b where a and b are the first and second arguments. The prototype of the function should be put in myinc.h and the prototype is:
      int sum(int a, int b);
    • The main() in my.c should convert the first two arguments into integers, pass them to sum(), and print them out.
    • For example:
      $ ls
      Makefile  my.c  myinc.h  mylib.c 
      $ make
      gcc    -c -o my.o my.c
      gcc    -c -o mylib.o mylib.c
      gcc -o my my.o mylib.o
      $ ./my 1 10
      1 + .... + 10 = 55
      $ ./my 10 1
      10 + .... + 1 = 0
      $ ./my 3 22
      3 + .... + 22 = 250
      $ 
             
    • Due: 2012/Mar/08, 23:59
      You have to put your files under ~/usp-1002/exer1.
    • For your reference, a program which shows the arguments is provided.
  • exercise 2: probing argv[]
    • This exercise asks you to list the addr of argv[] and the value of each argv[i] such that you can draw a picture of argv[].
      For example: (this example also shows env[] but you can ignore the stuff about it.)
      $ env -i A=1 B=2 ./a.out i am klim
      The argument list follows:
      argv[0]: ./a.out
      argv[1]: i
      argv[2]: am
      argv[3]: klim
      
      The environment list follows:
      environ[0]: A=1
      environ[1]: B=2
      
      argv    is 4290772772
      environ is 4290772792
      value of argv[ 0] is 4290772932
      value of argv[ 1] is 4290772940
      value of argv[ 2] is 4290772942
      value of argv[ 3] is 4290772945
      value of argv[ 4] is 0
      value of env [ 0] is 4290772950
      value of env [ 1] is 4290772954
      $ env -i A=1 B=2 ./a.out Hello World
      The argument list follows:
      argv[0]: ./a.out
      argv[1]: Hello
      argv[2]: World
      
      The environment list follows:
      environ[0]: A=1
      environ[1]: B=2
      
      argv    is 4290772772
      environ is 4290772788
      value of argv[ 0] is 4290772928
      value of argv[ 1] is 4290772936
      value of argv[ 2] is 4290772942
      value of argv[ 3] is 0
      value of env [ 0] is 4290772948
      value of env [ 1] is 4290772952
      $ 
                 
    • Due: 2012/Mar/15, 23:59
      You have to put your files under ~/usp-1002/exer2.
  • exercise 3: simulating env
    • Refer to section 2.12.
    • You have to support at least the following four usages.
      $ env                  
      $ env cmd arg1 arg2 ....
      $ env -i
      $ env -i e1=v1 e2=v2 .... cmd arg1 arg2 ....
                
    • Note that there may be more than one environment string and there may be more than one argument for the cmd. To invoke system(), you have to combine `cmd' and all the `arg1 arg2 ....' to a single string, which is then passed to system().
    • Due: 2012/Mar/22, 23:59
      You have to put your files under ~/usp-1002/exer3.
  • exercise 4: forking a tree
    • Create a process tree which depth equals to argv[1].
    • Each process prints a message which shows its pid and ppid.
    • Each process should wait for a while to prevent the parent from dying before its children. When this case does happen, the ppid of the child will become 1.
    • For example:
      $ echo $$                           #   pid of bash is 26688
      26688                               #
      $ ./a.out 1                         #
      my pid=26748, and my ppid=26688     #   n = 1, just one process
                                          #     bash=26688
                                          #         |
                                          #     a.out=26748
      $ ./a.out 2                         #
      my pid=26750, and my ppid=26749     #   n = 2, three processes are created
      my pid=26751, and my ppid=26749     #        26749
      my pid=26749, and my ppid=26688     #        /   \
                                          #     26750 26751
                                          #
      $ ./a.out 3                         #   n = 3, five processes are created
      my pid=26753, and my ppid=26752     #        26752
      my pid=26755, and my ppid=26754     #        /   \
      my pid=26752, and my ppid=26688     #     26753  26754
      my pid=26756, and my ppid=26754     #             /  \
      my pid=26754, and my ppid=26752     #           26755 26756
      $                                   #
                 
    • Due: 2012/Mar/29, 23:59
      You have to put your files under ~/usp-1002/exer4.
  • exercise 5: practicing wait()
    • Refer to the exercise 2 for explanation of the code .
    • Remove the wait(NULL) in the loop. After the line of printing a message to stderr, You should insert code like:
      If the process is a leaf,
                   while(1) pause();
                
      else (the process is an internal node)
                   while there are children alive do 
                      waiting..
                   exit(...);   
                
    • The internal node should wait for all children, and for each child, when waited, report the signal number if it was terminated by a signal, or the value returned if it exited though exit(). In either case, a number is gained from the child. Those numbers from children are summed and the sum are used as the argument of exit(). This is to say the sum are the return value of this process.
      Refer to example 3.22 for the usage of wait().
    • To test your program, you have to open another window through which you can kill a process with the command `kill'.
      For example, to kill a process which pid is 12011 with signal 15, you can type 'kill -15 12011'.
    • Due: 2012/Apr/05, 23:59
    • For example:
      $ ./a.out ddduuduu abcd
      I'm c, my pid=3590, and my ppid=3589
      I'm b, my pid=3589, and my ppid=3588
      I'm d, my pid=3591, and my ppid=3588
      I'm a, my pid=3588, and my ppid=3295
      Child 3590 is terminated with signal 3.           $ kill -3 3590
      Child 3589 exits with value 3.
      Child 3591 is terminated with signal 2.           $ kill -2 3591
      $ echo $?                                # Check the return value of root.
      5                                        # It is the sum of 2 and 3.
      $ ./a.out ddduuduu abcd                  # Run it agagin.
      I'm c, my pid=3594, and my ppid=3593     # This time we try to kill the 
      I'm b, my pid=3593, and my ppid=3592     # internal node. The leaf node will
      I'm d, my pid=3595, and my ppid=3592     # be an orphan and be adopted by init.
      I'm a, my pid=3592, and my ppid=3295 
      Child 3593 is terminated with signal 4.           $ kill -4 3593
      Child 3595 is terminated with signal 15.          $ kill -15 3595
      $ echo $?
      19
      $ ps -ef | grep a.out                    # Find the orphan. Check its ppid.
      klim      3594     1  0 13:39 pts/0    00:00:00 ./a.out ddduuduu abcd
      klim      3597  3295  0 13:40 pts/0    00:00:00 grep a.out
      $ 
      
                
  • exercise 6: practicing exec()
    • Refer to the exercise 2 for explanation of the code .
    • Instead of branching to the beginning when a child is born, you have to replace the goto with an exec().
    • You may need one or two executables, depending on your choice.
      But arguments for invoking the program, the output and the created process tree should be all the same to the original one.
    • Due: 2012/Apr/12, 23:59
  • exercise 7: practicing file I/O
    • Write a table manager.
    • Due: 2012/Apr/19, 23:59
  • exercise 8: practicing pipe()
    • Generate a process tree and each process writes its message to screen two times, first in pre-order and second in post-order.
    • Refer to the exercise 2 for explanation of the code .
    • Due: 2012/Apr/26, 23:59
  • exercise 9: practicing select() or poll()
    • Generate a bidirectional ring. Refer to program 7.1. The argv[1] specified the number of processes.
    • After the ring is setup, the root process then does
                  loop
                    read from stdin 
                    if got 'l' then 
                      generate 12 random numbers between 1 to 49
                      send them to the clockwise next process
                      read 12 numbers from clockwise previous process
                      write the first 6 out
                    if got 'p' then 
                      write a token to the anti-clockwise next process
                      read a token from anti-clockwise previous process
                  end loop
                
      Each child does
                  loop
                    monitor two inputs simultaneously 
                    (one clockwise and another anti-clockwise)
                    if clockwise input is ready then 
                      read 12 numbers from clockwise previous process
                      show them
                      randomly generate a, b
                      swap a-th and b-th numbers
                      write 12 numbers to clockwise next process
                    if anti-clockwise input is ready then
                      read a token from anti-clockwise previous process
                      show the a, b (previously generated random numbers)
                      write a token to the anti-clockwise next process
                  end loop
                
    • Note that the seeds used to generate random sequences should be distinct.
    • You may design a method with which all process can be terminated gracefully.
    • For example:
      $ ./a.out 7
      l
       13 17 16 26 49 38 43 20 47 19  1 33
       13 17 16 26 49 38 43 20 47 19 33  1
       47 17 16 26 49 38 43 20 13 19 33  1
       47 17 16 38 49 26 43 20 13 19 33  1
       47 17 26 38 49 16 43 20 13 19 33  1
       47 17 26 38 49 16 43 20  1 19 33 13
       47 17 26 38 49 16 43 20 33 19  1 13
      The six balls: 47 19 26 38 49 16
      p
      It is time to list the random numbers.
      I'am 23012 and my random numbers are  1 and  9
      I'am 23011 and my random numbers are 10 and  8
      I'am 23010 and my random numbers are  8 and 11
      I'am 23009 and my random numbers are  5 and  2
      I'am 23008 and my random numbers are  3 and  5
      I'am 23007 and my random numbers are  0 and  8
      I'am 23006 and my random numbers are 10 and 11
      l
        6 10  4 31 35  9 21 29 20 40 27 19
        6 10  4 31 35 40 21 29 20  9 27 19
       10  6  4 31 35 40 21 29 20  9 27 19
       10  6  4 20 35 40 21 29 31  9 27 19
       10  6  4 20 35 40 29 21 31  9 27 19
       10  6  4  9 35 40 29 21 31 20 27 19
       27  6  4  9 35 40 29 21 31 20 10 19
      The six balls: 27  6  4 10 35 40
      q
      $ 
      
    • Due: 2012/May/17, 23:59
  • exercise 10: practicing signal handling
    • Do the same thing as exercise 9. But now the root process is not special. Each process should handle at least two signals. One is for generating the balls. The other is for showing the random numbers. You may also use a third signal for terminating gacefully.
    • To handle the signals and multiple inputs simultaneously, you may employ the self pipe trick which is explained in Linux Programmers Manual and is shown as follows.
             ......
             designed to prevent.  On systems that  lack  pselect(),  reliable  (and
             more  portable)  signal  trapping  can  be achieved using the self-pipe
             trick (where a signal handler writes a byte to a pipe whose  other  end
             is monitored by select() in the main program.)
                
    • For example:
      $ ./a.out 3
      root pid is 4471                                     $ kill -USR1 4471
       27 37 14 24 45 28 39 38 12 25 43 16
       27 37 14 24 45 25 39 38 12 28 43 16
      The six balls: 27 37 25 24 45 14
      I'am  4471 and random numbers are ...                $ kill -USR2 4471
      I'am  4473 and my random numbers are  2 and  5
      I'am  4472 and my random numbers are  9 and  5
      I'am  4472 and random numbers are ...                $ kill -USR2 4472
      I'am  4471 and my random numbers are  0 and  0
      I'am  4473 and my random numbers are  2 and  5
        4 22 15 32 11  1 38 14 36 29 19 22                 $ kill -USR1 4472
        4 22 15 32 20  1 38 14 36 29 19 11
      The six balls: 4 22 36 32 20 1
      I'am  4472 and random numbers are ...                $ kill -USR2 4472
      I'am  4471 and my random numbers are  8 and  2
      I'am  4473 and my random numbers are 11 and  4
      $                                                    $ kill -INT  4473
      
    • Due: 2012/May/31, 23:59