©2004 by Marc J. Rochkind. All rights reserved. Portions marked "Open Source" may be copied under license.

 

Main Page   Modules   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

c9/sigminthr.c

Go to the documentation of this file.
00001 /*
00002     Minimal defensive signal handling using sigwait (bad example)
00003     AUP2, Sec. 9.02.2
00004 
00005     Copyright 2003 by Marc J. Rochkind. All rights reserved.
00006     May be copied only for purposes and under conditions described
00007     on the Web page www.basepath.com/aup/copyright.htm.
00008 
00009     The Example Files are provided "as is," without any warranty;
00010     without even the implied warranty of merchantability or fitness
00011     for a particular purpose. The author and his publisher are not
00012     responsible for any damages, direct or incidental, resulting
00013     from the use or non-use of these Example Files.
00014 
00015     The Example Files may contain defects, and some contain deliberate
00016     coding mistakes that were included for educational reasons.
00017     You are responsible for determining if and how the Example Files
00018     are to be used.
00019 
00020 */
00021 #include "defs.h"
00022 #include <pthread.h>
00023 
00024 /*[clean_up]*/
00025 static void clean_up(void)
00026 {
00027     /*
00028         Clean-up code goes here --
00029         need not be async-signal-safe.
00030     */
00031 }
00032 /*[]*/
00033 // redition of earlier example, but not necessarily what you want in a
00034 // multithreaded program
00035 /*[sig_thread]*/
00036 static void *sig_thread(void *arg)
00037 {
00038     int signum;
00039     int i;
00040     struct {
00041         int signum;
00042         char *msg;
00043     } sigmsg[] = {
00044         { SIGTERM, "Termination signal" },
00045         { SIGBUS, "Access to undefined portion of a memory object" },
00046         { SIGFPE, "Erroneous arithmetic operation" },
00047         { SIGILL, "Illegal instruction" },
00048         { SIGSEGV, "Invalid memory reference" },
00049         { SIGSYS, "Bad system call" },
00050         { SIGXCPU, "CPU-time limit exceeded" },
00051         { SIGXFSZ, "File-size limit exceeded" },
00052         { 0, NULL}
00053     };
00054 
00055     {
00056         int x = 1, y;
00057 
00058 printf("about to divide by zero\n");
00059         y = x / 0;
00060     }
00061 printf("still alive\n");
00062     while (true) {
00063         ec_rv( sigwait((sigset_t *)arg, &signum) )
00064         clean_up();
00065         for (i = 0; sigmsg[i].signum > 0; i++)
00066             if (sigmsg[i].signum == signum) {
00067                 fprintf(stderr, "%s\n", sigmsg[i].msg);
00068                 break;
00069             }
00070         _exit(EXIT_FAILURE);
00071     }
00072     return (void *)true; /* never get here */
00073 
00074 EC_CLEANUP_BGN
00075     EC_FLUSH("sig_thread")
00076     return (void *)false;
00077 EC_CLEANUP_END
00078 }
00079 /*[handler]*/
00080 static void handler(int signum)
00081 {
00082     printf("got %d in handler\n", signum);
00083 }
00084 /*[handle_signals]*/
00085 static bool handle_signals(void)
00086 {
00087     sigset_t *set;
00088     struct sigaction act;
00089     pthread_t tid;
00090 
00091     ec_null( set = malloc(sizeof(*set)) )
00092     ec_neg1( sigfillset(set) )
00093     ec_rv( pthread_sigmask(SIG_SETMASK, set, NULL) )
00094     memset(&act, 0, sizeof(act));
00095     act.sa_handler = SIG_IGN;
00096     ec_neg1( sigaction(SIGHUP, &act, NULL) )
00097     ec_neg1( sigaction(SIGINT, &act, NULL) )
00098     ec_neg1( sigaction(SIGQUIT, &act, NULL) )
00099     ec_neg1( sigaction(SIGPIPE, &act, NULL) )
00100     ec_neg1( sigemptyset(set) )
00101     ec_neg1( sigaddset(set, SIGTERM) )
00102     ec_neg1( sigaddset(set, SIGBUS) )
00103     ec_neg1( sigaddset(set, SIGFPE) )
00104     ec_neg1( sigaddset(set, SIGILL) )
00105     ec_neg1( sigaddset(set, SIGSEGV) )
00106     ec_neg1( sigaddset(set, SIGSYS) )
00107     ec_neg1( sigaddset(set, SIGXCPU) )
00108     ec_neg1( sigaddset(set, SIGXFSZ) )
00109     ec_rv( pthread_sigmask(SIG_SETMASK, set, NULL) )
00110     ec_rv( pthread_create(&tid, NULL, sig_thread, set) )
00111     return true;
00112 
00113 EC_CLEANUP_BGN
00114     return false;
00115 EC_CLEANUP_END
00116 }
00117 /*[]*/
00118 void process(void)
00119 {
00120     ec_false (handle_signals() )
00121     sleep(2);
00122     {
00123         int x = 1, y;
00124 
00125         //y = x / 0;
00126     }
00127     exit(EXIT_SUCCESS);
00128 
00129 EC_CLEANUP_BGN
00130     exit(EXIT_FAILURE);
00131 EC_CLEANUP_END
00132 }
00133 
00134 #define MAX_SIG 50
00135 
00136 int main(void)
00137 {
00138     int signum;
00139     pid_t pid[MAX_SIG + 1];
00140     int status;
00141 
00142     for (signum = 1; signum <= MAX_SIG; signum++) {
00143         ec_neg1( pid[signum] = fork() )
00144         if (pid[signum] == 0)
00145             process();
00146         sleep(1);
00147         printf("\nSending signal %d...\n", signum);
00148         //if (kill(pid[signum], signum) == -1)
00149         //  printf("\tkill failed\n");
00150         ec_neg1( waitpid(-1, &status, WUNTRACED) )
00151         if (WIFEXITED(status))
00152             printf("%ld exited normally\n", (long)pid[signum]);
00153         else if (WIFSIGNALED(status))
00154             printf("%ld exited with signal %d\n", (long)pid[signum],
00155               WTERMSIG(status));
00156         else
00157             printf("wait returned with other status\n");
00158     }
00159     for (signum = 1; signum <= MAX_SIG; signum++)
00160         (void)kill(pid[signum], SIGKILL);
00161     exit(EXIT_SUCCESS);
00162 
00163 EC_CLEANUP_BGN
00164     exit(EXIT_FAILURE);
00165 EC_CLEANUP_END
00166 }
00167 /*[]*/

Generated on Fri Apr 23 10:57:03 2004 for AUP2 Example Source by doxygen 1.3.1