函数setjmp,longjmp和sigsetjmp,siglongjmp
int sigsetjmp(sigjmp_buf env,int savemask);
返回值:若直接调用则返回0,若从siglongjmp调用返回则返回非0值;
int siglongjmp(sigjmp_buf env,int val);
setjmp和longjmp的使用如下:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<signal.h>
#include<setjmp.h>
#define MAXLINE 1024
void sig_alarm(int signo);
jmp_buf env_alrm;
int main() {
int n;
char buf[MAXLINE];
if (signal(SIGALRM, sig_alarm) == SIG_ERR) {
printf("can't catch sigalrm\n");
exit(0);
}
if (setjmp(env_alrm) != 0) {
printf("longjump called\n");
exit(0);
}
alarm(5);
if ((n = read(STDIN_FILENO, buf, MAXLINE)) < 0) {
printf("read error\n");
exit(0);
}
alarm(0);
write(STDOUT_FILENO, buf, n);
}
void sig_alarm(int signo) {
longjmp(env_alrm, 1);
}
也可以用在sleep函数中:
#include<setjmp.h>
#include<signal.h>
#include<unistd.h>
static jmp_buf env_alrm;
static void sig_alrm(int signo) {
longjmp(env_alrm, 1);
}
unsigned int sleep2(unsigned int secs) {
if (signal(SIGALRM, sig_alrm) == SIG_ERR) {
return (nsecs);
}
if (setjmp(env_alrm) == 0) {
alarm(nsecs);
pause();
}
return (alarm(0));
}
sigsetjmp和siglongjmp使用基本相同,只是siglongjmp比setjmp多一个参数,若savemask为非0值,则sigsetjmp在env中保存进程的当前屏蔽字。若调用siglongjmp时,如果带非0 savemask的sigsetjmp调用已经保存了env,则siglongjmp从其中回复保存的信号屏蔽字。
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<signal.h>
#include<setjmp.h>
//SIGINT,SIGQUIT,SIGUSR1,SIGALRM
//siglongjmp longjmp
//siglongjmp can handle singal automatic
void sig_alarm(int signo);
void sig_usr1(int signo);
void pr_mask(const char *str);
jmp_buf jmp_aaa;
static int canjmp = 0;
int main() {
pr_mask("start pro");
if (signal(SIGALRM, sig_alarm) == SIG_ERR) {
printf("can't catch sigalrm\n");
exit(0);
}
if (signal(SIGUSR1, sig_usr1) == SIG_ERR) {
printf("can't catch sigusr1\n");
exit(0);
}
if (sigsetjmp(jmp_aaa, 1) != 0) {
//if (setjmp(jmp_aaa) != 0) {
pr_mask("end pro");
exit(0);
}
canjmp = 1;
raise(SIGUSR1);
return 0;
}
void sig_alarm(int signo) {
pr_mask("in sig_alarm");
}
void sig_usr1(int signo) {
if (canjmp == 0) {
return;
}
pr_mask("before sigalrm");
alarm(3);
sleep(5);
pr_mask("after sigalrm");
siglongjmp(jmp_aaa, 1);
//longjmp(jmp_aaa, 1);
}
void pr_mask(const char *str) {
printf("%s\n", str);
sigset_t curset;
if (sigprocmask(0, NULL, &curset) < 0) {
printf("call sigprocmask error\n");
}
if (sigismember(&curset, SIGINT))
printf("SIGINT\n");
if (sigismember(&curset, SIGQUIT))
printf("SIGQUIT\n");
if (sigismember(&curset, SIGUSR1))
printf("SIGUSR1\n");
if (sigismember(&curset, SIGALRM))
printf("SIGALRM\n");
}
浙公网安备 33010602011771号