信号

2020-07-03  本文已影响0人  yuq329

信号

#include <apue.h>
#include <error.h>

static void sig_usr(int);

int main(void) {
    if (signal(SIGUSR1, sig_usr) == SIG_ERR)
        err_sys("can't catch SIGUSR1");
    if (signal(SIGUSR2, sig_usr) == SIG_ERR)
        err_sys("can't catch SIGUSR2");
    for (;;)
        pause();
}

static void sig_usr(int signo) {
    if (signo == SIGUSR1)
        printf("received SIGUSR1\n");
    if (signo == SIGUSR2)
        printf("received SIGUSR2\n");
    else
        err_dump("received signal %d\n", signo);
}
#include <apue.h>
#include <error.h>
#include <pwd.h>

static void my_alarm(int signo) {
    struct passwd *rootptr;
    printf("in signal handler\n");
    if ((rootptr = getpwnam("root")) == NULL)
        err_sys("getpwnam(root) error");
    alarm(1);
}

int main(void) {
    struct passwd *ptr;
    signal(SIGALRM, my_alarm);
    alarm(1);
    for (;;) {
        if ((ptr = getpwnam("yuq")) == NULL)
            err_sys("getpwnam error");
        if (strcmp(ptr->pw_name, "yuq") != 0)
            printf("return value corrupted!, pw_name = %s\n", ptr->pw_name);
    }
}
#include <apue.h>
#include <error.h>
#include <sys/wait.h>

#define SIGCLD SIGCHLD

static void sig_cld(int);

int main() {
    pid_t pid;
    if (signal(SIGCLD, sig_cld) == SIG_ERR)
        perror("signal error");
    if ((pid = fork()) < 0)
        perror("fork error");
    else if (pid == 0) {
        sleep(2);
        _exit(0);
    }

    pause();
    exit(0);
}

static void sig_cld(int signo) {
    pid_t pid;
    int status;
    printf("SIGCLD received\n");
    if (signal(SIGCLD, sig_cld) == SIG_ERR)
        perror("signal error");
    if ((pid = wait(&status)) < 0)
        perror("wait error");
    printf("pid = %d\n", pid);
}
#include <unistd.h>
#include <signal.h>
#include <setjmp.h>
#include <apue.h>
#include <error.h>

static void sig_alarm(int signo) {
    /* nothing to do, just return to wake up the pause */
}

unsigned int sleep1(unsigned int seconds) {
    if (signal(SIGALRM, sig_alarm) == SIG_ERR)
        return seconds;
    alarm(seconds);
    pause();
    return alarm(0);
}

static jmp_buf env_alrm;

static void sig_alrm(int signo) {
    longjmp(env_alrm, 1);
}

//避免alarm与pause的竞争条件
unsigned int sleep2(unsigned int seconds) {
    if (signal(SIGALRM, sig_alrm) == SIG_ERR)
        return seconds;
    if (setjmp(env_alrm) == 0) {
        alarm(seconds);
        pause();
    }
    return alarm(0);
}

int main1(void) {
    printf("test sleep1()\n");
    sleep1(5);
    return 0;
}

static void sig_int(int signo) {
    int i, j;
    volatile int k;
    printf("\nsig_int starting\n");
    for (i = 0; i < 300000; i++) {
        for (j = 0; j < 4000; j++)
            k += i * j;
    }
    printf("sig_int finished\n");
}

int main(void) {
    unsigned int unslept;
    if (signal(SIGINT, sig_int) == SIG_ERR)
        err_sys("signal(SIGINT) error");
    unslept = sleep2(5);
    printf("sleep2 returned: %u\n", unslept);
    exit(0);
}
#include <apue.h>
#include <error.h>

static void sig_alrm(int signo) {
}

int main(void) {
    int n;
    char line[MAXLINE];

    if (signal(SIGALRM, sig_alrm) == SIG_ERR)
        err_sys("signal(SIGALRM) error");
    alarm(10);
    if ((n = read(STDIN_FILENO, line, MAXLINE)) < 0)
        err_sys("read error");
    alarm(0);
    write(STDOUT_FILENO, line, n);
    exit(0);
}
#include <apue.h>
#include <error.h>
#include <setjmp.h>

