APUE函数笔记八: 信号

原创 2012年03月28日 21:01:09

第十章  信号:

0 < signo < NSIG

#include <signal.h>
void (*signal(int signo, void(*func)(int)))(int);
    if error return SIG_ERR, else return previous handler

#include <signal.h>
int kill(pid_t pid, int signo);
    pid:
         == -1, send to any process
         > 0,   send to the process which process-id == pid
         == 0,  send to any process 
                        which pgid == this-pgid
         < -1,  send to any process which pgid == abs(pid)
    this process need have privilege to send to receiver
    otherwise will not send
    particular: if signo == SIGCONT, will send to any process
                    which sid == this-sid
    if signo is 0, not real to send, but check the receiver is alive or not?
        if receiver is not exist, return -1, error is ESRCH
    if success return 0, else return -1
int raise(int signo);
    same as kill(getpid(), signo)
    if success return 0, else return -1

#include <unistd.h>
unsigned int alarm(unsigned int seconds);
    return 0 or rest seconds of last alarm

#include <unistd.h>
int pause(void);
    only catch a signal and handler it, will return
    always return -1, errno is EINTR

#include <signal.h>
int sigemptyset(sigset_t * set);
    if success return 0, else return -1
int sigfillset(sigset_t * set);
    if success return 0, else return -1
int sigaddset(sigset_t * set, int signo);
    if success return 0, else return -1
int sigdelset(sigset_t * set, int signo);
    if success return 0, else return -1
int sigismember(const sigset_t * set, int signo);
    ret: 1 means true, 0 means false, -1 means error

#include <signal.h>
int sigprocmask(int how, const sigset_t * restrict set, 
                sigset_t * restrict oset);
    how: SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK    
    if success return 0, else return -1

#include <signal.h>
int sigpending(sigset_t * set);
    if success return 0, else return -1

#include <signal.h>
int sigaction(int signo, const struct sigaction * restrict act,
              struct sigaction * restrict oact);
    if success return 0, else return -1
    struct sigaction {
        void       (*sa_handler)(int);
        sigset_t     sa_mask;
        int          sa_flags;
        void       (*sa_sigaction)(int, siginfo_t *, void *);
    };
    sa_flags:
              SA_INTERRUPT, SA_NOCLDSTOP, SA_NOCLDWAIT, SA_NODEFER
              SA_ONSTACK,   SA_RESETHAND, SA_RESTART,   SA_SIGINFO

#include <setjmp.h>
int sigsetjmp(sigjmp_buf env, int savemask);
    savemask: 0, not save mask to env; not 0, save mask to env
    if callback by siglongjmp return non-zero, else return 0
void siglongjmp(sigjmp_buf env, int val);

#include <signal.h>
int sigsuspend(const sigset_t * sigmask);
    always return -1, errno is EINTR

#include <stdlib.h>
void abort(void);
    cannot be block and ignore

#include <unistd.h>
unsigned int sleep(unsigned int seconds);
        return 0 or rest seconds

#include <signal.h>
void psignal(int signo, const char * msg);

#include <string.h>
#include <siginfo.h>  /* Solaris need it */
char * strsignal(int signo);

#include <signal.h>
int sig2str(int signo, char * str);
    SIG2STR_MAX defined by Solaris
    Never change errno
    if success return 0, else return -1
int str2sig(const char * str, int * signop);
    Never change errno
    if success return 0, else return -1

示例:

#include <stdio.h>
#include <signal.h>

void 
sig_usr(int signo)
{
    if (signo == SIGUSR1) {
        printf("received SIGUSR1\n");
    }
    else if (signo == SIGUSR2) {
        printf("received SIGUSR2\n");
    }
    else {
        printf("error: received signal %d\n", signo);
    }
}

int 
main(void)
{
    if (signal(SIGUSR1, sig_usr) == SIG_ERR) {
        printf("can not catch SIGUSR1\n");
        return -1;
    }
    if (signal(SIGUSR2, sig_usr) == SIG_ERR) {
        printf("can not catch SIGUSR2\n");
        return -1;
    }
    while (1) {
        pause();
    }
    return 0;
}

