《unix高级环境编程》信号——abort、system和sleep函数

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函数

        此函数使调用进程被挂起,直到满足下列条件之一:

  1. 已经过 seconds 所指定的墙上时钟时间;
  2. 调用进程捕捉到一个信号并从信号处理程序返回。
sleep 函数的实现如下:

#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高级环境编程》

你可能感兴趣的:(信号,system函数,Sleep函数,abort函数)