我是C Programming
的新手,并不完全了解信号捕捉的工作原理,并且与字符设备驱动程序一致。我很感激一些帮助,但我需要说明这是我第一个C Programming
课程中的项目。所以我没有发布任何直接代码,只是我最初方法的一个例子。
我的项目需要接受信号输入并将该信号设置为变量以传递给我的character device driver
。我编写的另一个程序需要访问该变量的值,以便在读取时执行某个结果。我试图运行我的控制程序(<name> &
),但它会立即退出。我通过在命令提示符下输入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
}
我等到这个daemon
收到一个信号,让device driver
进入特定模式。我还没有输入任何write()
方法,因为我正在尝试使用kill()
发送信号时执行此步骤,并使用printf()
返回正确的响应。
我的问题是,当我在等待打破pause()
循环的信号时,我似乎无法将此保持在if
模式。更糟糕的是(除了我缺乏知识和编程之外)我甚至无法保持这个daemon
打开足够长的时间来尝试发送信号。一旦我可以暂停并接收信号,我计划使用系统write()
方法将file_state
变量写入/dev/<filename>
,这将在我的可执行文件中交叉引用。
我离我有多远?这是(我相信)我坚持的最后一部分,我无法弄清楚应该如何处理这个问题。我在网上看过,大约有95%的例子都包含了我们还没有学到的方法。如果没有,这些示例更简单,它们不包括将值传递给character device driver
以供另一个程序使用驱动程序时使用。
非常感谢任何帮助。
ETA
我已经更新了我的代码,所以现在它一直保持打开状态,直到收到信号。问题是我想要pause()
并保持打开状态,直到收到SIGTERM
信号,打破循环并结束程序。我似乎无法让循环正确。当收到任何信号时,即使在int
循环中输入条件while()
变量仍然会被破坏。以下是我的更新代码:
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
static int file_state; //variable to pass to the driver for recording
int keep_alive = 1; //added for conditional checking to keep the while
//loop open to receive more than one signal
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){
keep_alive = 0;
}else{
}
}
int main(){
do{
signal(SIGINT, sig_handler);
pause(); //thought pausing here would help with waiting for a new signal
}while(keep_alive == 1); //keep looping until false
return 0; //tried with and without
}
我正在试图找出一种方法来保持这个过程并使信号捕获循环活着,直到收到特定的信号。我无法理解我的生活。
ETA 2
发现了我的问题。我没有注意并完全理解signal()
方法。第一个参数需要您尝试捕获的确切信号。我正在使用SIGINT
,我理解它是你想要捕获的中断的“类”。然后在signal_handler()
函数中,您将指定要捕获的中断类型。但是,实际上它正在寻找你感兴趣的完全信号。所以在我的示例代码中,我应该一直在使用:
int main(){
if(signal(SIGRMIN, sig_handler) == SIG_ERR){
printf("can't catch SIGRMIN Signal.\n")
}
...
}
我将使用我的新脚本作为答案进行更新,如果有人认为应该采取不同的方式或有任何建设性的批评,请告诉我。再次感谢!
答案 0 :(得分:0)
有2个部分,第1个用户空间,发生信号的产生和捕获。这与内核驱动程序无关。你的代码看起来还不错。
第二个是在捕获到信号时与驱动程序进行交互。对于char驱动程序,请查看此link。你可以简单地写一个值写(fd,1,&amp; buf);来自用户空间程序并在char驱动程序中实现相应的write()。
答案 1 :(得分:0)
所以我找到了我的问题,现在它正在运作。下面是我的固定代码,它会在捕获时产生正确的响应。我添加了一个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;
}