#include <stdio.h>
#include <stdlib.h>
#include <pwd.h>
#include <signal.h>

void 
my_alarm(int signo)
{
    struct passwd * rootptr;

    printf("int signal handler\n");
    if ((rootptr = getpwnam("root")) == NULL) {
        printf("getpwnam(root) error\n");
        exit(127);
    }
    alarm(1);   
}

int 
main(void)
{
    struct passwd * ptr;

    if (signal(SIGALRM, my_alarm) == SIG_ERR) {
        printf("signal(SIGALRM) error\n");
        exit(127);
    }
    printf("alarm\n");
    alarm(1);
    while (1) {
        if ((ptr = getpwnam("adwardink")) == NULL) {
            printf("getpwnam(adwardink) error\n");
            exit(127);
        }
        if (strcmp(ptr->pw_name, "adwardink") != 0) {
            printf("return value corrupted!, pw_name = %s\n", ptr->pw_name);
        }
    }
}

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

void 
sig_cld(int signo)
{
    pid_t     pid;
    int       status;

    printf("SIGCLD reccived\n");
    if (signal(SIGCLD, sig_cld) == SIG_ERR) { /* may error in some old sys*/
        printf("signal error\n");
        exit(127);
    }
    if ((pid = wait(&status)) < 0) {
        printf("wait error\n");
        exit(127);
    }
    printf("pid = %d\n", pid);
}

int 
main(void)
{
    pid_t     pid;

    if (signal(SIGCLD, sig_cld) == SIG_ERR) {
        printf("signal error\n");
        exit(127);
    }
    if ((pid = fork()) < 0) {
        printf("fork error\n");
        exit(127);
    }
    else if (pid == 0) {
        sleep(2);
        _exit(0); /* test exit(0), get same answer*/
    }
    else {
        pause();
        exit(0);
    }
}

#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
#include <unistd.h>
#include <signal.h>

jmp_buf   jmpbuf;

void 
sig_alm(int signo)
{
    longjmp(jmpbuf, 1);
}

int 
main(void)
{
    int     i;
    int     n;
    char    buff[BUFSIZ];

    if (signal(SIGALRM, sig_alm) == SIG_ERR) {
        printf("signal error\n");
        exit(127);
    }

    if (setjmp(jmpbuf) != 0) {
        printf("time out\n");
        exit(127);
    }

    for (i = 0; i < 5; ++i) {
        alarm(5);
        if ((n = read(STDIN_FILENO, buff, BUFSIZ)) < 0) {
            printf("read error\n");
            exit(127);
        }
        alarm(0);
        if (write(STDOUT_FILENO, buff, n) != n) {
            printf("write error\n");
            exit(127);
        }
    }

    exit(0);
}

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <signal.h>

void 
sig_quit(int signo)
{
    printf("caught SIGQUIT\n");
    if (signal(SIGQUIT, SIG_DFL) == SIG_ERR) {
        printf("cannot reset SIGQUIT\n");
        exit(127);
    }
}

int 
main(void)
{
    sigset_t   newmask;
    sigset_t   oldmask;
    sigset_t   pendmask;

    if (signal(SIGQUIT, sig_quit) == SIG_ERR) {
        printf("signal error\n");
        exit(127);
    }

    /*
     * block SIGQUIT and save current signal mask
     */
    if (sigemptyset(&newmask) < 0) {
        printf("sigemptyset error\n");
        exit(127);
    }
    if (sigaddset(&newmask, SIGQUIT) < 0) {
        printf("sigaddset error\n");
        exit(127);
    }
    if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) {
        printf("sigprocmask error\n");
        exit(127);
    }
    sleep(5); /* SIGQUIT here will remain pending */
    if (sigpending(&pendmask) < 0) {
        printf("sigpending error\n");
        exit(127);
    }
    if (sigismember(&pendmask, SIGQUIT) == 1) {
        printf("\nSIGQUIT pending\n");
    }
    /*
     * reset signal mask which unblocks SIGQUIT
     */
    if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) {
        printf("sigprocmask error\n");
        exit(127);
    }
    printf("SIGQUIT unblocked\n");
    sleep(5); /* SIGQUIT here will terminate with core file */
    exit(0);
}

