下面代碼第一版的文件,第二版的文件在 lib/tellwait.c中,不用再單獨下載。
默認是以信號量方式實現,但在Freebsd 9下面運行效果並不理想。參考資料2中有按管道方式實現。將 "ourhdr.h" 修改爲 "apue.h"。
FreeBSD 下
命令獲取
fetch http://www.yendor.com/programming/unix/apue/lib.44/tellwait.c
tellwait.c
#include <signal.h>
#include "apue.h"
static volatile sig_atomic_t sigflag;
/* set nonzero by signal handler */
static sigset_t newmask, oldmask, zeromask;
static void
sig_usr(int signo) /* one signal handler for SIGUSR1 and SIGUSR2 */
{
sigflag = 1;
return;
}
void
TELL_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");
}
void
TELL_PARENT(pid_t pid)
{
kill(pid, SIGUSR2); /* tell parent we're done */
}
void
WAIT_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");
}
void
TELL_CHILD(pid_t pid)
{
kill(pid, SIGUSR1); /* tell child we're done */
}
void
WAIT_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");
}
SVR4 和SunOS下
命令獲取命令
fetch http://www.yendor.com/programming/unix/apue/lib.svr4/tellwait.c
tellwait.c
#include <signal.h>
#include "apue.h"
static volatile sig_atomic_t sigflag;
/* set nonzero by signal handler */
static sigset_t newmask, oldmask, zeromask;
static void
sig_usr(int signo) /* one signal handler for SIGUSR1 and SIGUSR2 */
{
sigflag = 1;
return;
}
void
TELL_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");
}
void
TELL_PARENT(pid_t pid)
{
kill(pid, SIGUSR2); /* tell parent we're done */
}
void
WAIT_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");
}
void
TELL_CHILD(pid_t pid)
{
kill(pid, SIGUSR1); /* tell child we're done */
}
void
WAIT_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");
}
將下載後的tellwait.c(或者apue源文件包中的 /lib/tellwait.c)拷貝至/usr/include,然後在源文件中將tellwait.c包含即可編譯。
#include "tellwait.c"
參考資料:
[1]Chapter 8 Process Control.http://www.yendor.com/programming/unix/apue/ch8.html
[2]APUE 中的TELL函數.http://blog.csdn.net/born1985man/article/details/4635778
[3]《UNIX環境高級編程》程序清單8-7編譯錯誤:TELL_WAIT, WAIT_PARENT, TELL_CHILD未定義.http://blog.csdn.net/fushaobing2010/article/details/6160204