abort函数
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函数
这里和之前介绍的《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
sleep函数
此函数使调用进程被挂起,直到满足下列条件之一:
- 已经过 seconds 所指定的墙上时钟时间;
- 调用进程捕捉到一个信号并从信号处理程序返回。
- #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.