#include <stdio.h>
#include <errno.h>
#include <time.h>
#include <setjmp.h>
#include <stdlib.h>
#include <signal.h>

sigjmp_buf              jmpbuf;
volatile sig_atomic_t   canjump;

void 
pr_mask(const char * str)
{
    sigset_t   sigset;
    int        errno_save;

    errno_save = errno;

    if (sigprocmask(0, NULL, &sigset) == -1) {
        printf("sigprocmask error\n");
        return;
    }

    printf("%s", str);
    if (sigismember(&sigset, SIGINT) == 1) {
        printf("SIGINT ");
    }
    if (sigismember(&sigset, SIGQUIT) == 1) {
        printf("SIGQUIT ");
    }
    if (sigismember(&sigset, SIGUSR1) == 1) {
        printf("SIGUSR1 ");
    }
    if (sigismember(&sigset, SIGUSR2) == 1) {
        printf("SIGUSR2 ");
    }
    if (sigismember(&sigset, SIGALRM) == 1) {
        printf("SIGALRM ");
    }
    printf("\n");

    errno = errno_save;
}

void 
sig_usr1(int signo)
{
    time_t starttime;

    if (canjump = 0) {
        return; /* unexpected signal, ignore */
    }

    pr_mask("starting sig_usr1: ");
    alarm(3); /* SIGALRM in 3 seconds */
    starttime = time(NULL);
    while (1) {
        if (time(NULL) > starttime + 5) { /* busy wait for 5 seconds */
            break;
        }
    }
    pr_mask("finishing sig_usr1: ");

    canjump = 0;
    siglongjmp(jmpbuf, 1); /* jump back to main, donot return */
}

void 
sig_alrm(int signo)
{
    pr_mask("in sig_alrm: ");
}

int 
main(void)
{
    if (signal(SIGUSR1, sig_usr1) == SIG_ERR) {
        printf("signal(SIGUSR1) error\n");
        exit(127);
    }
    if (signal(SIGALRM, sig_alrm) == SIG_ERR) {
        printf("signal(SIGALRM) error\n");
        exit(127);
    }
    pr_mask("starting main: ");

    if (sigsetjmp(jmpbuf, 1) != 0) {
        pr_mask("ending main: ");
        exit(0);
    }
    canjump = 1; /* now sigsetjmp() is OK */
    while (1) {
        pause();
    }
}

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <signal.h>

void 
pr_mask(const char * str)
{
    sigset_t   sigset;
    int        errno_save;

    errno_save = errno;

    if (sigprocmask(0, NULL, &sigset) == -1) {
        printf("sigprocmask error\n");
        return;
    }

    printf("%s", str);
    if (sigismember(&sigset, SIGINT) == 1) {
        printf("SIGINT ");
    }
    if (sigismember(&sigset, SIGQUIT) == 1) {
        printf("SIGQUIT ");
    }
    if (sigismember(&sigset, SIGUSR1) == 1) {
        printf("SIGUSR1 ");
    }
    if (sigismember(&sigset, SIGUSR2) == 1) {
        printf("SIGUSR2 ");
    }
    if (sigismember(&sigset, SIGALRM) == 1) {
        printf("SIGALRM ");
    }
    printf("\n");

    errno = errno_save;
}

void 
sig_int(int signo)
{
    pr_mask("\nin sig_int: ");
}

