为什么 file_operations 中的 unlocked_ioctl 返回 long,而 sys/ioctl.h 中的 ioctl() 返回 int?

xyz*_*zyz 2 c unix ioctl linux-device-driver linux-kernel

struct file_operations 中的unlocked_ioctl 的签名是

long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
Run Code Online (Sandbox Code Playgroud)

而 man 2 ioctl 说 ioctl(2) 的签名是:

int ioctl(int d, int request, ...);
Run Code Online (Sandbox Code Playgroud)

我知道参数在内核内部是如何被破坏的,但是为什么内核空间中的返回类型是long,而用户空间中的返回类型却是int?当我想返回一个负值作为错误时,这会产生一个问题:由于二补码编码,我返回的所有负值都会变成 -1。

nne*_*neo 5

如果从函数返回负值file_operations,内核会将其解释为负数errno(即错误返回)。然后,用户代码获取-1返回值,并将errno其设置为原始返回值的负值。这与补码无关。

\n

man 2 intro,\xe2\x80\x9c系统调用介绍\xe2\x80\x9d:

\n
\n

出错时,大多数系统调用都会返回一个负错误号(即,\nerrno(3) 中描述的常量之一的负值)。\nC 库包装器向调用者隐藏此详细信息:当\n系统调用返回一个负值,包装器将绝对值复制到 errno 变量中,并返回 -1 作为包装器的返回值。

\n
\n

例如,如果-ENOTTY从 中返回unlocked_ioctl,则用户程序从ioctl和中获取 -1 errno = ENOTTY

\n