mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-18 08:06:32 +00:00
允许用户自定义信号处理函数 (#112)
* new: 用户注册信号处理函数,能够进入自定义的handler * 修复忘了传信号的数字给用户的处理函数的bug * new:sigreturn * 删除注释
This commit is contained in:
@ -11,6 +11,15 @@ ifeq ($(ARCH), __x86_64__)
|
||||
libc_sub_dirs += sysdeps/x86_64
|
||||
endif
|
||||
|
||||
libc_objs:= $(shell find ./*.c)
|
||||
|
||||
ECHO:
|
||||
@echo "$@"
|
||||
|
||||
|
||||
$(libc_objs): ECHO
|
||||
$(CC) $(CFLAGS) -c $@ -o $@.o
|
||||
|
||||
clean:
|
||||
cargo clean
|
||||
rm -rf $(GARBAGE)
|
||||
@ -20,7 +29,7 @@ clean:
|
||||
cd .. ;\
|
||||
done
|
||||
|
||||
libc: unistd.o fcntl.o malloc.o errno.o printf.o stdlib.o ctype.o string.o dirent.o time.o libc_rust
|
||||
libc: $(libc_objs) libc_rust
|
||||
@list='$(libc_sub_dirs)'; for subdir in $$list; do \
|
||||
echo "make all in $$subdir";\
|
||||
cd $$subdir;\
|
||||
@ -28,36 +37,6 @@ libc: unistd.o fcntl.o malloc.o errno.o printf.o stdlib.o ctype.o string.o diren
|
||||
cd ..;\
|
||||
done
|
||||
|
||||
unistd.o: unistd.c
|
||||
$(CC) $(CFLAGS) -c unistd.c -o unistd.o
|
||||
|
||||
fcntl.o: fcntl.c
|
||||
$(CC) $(CFLAGS) -c fcntl.c -o fcntl.o
|
||||
|
||||
malloc.o: malloc.c
|
||||
$(CC) $(CFLAGS) -c malloc.c -o malloc.o
|
||||
|
||||
errno.o: errno.c
|
||||
$(CC) $(CFLAGS) -c errno.c -o errno.o
|
||||
|
||||
printf.o: printf.c
|
||||
$(CC) $(CFLAGS) -c printf.c -o printf.o
|
||||
|
||||
stdlib.o: stdlib.c
|
||||
$(CC) $(CFLAGS) -c stdlib.c -o stdlib.o
|
||||
|
||||
ctype.o: ctype.c
|
||||
$(CC) $(CFLAGS) -c ctype.c -o ctype.o
|
||||
|
||||
string.o: string.c
|
||||
$(CC) $(CFLAGS) -c string.c -o string.o
|
||||
|
||||
dirent.o: dirent.c
|
||||
$(CC) $(CFLAGS) -c dirent.c -o dirent.o
|
||||
|
||||
time.o: time.c
|
||||
$(CC) $(CFLAGS) -c time.c -o time.o
|
||||
|
||||
libc_rust:
|
||||
rustup default nightly
|
||||
cargo +nightly build --release --target ./x86_64-unknown-none.json
|
@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include <libc/src/unistd.h>
|
||||
|
||||
#define SIGHUP 1
|
||||
#define SIGINT 2
|
||||
@ -37,4 +38,52 @@
|
||||
|
||||
/* These should not be considered constants from userland. */
|
||||
#define SIGRTMIN 32
|
||||
#define SIGRTMAX MAX_SIG_NUM
|
||||
#define SIGRTMAX MAX_SIG_NUM
|
||||
|
||||
typedef void (*__sighandler_t) (int);
|
||||
|
||||
// 注意,该结构体最大16字节
|
||||
union __sifields {
|
||||
/* kill() */
|
||||
struct
|
||||
{
|
||||
pid_t _pid; /* 信号发送者的pid */
|
||||
} _kill;
|
||||
};
|
||||
|
||||
// 注意,该结构体最大大小为32字节
|
||||
#define __SIGINFO \
|
||||
struct \
|
||||
{ \
|
||||
int32_t si_signo; /* signal number */ \
|
||||
int32_t si_code; \
|
||||
int32_t si_errno; \
|
||||
uint32_t reserved; /* 保留备用 */ \
|
||||
union __sifields _sifields; \
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
union {
|
||||
__SIGINFO;
|
||||
uint64_t padding[4]; // 让siginfo占用32字节大小
|
||||
};
|
||||
} siginfo_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint64_t set;
|
||||
} sigset_t;
|
||||
|
||||
struct sigaction
|
||||
{
|
||||
// sa_handler和sa_sigaction二选1
|
||||
__sighandler_t sa_handler;
|
||||
void (*sa_sigaction)(int, siginfo_t *, void *);
|
||||
sigset_t sa_mask;
|
||||
uint64_t sa_flags;
|
||||
void (*sa_restorer)(void);
|
||||
};
|
||||
|
||||
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
|
||||
int signal(int signum, __sighandler_t handler);
|
44
user/libs/libc/src/signal.c
Normal file
44
user/libs/libc/src/signal.c
Normal file
@ -0,0 +1,44 @@
|
||||
#include <libc/src/include/signal.h>
|
||||
#include <libc/src/printf.h>
|
||||
#include <libc/src/stddef.h>
|
||||
#include <libsystem/syscall.h>
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize("O0")
|
||||
void __libc_sa_restorer()
|
||||
{
|
||||
// 在这里发起sigreturn,请注意,由于内核需要读取到原来的do_signal时保存的栈帧,因此这里不能发生函数调用(会导致函数压栈),只能够这样来完成sigreturn
|
||||
__asm__ __volatile__("int $0x80 \n\t" ::"a"(SYS_RT_SIGRETURN) : "memory");
|
||||
}
|
||||
#pragma GCC pop_options
|
||||
|
||||
/**
|
||||
* @brief 设置信号处理动作(简单版本)
|
||||
*
|
||||
* @param signum
|
||||
* @param handler
|
||||
* @return int
|
||||
*/
|
||||
int signal(int signum, __sighandler_t handler)
|
||||
{
|
||||
struct sigaction sa = {0};
|
||||
sa.sa_handler = handler;
|
||||
// 由于DragonOS必须由用户程序指定一个sa_restorer,因此这里设置为libc的sa_restorer
|
||||
sa.sa_restorer = &__libc_sa_restorer;
|
||||
// printf("handler address: %#018lx\n", handler);
|
||||
// printf("restorer address: %#018lx\n", &__libc_sa_restorer);
|
||||
sigaction(SIGKILL, &sa, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置信号处理动作
|
||||
*
|
||||
* @param signum 信号
|
||||
* @param act 处理动作(不可为NULL)
|
||||
* @param oldact 返回的旧的处理动作(若为NULL,则不返回)
|
||||
* @return int 错误码(遵循posix)
|
||||
*/
|
||||
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
|
||||
{
|
||||
return syscall_invoke(SYS_SIGACTION, (uint64_t)signum, (uint64_t)act, (uint64_t)oldact, 0, 0, 0, 0, 0);
|
||||
}
|
@ -15,20 +15,22 @@
|
||||
#define SYS_BRK 9
|
||||
#define SYS_SBRK 10
|
||||
|
||||
#define SYS_REBOOT 11 // 重启
|
||||
#define SYS_CHDIR 12 // 切换工作目录
|
||||
#define SYS_REBOOT 11 // 重启
|
||||
#define SYS_CHDIR 12 // 切换工作目录
|
||||
#define SYS_GET_DENTS 13 // 获取目录中的数据
|
||||
#define SYS_EXECVE 14 // 执行新的应用程序
|
||||
#define SYS_WAIT4 15 // 等待进程退出
|
||||
#define SYS_EXIT 16 // 进程退出
|
||||
#define SYS_MKDIR 17 // 创建文件夹
|
||||
#define SYS_EXECVE 14 // 执行新的应用程序
|
||||
#define SYS_WAIT4 15 // 等待进程退出
|
||||
#define SYS_EXIT 16 // 进程退出
|
||||
#define SYS_MKDIR 17 // 创建文件夹
|
||||
#define SYS_NANOSLEEP 18 // 纳秒级休眠
|
||||
#define SYS_CLOCK 19 // 获取当前cpu时间
|
||||
#define SYS_CLOCK 19 // 获取当前cpu时间
|
||||
#define SYS_PIPE 20
|
||||
|
||||
#define SYS_MSTAT 21 // 获取系统的内存状态信息
|
||||
#define SYS_MSTAT 21 // 获取系统的内存状态信息
|
||||
#define SYS_UNLINK_AT 22 // 删除文件夹/删除文件链接
|
||||
#define SYS_KILL 23 // kill一个进程(向这个进程发出信号)
|
||||
#define SYS_KILL 23 // kill一个进程(向这个进程发出信号)
|
||||
#define SYS_SIGACTION 24 // 设置进程的信号处理动作
|
||||
#define SYS_RT_SIGRETURN 25 // 从信号处理函数返回
|
||||
|
||||
/**
|
||||
* @brief 用户态系统调用函数
|
||||
@ -44,4 +46,5 @@
|
||||
* @param arg7
|
||||
* @return long
|
||||
*/
|
||||
long syscall_invoke(uint64_t syscall_id, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7);
|
||||
long syscall_invoke(uint64_t syscall_id, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4,
|
||||
uint64_t arg5, uint64_t arg6, uint64_t arg7);
|
Reference in New Issue
Block a user