int 
main(void)
{
    sigset_t    newmask;
    sigset_t    oldmask;
    sigset_t    waitmask;

    if (signal(SIGINT, sig_int) == SIG_ERR) {
        printf("signal error\n");
        exit(127);
    }

    if (sigemptyset(&newmask) < 0) {
        printf("sigemptyset error\n");
        exit(127);
    }
    if (sigaddset(&newmask, SIGINT) < 0) {
        printf("sigaddset error\n");
        exit(127);
    }
    if (sigemptyset(&waitmask) < 0) {
        printf("sigemptyset error\n");
        exit(127);
    }
    if (sigaddset(&waitmask, SIGUSR1) < 0) {
        printf("sigaddset error\n");
        exit(127);
    }

    /*
     * block SIGINT and save current signal mask
     */
    if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) {
        printf("sigprocmask error\n");
        exit(127);
    }

    /*
     * critical region of code
     */
    pr_mask("in critical region: ");

    /*
     * pause, allowing all signals, except SIGUSR1
     */
    if (sigsuspend(&waitmask) != -1) {
        printf("sigsuspend error\n");
        exit(127);
    }

    pr_mask("after return from sigsuspend: ");

    /*
     * reset signal mask which unblocks SIGINT
     */
    if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) {
        printf("sigprocmask error\n");
        exit(0);
    }

    /*
     * and continue processing ...
     */
    pr_mask("program exit: ");

    exit(0);
}

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

volatile sig_atomic_t quitflag; /* set nonzero by signal handler */

void 
sig_int(int signo)
{
    if (signo == SIGINT) {
        printf("\ninterrupt\n");
    }
    else if (signo == SIGQUIT) {
        quitflag = 1;
    }
}

int 
main(void)
{
    sigset_t    newmask;
    sigset_t    oldmask;
    sigset_t    zeromask;

    if (signal(SIGINT, sig_int) == SIG_ERR) {
        printf("signal error\n");
        exit(127);
    }
    if (signal(SIGQUIT, sig_int) == SIG_ERR) {
        printf("signal error\n");
        exit(127);
    }

    if (sigemptyset(&zeromask) < 0) {
        printf("sigemptyset error\n");
        exit(127);
    }
    if (sigemptyset(&newmask) < 0) {
        printf("sigemptyset error\n");
        exit(127);
    }
    if (sigaddset(&newmask, SIGQUIT) < 0) {
        printf("sigaddset error\n");
        exit(127);
    }

    /*
     * block SIGQUIT and save current signal mask
     */
    if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) {
        printf("sigprocmask error\n");
        exit(127);
    }

    /*
     * pause, allowing all signals
     */
    while (quitflag == 0) {
        if (sigsuspend(&zeromask) != -1) {
            printf("sigsuspend error\n");
            exit(127);
        }
    }

    /*
     * SIGQUIT has been caught and is now blocked, do whatever
     */
    quitflag = 0;

    /*
     * reset signal mask which unblocks SIGINT
     */
    if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) {
        printf("sigprocmask error\n");
        exit(0);
    }

    exit(0);
}

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

#define BUFFSIZE     (1024)

void 
sig_tstp(int signo) /* signal handler for SIGTSTP */
{
    sigset_t    mask;

    /* ... move cursor to lower left corner, reset tty mod ... */

    /*
     * unblock SIGTSTP, since it is blocked while we are handling it
     */
    sigemptyset(&mask);
    sigaddset(&mask, SIGTSTP);
    sigprocmask(SIG_UNBLOCK, &mask, NULL);

    signal(SIGTSTP, SIG_DFL); /* reset disposition to default */

    kill(getpid(), SIGTSTP); /* and send the signal to ourselves */

    /* we wonnot return from the kill until we are continued */

    signal(SIGTSTP, sig_tstp); /* reestablish signal handler */

    /* ... reset tty mode, redraw screen ... */
}

