对于那些在执行完信号处理函数之后自动重启系统调用的应用平台例如FreeBSD 6.2 等来说可以用 setjmp 和 longjmp 这一对函数来实现程序的中止。
例如:
[@more@]#include
#include
#include
#include
static void sig_alrm(int);
static jmp_buf env_alrm;
int main()
{
int n=-10;
char line[1024];
if(signal(SIGALRM,sig_alrm)==SIG_ERR)
{
printf("nError in signal!n");
fflush(stdout);
return 1;
}
if(setjmp(env_alrm)!=0)
{
printf("nError in jump!n");
fflush(stdout);
return 1;
}
alarm(10);
if((n=read(STDIN_FILENO,line,1024))<0)
{
printf("nError in read! n=%dn",&n);
fflush(stdout);
return 1;
}
alarm(0);
write(STDOUT_FILENO,line,n);
return 0;
}
static void sig_alrm(int signo)
{
longjmp(env_alrm,1);
}
执行结果如下:
$ gcc ./chaoshi.c -o ./chaoshi
$ ./chaoshi
Error in jump! ---------------10 秒后输出
$
原因我大概清楚了,是由于longjmp 之后返回到main中去执行
if(setjmp(env_alrm)!=0)
{
printf("nError in jump!n");
fflush(stdout);
return 1;
}
这段代码导致的,由于是longjmp返回额的所以返回值!=0,所以这样曲线实现了进程的中止。
但是对于set 和 jmp 我不知道一旦在jmp回来之后难道仅仅是恢复buf中的栈变量吗?
进程的fd表中所打开的那些fd是否在jmp回来之后仍旧保留着呢??
事实证明fd还是保留着的:
#include
#include
#include
#include
#include
#include
static void sig_alrm(int);
static jmp_buf env_alrm;
int main()
{
int n=-10,fd;
char line[1024];
char ttt[]="1234";
if(signal(SIGALRM,sig_alrm)==SIG_ERR)
{
printf("nError in signal!n");
fflush(stdout);
return 1;
}
if(setjmp(env_alrm)!=0)
{
if(write(fd,ttt,4)!=4)
{
printf("nError in write file!n");
fflush(stdout);
return 1;
}
printf("nError in jump!n");
fflush(stdout);
return 1;
}
if((fd=open("./test.txt",O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR))<0)
{
printf("nError in open file!n");
fflush(stdout);
return 1;
}
if(write(fd,ttt,4)!=4)
{
printf("nError in write file!n");
fflush(stdout);
return 1;
}
/* if(setjmp(env_alrm)!=0)
{
printf("nError in jump!n");
fflush(stdout);
return 1;
} */
alarm(10);
if((n=scanf("%s",line))<0)
{
printf("nError in read! n=%dn",&n);
fflush(stdout);
return 1;
}
alarm(0);
write(STDOUT_FILENO,line,n);
return 0;
}
static void sig_alrm(int signo)
{
longjmp(env_alrm,1);
}
运行结果:
$
$ gcc ./test.c -o ./test
$ ./test
Error in jump!
$ cat test.txt
12341234$
$
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/7437037/viewspace-978695/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/7437037/viewspace-978695/