static jmp_buf env_alrm;

static void sig_alrm(int signo) {
    longjmp(env_alrm, 1);
}

int main(void) {
    int n;
    char line[MAXLINE];

    if (signal(SIGALRM, sig_alrm) == SIG_ERR)
        err_sys("signal(SIGALRM) error");
    if(setjmp(env_alrm)!=0)
        err_quit("read timeout");
    alarm(10);
    if ((n = read(STDIN_FILENO, line, MAXLINE)) < 0)
        err_sys("read error");
    alarm(0);
    write(STDOUT_FILENO, line, n);
    exit(0);
}
#define __DARWIN_NSIG   32  
#if defined(__i386__) || defined(__x86_64__)
/* The left shift operator on intel is modulo 32 */
__header_always_inline int
__sigbits(int __signo)
{
    return __signo > __DARWIN_NSIG ? 0 : (1 << (__signo - 1));
}
#else /* !__i386__ && !__x86_64__ */
#define __sigbits(signo)    (1 << ((signo) - 1))
#endif /* __i386__ || __x86_64__ */

#define sigaddset(set, signo)   (*(set) |= __sigbits(signo), 0)
#define sigdelset(set, signo)   (*(set) &= ~__sigbits(signo), 0)
#define sigismember(set, signo) ((*(set) & __sigbits(signo)) != 0)
#define sigemptyset(set)    (*(set) = 0, 0)
#define sigfillset(set)     (*(set) = ~(sigset_t)0, 0)
void pr_mask(const char *str) {
    sigset_t sigset;
    int errno_save;
    errno_save = errno;
    if (sigprocmask(0, NULL, &sigset) < 0) {
        err_ret("sigprocmask error");
    } else {
        printf("%s", str);
        if (sigismember(&sigset, SIGINT))
            printf(" SIGINT");
        if (sigismember(&sigset, SIGQUIT))
            printf(" SIGOUIT");
        if (sigismember(&sigset, SIGUSR1))
            printf(" SIGUSR1");
        if (sigismember(&sigset, SIGALRM))
            printf(" SIGALRM");
        printf("\n");
    }
    errno = errno_save;
}

int main(void) {
    pr_mask("signal mask: ");
}
#include <apue.h>
#include <error.h>

static void sig_quit(int);

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

    if (signal(SIGQUIT, sig_quit) == SIG_ERR)
        err_sys("can't catch SIGQUIT");

    sigemptyset(&newmask);
    sigaddset(&newmask, SIGQUIT);
    if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
        err_sys("SIG_BLOCK error");
    sleep(5);

    if (sigpending(&pendmask) < 0) {
        err_sys("sigpending error");
    }

    if (sigismember(&pendmask, SIGQUIT))
        printf("\nSIGQUIT pending\n");

    if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
        err_sys("SIG_SETMASK error");
    printf("SIGQUIT unblocked\n");
    sleep(5);

    exit(0);
}

static void sig_quit(int signo) {
    printf("caught SIGQUIT\n");
    if (signal(SIGQUIT, SIG_DFL) == SIG_ERR) {
        err_sys("can't reset SIGOUIT");
    }
}
#include <apue.h>

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

Sigfunc *signal_intr(int signo, Sigfunc *func) {
    struct sigaction act, 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;
    return oact.sa_handler;
}
#include <apue.h>
#include <error.h>
#include <prmask.h>

static void sig_int(int);

int main(void) {
    sigset_t newmask, oldmask, waitmask;
    pr_mask("program start: ");
    if (signal(SIGINT, sig_int) == SIG_ERR)
        err_sys("signal(SIGINT) error");
    sigemptyset(&waitmask);
    sigaddset(&waitmask, SIGUSR1);
    sigemptyset(&newmask);
    sigaddset(&newmask, SIGINT);
    if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
        err_sys("SIG_BLOCK error");

    pr_mask("in critical region: ");
    if (sigsuspend(&waitmask) != -1)
        err_sys("sigsuspend error");

    pr_mask("after return from sigsuspend: ");
    if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
        err_sys("SIG_SETMASK error");
    pr_mask("program exit: ");
    exit(0);
}