int 
main(void)
{
    int     n;
    char    buf[BUFFSIZE];

    /*
     * only catch SIGTSTP if we are running with a job-control shell
     */
    if (signal(SIGTSTP, SIG_IGN) == SIG_DFL) {
        signal(SIGTSTP, sig_tstp);
    }

    while ((n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0) {
        if (write(STDOUT_FILENO, buf, n) != n) {
            printf("write error\n");
            exit(127);
        }
    }

    if (n < 0) {
        printf("read error\n");
        exit(127);
    }

    exit(0);
}

#ifndef __MY_SIGNAL_H__
#define __MY_SIGNAL_H__


#include <stdio.h>
#include <errno.h>
#include <signal.h>

typedef void Sigfunc(int);

Sigfunc * 
my_signal(int signo, Sigfunc * func)
{
    struct sigaction act;
    struct sigaction oact;

    act.sa_handler = func;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    if (signo == SIGALRM) {
#ifdef SA_INTERRUPT
        act.sa_flags |= SA_INTERRUPT;
#endif
    }
    else {
#ifdef SA_RESTART
        act.sa_flags |= SA_RESTART;
#endif
    }
    if (sigaction(signo, &act, &oact) < 0) {
        return SIG_ERR;
    }
    else {
        return oact.sa_handler;
    }
}

Sigfunc * 
my_signal_intr(int signo, Sigfunc * func)
{
    struct sigaction act;
    struct sigaction oact;

    act.sa_handler = func;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
#ifdef SA_INTERRUPT
    act.sa_flags |= SA_INTERRUPT;
#endif
    if (sigaction(signo,&act, &oact) < 0) {
        return SIG_ERR;
    }
    else {
        return oact.sa_handler;
    }
}

#endif

#include <stdlib.h>
#include <signal.h>

void 
sig_alrm(int signo)
{
    /* nothing to do, just returning wakes up sigsuspend() */
}

unsigned int
sleep(unsigned int seconds)
{
    struct sigaction   newact;
    struct sigaction   oldact;
    sigset_t           newmask;
    sigset_t           oldmask;
    sigset_t           pendmask;
    unsigned int       unslept;

    /* set our handler, save previous information */
    newact.sa_handler = sig_alrm;
    sigemptyset(&newact.sa_mask);
    newact.sa_flags = 0;
    sigaction(SIGALRM, &newact, &oldact); 

    /* block SIGALRM and save current signal mask */
    sigemptyset(&newmask);
    sigaddset(&newmask, SIGALRM);
    sigprocmask(SIG_BLOCK, &newmask, &oldmask);

    alarm(seconds);

    pendmask = oldmask;
    sigdelset(&pendmask, SIGALRM); /* make sure SIGALRM is not blocked */
    sigsuspend(&pendmask); /* wait for any signal to be caught */

    /* some signal has been caught, SIGALRM is now blocked */

    unslept = alarm(0);
    sigaction(SIGALRM, &oldact, NULL); /* reset previous action */

    /* reset signal mask, which unblocks SIGALRM */
    sigprocmask(SIG_SETMASK, &oldmask, NULL);
    return unslept;
}

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

void 
my_abort(void) /* POSIX-style abort() function */
{
    sigset_t            mask;
    struct sigaction    action;

    /*
     * caller cannot 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); /* flush all open stdio streams */
    }

    /*
     * caller cannot block SIGABRT, make sure it is unblocked
     */
    sigfillset(&mask);
    sigdelset(&mask, SIGABRT); /* make has only SIGABRT turned off */
    sigprocmask(SIG_SETMASK, &mask, NULL);
    kill(getpid(), SIGABRT); /* send the signal */

    /*
     * if we are here, process caught SIGABRT and returned
     */
    fflush(NULL); /* flush all open stdio streams */
    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 ... */
}

#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include <sys/wait.h>

