Examples&Exercises:

  1. Using fork and exec Together,http://siber.cankaya.edu.tr/SystemsProgramming/cfiles/fork-exec.cfork-exec.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <unistd.h>
    /* Spawn a child process running a new program.  PROGRAM is the name
       of the program to run; the path will be searched for this program.
       ARG_LIST is a NULL-terminated list of character strings to be
       passed as the program's argument list.  Returns the process id of
       the spawned process.  */
    int spawn (char* program, char** arg_list)
    {
      pid_t child_pid;
      /* Duplicate this process.  */
      child_pid = fork ();
      if (child_pid != 0)
        /* This is the parent process.  */
        return child_pid;
      else {
        /* Now execute PROGRAM, searching for it in the path.  */
        execvp (program, arg_list);
        /* The execvp function returns only if an error occurs.  */
        fprintf (stderr, "an error occurred in execvp\n");
        abort ();
      }
    }
    int main ()
    {
      /* The argument list to pass to the "ls" command.  */
      char* arg_list[] = {
        "ls",     /* argv[0], the name of the program.  */
        "-l", 
        "/",
        NULL      /* The argument list must end with a NULL.  */
      };
      /* Spawn a child process running the "ls" command.  Ignore the
         returned child process id.  */
      spawn ("ls", arg_list); 
      printf ("done with main program\n");
      return 0;
    }
    
  2. Using a Signal Handler; complete the following program http://siber.cankaya.edu.tr/SystemsProgramming/cfiles/sigusr1.ctsigusr1.c
    #include <signal.h>
    #include <stdio.h>
    #include <string.h>
    #include <sys/types.h>
    #include <unistd.h>
    
    sig_atomic_t sigusr1_count = 0;
    
    void handler (int signal_number)
    {
      ++sigusr1_count;
    }
    
    int main ()
    {
      struct sigaction sa;
      memset (&sa, 0, sizeof (sa));
      sa.sa_handler = &handler;
      sigaction (SIGUSR1, &sa, NULL);
    
      /* Do some lengthy stuff here.  */
      /* ...  */
    
      printf ("SIGUSR1 was raised %d times\n", sigusr1_count);
      return 0;
    }
    
  3. The wait System Calls; complete the following program http://siber.cankaya.edu.tr/SystemsProgramming/cfiles/wait1.cwait1.c
    int main ()
    {
      int child_status;
      /* The argument list to pass to the "ls" command. */
      char* arg_list[] = {
        "ls", /* argv[0], the name of the program. */
        "-l",
        "/",
        NULL /* The argument list must end with a NULL. */
      };
      /* Spawn a child process running the "ls" command. Ignore the
         returned child process ID. */
      spawn ("ls", arg_list);
      /* Wait for the child process to complete. */
      wait (&child_status);
      if (WIFEXITED (child_status))
        printf ("the child process exited normally, with exit code %d\n",
                WEXITSTATUS (child_status));
      else
        printf ("the child process exited abnormally\n");
      return 0;
    }
    
  4. Making a Zombie Process, http://siber.cankaya.edu.tr/SystemsProgramming/cfiles/zombie.czombie.c
    #include <stdlib.h>
    #include <sys/types.h>
    #include <unistd.h>
    
    int main ()
    {
      pid_t child_pid;
    
      /* Create a child process.  */
      child_pid = fork ();
      if (child_pid > 0) {
        /* This is the parent process.  Sleep for a minute.  */
        sleep (60);
      }
      else {
        /* This is the child process.  Exit immediately.  */
        exit (0);
      }
      return 0;
    }
    
  5. Cleaning Up Children Asynchronously; complete the following program http://siber.cankaya.edu.tr/SystemsProgramming/cfiles/cleaning.ccleaning.c
    #include <signal.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    
    sig_atomic_t child_exit_status;
    
    void clean_up_child_process (int signal_number)
    {
      /* Clean up the child process.  */
      int status;
      wait (&status);
      /* Store its exit status in a global variable.  */
      child_exit_status = status;
    }
    
    int main ()
    {
      /* Handle SIGCHLD by calling clean_up_child_process.  */
      struct sigaction sigchld_action;
      memset (&sigchld_action, 0, sizeof (sigchld_action));
      sigchld_action.sa_handler = &clean_up_child_process;
      sigaction (SIGCHLD, &sigchld_action, NULL);
    
      /* Now do things, including forking a child process.  */
      /* ...  */
    
      return 0;
    }
    
  6. The child_demo1.c Program, http://siber.cankaya.edu.tr/SystemsProgramming/cfiles/child_demo1.cchild_demo1.c http://siber.cankaya.edu.tr/SystemsProgramming/cfiles/child.cchild.c, http://siber.cankaya.edu.tr/SystemsProgramming/cfiles/child.hchild.h
  7. Rewrite the Makefile so that all the C-codes for today's lab can be compiled.
2006-03-20