©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/prcssync.c

Go to the documentation of this file.
00001 /*
00002     Process-synchronization examples
00003     AUP2, Sec. 9.02.3
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 /*[try1]*/
00023 void try1(void)
00024 {
00025     if (fork() == 0) {
00026         printf("child\n");
00027         exit(EXIT_SUCCESS);
00028     }
00029     printf("parent\n");
00030     return;
00031 }
00032 /*[]*/
00033 // SIGUSR1 arriving before handler is installed will kill process
00034 /*[try2]*/
00035 static volatile sig_atomic_t got_sig;
00036 
00037 static void handler(int signum)
00038 {
00039     if (signum == SIGUSR1)
00040         got_sig = 1;
00041 }
00042 
00043 void try2(void)
00044 {
00045     pid_t pid;
00046 
00047     got_sig = 0;
00048     ec_neg1( pid = fork() )
00049     if (pid == 0) {
00050         struct sigaction act;
00051 
00052         memset(&act, 0, sizeof(act));
00053         act.sa_handler = handler;
00054         ec_neg1( sigaction(SIGUSR1, &act, NULL) )
00055         while (got_sig == 0)
00056             if (pause() == -1 && errno != EINTR)
00057                 EC_FAIL
00058         printf("child\n");
00059         exit(EXIT_SUCCESS);
00060     }
00061     printf("parent\n");
00062     ec_neg1( kill(pid, SIGUSR1) )
00063     return;
00064 
00065 EC_CLEANUP_BGN
00066     EC_FLUSH("try2")
00067 EC_CLEANUP_END
00068 }
00069 /*[]*/
00070 // fixed: SIGUSR1 arriving before handler is installed will kill process
00071 // arriving between while and pause will cause it to be lost
00072 /*[try3]*/
00073 void try3(void)
00074 {
00075     sigset_t set;
00076     pid_t pid;
00077 
00078     got_sig = 0;
00079     ec_neg1( sigemptyset(&set) )
00080     ec_neg1( sigaddset(&set, SIGUSR1) )
00081     ec_neg1( sigprocmask(SIG_SETMASK, &set, NULL) )
00082     ec_neg1( pid = fork() )
00083     if (pid == 0) {
00084         struct sigaction act;
00085         sigset_t suspendset;
00086 
00087         memset(&act, 0, sizeof(act));
00088         act.sa_handler = handler;
00089         ec_neg1( sigaction(SIGUSR1, &act, NULL) )
00090         ec_neg1( sigfillset(&suspendset) )
00091         ec_neg1( sigdelset(&suspendset, SIGUSR1) )
00092         ec_neg1( sigprocmask(SIG_SETMASK, &suspendset, NULL) )
00093         while (got_sig == 0)
00094             if (pause() == -1 && errno != EINTR)
00095                 EC_FAIL
00096         printf("child\n");
00097         exit(EXIT_SUCCESS);
00098     }
00099     printf("parent\n");
00100     ec_neg1( kill(pid, SIGUSR1) )
00101     return;
00102 
00103 EC_CLEANUP_BGN
00104     EC_FLUSH("try3")
00105 EC_CLEANUP_END
00106 }
00107 /*[try4]*/
00108 void try4(void)
00109 {
00110     sigset_t set;
00111     pid_t pid;
00112 
00113     got_sig = 0;
00114     ec_neg1( sigemptyset(&set) )
00115     ec_neg1( sigaddset(&set, SIGUSR1) )
00116     ec_neg1( sigprocmask(SIG_SETMASK, &set, NULL) )
00117     ec_neg1( pid = fork() )
00118     if (pid == 0) {
00119         struct sigaction act;
00120         sigset_t suspendset;
00121 
00122         memset(&act, 0, sizeof(act));
00123         act.sa_handler = handler;
00124         ec_neg1( sigaction(SIGUSR1, &act, NULL) )
00125         ec_neg1( sigfillset(&suspendset) )
00126         ec_neg1( sigdelset(&suspendset, SIGUSR1) )
00127         if (sigsuspend(&suspendset) == -1 && errno != EINTR)
00128             EC_FAIL
00129         printf("child\n");
00130         exit(EXIT_SUCCESS);
00131     }
00132     printf("parent\n");
00133     ec_neg1( kill(pid, SIGUSR1) )
00134     return;
00135 
00136 EC_CLEANUP_BGN
00137     EC_FLUSH("try4")
00138 EC_CLEANUP_END
00139 }
00140 
00141 /*
00142     FreeBSD defines sigwait only if the pthread libraries are included,
00143     but then sigaction seems to fail with EINVAL. If you manage to sort
00144     this out, please send email to aup#basepath.com.
00145 */
00146 #ifndef FREEBSD
00147 /*[try5]*/
00148 void try5(void)
00149 {
00150     sigset_t set;
00151     pid_t pid;
00152 
00153     ec_neg1( sigemptyset(&set) )
00154     ec_neg1( sigaddset(&set, SIGUSR1) )
00155     ec_neg1( sigprocmask(SIG_SETMASK, &set, NULL) )
00156     ec_neg1( pid = fork() )
00157     if (pid == 0) {
00158         int signum;
00159 
00160         ec_rv( sigwait(&set, &signum) )
00161         printf("child\n");
00162         exit(EXIT_SUCCESS);
00163     }
00164     printf("parent\n");
00165     ec_neg1( kill(pid, SIGUSR1) )
00166     return;
00167 
00168 EC_CLEANUP_BGN
00169     EC_FLUSH("try5")
00170 EC_CLEANUP_END
00171 }
00172 /*[]*/
00173 #endif /* FREEBSD */
00174 /*
00175     Same thing, but with a pipe.
00176 */
00177 /*[try6]*/
00178 void try6(void)
00179 {
00180     int pfd[2];
00181     pid_t pid;
00182 
00183     ec_neg1( pipe(pfd) )
00184     ec_neg1( pid = fork() )
00185     if (pid == 0) {
00186         char c;
00187 
00188         ec_neg1( close(pfd[1]) )
00189         ec_neg1( read(pfd[0], &c, 1) )
00190         ec_neg1( close(pfd[0]) )
00191         printf("child\n");
00192         exit(EXIT_SUCCESS);
00193     }
00194     printf("parent\n");
00195     ec_neg1( close(pfd[0]) )
00196     ec_neg1( close(pfd[1]) )
00197     return;
00198 
00199 EC_CLEANUP_BGN
00200     EC_FLUSH("try6")
00201 EC_CLEANUP_END
00202 }
00203 /*[]*/
00204 int main(void)
00205 {
00206     try1();
00207     sleep(2);
00208     try2();
00209     sleep(2);
00210     try3();
00211     sleep(2);
00212     try4();
00213     sleep(2);
00214 #ifndef FREEBSD
00215     try5();
00216     sleep(2);
00217 #endif /* FREEBSD */
00218     try6();
00219     sleep(2);
00220     exit(EXIT_SUCCESS);
00221 }

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