int 
my_system(const char * cmdstring) /* with appropriate signal handling */
{
    pid_t               pid;
    int                 status;
    struct sigaction    ignore;
    struct sigaction    saveintr;
    struct sigaction    savequit;
    sigset_t            chldmask;
    sigset_t            savemask;

    if (cmdstring == NULL) {
        return 1; /* always a command processor with UNIX */
    }

    ignore.sa_handler = SIG_IGN; /* ignore SIGINT and SIGQUIT */
    sigemptyset(&ignore.sa_mask);
    ignore.sa_flags = 0;
    if (sigaction(SIGINT, &ignore, &saveintr) < 0) {
        return -1;
    }
    if (sigaction(SIGQUIT, &ignore, &savequit) < 0) {
        return -1;
    }
    sigemptyset(&chldmask);
    sigaddset(&chldmask, SIGCHLD); /* now block SIGCHLD */
    if (sigprocmask(SIG_BLOCK, &chldmask, &savemask) < 0) {
        return -1;
    }

    if ((pid = fork()) < 0) {
        status = -1; /* probably out of processes */
    }
    else if (pid == 0) {
        /* restore previous signal actions, reset signal mask */
        sigaction(SIGINT, &saveintr, NULL);
        sigaction(SIGQUIT, &savequit, NULL);
        sigprocmask(SIG_SETMASK, &savemask, NULL);

        execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
        _exit(127); /* exec error */
    }
    else {
        while (waitpid(pid, &status, 0) < 0) {
            if (errno != EINTR) {
                status = -1; /* error other than EINTR from waitpid() */
                break;
            }
        }
    }

    /* restore previous signal actions, reset signal mask */
    if (sigaction(SIGINT, &saveintr, NULL) < 0) {
        return -1;
    }
    if (sigaction(SIGQUIT, &savequit, NULL) < 0) {
        return -1;
    }
    if (sigprocmask(SIG_SETMASK, &savemask, NULL) < 0) {
        return -1;
    }

    return status;
}

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include "signal.h"

volatile sig_atomic_t sigflag; /* set nonzero by sig handler */
sigset_t newmask, oldmask, zeromask;

void 
sig_usr(int signo) /* one signal handler for SIGUSR1 and SIGUSR2 */
{
    sigflag = 1;
}

void 
TELL_WAIT(void)
{
    if (signal(SIGUSR1, sig_usr) == SIG_ERR) {
        printf("signal(SIGUSR1) error\n");
        exit(127);
    }
    if (signal(SIGUSR2, sig_usr) == SIG_ERR) {
        printf("signal(SIGUSR2) error\n");
        exit(127);
    }

    if (sigemptyset(&zeromask) < 0) {
        printf("sigemptyset error\n");
        exit(127);
    }
    if (sigemptyset(&newmask) < 0) {
        printf("sigemptyset error\n");
        exit(127);
    }
    if (sigaddset(&newmask, SIGUSR1) < 0) {
        printf("sigaddset error\n");
        exit(127);
    }
    if (sigaddset(&newmask, SIGUSR2) < 0) {
        printf("sigaddset error\n");
        exit(127);
    }

    /*
     * block SIGUSR1 and SIGUSR2, and save current signal mask
     */
    if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) {
        printf("sigprocmask(SIG_BLOCK) error\n");
        exit(127);
    }
}

void 
TELL_PARENT(pid_t pid)
{
    kill(pid, SIGUSR2); /* tell parent we are done */
}

void 
WAIT_PARENT(void)
{
    while (sigflag == 0) {
        if (sigsuspend(&zeromask) != -1) { /* and wait for parent */
            printf("sigsuspend error\n");
            exit(127);
        }
    }
    sigflag = 0;

    /*
     * reset signal mask to original value
     */
    if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) {
        printf("sigprocmask(SIG_SETMASK) error\n");
        exit(0);
    }
}

void 
TELL_CHILD(pid_t pid)
{
    kill(pid, SIGUSR1); /* tell child we are done */
}

void 
WAIT_CHILD(void)
{
    while (sigflag == 0) {
        if (sigsuspend(&zeromask) != -1) { /* and wait for child */
            printf("sigsuspend error\n");
            exit(127);
        }
    }
    sigflag = 0;

    /*
     * reset signal mask to original value
     */
    if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) {
        printf("sigprocmask(SIG_SETMASK) error\n");
        exit(0);
    }
}


关于SIGKILL/SIGSTOP/SIGTSTP:http://blog.sina.com.cn/s/blog_53a7e8a3010155hx.html

