我发现在Linux上,通过自己调用rt_sigqueue系统调用,我可以在si_uid和si_pid字段中放入我喜欢的任何内容,并且调用成功并愉快地传递不正确的值.当然,发送信号的uid限制提供了一些防止这种欺骗的保护,但我担心依赖这些信息可能是危险的.关于我能读到的主题,有没有好的文件?为什么Linux允许调用者指定siginfo参数而不是在内核空间中生成它们的明显不正确的行为?这似乎是荒谬的,特别是因为可能需要额外的sys调用(因此性能成本)才能在用户空间中获取uid/gid.
编辑:基于我对POSIX的阅读(我强调):
如果si_code是SI_USER或SI_QUEUE,[XSI]或小于或等于0的任何值,则信号由进程生成,si_pid和si_uid 应分别设置为进程ID和发送方的真实用户ID.
我相信Linux的这种行为是不符合的并且是一个严重的错误.
我如何收到在ac程序中使用sigqueue发送的信号(在linux上)?
如果只是使用kill来发送信号,我只需添加一个类似这样的接收器
signal(SIGUSR1, sigusr1);
Run Code Online (Sandbox Code Playgroud)
这指向一个像这样的简单函数:
void sigusr1()
{
signal(SIGUSR1,sigusr1);
printf("SIGUSR1 ....\n");
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我发送带有sigqueue的信号,我该怎么办呢?
谢谢约翰
添加一个sigaction:
struct sigaction action;
action.sa_flags = SA_SIGINFO;
action.sa_sigaction = &sigusr2;
if (sigaction(SIGUSR2, &action, NULL) == -1) {
perror("sigusr: sigaction");
_exit(1);
}
Run Code Online (Sandbox Code Playgroud)
sigusr2看起来像这样:
void sigusr2(int signo, siginfo_t *info, void *extra)
{
void *ptr_val = info->si_value.sival_ptr;
int int_val = info->si_value.sival_int;
printf("Signal %d, value %d \n", signo, int_val);
}
Run Code Online (Sandbox Code Playgroud)
而且只是为了一个sigqueue例子
sigval value;
for(int i=10;i<20;i++)
{
value.sival_int = i;
sigqueue(pid,SIGUSR2, value);
}
Run Code Online (Sandbox Code Playgroud) 我有2个进程sigserver和sigclient.sigserver等待信号到来,sigclient将数据(int + char)发送到sigserver.
sigserver.c
void sighand(int signo, siginfo_t *info, void *extra)
{
void *ptr_val = info->si_value.sival_ptr;
int int_val = info->si_value.sival_int;
printf("Signal: %d, value: [%d] %s\n", signo, int_val, (char*)ptr_val);
}
int main()
{
struct sigaction action;
action.sa_flags = SA_SIGINFO;
action.sa_sigaction = &sighand;
if (sigaction(SIGUSR2, &action, NULL) == -1) {
perror("sigusr: sigaction");
return 0;
}
printf("Signal handler installed, waiting for signal\n");
while(1) {sleep(2);}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
sigclient.c
int main(int argc, char *argv[])
{
union sigval value;
int pid = atoi(argv[1]);
value.sival_int = …Run Code Online (Sandbox Code Playgroud) 我有一个奇怪的构建问题.
我有一个简单的测试程序,它将sigqueue发送到另一个进程.
这个小代码示例在我将其构建为c ++程序(使用g ++编译)时构建并运行,但是当我将其编译为ac程序(使用gcc)时,我得到一个错误,他无法找到sigval结构.
简短的例子:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
int main(int argc, char *argv[])
{
sigval value;
value.sival_int = 123;
sigqueue(0,SIGUSR1, value);
}
Run Code Online (Sandbox Code Playgroud)
请注意,我将pid替换为0以简化此问题.
如果我用gcc编译,我得到这个:
$> gcc sigusr1_mini.c
sigusr1_mini.c: In function ‘main’:
sigusr1_mini.c:9: error: ‘sigval’ undeclared (first use in this function)
sigusr1_mini.c:9: error: (Each undeclared identifier is reported only once
sigusr1_mini.c:9: error: for each function it appears in.)
sigusr1_mini.c:9: error: expected ‘;’ before ‘value’
sigusr1_mini.c:10: error: ‘value’ undeclared (first use in this function) …Run Code Online (Sandbox Code Playgroud)