abort 函数的功能是使异常终止,此函数将 SIGABRT 信号发送给调用进程,让进程捕捉 SIGABRT 信号目的是在进程终止之前由其执行所需的清理操作。默认情况是终止调用进程。该函数实现如下:
#include <signal.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> void Mabort(void) { sigset_t mask; struct sigaction action; /* * caller can't ignore SIGABRT, if so reset to default. */ sigaction(SIGABRT, NULL, &action); if(action.sa_handler == SIG_IGN) { action.sa_handler = SIG_DFL; sigaction(SIGABRT, &action, NULL); } if(action.sa_handler == SIG_DFL) fflush(NULL); /* * caller can't block SIGABRT; make sure it's unblock */ sigfillset(&mask); sigdelset(&mask, SIGABRT); /* mask has only SIGABRT turned off */ sigprocmask(SIG_SETMASK, &mask, NULL); kill(getpid(), SIGABRT); /* send the signal */ fflush(NULL); /* flush all open stdio stream */ action.sa_handler = SIG_DFL; sigaction(SIGABRT, &action, NULL); /* reset to default */ sigprocmask(SIG_SETMASK, &mask, NULL); /* just in case ... */ kill(getpid(), SIGABRT); /* and one more time */ exit(1); /* this should never be executed ... */ } static void sig_abort(int signo) { printf("Recevied abort ...\n"); } int main(void) { signal(SIGABRT, sig_abort); Mabort(); pause(); exit(0); }输出结果:
Recevied abort ... Aborted (core dumped)
这里和之前介绍的《system函数》有区别,增加了信号处理机制。POSIX.1要求 system 函数忽略 SIGINT 和 SITQUIT 信号,阻塞 SIGCHLD。system 函数实现如下:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <errno.h> #include <signal.h> #include <sys/wait.h> int Msystem(const char*cmdstring) { pid_t pid; int status; struct sigaction ignore,saveintr,savequit; sigset_t chldmask,savemask; if(cmdstring == NULL) return 1; ignore.sa_handler = SIG_IGN; sigemptyset(&ignore.sa_mask); ignore.sa_flags = 0; if(sigaction(SIGINT,&ignore,&savequit)<0) { perror("sigaction() error"); exit(-1); } if(sigaction(SIGQUIT,&ignore,&savequit) <0) { perror("sigaction() error"); exit(-1); } sigemptyset(&chldmask); sigaddset(&chldmask,SIGCHLD); if(sigprocmask(SIG_BLOCK,&chldmask,&savemask) < 0) { perror("sigprocmask() error"); exit(-1); } if((pid = fork()) == -1) { perror("fork() error"); exit(-1); } else if(pid == 0) { sigaction(SIGINT,&saveintr,NULL); sigaction(SIGQUIT,&savequit,NULL); sigprocmask(SIG_SETMASK,&savemask,NULL); execl("/bin/sh","sh","-c",cmdstring,(char *)0); _exit(-127); } else { while(waitpid(pid,&status,0) < 0) { if(errno != EINTR) { status = -1; break; } } } if (sigaction(SIGINT,&saveintr,NULL)<0) return -1; if (sigaction(SIGQUIT,&saveintr,NULL)<0) return -1; if (sigprocmask(SIG_SETMASK,&savemask,NULL)<0) return -1; return (status); } int main() { printf("Print date:\n"); Msystem("date"); printf("Print process:\n"); Msystem("ps"); exit(0); }输出结果:
Print date: Sun Nov 9 21:45:37 CST 2014 Print process: PID TTY TIME CMD 15133 pts/3 00:00:00 bash 16236 pts/3 00:00:00 sigsuspend 17750 pts/3 00:00:00 system 17752 pts/3 00:00:00 ps
此函数使调用进程被挂起,直到满足下列条件之一:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <errno.h> #include <signal.h> static void sig_alrm(int signo) { printf("Recevied alarm ... \n"); } unsigned int Msleep(unsigned int nsecs) { struct sigaction newact,oldact; sigset_t newmask,oldmask,suspmask; unsigned int unslept; newact.sa_handler = sig_alrm; sigemptyset(&newact.sa_mask); newact.sa_flags = 0; sigaction(SIGALRM,&newact,&oldact); sigemptyset(&newmask); sigaddset(&newmask,SIGALRM); sigprocmask(SIG_BLOCK,&newmask,&oldmask); alarm(nsecs); suspmask = oldmask; sigdelset(&suspmask,SIGALRM); sigsuspend(&suspmask); unslept = alarm(0); sigprocmask(SIG_SETMASK,&oldmask,NULL); return unslept; } int main() { int i; printf("Program starting.\n"); printf("sleep 5 seconds.....\n"); for(i=1;i<=5;++i) { printf("The %dth second.\n",i); Msleep(1); } printf("wake up.\n"); exit(0); }输出结果:
Program starting. sleep 5 seconds..... The 1th second. Recevied alarm ... The 2th second. Recevied alarm ... The 3th second. Recevied alarm ... The 4th second. Recevied alarm ... The 5th second. Recevied alarm ... wake up.
《UNIX高级环境编程》