mirror of
https://github.com/ish-app/ish.git
synced 2026-05-28 21:10:35 +00:00
Require a siginfo when sending a signal
This commit is contained in:
@@ -345,7 +345,7 @@ canon_wake:
|
||||
if (fg_group != 0) {
|
||||
for (int sig = 0; sig < NUM_SIGS; sig++) {
|
||||
if (queue & (1l << sig))
|
||||
send_group_signal(fg_group, sig);
|
||||
send_group_signal(fg_group, sig, SIGINFO_NIL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -732,7 +732,7 @@ static int tty_ioctl(struct fd *fd, int cmd, void *arg) {
|
||||
void tty_set_winsize(struct tty *tty, struct winsize_ winsize) {
|
||||
tty->winsize = winsize;
|
||||
if (tty->fg_group != 0)
|
||||
send_group_signal(tty->fg_group, SIGWINCH_);
|
||||
send_group_signal(tty->fg_group, SIGWINCH_, SIGINFO_NIL);
|
||||
}
|
||||
|
||||
void tty_hangup(struct tty *tty) {
|
||||
|
||||
+11
-3
@@ -211,7 +211,7 @@ void handle_interrupt(int interrupt) {
|
||||
unsigned syscall_num = cpu->eax;
|
||||
if (syscall_num >= NUM_SYSCALLS || syscall_table[syscall_num] == NULL) {
|
||||
printk("%d missing syscall %d\n", current->pid, syscall_num);
|
||||
send_signal(current, SIGSYS_);
|
||||
deliver_signal(current, SIGSYS_, SIGINFO_NIL);
|
||||
} else {
|
||||
STRACE("%d call %-3d ", current->pid, syscall_num);
|
||||
int result = syscall_table[syscall_num](cpu->ebx, cpu->ecx, cpu->edx, cpu->esi, cpu->edi, cpu->ebp);
|
||||
@@ -220,7 +220,11 @@ void handle_interrupt(int interrupt) {
|
||||
}
|
||||
} else if (interrupt == INT_GPF) {
|
||||
printk("%d page fault on 0x%x at 0x%x\n", current->pid, cpu->segfault_addr, cpu->eip);
|
||||
deliver_signal(current, SIGSEGV_);
|
||||
struct siginfo_ info = {
|
||||
.code = SI_KERNEL_,
|
||||
.fault.addr = cpu->segfault_addr,
|
||||
};
|
||||
deliver_signal(current, SIGSEGV_, info);
|
||||
} else if (interrupt == INT_UNDEFINED) {
|
||||
printk("%d illegal instruction at 0x%x: ", current->pid, cpu->eip);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
@@ -230,7 +234,11 @@ void handle_interrupt(int interrupt) {
|
||||
printk("%02x ", b);
|
||||
}
|
||||
printk("\n");
|
||||
deliver_signal(current, SIGILL_);
|
||||
struct siginfo_ info = {
|
||||
.code = SI_KERNEL_,
|
||||
.fault.addr = cpu->eip,
|
||||
};
|
||||
deliver_signal(current, SIGILL_, info);
|
||||
} else if (interrupt != INT_TIMER) {
|
||||
printk("%d unhandled interrupt %d\n", current->pid, interrupt);
|
||||
sys_exit(interrupt);
|
||||
|
||||
+1
-1
@@ -97,6 +97,6 @@ int err_map(int err) {
|
||||
|
||||
int errno_map() {
|
||||
if (errno == EPIPE)
|
||||
send_signal(current, SIGPIPE_);
|
||||
send_signal(current, SIGPIPE_, SIGINFO_NIL);
|
||||
return err_map(errno);
|
||||
}
|
||||
|
||||
+12
-2
@@ -56,6 +56,7 @@ noreturn void do_exit(int status) {
|
||||
struct rusage_ rusage = rusage_get_current();
|
||||
lock(¤t->group->lock);
|
||||
rusage_add(¤t->group->rusage, &rusage);
|
||||
struct rusage_ group_rusage = current->group->rusage;
|
||||
unlock(¤t->group->lock);
|
||||
|
||||
// the actual freeing needs pids_lock
|
||||
@@ -83,7 +84,16 @@ noreturn void do_exit(int status) {
|
||||
} else {
|
||||
leader->zombie = true;
|
||||
notify(&parent->group->child_exit);
|
||||
send_signal(parent, leader->exit_signal);
|
||||
struct siginfo_ info = {
|
||||
.code = SI_KERNEL_,
|
||||
.child.pid = current->pid,
|
||||
.child.uid = current->uid,
|
||||
.child.status = current->exit_code,
|
||||
.child.utime = clock_from_timeval(group_rusage.utime),
|
||||
.child.stime = clock_from_timeval(group_rusage.stime),
|
||||
};
|
||||
if (leader->exit_signal != 0)
|
||||
send_signal(parent, leader->exit_signal, info);
|
||||
}
|
||||
|
||||
if (exit_hook != NULL)
|
||||
@@ -111,7 +121,7 @@ noreturn void do_exit_group(int status) {
|
||||
// kill everyone else in the group
|
||||
struct task *task;
|
||||
list_for_each_entry(&group->threads, task, group_links) {
|
||||
deliver_signal(task, SIGKILL_);
|
||||
deliver_signal(task, SIGKILL_, SIGINFO_NIL);
|
||||
task->group->stopped = false;
|
||||
notify(&task->group->stopped_cond);
|
||||
}
|
||||
|
||||
+15
-7
@@ -65,13 +65,13 @@ retry:
|
||||
}
|
||||
}
|
||||
|
||||
void deliver_signal(struct task *task, int sig) {
|
||||
void deliver_signal(struct task *task, int sig, struct siginfo_ UNUSED(info)) {
|
||||
lock(&task->sighand->lock);
|
||||
deliver_signal_unlocked(task, sig);
|
||||
unlock(&task->sighand->lock);
|
||||
}
|
||||
|
||||
void send_signal(struct task *task, int sig) {
|
||||
void send_signal(struct task *task, int sig, struct siginfo_ UNUSED(info)) {
|
||||
// signal zero is for testing whether a process exists
|
||||
if (sig == 0)
|
||||
return;
|
||||
@@ -97,6 +97,8 @@ void send_signal(struct task *task, int sig) {
|
||||
}
|
||||
|
||||
bool try_self_signal(int sig) {
|
||||
assert(sig == SIGTTIN_ || sig == SIGTTOU_);
|
||||
|
||||
struct sighand *sighand = current->sighand;
|
||||
lock(&sighand->lock);
|
||||
bool can_send = signal_action(sighand, sig) != SIGNAL_IGNORE &&
|
||||
@@ -107,7 +109,7 @@ bool try_self_signal(int sig) {
|
||||
return can_send;
|
||||
}
|
||||
|
||||
int send_group_signal(dword_t pgid, int sig) {
|
||||
int send_group_signal(dword_t pgid, int sig, struct siginfo_ info) {
|
||||
lock(&pids_lock);
|
||||
struct pid *pid = pid_get(pgid);
|
||||
if (pid == NULL) {
|
||||
@@ -116,7 +118,7 @@ int send_group_signal(dword_t pgid, int sig) {
|
||||
}
|
||||
struct tgroup *tgroup;
|
||||
list_for_each_entry(&pid->pgroup, tgroup, pgroup) {
|
||||
send_signal(tgroup->leader, sig);
|
||||
send_signal(tgroup->leader, sig, info);
|
||||
}
|
||||
unlock(&pids_lock);
|
||||
return 0;
|
||||
@@ -227,7 +229,8 @@ bool receive_signals() {
|
||||
if (now_stopped) {
|
||||
lock(&pids_lock);
|
||||
notify(¤t->parent->group->child_exit);
|
||||
send_signal(current->parent, current->group->leader->exit_signal);
|
||||
// TODO add siginfo
|
||||
send_signal(current->parent, current->group->leader->exit_signal, SIGINFO_NIL);
|
||||
unlock(&pids_lock);
|
||||
}
|
||||
}
|
||||
@@ -462,11 +465,16 @@ int do_kill(pid_t_ pid, dword_t sig, pid_t_ tgid) {
|
||||
STRACE("kill(%d, %d)", pid, sig);
|
||||
if (sig >= NUM_SIGS)
|
||||
return _EINVAL;
|
||||
struct siginfo_ info = {
|
||||
.code = SI_USER_,
|
||||
.kill.pid = current->pid,
|
||||
.kill.uid = current->uid,
|
||||
};
|
||||
// TODO check permissions
|
||||
if (pid == 0)
|
||||
pid = -current->group->pgid;
|
||||
if (pid < 0)
|
||||
return send_group_signal(-pid, sig);
|
||||
return send_group_signal(-pid, sig, info);
|
||||
|
||||
lock(&pids_lock);
|
||||
struct task *task = pid_get_task(pid);
|
||||
@@ -481,7 +489,7 @@ int do_kill(pid_t_ pid, dword_t sig, pid_t_ tgid) {
|
||||
return _ESRCH;
|
||||
}
|
||||
|
||||
send_signal(task, sig);
|
||||
send_signal(task, sig, info);
|
||||
unlock(&pids_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
+45
-3
@@ -51,16 +51,58 @@ struct sigaction_ {
|
||||
#define SIGPWR_ 30
|
||||
#define SIGSYS_ 31
|
||||
|
||||
#define SI_USER_ 0
|
||||
#define SI_TIMER_ -2
|
||||
#define SI_TKILL_ -6
|
||||
#define SI_KERNEL_ 128
|
||||
|
||||
union sigval_ {
|
||||
int_t sv_int;
|
||||
addr_t sv_ptr;
|
||||
};
|
||||
|
||||
struct siginfo_ {
|
||||
int_t signo;
|
||||
int_t code;
|
||||
int_t sig_errno;
|
||||
union {
|
||||
struct {
|
||||
pid_t_ pid;
|
||||
uid_t_ uid;
|
||||
} kill;
|
||||
struct {
|
||||
pid_t_ pid;
|
||||
uid_t_ uid;
|
||||
int_t status;
|
||||
clock_t_ utime;
|
||||
clock_t_ stime;
|
||||
} child;
|
||||
struct {
|
||||
addr_t addr;
|
||||
} fault;
|
||||
struct {
|
||||
addr_t addr;
|
||||
int_t syscall;
|
||||
} sigsys;
|
||||
char __pad[128 - 3 * sizeof(int_t)];
|
||||
};
|
||||
};
|
||||
|
||||
// a reasonable default siginfo
|
||||
static const struct siginfo_ SIGINFO_NIL = {
|
||||
.code = SI_KERNEL_,
|
||||
};
|
||||
|
||||
// send a signal
|
||||
// you better make sure the task isn't gonna get freed under me (pids_lock or current)
|
||||
void send_signal(struct task *task, int sig);
|
||||
void send_signal(struct task *task, int sig, struct siginfo_ info);
|
||||
// send a signal without regard for whether the signal is blocked or ignored
|
||||
void deliver_signal(struct task *task, int sig);
|
||||
void deliver_signal(struct task *task, int sig, struct siginfo_ info);
|
||||
// send a signal to current if it's not blocked or ignored, return whether that worked
|
||||
// exists specifically for sending SIGTTIN/SIGTTOU
|
||||
bool try_self_signal(int sig);
|
||||
// send a signal to all processes in a group, could return ESRCH
|
||||
int send_group_signal(dword_t pgid, int sig);
|
||||
int send_group_signal(dword_t pgid, int sig, struct siginfo_ info);
|
||||
// check for and deliver pending signals on current
|
||||
// returns whether signals were received
|
||||
// must be called without pids_lock
|
||||
|
||||
+6
-3
@@ -77,7 +77,10 @@ dword_t sys_clock_settime(dword_t UNUSED(clock), addr_t UNUSED(tp)) {
|
||||
}
|
||||
|
||||
static void itimer_notify(struct task *task) {
|
||||
send_signal(task, SIGALRM_);
|
||||
struct siginfo_ info = {
|
||||
.code = SI_TIMER_,
|
||||
};
|
||||
send_signal(task, SIGALRM_, info);
|
||||
}
|
||||
|
||||
static int itimer_set(struct tgroup *group, int which, struct timer_spec spec, struct timer_spec *old_spec) {
|
||||
@@ -179,8 +182,8 @@ dword_t sys_times(addr_t tbuf) {
|
||||
if (tbuf) {
|
||||
struct tms_ tmp;
|
||||
struct rusage_ rusage = rusage_get_current();
|
||||
tmp.tms_utime = (rusage.utime.sec * 100) + (rusage.utime.usec/10000);
|
||||
tmp.tms_stime = (rusage.utime.sec * 100) + (rusage.utime.usec/10000);
|
||||
tmp.tms_utime = clock_from_timeval(rusage.utime);
|
||||
tmp.tms_stime = clock_from_timeval(rusage.stime);
|
||||
tmp.tms_cutime = tmp.tms_utime;
|
||||
tmp.tms_cstime = tmp.tms_stime;
|
||||
if (user_put(tbuf, tmp))
|
||||
|
||||
+8
-4
@@ -24,6 +24,10 @@ struct timezone_ {
|
||||
dword_t dsttime;
|
||||
};
|
||||
|
||||
static inline clock_t_ clock_from_timeval(struct timeval_ timeval) {
|
||||
return timeval.sec * 100 + timeval.usec / 10000;
|
||||
}
|
||||
|
||||
#define ITIMER_REAL_ 0
|
||||
#define ITIMER_VIRTUAL_ 1
|
||||
#define ITIMER_PROF_ 2
|
||||
@@ -33,10 +37,10 @@ struct itimerval_ {
|
||||
};
|
||||
|
||||
struct tms_ {
|
||||
dword_t tms_utime; /* user time */
|
||||
dword_t tms_stime; /* system time */
|
||||
dword_t tms_cutime; /* user time of children */
|
||||
dword_t tms_cstime; /* system time of children */
|
||||
clock_t_ tms_utime; /* user time */
|
||||
clock_t_ tms_stime; /* system time */
|
||||
clock_t_ tms_cutime; /* user time of children */
|
||||
clock_t_ tms_cstime; /* system time of children */
|
||||
};
|
||||
|
||||
int_t sys_setitimer(int_t which, addr_t new_val, addr_t old_val);
|
||||
|
||||
Reference in New Issue
Block a user