The following code uses the first version of the file. The second version of the file is in lib/tellwait. C and does not need to be downloaded separately.
By default, it is implemented by means of semaphores, but the Running Effect in FreeBSD 9 is not ideal. See section 2 for pipeline-based implementation. Change "ourhdr. H" to "apue. H ".
Under FreeBSD
Command to obtain
fetch http://www.yendor.com/programming/unix/apue/lib.44/tellwait.c
Tellwait. c
#include<signal.h>#include"apue.h"static volatile sig_atomic_tsigflag;/* set nonzero by signal handler */static sigset_tnewmask, oldmask, zeromask;static voidsig_usr(int signo)/* one signal handler for SIGUSR1 and SIGUSR2 */{sigflag = 1;return;}voidTELL_WAIT(){if (signal(SIGUSR1, sig_usr) == SIG_ERR)err_sys("signal(SIGINT) error");if (signal(SIGUSR2, sig_usr) == SIG_ERR)err_sys("signal(SIGQUIT) error");sigemptyset(&zeromask);sigemptyset(&newmask);sigaddset(&newmask, SIGUSR1);sigaddset(&newmask, SIGUSR2);/* block SIGUSR1 and SIGUSR2, and save current signal mask */if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)err_sys("SIG_BLOCK error");}voidTELL_PARENT(pid_t pid){kill(pid, SIGUSR2);/* tell parent we're done */}voidWAIT_PARENT(void){while (sigflag == 0)sigsuspend(&zeromask);/* and wait for parent */sigflag = 0;/* reset signal mask to original value */if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)err_sys("SIG_SETMASK error");}voidTELL_CHILD(pid_t pid){kill(pid, SIGUSR1);/* tell child we're done */}voidWAIT_CHILD(void){while (sigflag == 0)sigsuspend(&zeromask);/* and wait for child */sigflag = 0;/* reset signal mask to original value */if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)err_sys("SIG_SETMASK error");}
Under svr4 and SunOS
Command to obtain the command
fetch http://www.yendor.com/programming/unix/apue/lib.svr4/tellwait.c
Tellwait. c
#include<signal.h>#include"apue.h"static volatile sig_atomic_tsigflag;/* set nonzero by signal handler */static sigset_tnewmask, oldmask, zeromask;static voidsig_usr(int signo)/* one signal handler for SIGUSR1 and SIGUSR2 */{sigflag = 1;return;}voidTELL_WAIT(){if (signal(SIGUSR1, sig_usr) == SIG_ERR)err_sys("signal(SIGINT) error");if (signal(SIGUSR2, sig_usr) == SIG_ERR)err_sys("signal(SIGQUIT) error");sigemptyset(&zeromask);sigemptyset(&newmask);sigaddset(&newmask, SIGUSR1);sigaddset(&newmask, SIGUSR2);/* block SIGUSR1 and SIGUSR2, and save current signal mask */if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)err_sys("SIG_BLOCK error");}voidTELL_PARENT(pid_t pid){kill(pid, SIGUSR2);/* tell parent we're done */}voidWAIT_PARENT(void){while (sigflag == 0)sigsuspend(&zeromask);/* and wait for parent */sigflag = 0;/* reset signal mask to original value */if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)err_sys("SIG_SETMASK error");}voidTELL_CHILD(pid_t pid){kill(pid, SIGUSR1);/* tell child we're done */}voidWAIT_CHILD(void){while (sigflag == 0)sigsuspend(&zeromask);/* and wait for child */sigflag = 0;/* reset signal mask to original value */if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)err_sys("SIG_SETMASK error");}
Copy the downloaded tellwait. C (or/lib/tellwait. c In the apue source file package) to/usr/include, and then include tellwait. c In the source file to compile.
#include "tellwait.c"
References:
[1] Chapter 8 process control. http://www.yendor.com/programming/unix/apue/ch8.html
[2] Tell function in apue. http://blog.csdn.net/born1985man/article/details/4635778
[3] The Unix environment advanced programming program list 8-7 Compilation error: tell_wait, wait_parent, tell_child undefined. http://blog.csdn.net/fushaobing2010/article/details/6160204