首页 > 解决方案 > 如何在 Linux 中定义具有非默认返回类型的系统调用?

问题描述

我正在尝试定义一个遍历当前正在运行的所有进程的自定义系统调用。函数声明看起来像这样: ssize_t traverse_process(struct customStructure *list, size_t length);

我发现为了定义一个新的系统调用,我们使用 SYSCALL_DEFINEx 宏(在我的例子中是 2)。

但是,我还读到宏实际上等同于asmlinkage long sys_traverse_process(struct customStructure *list, size_t length);.

但是,如您所见,我的 traverse_process 函数声明返回一个 ssize_t。有没有办法在不使用上述宏的情况下定义系统调用?

任何帮助将不胜感激!谢谢你。

标签: clinuxmacroskernelsystem-calls

解决方案


在 Linux 中,返回long是唯一正确的系统调用方式。

系统调用无法返回一个值,该值的大小不同于long.

您是否希望拥有与所有平台ssize_t相同的尺寸?如果是(这是一个正确的期望),那么没有理由更喜欢. 如果您不确定您的返回类型是否适合每个平台,那么您根本无法使用此返回类型。longssize_tlonglong

例如,根据您知道的 C 标准,读取函数返回ssize_t. 但是read系统调用具有long作为返回类型(它是使用宏定义的):DEFINE_SYSCALL

SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
{
    struct fd f = fdget(fd);
    ssize_t ret = -EBADF;

    if (f.file) {
        loff_t pos = file_pos_read(f.file);
        ret = vfs_read(f.file, buf, count, &pos);
        file_pos_write(f.file, pos);
        fdput(f);
    }
    return ret;
}

请注意,尽管long是系统调用的返回类型,但上述实现仍返回 type 的值ssize_t


推荐阅读