信号
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);
}