C 使用字符设备驱动程序捕捉信号和暂停
我是C 使用字符设备驱动程序捕捉信号和暂停,c,linux,signals,linux-device-driver,daemon,C,Linux,Signals,Linux Device Driver,Daemon,我是C编程的新手,不完全了解信号捕获的工作原理,也不完全了解字符设备驱动程序。我非常感谢您的帮助,但我需要声明,这是我第一次C编程课上的一个项目。因此,我没有发布任何直接代码,只是我最初方法的一个示例 #include <stdio.h> #include <unistd.h> #include <signal.h> #include <stdlib.h> static int file_state; //v
C编程的新手
,不完全了解信号捕获的工作原理,也不完全了解字符设备驱动程序。我非常感谢您的帮助,但我需要声明,这是我第一次C编程
课上的一个项目。因此,我没有发布任何直接代码,只是我最初方法的一个示例
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
static int file_state; //variable to pass to the driver for recording
void sig_handler(int sig);
void sig_handler(int sig){
if(sig == SIGRTMIN){
printf("SIG = SIGRTMIN\n");
file_state = 0;
}else if(sig == SIGRTMIN+1){
printf("SIG = SIGRTMIN1\n");
file_state = 1;
}else if(sig == SIGTERM){
exit(0);
EXIT_SUCCESS;
}else{
printf("SIGNAL CAUGHT #%d\n", sig);
}
}
int main(){
if(signal(SIGRTMIN, sig_handler)==SIG_ERR){
printf("Unable to catch SIGRTMIN\n");
}
if(signal(SIGRTMIN+1, sig_handler)==SIG_ERR){
printf("Unable to catch SIGRTMIN+1\n");
}
if(signal(SIGTERM, sig_handler)==SIG_ERR){
printf("Unable to terminate process.\n");
}
//This for loop will catch all other signals except the un-catchable and
//other user-specified above signal #31.
int s;
for(s = 0; s < 32; s++){
signal(s, sig_handler);
}
while(1);
pause();
return 0;
}
我的项目需要接受一个信号输入,并将该信号设置为一个变量,以传递给我的字符设备驱动程序
。我编写的另一个程序需要访问该变量的值,以便在读取时执行特定的结果。我试图运行我的控制程序(&
),但它立即退出。我通过在命令提示符中输入ps
进行双重检查,该过程即告结束
基本上,我需要我的控制程序暂停,等待信号被接收。一旦收到,如果信号匹配,它将设置一个变量为其值。否则,如果它是SIGTERM
,它将结束或pause()
,在那里它将等待,直到收到满足另一条件的另一个信号。目前,当我使用&
编译并运行它时,它只是运行并退出。下面是我的代码示例:
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
static int file_state; //variable to pass to the driver for recording
void sig_handler(int sig);
void sig_handler(int sig){
while(1){
if(sig == SIGRTMIN){
printf("SIG = SIGRTMIN\n");
file_state = 0;
}else if(sig == SIGRTMIN+1){
printf("SIG = SIGRTMIN1\n");
file_state = 1;
}else if(sig == SIGTERM){
printf("Exiting\n");
exit(0); //exit
}else{
printf("SIG = %i\n", sig);
pause(); //doesn't match, pause for next signal
}
}
}
int main(){
signal(SIGINT, sig_handler);
//return 0; //tried with and without
}
我正试图找出一种方法,使这个过程和信号捕获循环保持活动状态,直到收到特定的信号。我一辈子都搞不懂
ETA 2
发现了我的问题。我没有注意并完全理解signal()
方法。第一个参数需要您试图捕获的确切信号。我使用的是SIGINT
,我认为这是一个你想要捕捉的中断的“类”。然后在signal\u handler()
函数中,指定捕获的中断类型。但是,它实际上是在寻找你感兴趣的确切信号。因此,在我的示例代码中,我应该使用:
int main(){
if(signal(SIGRMIN, sig_handler) == SIG_ERR){
printf("can't catch SIGRMIN Signal.\n")
}
...
}
我将更新我的新脚本作为答案,如果有人认为应该以不同的方式进行,或者有任何建设性的批评,请让我知道。再次感谢 有两个部分,第一个用户空间,用于生成和捕获信号。这与内核驱动程序无关。你的代码似乎还可以
当信号被捕获时,第二个与驾驶员交互。对于char驱动程序,请看一下这个。您可以简单地编写一个值write(fd、1和buf);从用户空间程序,在char驱动程序中实现相应的write()。下面是我的固定代码,当被捕获时,它会向终端返回正确的响应。我已经添加了一个
for()
循环来捕获我不担心的任何其他信号。没有停止我的进程,只有SIGTERM
会停止。期待被批评,以及为什么我永远不想做我的方法
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
static int file_state; //variable to pass to the driver for recording
void sig_handler(int sig);
void sig_handler(int sig){
if(sig == SIGRTMIN){
printf("SIG = SIGRTMIN\n");
file_state = 0;
}else if(sig == SIGRTMIN+1){
printf("SIG = SIGRTMIN1\n");
file_state = 1;
}else if(sig == SIGTERM){
exit(0);
EXIT_SUCCESS;
}else{
printf("SIGNAL CAUGHT #%d\n", sig);
}
}
int main(){
if(signal(SIGRTMIN, sig_handler)==SIG_ERR){
printf("Unable to catch SIGRTMIN\n");
}
if(signal(SIGRTMIN+1, sig_handler)==SIG_ERR){
printf("Unable to catch SIGRTMIN+1\n");
}
if(signal(SIGTERM, sig_handler)==SIG_ERR){
printf("Unable to terminate process.\n");
}
//This for loop will catch all other signals except the un-catchable and
//other user-specified above signal #31.
int s;
for(s = 0; s < 32; s++){
signal(s, sig_handler);
}
while(1);
pause();
return 0;
}
#包括
#包括
#包括
#包括
静态int文件_状态//要传递给驱动程序进行记录的变量
无效信号处理器(int sig);
无效信号处理器(int sig){
如果(sig==SIGRTMIN){
printf(“SIG=SIGRTMIN\n”);
文件状态=0;
}否则如果(sig==SIGRTMIN+1){
printf(“SIG=SIGRTMIN1\n”);
文件状态=1;
}else if(sig==SIGTERM){
出口(0);
成功退出;
}否则{
printf(“信号捕获#%d\n”,sig);
}
}
int main(){
if(信号(SIGRTMIN,sig_处理程序)=sig_ERR){
printf(“无法捕获SIGRTMIN\n”);
}
if(信号(SIGRTMIN+1,sig_处理程序)=sig_ERR){
printf(“无法捕获SIGRTMIN+1\n”);
}
if(信号(SIGTERM,sig_处理程序)=sig_ERR){
printf(“无法终止进程。\n”);
}
//该for循环将捕获除不可捕获和
//上述信号#31指定的其他用户。
int-s;
对于(s=0;s<32;s++){
信号(s、sig_处理器);
}
而(1),;
暂停();
返回0;
}
我想我不明白你的回答(顺便说一句,谢谢)。如果代码显示正常,为什么不暂停并保持打开状态?我一运行它,进程就关闭了,没有任何信号发送给它。关于第二点,我不能在基于捕获的信号链接的文件(进程、驱动程序、用户程序)中使用静态变量,还是应该写入设备驱动程序并从用户程序中引用该值?内核空间驱动程序和用户空间进度是两件完全不同的事情。它们只能通过linux内核提供的接口(系统调用)进行交互。所以我们需要有一个C源文件的用户程序和一个C源文件,这将是我们的驱动程序。是的,实际上我们的任务是使用三个文件。一个是信号控制器,它将向我的设备驱动程序发送功能信号(.ko扩展名和第二个文件),第三个文件是应用程序,它将从设备文件中读取。我正在尝试捕获信号(在收到有效信号后不关闭),并让设备驱动程序在读取时为我的应用程序提供正确的输出(同样,取决于捕获的信号)。您只能从信号处理程序中安全地调用异步信号安全函数。POSIX强制的异步信号安全函数可在以下位置找到:printf()
不是异步信号安全的。@AndrewHenle感谢链接。老实说,我的printf()
调用现在只是为我进行故障排除。然而,我不知道关于他们的细节。我只是想确保它工作正常,并且在收到不同的信号后,过程不会停止。