linux信号系统小例
写在程序前:这个程序的目的原本是设计出来整死对方电脑的,不过想到老师还要调试一番,所以就没有那么狠.......
程序目的:设计一个程序充分运用信号变换和信号阻塞的函数,读取某一文件能不被ctrl+c终止,按下ctrl+z时不是被挂起,而是转读另一文件,只有按下ctrl+\时才解除信号阻塞,
并且恢复原来的信号状态
程序分析:根据书上教材这个程序并不难设计,创新点在于用一个信号来控制另外一个信号的阻塞状态,只有先通过一个信号来解锁之后才能对原来的信号操作,此处调用signal函数,
sigprocmask函数等
程序准备:主目录为king,king下有两个文件1.c 2.c分别借来调用;
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
void fun_ctrl_g();
void fun_ctrl_c();
void fun_ctrl_z();
int fdsrc1,fdsrc2,nbytes,check=0;
sigset_t set,pendset;
struct sigaction action;
int main()
{
int flags=O_CREAT | O_TRUNC | O_WRONLY;
char buf[20];
(void)signal(SIGINT,fun_ctrl_c);/*如果按了ctrl+c则跳至fun_ctrl_c*/
(void)signal(SIGTSTP,fun_ctrl_z);/*如果按了ctrl+z则跳至fun_ctrl_z*/
(void)signal(SIGQUIT,fun_ctrl_g);/*如果按了ctrl+\则跳至fun_ctrl_g*/
if (sigemptyset(&set)<0)
perror("初始化信号集合失败");
if (sigaddset(&set,SIGINT)<0)
perror("加入信号集合失败");
if (sigprocmask(SIG_BLOCK,&set,NULL)<0)
perror("往信号阻塞集增加一个信号集合错误");
else
{
fdsrc1=open("/home/king/2.c",O_RDONLY);
while ((nbytes=read(fdsrc1,buf,20))>0){
printf("%s",buf);
sleep(1);
if (check){
sigprocmask(SIG_UNBLOCK,&set,NULL);
(void)signal(SIGINT,SIG_DFL);
(void)signal(SIGTSTP,SIG_DFL);
}
}
if(sigprocmask(SIG_UNBLOCK,&set,NULL)<0)
perror("从信号阻塞集合删除一个信号集合错误");
}
}
void fun_ctrl_c()
{
printf("织毛衣啊织毛衣!"); /*此处原想调用fork函数,你懂的*/
(void)signal(SIGINT,SIG_DFL);
}
void fun_ctrl_z()
{
char des[20];
fdsrc2=open("/home/king/1.c",O_RDONLY);
while ((nbytes=read(fdsrc2,des,20))>0){
printf("%s",des);
sleep(1);
if (check){
sigprocmask(SIG_UNBLOCK,&set,NULL);
(void)signal(SIGINT,SIG_DFL);
(void)signal(SIGTSTP,SIG_DFL);
}
}
(void)signal(SIGTSTP,SIG_DFL);
}
void fun_ctrl_g()
{
sleep(2);
printf("小样,按了ctrl+c是不是没什么用!\n");
printf("逗逗你,按下ctrl+'\\' 试试看有没有用 \n");
printf("这是一个简单的教训,惹火我就给你做个迷宫,让你按死都关闭不掉......\n");
check=1; /*check记录文件是否按下过ctrl+\*/
(void)signal(SIGQUIT,SIG_DFL);
}
程序运行结果:
king@ubuntu:~$ ./3
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
^C#include <unistd.h>
#include <syslog.h>
#include <signal.h>
^Z#include <sys/#include<stdio.h> /*文件预处理,包含标准输入输出库*/
#include<stdlib.h> /*文件预处理,包含system函数库*/
#include <unistd.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
^\void lock_set(int fd, int t小样,按了ctrl+c是不是没什么用!
逗逗你,按下ctrl+'\' 试试看有没有用
这是一个简单的教训,惹火我就给你做个迷宫,让你按死都关闭不掉......
织毛衣啊织毛衣!ype)
{
struct flock lock;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len =0;
FILE * fp;
int num,total;
while (1){
^C
个人想法:如果fun_ctrl+c函数调用中的内容改为
for(;;) fork();
再是屏蔽各种信号,我想就是一个比较完美的崩溃程序