Skip to content

Commit

Permalink
sighandled pseudo system call
Browse files Browse the repository at this point in the history
Allows services to learn how a signal will be handled if
sent to a given process.
Implementation in PM parallels sig_proc() but does not change any state.
  • Loading branch information
antoineL committed Apr 6, 2013
1 parent 8507886 commit 9dcc461
Show file tree
Hide file tree
Showing 10 changed files with 137 additions and 4 deletions.
2 changes: 1 addition & 1 deletion include/minix/Makefile
Expand Up @@ -16,7 +16,7 @@ INCS+= acpi.h audio_fw.h bitmap.h \
netdriver.h optset.h padconf.h partition.h portio.h \
priv.h procfs.h profile.h queryparam.h \
reboot.h rs.h safecopies.h sched.h sef.h sffs.h \
sound.h spin.h sys_config.h sysinfo.h \
sighandled.h sound.h spin.h sys_config.h sysinfo.h \
syslib.h sysutil.h termios.h timers.h type.h \
tty.h u64.h usb.h usb_ch9.h vbox.h \
vboxfs.h vboxif.h vboxtype.h vm.h \
Expand Down
3 changes: 2 additions & 1 deletion include/minix/callnr.h
Expand Up @@ -124,8 +124,9 @@
#define CLOCK_GETTIME 115 /* clock_gettime() */
#define CLOCK_SETTIME 116 /* clock_settime() */

/* Provisional number reusing old value to avoid conflicts */
/* Provisional numbers reusing old values to avoid conflicts */
#define SETPGID 108 /* to PM: setpgid() */
#define SIGHANDLED 109 /* to PM: sighandled() [from services] */

#define TASK_REPLY 121 /* to VFS: reply code from drivers, not
* really a standalone call.
Expand Down
25 changes: 25 additions & 0 deletions include/minix/sighandled.h
@@ -0,0 +1,25 @@

#ifndef _MINIX_SIGHANDLED_H
#define _MINIX_SIGHANDLED_H

#include <minix/endpoint.h>

int sighandled(endpoint_t who, int signo);

/* Which behaviour would the process have in front of some signal: */
#define SIG_IS_IGNORED 0x0001 /* signal is to be ignored */
#define SIG_IS_CAUGHT 0x0002 /* there is a signal handler */
#define SIG_IS_KILLER 0x0004 /* signal kills the process */
#define SIG_IS_STOPPER 0x0008 /* signal stops the process */
#define SIG_IS_CONT 0x0010 /* signal restarts the process */
#define SIG_IS_SYSMSG 0x0020 /* signal is transformed into message */
#define SIG_IS_BLOCKED 0x0080 /* signal is blocked/masked */

#define SIG_IS_PENDING 0x0100 /* a new signal is pending delivery */

#define PROC_IS_STOPPED 0x1000 /* the process is stopped (job control) */
#define PROC_IS_PAUSED 0x2000 /* the process waits (pause, sigsuspend) */
#define PGRP_IS_ORPHAN 0x8000 /* its process group is orphaned */

#endif

1 change: 1 addition & 0 deletions lib/libsys/Makefile
Expand Up @@ -33,6 +33,7 @@ SRCS+= \
sef_liveupdate.c \
sef_ping.c \
sef_signal.c \
sighandled.c \
sqrt_approx.c \
stacktrace.c \
sys_abort.c \
Expand Down
12 changes: 12 additions & 0 deletions lib/libsys/sighandled.c
@@ -0,0 +1,12 @@
#include "syslib.h"
#include <minix/sighandled.h>

int
sighandled(endpoint_t who, int signo)
{
message m;

m.m1_i1 = who;
m.m1_i2 = signo;
return(_syscall(PM_PROC_NR, SIGHANDLED, &m));
}
1 change: 1 addition & 0 deletions servers/pm/param.h
Expand Up @@ -41,6 +41,7 @@
#define sysuname_field m1_i2
#define sysuname_len m1_i3
#define sysuname_value m1_p1
#define who m1_i1

/* The following names are synonyms for the variables in a reply message. */
#define reply_res m_type
Expand Down
1 change: 1 addition & 0 deletions servers/pm/proto.h
Expand Up @@ -75,6 +75,7 @@ int do_pause(void);
int check_sig(pid_t proc_id, int signo, int ksig);
void sig_proc(struct mproc *rmp, int signo, int trace, int ksig);
int do_sigaction(void);
int do_sighandled(void);
int do_sigpending(void);
int do_sigprocmask(void);
int do_sigreturn(void);
Expand Down
92 changes: 92 additions & 0 deletions servers/pm/signal.c
Expand Up @@ -6,6 +6,7 @@
*
* The entry points into this file are:
* do_sigaction: perform the SIGACTION system call
* do_sighandled: perform the SIGHANDLED pseudo system call
* do_sigpending: perform the SIGPENDING system call
* do_sigprocmask: perform the SIGPROCMASK system call
* do_sigreturn: perform the SIGRETURN system call
Expand All @@ -25,6 +26,7 @@
#include <minix/callnr.h>
#include <minix/endpoint.h>
#include <minix/com.h>
#include <minix/sighandled.h>
#include <minix/vm.h>
#include <signal.h>
#include <sys/resource.h>
Expand Down Expand Up @@ -301,6 +303,96 @@ int do_pause()
return(SUSPEND);
}