static void sig_int(int signo) {
    pr_mask("\nin sig_int: ");
}
#include <apue.h>
#include <error.h>

volatile sig_atomic_t quitflag;

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

int main(void) {
    sigset_t newmask, oldmask, zeromask;
    if (signal(SIGINT, sig_int) == SIG_ERR)
        err_sys("signal(SIGINT) error");
    if (signal(SIGQUIT, sig_int) == SIG_ERR)
        err_sys("signal(SIGQUIT) error");

    sigemptyset(&zeromask);
    sigemptyset(&newmask);
    sigaddset(&newmask, SIGQUIT);

    if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
        err_sys("SIG_BLOCK error");

    while (quitflag == 0)
        sigsuspend(&zeromask);

    quitflag = 0;

    if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
        err_sys("SIG_SETMASK error");
    exit(0);
}
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void abort(void) {

    sigset_t mask;
    struct sigaction action;
    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);
    }
    sigfillset(&mask);
    sigdelset(&mask, SIGABRT);
    sigprocmask(SIG_SETMASK, &mask, NULL);
    kill(getpid(), SIGABRT);

    fflush(NULL);
    action.sa_handler = SIG_DFL;
    sigaction(SIGABRT, &action, NULL);
    sigprocmask(SIG_SETMASK, &mask, NULL);
    kill(getpid(), SIGABRT);

    exit(1);
}

int main(void) {
    printf("test abort");
    abort();
    printf("test abort");
}
#include <apue.h>
#include <error.h>

static void sig_int(int signo) {
    printf("caught SIGINT\n");
}

static void sig_chld(int signo) {
    printf("caught SIGCHID\n");
}

int system(const char *cmdstring) {
    pid_t pid;
    int status;
    if (cmdstring == NULL) {
        return 1;
    }
    if ((pid = fork()) < 0) {
        status = -1;
    } else if (pid == 0) {
        execl("/bin/sh", "sh", "-c", cmdstring, (char *) 0);
        _exit(127);
    } else {
        while (waitpid(pid, &status, 0) < 0) {
            if (errno != EINTR) {
                status = -1;
                break;
            }
        }
    }
    return status;
}


int main(void) {
    if (signal(SIGINT, sig_int) == SIG_ERR) {
        err_sys("signal(SIGINT) error");
    }
    if (signal(SIGCHLD, sig_chld) == SIG_ERR)
        err_sys("signal(SIGCHLD) error");
    if (system("/bin/ed") < 0)
        err_sys("system() error");
    exit(0);
}
#include <sys/wait.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>

int system(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, &saveintr) < 0)
        return -1;
    if (sigaction(SIGQUIT, &ignore, &savequit) < 0)
        return -1;
    sigemptyset(&chldmask);
    sigaddset(&chldmask, SIGCHLD);
    if (sigprocmask(SIG_BLOCK, &chldmask, &savemask) < 0)
        return -1;
    if ((pid = fork()) < 0)
        status = -1;
    else if (pid == 0) {
        sigaction(SIGINT, &saveintr, NULL);
        sigaction(SIGQUIT, &saveintr, NULL);
        execl("/bin/sh", "sh", "-c", cmdstring, (char *) 0);
        _exit(127);
    } else {
        while (waitpid(pid, &status, 0) < 0) {
            status = -1;
            break;
        }
    }

    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 <apue.h>
#include <error.h>

#define BUFFSIZE 1024

static void sig_tstp(int signo) {
    sigset_t mask;
    sigemptyset(&mask);
    sigaddset(&mask, SIGTSTP);
    sigprocmask(SIG_UNBLOCK, &mask, NULL);

    signal(SIGTSTP, SIG_DFL);

    kill(getpid(), SIGTSTP);

    signal(SIGTSTP, sig_tstp);
    /* ... reset tty mode, redraw screen ... */
}

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

    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)
            err_sys("write error");
    }
    if (n < 0)
        err_sys("read error");
    exit(0);
}
上一篇下一篇

猜你喜欢

热点阅读