#include <stdio.h> // for printf(), fprintf(), stderr, NULL
#include <stdlib.h> // for abort()
#include <sys/types.h> // for pid_t
#include <unistd.h> // for fork(), execvp(), sleep()
#include <signal.h> // for kill(), SIGTERM
// signal.h includes bits/signum.h, which includes
// bits/signum-generic.h, which defines SIGTERM:
// /usr/include/x86_64-linux-gnu/bits/signum-generic.h:
// #define SIGTERM 15 /* Termination request. */
int spawn (char * program, char ** arg_list);
// Spawn a child process running a new program
int main()
{
pid_t childid;
/* The argument list to pass to the `ls' command: */
char * arg_list[] =
{
"ls", /* argv[0], the name of the program */
"-l", // long listing
// "/", // root directory
NULL /* The argument list must end with a NULL */
};
/* Spawn a child process running the "ls" command: */
childid = spawn ("ls", arg_list);
printf ("SIGTERM = %d\n", SIGTERM);
printf ("Done with main program\n");
sleep(1); // wait for child to finish
kill (childid, SIGTERM);
return 0;
}
int spawn (char * program, char ** arg_list)
{
pid_t child_pid;
child_pid = fork(); /* Duplicate this process */
if (child_pid != 0) /* This is the parent process. */
{return child_pid;} // the returned value is ignored in main()
else // child process
{ /* 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(); // end program
}
}
/*
gcc fork-exec.c -o fork-exec
./fork-exec
SIGTERM = 15
Done with main program
total 24
-rwxrwxr-x 1 user user 17128 Sep 16 08:17 fork-exec
-rw-rw-r-- 1 user user 1764 Sep 16 08:17 fork-exec.c
*/
*********************************************************************************
*********************************************************************************
*********************************************************************************
*********************************************************************************
*********************************************************************************
#include <stdio.h> // for printf(), fprintf(), stderr, NULL
#include <stdlib.h> // for abort(), WIFEXITED(), WEXITSTATUS()
#include <sys/types.h> // for pid_t
#include <unistd.h> // for fork(), execvp()
#include <wait.h> // wait.h includes sys/wait.h,
// full path /usr/include/x86_64-linux-gnu/sys/wait.h,
// which defines wait(), WIFEXITED(), WEXITSTATUS()
int spawn (char * program, char ** arg_list);
// Spawn a child process running a new program
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", // long listing
// "/", // root directory
NULL /* The argument list must end with a NULL */
};
/* Spawn a child process running the "ls" command: */
spawn ("ls", arg_list); // ignore child ID return value
printf ("Done with main program\n");
/* Wait for the child process to complete: */
wait (&child_status); // wait() exits when any child finishes
if (WIFEXITED (child_status))
{
printf ("Child process exited normally, with exit code %d\n",
WEXITSTATUS (child_status));
}
else {printf ("The child process exited abnormally\n");}
return 0;
}
int spawn (char * program, char ** arg_list)
{
pid_t child_pid;
child_pid = fork(); /* Duplicate this process */
if (child_pid != 0) /* This is the parent process. */
{return child_pid;} // the returned value is ignored in main()
else // child process
{ /* 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(); // end program
}
}
/*
gcc fork-exec.c -o fork-exec
./fork-exec
Done with main program
total 24
-rwxrwxr-x 1 user user 17088 Sep 16 09:07 fork-exec
-rw-rw-r-- 1 user user 1728 Sep 16 09:07 fork-exec.c
Child process exited normally, with exit code 0
*/
*********************************************************************************
*********************************************************************************
*********************************************************************************
*********************************************************************************
*********************************************************************************
#include <stdlib.h> // for exit()
#include <sys/types.h> // for pid_t
#include <unistd.h> // for fork(), sleep()
int main()
{
pid_t child_pid;
child_pid = fork (); /* Create a child process */
if (child_pid > 0) // parent
{sleep (60);} // 60 seconds
else // child
{exit (0);} // Exit immediately
return 0; // parent returns after 1 minute
}
/*
gcc zombie.c -o zombie
./zombie & // run in background
[1] 50064
ps -e -o pid,ppid,stat,cmd
PID PPID STAT CMD
1 0 Ss /sbin/init splash
......................
50037 1 Sl qterminal
50040 50037 Ss /bin/bash
50064 50040 S ./zombie
50065 50064 Z [zombie] <defunct>
50066 50040 R+ ps -e -o pid,ppid,stat,cmd
// after 1 minute:
ps -e -o pid,ppid,stat,cmd
......................
50368 50040 R+ ps -e -o pid,ppid,stat,cmd
[1]+ Done ./zombie
ps -e -o pid,ppid,stat,cmd
......................
50420 50040 R+ ps -e -o pid,ppid,stat,cmd
*/
*********************************************************************************
*********************************************************************************
*********************************************************************************
*********************************************************************************
*********************************************************************************
#include <stdio.h> // for printf(), NULL
#include <stdlib.h> // for exit()
#include <signal.h> // for sigaction()
// signal.h includes bits/types/sig_atomic_t.h, which defines sig_atomic_t
// signal.h includes bits/sigaction.h, which defines struct sigaction
// signal.h includes bits/signum.h, which defines SIGCHLD:
// /usr/include/x86_64-linux-gnu/bits/signum.h:
// #define SIGCHLD 17
#include <string.h> // for memset()
#include <sys/types.h> // for pid_t
#include <sys/wait.h> // for wait()
#include <unistd.h> // for fork(), sleep()
sig_atomic_t child_exit_status;
void clean_up_child_process (int signal_number)
{
int status;
wait (&status);
/* Store its exit status in a global variable: */
child_exit_status = status;
printf("Signal number: %d\n", signal_number);
}
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);
printf("SIGCHLD = %d\n", SIGCHLD);
int awake;
pid_t childid;
childid = fork(); // fork a child process
if (childid > 0) // parent process
{
printf("Child pid: %d\n", childid);
awake = sleep(10); // wait for child to finish,
printf("Awake: %d\n", awake); // sleep interrupted by signal
printf("Child exit status: %d\n", child_exit_status);
}
else // child process
{exit(0);} // exit immediately
return 0; // parent process
}
/*
gcc sigchld.c -o sigchld
./sigchld
SIGCHLD = 17
Child pid: 60301
Signal number: 17
Awake: 9
Child exit status: 0
*/