SIGKILL和SIGSTOP的区别
SIGKILL提供给管理员杀死进程的权利, SIGSTOP提供给管理员暂停进程的权利, 所以这两个信号不能被忽略和重定义。
Kill父进程后, 子进程的父进程号为1; 但是stop父进程后子进程的父进程号还是该父进程。

SIGSTOP和SIGTSTP的区别
SIGSTOP提供给管理员暂停进程的特权, 所以不能忽略和重定义。
当用户按下CTRL-Z时, 向前台进程组发送SIGTSTP信号以暂停进程(默认动作), 该信号可以被忽略和重定义。
另外用户在控制终端上输入CTRL-S可以暂停进程的输出, 输入CTRL-Q可以恢复进程的输出。



相关文章推荐

APUE学习笔记——10信号——信号接口函数 signal 和 sigaction

signal函数是早起Unix系统的信号接口,早期系统中提供不可靠的信号机制。 信号有三种处理方式,1)忽略,此时func赋值为SIG_IGN; 2)使用默认动作,此时func赋值为SIG_DFL; ...
  • Windeal
  • Windeal
  • 2014年09月01日 09:56
  • 1076

apue-alarm和pause函数,关于信号

题记: 这里主要是用alarm和pause来实现sleep函数。会分析其中存在的bug,会很精辟。当然,大牛的恩赐啦~~不然我介些小生怎看到如此的经典呢?! 1实现sleep 1...
  • wusoule
  • wusoule
  • 2013年04月16日 14:58
  • 884

APUE阅读笔记(十)——信号

说明:1、信号真的看的很模糊 2、但是还是要坚持看概念 产生信号的进程是异步随机的,信号产生了以后我们常常对信号做以下三种操作:1、捕捉信号 我们可以在程序里用signal函数设置一个信号的操作方式...
  • sium__
  • sium__
  • 2016年04月27日 09:35
  • 428

APUE读书笔记---第10章 信号

APUE读书笔记—第10章 信号1. 信号概念 信号是软件中断,信号提供了一种处理异步事件的方法。 信号名在 < signal.h > 都被定义为正整数常量。 不存在编号为0的信号。 1.1 产生信号...
  • men_wen
  • men_wen
  • 2017年03月10日 19:09
  • 151

APUE学习笔记——10 信号

信号的基本概念 用sigaction代替signal 可靠信号与不可靠信号 现在大部分Unix系系统如Linux都已经实现可靠信号。 SIGKILL和SIGSTOP信号既不能被忽略也不能被...
  • Windeal
  • Windeal
  • 2014年08月27日 14:07
  • 779

APUE读书笔记-第十章 信号

今天开始写写APUE读书笔记

读书笔记-APUE第三版-(10)信号

读书笔记-APUE第三版-(10)信号信号概念信号是一种软件中断,用于提供异步事件处理机制。以下情形会产生信号: 终端键盘输入,比如Ctrl+c(SIGINT)。 硬件异常,比如除零&浮点数溢出(SI...
  • cargogo
  • cargogo
  • 2015年08月12日 18:32
  • 506

apue-第十章 信号 笔记

CTRL+c   SIGINT 终止 CTRL+z  SIGTSTP 停止进程 SIGCONT  让进程后台继续运行,若改为前台运行,需要waitpid 终端KILL指令: kill -s pid...

《APUE》笔记-第十章-信号

重点:信号意义、几种常见信号 1.信号 信号是软件中断,信号提供了一种处理异步事件的方法:产生信号的事件是随机出现的,需要告诉内核当什么信号发生时该执行什么操作。 定义在里(本机实际位置:/usr/i...

APUE读书笔记-第10章 信号

第10章 信号 10.1 引言 *信号是软件中断。信号提供了一种处理异步事件的方法   10.2 信号概念 *每个信号都有一个名字。这些名字都以三个字符SIG开头 *在头文件中,这些信号被定义为正整数...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:APUE函数笔记八: 信号
举报原因:
原因补充:

(最多只允许输入30个字)