/*===========================================================================*
* do_sighandled *
*===========================================================================*/
int do_sighandled(void)
{
/* Check how would be handled a signal sent to a process.
* Check to see if the signal is to be caught, ignored, or blocked.
* Check if the signal is already pending.
* Check if the process is stopped or paused (waiting).
*
* The code in this function should be kept synchronised with
* sig_proc below.
*/
register struct mproc *rmp; /* pointer to the process */
int signo; /* signal to examine (1 to _NSIG-1) */
int r, proc_nr;

/* Only system services are allowed to use sighandled. */
if (! (mp->mp_flags & PRIV_PROC) )
return EPERM;
if ((signo=m_in.sig_nr) < 1 || signo >= _NSIG) return(EINVAL);
if(pm_isokendpt(m_in.who, &proc_nr) != OK || proc_nr < 0) {
printf("PM: sighandled: %d?? not ok\n", m_in.who);
return EDEADEPT; /* process is gone. */
}
rmp = &mproc[proc_nr];
if ((rmp->mp_flags & (IN_USE | EXITING)) != IN_USE) {
printf("PM: sighandled: %d?? exiting / not in use\n", m_in.who);
return EDEADEPT; /* process is gone. */
}

r = 0;
if(rmp->mp_flags & PRIV_PROC) {
if (! SIGS_IS_TERMINATION(signo))
r = SIG_IS_SYSMSG;
else
r = SIG_IS_KILLER;
}
else
/* See if the signal cannot be safely ignored (badignore in sig_proc). */
if (sigismember(&noign_sset, signo)
&& ( sigismember(&rmp->mp_ignore, signo)
|| sigismember(&rmp->mp_sigmask, signo) )) {
r = SIG_IS_KILLER;
}
else
if (sigismember(&rmp->mp_ignore, signo))
r = SIG_IS_IGNORED;
else
if (sigismember(&rmp->mp_sigmask, signo))
r = SIG_IS_BLOCKED;
else
if (sigismember(&rmp->mp_catch, signo)) {
r = SIG_IS_CAUGHT;
if (signo==SIGCONT)
/* SIGCONT can be caught, but it still causes process to continue */
r |= SIG_IS_CONT;
}
else
if (sigismember(&ign_sset, signo))
/* Signal defaults to being ignored. */
r = SIG_IS_IGNORED;
else
if (sigismember(&stop_sset, signo))
/* Signal defaults to stop process. */
r = SIG_IS_STOPPER;
else
if (signo==SIGCONT)
r |= SIG_IS_CONT;
else {
/* Terminate process */
r = SIG_IS_KILLER;
}
if (r == 0) {
printf("PM:sighandled: bad logic for sig=%d proc=%d pid=%d\n",
signo, m_in.who, rmp->mp_pid);
r = SIG_IS_IGNORED;
}

if (sigismember(&rmp->mp_sigpending, signo))
r |= SIG_IS_PENDING;

if (rmp->mp_flags & (STOPPED | JOBCTL_STOPPED) )
r |= PROC_IS_STOPPED;
if (rmp->mp_flags & (PAUSED | WAITING | SIGSUSPENDED) )
r |= PROC_IS_PAUSED;
/* FIXME: + ORPHANED */
return r;
}

/*===========================================================================*
* sig_proc *
*===========================================================================*/
Expand Down
2 changes: 1 addition & 1 deletion servers/pm/table.c
Expand Up @@ -120,7 +120,7 @@ int (*call_vec[])(void) = {
do_get, /* 106 = issetugid */
do_getepinfo_o, /* 107 = getepinfo XXX: old implementation*/
do_set, /* 108 = */ /* tentative 108 = setpgid */
no_sys, /* 109 = unused */
do_sighandled, /* 109 = */ /* tentative 109 = sighandled */
no_sys, /* 110 = unused */
do_srv_kill, /* 111 = srv_kill */
no_sys, /* 112 = gcov_flush */
Expand Down
2 changes: 1 addition & 1 deletion servers/vfs/table.c
Expand Up @@ -124,7 +124,7 @@ int (*call_vec[])(void) = {
no_sys, /* 106 = unused */
no_sys, /* 107 = (getepinfo) */
no_sys, /* 108 = */ /* tentative (setpgid) */
no_sys, /* 109 = unused */
no_sys, /* 109 = */ /* tentative (sighandled) */
no_sys, /* 110 = unused */
no_sys, /* 111 = (srv_kill) */
do_gcov_flush, /* 112 = gcov_flush */
Expand Down

0 comments on commit 9dcc461

Please sign in to comment.