Unix Processes (Cont.) Today's Topics

Unix Processes (Cont.) Today's Topics

CS 3411 Systems Programming Department of Computer Science Michigan Technological University Unix Processes (cont.) Today's Topics I More about execve I Debugging fork() I A forked child inherits open les of the parent I The child process descriptor is a copy of the parent's process descriptor, except: I Return value from fork() I PID, PPID I Pending signals and alarms I File locks I Execution times Executing a New Binary I execve() is used to execute a new program I Manual page! I This function executes the program it is pointed to I On success, execve() does not return: The process calling execve() is completely replaced by the newly executed process I On error, -1 is returned I File descriptors may be set to close on exec! Creating a New Process I Exec is most useful when used with fork I In Unix, a new process is created by rst forking an existing process, then calling a variant of exec from there I Most process attributes are preserved, including the PID, PPID, le locks, pending signals, execution times and open les execve() Example #i n c l u d e <s t d i o . h> #i n c l u d e <e r r n o . h> #i n c l u d e < s t d l i b . h> main ( ) { char ∗a [ 4 ] , ∗ e [ 3 ] ; a[0] = "child"; a[1] = "argument1"; a[2] = "argument2"; a [ 3 ] = NULL ; e[0] = "ENV0=val0"; e[1] = "ENV1=val1"; e [ 2 ] = NULL ; execve("child1", a, e); /∗ If we get here, something went wrong ∗/ perror("parent1"); e x i t ( 1 ) ; } execve() Example #i n c l u d e <s t d i o . h> main(argc, argv, envp) i n t a r g c ; char ∗ a r g v [ ] , ∗ envp [ ] ; { i n t i ; char ∗∗ ep ; printf("child is running\n"); f o r (i = 0; i < argc; i++) { printf("argv[%d]=%s\n",i ,argv[ i ]); } f o r ( ep = envp ; ∗ ep ; ep++) { printf ("%s\n", ∗ ep ) ; } } More Examples #i n c l u d e < f c n t l . h> #i n c l u d e <s t d i o . h> #i n c l u d e <u n i s t d . h> #i n c l u d e < s t d l i b . h> main(argc , argv) i n t a r g c ; char ∗ a r g v [ ] ; { i n t forkid , charnum; char f d v a l [ 2 0 ] ; i f ( a r g c != 3) { fprintf (stderr ,"Usage: pexec filename charnum\n"); e x i t ( 1 ) ; } i f ((forkid = open(argv[1], O_RDONLY)) < 0 ) { fprintf(stderr , "Cannot open %s\n", argv[1]); e x i t ( 2 ) ; } sprintf(fdval , "%d", forkid); /∗ s p r i n t f ! ∗/ i f (fork() == 0) { execl("pchild", "pchild", fdval , argv[2], ( char ∗ ) 0 ) ; fprintf(stderr , "Unable to exec\n"); e x i t ( 3 ) ; } printf("Parent is after fork/exec\n"); } More Examples #i n c l u d e <sys/types .h> #i n c l u d e <u n i s t d . h> #i n c l u d e <s t d i o . h> #i n c l u d e < s t d l i b . h> main(argc , argv) i n t a r g c ; char ∗ a r g v [ ] ; { i n t myfd ; char gotch , v a l ; i f ( a r g c != 3) { fprintf(stderr ,"Usage: pchild filename charnum\n"); e x i t ( 1 ) ; } myfd = atoi(argv[1]); gotch = atoi(argv[2]); lseek(myfd, (off_t)gotch , SEEK_SET); read(myfd, &val , 1); printf("Child got char %d from fd %d: %c\n", gotch , myfd, val ); } More Examples #i n c l u d e < f c n t l . h> #i n c l u d e <s t d i o . h> #i n c l u d e <u n i s t d . h> #i n c l u d e < s t d l i b . h> main(argc , argv) i n t a r g c ; char ∗ a r g v [ ] ; { i n t forkid , charnum; i f ( a r g c != 3) { fprintf (stderr ,"Usage: pioexec filename charnum\n"); e x i t ( 1 ) ; } i f ((forkid = open(argv[1], O_RDONLY)) < 0 ) { fprintf(stderr , "Cannot open %s\n", argv[1]); e x i t ( 2 ) ; } i f (fork() == 0) { close(0); dup(forkid); close(forkid); execl("piochild", "piochild", argv[2], ( char ∗ ) 0 ) ; fprintf(stderr , "Unable to exec\n"); e x i t ( 3 ) ; } printf("Parent is after fork/exec\n"); } More Examples #i n c l u d e <sys/types .h> #i n c l u d e <u n i s t d . h> #i n c l u d e <s t d i o . h> #i n c l u d e < s t d l i b . h> main(argc , argv) i n t a r g c ; char ∗ a r g v [ ] ; { i n t myfd ; char gotch , v a l ; i f ( a r g c != 2) { fprintf(stderr ,"Usage: piokid charnum\n"); e x i t ( 1 ) ; } gotch = atoi(argv[1]); lseek(0, (off_t)gotch , SEEK_SET); read(0, &val, 1); printf("Child got char %d from stdin : %c\n", gotch , val ); } File Descriptor Example #i n c l u d e <sys/types .h> #i n c l u d e <u n i s t d . h> #i n c l u d e <sys/stat .h> #i n c l u d e < f c n t l . h> main ( ) { pid_t c p i d ; i n t x , f d ; char ch ; x = 5 ; cpid = fork(); i f ( c p i d == 0) { fd = open("aFile", O_RDWR|O_CREAT, 0644); x++; ch=x +48; write(fd,&ch,1); } e l s e { fd = open("aFile", O_RDWR|O_CREAT, 0644); x++; ch=x +48; write(fd,&ch,1); } } More Examples How would we need to code to get the following process structure: I Parent I Child 1 I Child 2 More Examples How would we need to code to get the following process structure: I Parent I Child 1 I Child 2 More Examples How would we need to code to get the following process structure: I Parent I Child 1 I Child 2 Exec Example #i n c l u d e <sys/types .h> #i n c l u d e <u n i s t d . h> main ( ) { pid_t c p i d ; i n t i ; f o r (i = 0; i < 2; i++){ cpid=fork (); i f (cpid==0) execl("bogus", "bogus", ( char ∗ ) 0 ) ; } } Exec Example #i n c l u d e <sys/types .h> #i n c l u d e <u n i s t d . h> main ( ) { pid_t c p i d ; i n t i ; f o r (i = 0; i < 2; i++){ cpid=fork (); i f ( c p i d ==0) { execl("bogus", "bogus", ( char ∗ ) 0 ) ; e x i t ( 1 ) ; } } } Parent/Child Synchronization (wait/exit) I The exit() and _exit() calls I As usual, take a look at the manual page. I Terminates the calling process immediately I As a convention: exit status of 0 is normal termination I Any other status denotes an error or an exceptional condition on termination wait() call I The wait() call I The manual! I A parent process is obligated to wait for its children to exit I Suspends execution of the current process until a child has exited No Waiting #i n c l u d e <u n i s t d . h> #i n c l u d e < s t d l i b . h> main ( ) { i f (fork() == 0) { e x i t ( 1 ) ; } e l s e { s l e e p ( 2 0 ) ; e x i t ( 1 ) ; } } With Waiting #i n c l u d e <u n i s t d . h> #i n c l u d e < s t d l i b . h> #i n c l u d e <s t d i o . h> #i n c l u d e <sys/types .h> #i n c l u d e <sys/wait .h> main ( ) { i n t s t a t u s ; i f (fork() == 0) { s l e e p ( 2 0 ) ; e x i t ( 5 1 ) ; } e l s e { printf("pid = %d\n", wait(&status )); printf("status = %x\n", status ); i f (WIFEXITED( status )) printf ("Status (via macro): %d\n", WEXITSTATUS(status )); e x i t ( 0 ) ; } } Debugging I We'll focus on gcc and gdb I We'll also take a look at ddd, which is a GUI for gdb and various other debuggers I What is debugging? I Program state is a snapshot of all variables, PC, etc. I A statement in your program transforms one program state into another I You should be able (at some level) to express what you expect the state of your program to be after every statement I Often state predicates on program state; i.e., if control is here, I expect the following to be true. I Let's look at a toy example Sample Program #i n c l u d e <s t d i o . h> i n t sum=0, val , num=0; double ave ; /∗ sum and num should be 0 ∗/ main ( ) { /∗ sum should be the total of the num input values processed ∗/ w h i l e (scanf("%d\n",&val) != EOF) { sum += v a l ; num++; } /∗ sum should be the total of the num input values and there is no more input ∗/ i f (num > 0) { ave= sum/num; /∗ ave should be the floating point mean of the num input data values ∗/ printf("Average is %f\n", ave); } } Using gdb I Make sure to compile source with the -g switch asserted.

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    27 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us