好的,所以我刚刚读完了FreeBSD的kill(2)的实现,并试图编写自己的“kill”。此系统调用采用uid
和signum
并将信号发送到uid拥有的进程,不包括调用进程。
如何将uid
传递给系统调用?在kill(2)中,pid
在参数struct kill_args
中。是否存在uid
包含struct kill_args
pid
的方式的结构?如果没有,我可以在内核之外定义一个结构吗?
答案 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;
}
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