关于在FreeBSD中编写自己的系统调用的问题

时间:2011-07-01 01:01:45

标签: freebsd kernel system-calls

好的,所以我刚刚读完了FreeBSD的kill(2)的实现,并试图编写自己的“kill”。此系统调用采用uidsignum并将信号发送到uid拥有的进程,不包括调用进程。

如何将uid传递给系统调用?在kill(2)中,pid在参数struct kill_args中。是否存在uid包含struct kill_args pid的方式的结构?如果没有,我可以在内核之外定义一个结构吗?

1 个答案:

答案 0 :(得分:8)

这很容易,但是涉及到一个过程。这是一个安装系统调用的模块。

包括一堆东西

#include <sys/types.h>
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/module.h>
#include <sys/sysent.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/sysproto.h>

定义您的结构以保存参数

struct mykill_args {
    int pid;
    int signo;
};

定义处理函数

static int
mykill(struct thread *td, void *args)
{
    struct mykill_args *uap = args;

    uprintf("mykill called. pid=%d, signo=%d\n", uap->pid, uap->signo);

    return 0;
}

您需要一个sysent对象

static struct sysent mykill_sysent = {
    2,          /* number of arguments */
    mykill      /* function handling system call */
};

和将安装系统调用的偏移量。

/* Choose "the next" value later. */
static int offset = NO_SYSCALL;

load功能

static int
load(struct module *module, int cmd, void *arg)
{
    int error = 0;

    switch (cmd) {
        case MOD_LOAD:
            uprintf("Loading module. Installing syscall at"
                " offset %d\n", offset);
            break;
        case MOD_UNLOAD:
            uprintf("Unloading module. syscall uninstalled from"
                " offset %d\n", offset);
            break;
        default:
            error = EOPNOTSUPP;
            break;
    }

    return error;
}

安装系统调用

SYSCALL_MODULE(mykill, &offset, &mykill_sysent, load, NULL);

您可以使用syscall(2)运行系统调用。或者使用perl :))。这是一个例子

[root@aiur /home/cnicutar/kld-syscall]# kldload ./mykill.ko
Loading module. Installing syscall at offset 210

[cnicutar@aiur ~/kld-syscall]$ perl -e 'syscall(210, 30, 15);'
mykill called. pid=30, signo=15
相关问题