在C中调用syscall函数的问题

时间:2017-02-26 14:14:55

标签: c linux gcc linux-kernel system-calls

对于家庭作业,我必须修改linux内核。

我正在使用虚拟机,并且我向内核添加了一个系统调用,我称之为get_unique_id。以下是get_unique_id.c的代码:

#include <linux/linkage.h>
#include <asm/uaccess.h>

asmlinkage long sys_get_unique_id(int * uuid)
{
    // static because we want its state to persist between calls
    static int uid = 0;

    ++uid;

    // assign new uid value to user-provided mem location
    // returns non-zero if success or -EFAULT otherwise
    int ret = put_user(uid, uuid);
    return ret;
}

我还将此行添加到syscalls.h

asmlinkage long sys_get_unique_id(int * uuid);

这行到syscall_32.tbl:

383 i386    get_unique_id       sys_get_unique_id

最后这一行到syscall_64.tbl

548 common  get_unique_id       sys_get_unique_id

重新编译并重新加载内核后,我写了一个小程序来测试我的系统调用,这里是C测试文件的代码:

// get_unique_id_test.c
#include <stdio.h>
#include <limits.h>

#include "syscalls_test.h"

int main(void)
{
    // initialize the ints we want
    int id1;
    int id2;

    // check the id's are unique and that no error occured
    for (int i = INT_MIN; i < INT_MAX - 1; i += 2) {
        long ret1 = get_unique_id(&id1);
        long ret2 = get_unique_id(&id2);

        if (ret1 != 0)
            printf("ERROR: get_unique_id returned: %ld\n", ret1);

        if (ret2 != 0)
            printf("ERROR: get_unique_id returned: %ld\n", ret2);

        if (id2 != id1 + 1)
            printf("ERROR: successive id's did not increment properly: id1 = %d, id2 = %d\n", id1, id2);
    }

    return 0;
}

及其头文件:

// syscalls_test.h
#include <errno.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>

#define __NR_get_unique_id 383

inline long get_unique_id(int * uuid)
{
    return syscall(__NR_get_unique_id, uuid) ? errno : 0;
}

不幸的是,在尝试使用以下命令编译C测试文件时:gcc -std=c99 get_unique_id_test.c -o get_unique_id_test,我收到以下错误:

In file included from get_unique_id_test.c:4:0:
syscalls_test.h: In function ‘get_unique_id’:
syscalls_test.h:10:5: warning: implicit declaration of function        ‘syscall’ [-Wimplicit-function-declaration]
     return syscall(__NR_get_unique_id, uuid) ? errno : 0;
     ^
syscalls_test.h: In function ‘get_unique_id’:
syscalls_test.h:10:5: warning: implicit declaration of function ‘syscall’ [-Wimplicit-function-declaration]
     return syscall(__NR_get_unique_id, uuid) ? errno : 0;
     ^
/tmp/cc1euZ3r.o: In function `main':
get_unique_id_test.c:(.text+0x22): undefined reference to `get_unique_id'
get_unique_id_test.c:(.text+0x34): undefined reference to `get_unique_id'
collect2: error: ld returned 1 exit status

看来gcc找不到get_unique_id(int * uuid)中声明的函数syscalls_test.hsyscall函数,我认为应该在syscall.h中声明,对吗?

我不明白为什么会这样。有人有想法吗?

编辑:使用a3f的解决方案解决了我的问题(见下文) PLUS 移动文件最顶端的#include "syscalls_test.h",正如他在评论中所说的那样。非常感谢你。

2 个答案:

答案 0 :(得分:1)

    在包含#define _GNU_SOURCE或任何其他标题syscall(2)之前
  • unistd.h不是POSIX。
  • 使用static inline代替普通inline。普通inline提供内联定义,但编译器可以自由地忽略它并使用外部定义,而不是你提供的。

答案 1 :(得分:0)

尝试以下方法:

#include <unistd.h>