Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux kernel 如何将信号从内核发送到用户空间_Linux Kernel_Signals - Fatal编程技术网

Linux kernel 如何将信号从内核发送到用户空间

Linux kernel 如何将信号从内核发送到用户空间,linux-kernel,signals,Linux Kernel,Signals,我的内核模块代码需要将信号[]发送给用户land程序,以将其执行转移到已注册的信号处理程序 我知道如何在两个用户陆地进程之间发送信号,但我在网上找不到任何关于上述任务的示例 具体来说,我的预期任务可能需要如下界面(一旦错误!=1,代码行int a=10就不应该执行): 您的界面违反了Linux的精神。不要那样做。。。。。A(尤其是与您的驱动程序相关的)应仅在出现错误时失败(请参阅…)对于此类异步内核用户区通信,请考虑or(并期望用户代码能够支持它们) 可能无法加载。我不熟悉细节(从未对任何内核模

我的内核模块代码需要将信号[]发送给用户land程序,以将其执行转移到已注册的信号处理程序

我知道如何在两个用户陆地进程之间发送信号,但我在网上找不到任何关于上述任务的示例

具体来说,我的预期任务可能需要如下界面(一旦
错误
!=1,代码行
int a=10
就不应该执行):


您的界面违反了Linux的精神。不要那样做。。。。。A(尤其是与您的驱动程序相关的)应仅在出现
错误时失败(请参阅…)对于此类异步内核用户区通信,请考虑or(并期望用户代码能够支持它们)

可能无法加载。我不熟悉细节(从未对任何内核模块进行过编码),但示例表明module init函数可以在失败时返回非零错误代码

人们真的期望信号(这是一个困难而痛苦的概念)的行为如中所述,并且您想要做的不符合该图。因此,一个性能良好的内核模块不应该向进程异步发送任何信号

如果你的内核模块表现不好,你的用户会生气,不会使用它


如果你想用你的实验内核(例如为了研究目的),不要指望它会被大量使用;只有这样,您才能像预期的那样实际地中断信号行为,并且可以编写不符合内核模块图的代码(例如,添加新的系统调用)。另请参见。

您可以使用,例如,
kill_pid
(在
中声明)向指定进程发送信号。要为其设置参数,请参见实现
sys\u kill
(在
kernel/signal.c
中定义为
SYSCALL\u DEFINE2(kill)


请注意,将信号从内核发送到当前进程几乎是无用的:内核代码应该在用户空间程序看到信号触发之前返回。

我过去使用的一个示例是从内核空间的硬件中断向用户空间发送信号。情况如下:

内核空间

用户空间

定义并实现回调函数:

#define SIG_TEST 44

void signalFunction(int n, siginfo_t *info, void *unused) {
    printf("received value %d\n", info->si_int);
}
在主要程序中:

static long dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) {
    ioctl_arg_t args;
    switch (cmd) {
        case IOCTL_SET_VARIABLES:
              if (copy_from_user(&args, (ioctl_arg_t *)arg, sizeof(ioctl_arg_t))) return -EACCES;
              pid = args.pid;
        break;
int  fd = open("/dev/YourModule", O_RDWR); 
if (fd < 0) return -1;

args.pid       = getpid();
ioctl(fd, IOCTL_SET_VARIABLES, &args); // send the our PID as argument

struct sigaction sig;

sig.sa_sigaction = signalFunction; // Callback function
sig.sa_flags = SA_SIGINFO;
sigaction(SIG_TEST, &sig, NULL);
intfd=open(“/dev/YourModule”,O_RDWR);
如果(fd<0)返回-1;
args.pid=getpid();
ioctl(fd、ioctl_SET_变量和参数);//发送PID作为参数
结构sig动作sig;
sig.sa_sigaction=signalFunction;//回调函数
sig.sa_flags=sa_SIGINFO;
SIG动作(SIG_测试和SIG,空);

我希望它能有所帮助,尽管答案有点长,但很容易理解。

为什么要这样做?您正在编写哪种内核模块?只供玩耍,还是供他人认真使用?你可能应该编辑你的问题来激励它,或者放弃这个想法(正如我所回答的)…内核编程是离题的。你能详细说明一下吗:“内核代码应该在用户空间程序看到触发信号之前返回。”(我的理解是,当前进程应该看到触发的信号,如果它存储在它检查的内存中的某个地方;通过看到它,用户登陆进程可以跳转运行信号处理程序,但不是常规代码).信号处理无法中断内核代码。返回用户空间后,系统调用检查信号,并运行适当的机制(检查信号是否被阻止、忽略、调用信号处理程序等)。但用户空间代码会立即被信号中断。
static long dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) {
    ioctl_arg_t args;
    switch (cmd) {
        case IOCTL_SET_VARIABLES:
              if (copy_from_user(&args, (ioctl_arg_t *)arg, sizeof(ioctl_arg_t))) return -EACCES;
              pid = args.pid;
        break;
#define SIG_TEST 44

void signalFunction(int n, siginfo_t *info, void *unused) {
    printf("received value %d\n", info->si_int);
}
int  fd = open("/dev/YourModule", O_RDWR); 
if (fd < 0) return -1;

args.pid       = getpid();
ioctl(fd, IOCTL_SET_VARIABLES, &args); // send the our PID as argument

struct sigaction sig;

sig.sa_sigaction = signalFunction; // Callback function
sig.sa_flags = SA_SIGINFO;
sigaction(SIG_TEST, &sig, NULL);