Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.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
C 为什么内核sigset在包含signal.h之后是一个未声明的标识符?_C_Include_System Calls - Fatal编程技术网

C 为什么内核sigset在包含signal.h之后是一个未声明的标识符?

C 为什么内核sigset在包含signal.h之后是一个未声明的标识符?,c,include,system-calls,C,Include,System Calls,从signal.h手册页中,rt\u sigprocmask的原型如下: /* Prototype for the glibc wrapper function */ int sigprocmask(int how, const sigset_t *set, sigset_t *oldset); /* Prototype for the underlying system call */ int rt_sigprocmask(int how, const kernel_sigset

signal.h
手册页中,
rt\u sigprocmask
的原型如下:

/* Prototype for the glibc wrapper function */
   int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

/* Prototype for the underlying system call */
   int rt_sigprocmask(int how, const kernel_sigset_t *set,
              kernel_sigset_t *oldset, size_t sigsetsize);
鉴于
rt\u sigprocmask
的原型中有
kernel\u sigset\u t
,我假设该类型的定义将包含在
signal.h
中。但是当我试图在程序中使用
kernel\u sigset\u t
时,我得到了一个错误,即
kernel\u sigset\u t
未声明

我编写了一个简单的小程序来演示错误:

#include <stdio.h>
#include <signal.h>
int main()
{
    printf("%d\n", sizeof(kernel_sigset_t));
    return 0;
}
为什么会发生这种情况? 我是不是把错误的东西包括进去了


编辑:进一步信息

我问这个问题的原因是因为我正在制作一个程序,跟踪两个并行运行的相同程序,并比较每个系统调用的参数,以检查它们是否相等

为了做到这一点,我需要检查作为指针的系统调用参数是否指向两个跟踪程序中的相同数据

因此,通过
rt\u sigprocmask
系统调用,我想检查
kernel\u sigset\u t
指针
set
oldset
都指向相同的数据。我将通过比较这些指针指向的地址处的数据长度来实现这一点,并查看它们是否相同(使用
process\u vm\u readv


然而,由于
kernel\u sigset\u t
似乎没有定义,我不知道如何做到这一点。正如手册页所说,内核的
sigset\u t
和用户空间大小不同:我怎么知道要比较的正确大小?如果我只使用
sigset_t
,如果内核不同,这是否正确?

作为一般规则,包含头文件并不总是足够的,有时这些定义深入到
\idfef
层次结构中

例如,检查,您可以看到所需的:

这意味着其中一个必须为真才能获得
sigprocmask


然而,在这种特殊情况下,
手册页
显示了最可能的问题。在详细介绍
glibc
(用户空间)和内核调用之间的差异的部分中,我们看到(重点添加):

内核的
sigset\u t
定义的大小与C库使用的定义不同。在本手册页面中,前者被称为
kernel\u sigset\u t
(但在内核源代码中它被命名为
sigset\u t

换句话说,它与文档化原型中显示的名称不同,不幸的是,它与用户空间中定义的名称相同

如果混合使用用户空间和内核方法,这可能会导致各种问题——我的建议是,如果可能,只使用用户空间方法,而将内核方法留给内核开发人员:-)

从a开始,添加了系统调用的
rt
变体(这不是用户空间函数)以适应更大的信号集-一旦添加了实时信号,信号位掩码将超过32位,因此必须扩展信号集

用户空间函数将智能地调用正确的系统调用,旧的系统调用仍然存在,但已弃用。该函数调用还将静默地防止您篡改本机POSIX线程库NPTL使用的信号


对于问题的更新,您声明要跟踪系统调用以确保传入的参数相同,实际上不需要知道该结构的大小


rt_sigprocmask
的工作方式是,结构的长度实际上是参数之一,
sigsetsize
。因此,这就是您应该用于比较的大小。

作为一般规则,包含头文件并不总是足够的,有时这些定义深入到
#idfef
层次结构中

例如,检查,您可以看到所需的:

这意味着其中一个必须为真才能获得
sigprocmask


然而,在这种特殊情况下,
手册页
显示了最可能的问题。在详细介绍
glibc
(用户空间)和内核调用之间的差异的部分中,我们看到(重点添加):

内核的
sigset\u t
定义的大小与C库使用的定义不同。在本手册页面中,前者被称为
kernel\u sigset\u t
(但在内核源代码中它被命名为
sigset\u t

换句话说,它与文档化原型中显示的名称不同,不幸的是,它与用户空间中定义的名称相同

如果混合使用用户空间和内核方法,这可能会导致各种问题——我的建议是,如果可能,只使用用户空间方法,而将内核方法留给内核开发人员:-)

从a开始,添加了系统调用的
rt
变体(这不是用户空间函数)以适应更大的信号集-一旦添加了实时信号,信号位掩码将超过32位,因此必须扩展信号集

用户空间函数将智能地调用正确的系统调用,旧的系统调用仍然存在,但已弃用。该函数调用还将静默地防止您篡改本机POSIX线程库NPTL使用的信号


对于问题的更新,您声明要跟踪系统调用以确保传入的参数相同,实际上不需要知道该结构的大小

rt\u sigprocmask
的工作方式
>gcc -o tmp tmp.c
tmp.c: In function ‘main’:
tmp.c:5:24: error: ‘kernel_sigset_t’ undeclared (first use in this function)
    5 |  printf("%d\n", sizeof(kernel_sigset_t));
      |                        ^~~~~~~~~~~~~~~
tmp.c:5:24: note: each undeclared identifier is reported only once for each function it appears in
 _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE