SIGTRAP generated in PM (where it belongs / no longer in kernel).
Updated Makefiles: servers are now installed in /usr/sbin.
install -S 512w $@
# install with other servers
-install: /usr/sbin/servers/$(SERVER)
-/usr/sbin/servers/$(SERVER): $(SERVER)
+install: /usr/sbin/$(SERVER)
+/usr/sbin/$(SERVER): $(SERVER)
install -o root -cs $? $@
# clean up local files
inet: $(OBJ)
$(CC) -o $@ $(LDFLAGS) $(OBJ) version.c $(LIBS)
-install: /usr/sbin/servers/inet
+install: /usr/sbin/inet
-/usr/sbin/servers/inet: inet
+/usr/sbin/inet: inet
install -c $? $@
clean:
install -S 192w $@
# install with other servers
-install: /usr/sbin/servers/$(SERVER)
-/usr/sbin/servers/$(SERVER): $(SERVER)
+install: /usr/sbin/$(SERVER)
+/usr/sbin/$(SERVER): $(SERVER)
install -o root -cs $? $@
# clean up local files
# install -S 256w $@
# install with other servers
-install: /usr/sbin/servers/$(SERVER)
-/usr/sbin/servers/$(SERVER): $(SERVER)
+install: /usr/sbin/$(SERVER)
+/usr/sbin/$(SERVER): $(SERVER)
install -o root -c $? $@
# install -o root -cs $? $@
* sending the reply. The loop never terminates, unless a panic occurs.
*/
int result;
+ sigset_t sigset;
/* Initialize the server, then go to work. */
init_server();
get_work();
switch (callnr) {
- case NEW_KMESS:
- result = do_new_kmess(&m_in);
- break;
+ case SYS_EVENT:
+ sigset = (sigset_t) m_in.NOTIFY_ARG;
+ if (sigismember(&sigset, SIGKMESS)) {
+ printf("IS proc SIGKMESS\n");
+ result = do_new_kmess(&m_in);
+ } else if (sigismember(&sigset, SIGTERM)) {
+ printf("IS proc SIGTERM\n");
+ } else {
+ report("IS","warning, got unknown signal", NO_NUM);
+ }
+ continue;
case DIAGNOSTICS:
result = do_diagnostics(&m_in);
break;
int i, s;
struct sigaction sigact;
- /* Install signal handler.*/
- sigact.sa_handler = signal_handler;
+ /* Install signal handler. Ask PM to transform signal into message. */
+ sigact.sa_handler = SIG_MESS;
sigact.sa_mask = ~0; /* block all other signals */
sigact.sa_flags = 0; /* default behaviour */
if (sigaction(SIGTERM, &sigact, NULL) != OK)
install -S 256w $@
# install with other servers
-install: /usr/sbin/servers/$(SERVER)
-/usr/sbin/servers/$(SERVER): $(SERVER)
+install: /usr/sbin/$(SERVER)
+/usr/sbin/$(SERVER): $(SERVER)
install -o root -cs $? $@
# clean up local files
rmp->mp_name[PROC_NAME_LEN] = '\0';
sys_exec(who, new_sp, rmp->mp_flags & TRACED, basename, pc);
+ if (rmp->mp_flags & TRACED) check_sig(rmp->mp_pid, SIGTRAP);
+
return(SUSPEND); /* no reply, new program just runs */
}
PUBLIC void main()
{
/* Main routine of the process manager. */
-
int result, s, proc_nr;
struct mproc *rmp;
+ sigset_t sigset;
pm_init(); /* initialize process manager tables */
if (call_nr == SYN_ALARM) {
pm_expire_timers(m_in.NOTIFY_TIMESTAMP);
result = SUSPEND; /* don't reply */
- } else if (call_nr == KSIG_PENDING) { /* signals pending */
- (void) ksig_pending();
+ } else if (call_nr == SYS_EVENT) { /* signals pending */
+ sigset = m_in.NOTIFY_ARG;
+ if (sigismember(&sigset, SIGKSIG)) {
+ (void) ksig_pending();
+ }
result = SUSPEND; /* don't reply */
}
/* Else, if the system call number is valid, perform the call. */
call_nr = m_in.m_type; /* system call number */
/* Process slot of caller. Misuse PM's own process slot if the kernel is
- * calling. The can happen in case of pending kernel signals.
+ * calling. This can happen in case of synchronous alarms (CLOCK) or or
+ * event like pending kernel signals (SYSTEM).
*/
mp = &mproc[who < 0 ? PM_PROC_NR : who];
}
static char core_sigs[] = { SIGQUIT, SIGILL, SIGTRAP, SIGABRT,
SIGEMT, SIGFPE, SIGUSR1, SIGSEGV, SIGUSR2 };
static char ign_sigs[] = { SIGCHLD };
- register int proc_nr;
register struct mproc *rmp;
register char *sig_ptr;
phys_clicks total_clicks, minix_clicks, free_clicks;
/* Set process details found in the image table. */
rmp = &mproc[ip->proc_nr];
- rmp->mp_flags |= IN_USE | DONT_SWAP;
- rmp->mp_pid = get_free_pid();
- rmp->mp_parent = INIT_PROC_NR;
strncpy(rmp->mp_name, ip->proc_name, PROC_NAME_LEN);
- sigfillset(&rmp->mp_ignore);
- sigfillset(&rmp->mp_sigmask);
+ if (ip->proc_nr == INIT_PROC_NR) { /* user process */
+ rmp->mp_pid = INIT_PID;
+ rmp->mp_parent = PM_PROC_NR;
+ rmp->mp_flags |= IN_USE;
+ sigemptyset(&rmp->mp_ignore);
+ rmp->mp_nice = 0;
+ }
+ else { /* system process */
+ rmp->mp_pid = get_free_pid();
+ rmp->mp_parent = INIT_PROC_NR;
+ rmp->mp_flags |= IN_USE | DONT_SWAP | PRIV_PROC;
+ sigfillset(&rmp->mp_ignore);
+ }
+ sigemptyset(&rmp->mp_sigmask);
sigemptyset(&rmp->mp_catch);
+ sigemptyset(&rmp->mp_sig2mess);
/* Get memory map for this process from the kernel. */
if ((s=get_mem_map(ip->proc_nr, rmp->mp_seg)) != OK)
}
}
- /* PM and INIT are somewhat special. Override some details. Set signal
- * handling behaviour for PM, since PM cannot call sigaction() as others.
- */
- mproc[INIT_PROC_NR].mp_pid = INIT_PID;
- mproc[INIT_PROC_NR].mp_nice = 0;
- mproc[INIT_PROC_NR].mp_parent = PM_PROC_NR;
- sigemptyset(&mproc[INIT_PROC_NR].mp_ignore);
- sigemptyset(&mproc[INIT_PROC_NR].mp_sigmask);
-
+ /* PM is somewhat special. Override some details. */
mproc[PM_PROC_NR].mp_pid = PM_PID;
mproc[PM_PROC_NR].mp_parent = PM_PROC_NR;
/* Only support PRIO_PROCESS for now. */
if(arg_which != PRIO_PROCESS)
- return EINVAL;
+ return(EINVAL);
if(arg_who == 0)
rmp_nr = who;
else
if((rmp_nr = proc_from_pid(arg_who)) < 0)
- return ESRCH;
+ return(ESRCH);
rmp = &mproc[rmp_nr];
return EPERM;
/* If GET, that's it. */
-
if(call_nr == GETPRIORITY) {
- return rmp->mp_nice - PRIO_MIN;
+ return(rmp->mp_nice - PRIO_MIN);
}
/* Only root is allowed to reduce the nice level. */
if(rmp->mp_nice > arg_pri && mp->mp_effuid != SUPER_USER)
- return EACCES;
-
+ return(EACCES);
+
/* We're SET, and it's allowed. Do it and tell kernel. */
rmp->mp_nice = arg_pri;
- return sys_setpriority(rmp_nr, arg_pri);
+ return sys_nice(rmp_nr, arg_pri);
}
/*=====================================================================*
return OK;
}
case MMSIGNON: {
+#if DEAD_CODE
/* A user process becomes a task. Simulate an exit by
* releasing a waiting parent and disinheriting children.
*/
rmp->mp_parent = INIT_PROC_NR;
}
}
-
- /* Become like PM and FS. */
- mp->mp_pid = mp->mp_procgrp = 0;
- mp->mp_parent = 0;
+#endif
return(OK); }
#if ENABLE_SWAP
/* Signal handling information. */
sigset_t mp_ignore; /* 1 means ignore the signal, 0 means don't */
sigset_t mp_catch; /* 1 means catch the signal, 0 means don't */
+ sigset_t mp_sig2mess; /* 1 means transform into notify message */
sigset_t mp_sigmask; /* signals to be blocked */
sigset_t mp_sigmask2; /* saved copy of mp_sigmask */
sigset_t mp_sigpending; /* pending signals to be handled */
#define ONSWAP 0x400 /* set if data segment is swapped out */
#define SWAPIN 0x800 /* set if on the "swap this in" queue */
#define DONT_SWAP 0x1000 /* never swap out this process */
+#define PRIV_PROC 0x2000 /* system process, special privileges */
#define NIL_MPROC ((struct mproc *) 0)
-#define NEW_AL 1
/* This file handles signals, which are asynchronous events and are generally
* a messy and unpleasant business. Signals can be generated by the KILL
* system call, or from the keyboard (SIGINT) or from the clock (SIGALRM).
sigaddset(&mp->mp_ignore, m_in.sig_nr);
sigdelset(&mp->mp_sigpending, m_in.sig_nr);
sigdelset(&mp->mp_catch, m_in.sig_nr);
+ sigdelset(&mp->mp_sig2mess, m_in.sig_nr);
+ } else if (svec.sa_handler == SIG_DFL) {
+ sigdelset(&mp->mp_ignore, m_in.sig_nr);
+ sigdelset(&mp->mp_catch, m_in.sig_nr);
+ sigdelset(&mp->mp_sig2mess, m_in.sig_nr);
+ } else if (svec.sa_handler == SIG_MESS) {
+ if (! (mp->mp_flags & PRIV_PROC)) return(EPERM);
+ sigdelset(&mp->mp_ignore, m_in.sig_nr);
+ sigaddset(&mp->mp_sig2mess, m_in.sig_nr);
+ sigdelset(&mp->mp_catch, m_in.sig_nr);
} else {
sigdelset(&mp->mp_ignore, m_in.sig_nr);
- if (svec.sa_handler == SIG_DFL)
- sigdelset(&mp->mp_catch, m_in.sig_nr);
- else
- sigaddset(&mp->mp_catch, m_in.sig_nr);
+ sigaddset(&mp->mp_catch, m_in.sig_nr);
+ sigdelset(&mp->mp_sig2mess, m_in.sig_nr);
}
mp->mp_sigact[m_in.sig_nr].sa_handler = svec.sa_handler;
sigdelset(&svec.sa_mask, SIGKILL);
int signo; /* signal to send to process (1 to _NSIG) */
{
/* Send a signal to a process. Check to see if the signal is to be caught,
- * ignored, or blocked. If the signal is to be caught, coordinate with
- * KERNEL to push a sigcontext structure and a sigframe structure onto
- * the catcher's stack. Also, KERNEL will reset the program counter and
- * stack pointer, so that when the process next runs, it will be executing
- * the signal handler. When the signal handler returns, sigreturn(2)
- * will be called. Then KERNEL will restore the signal context from the
- * sigcontext structure.
- *
+ * ignored, tranformed into a message (for system processes) or blocked.
+ * - If the signal is to be transformed into a message, request the KERNEL to
+ * send the target process a system notification with the pending signal as an
+ * argument.
+ * - If the signal is to be caught, request the KERNEL to push a sigcontext
+ * structure and a sigframe structure onto the catcher's stack. Also, KERNEL
+ * will reset the program counter and stack pointer, so that when the process
+ * next runs, it will be executing the signal handler. When the signal handler
+ * returns, sigreturn(2) will be called. Then KERNEL will restore the signal
+ * context from the sigcontext structure.
* If there is insufficient stack space, kill the process.
*/
DEBUG(m_in.pid == 11, printf("PM: sig_proc ignored sig\n"));
return;
}
-
if (sigismember(&rmp->mp_sigmask, signo)) {
/* Signal should be blocked. */
sigaddset(&rmp->mp_sigpending, signo);
return;
}
+ if (rmp->mp_flags & ONSWAP) {
+ /* Process is swapped out, leave signal pending. */
+ sigaddset(&rmp->mp_sigpending, signo);
+ swap_inqueue(rmp);
+ return;
+ }
+
sigflags = rmp->mp_sigact[signo].sa_flags;
if (sigismember(&rmp->mp_catch, signo)) {
DEBUG(m_in.pid == 11, printf("PM: sig_proc catch sig!\n"));
- if (rmp->mp_flags & ONSWAP) {
- /* Process is swapped out, leave signal pending. */
- sigaddset(&rmp->mp_sigpending, signo);
- swap_inqueue(rmp);
- return;
- }
if (rmp->mp_flags & SIGSUSPENDED)
sm.sm_mask = rmp->mp_sigmask2;
else
}
panic(__FILE__, "warning, sys_sigsend failed", s);
}
+ else if (sigismember(&rmp->mp_sig2mess, signo)) {
+ if (OK != (s=sys_kill(slot,signo)))
+ panic(__FILE__, "warning, sys_kill failed", s);
+ return;
+ }
+
doterminate:
DEBUG(m_in.pid == 11, printf("PM: sig_proc doterminate\n"));
/* Signal should not or cannot be caught. Take default action. */