信号

作者: yuq329 | 来源:发表于2020-07-03 12:15 被阅读0次

    信号

    #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);
    }
    

    相关文章

      网友评论

          本文标题:信号

          本文链接:https://www.haomeiwen.com/subject/alcsqktx.html