Various updates to support dynamically starting servers and suppress output.
#include <fcntl.h>
#include <minix/callnr.h>
#include <minix/com.h>
-#include "dmap.h"
#include "file.h"
#include "fproc.h"
#include "inode.h"
#include "fs.h"
#include "fproc.h"
-#include "dmap.h"
#include <string.h>
#include <unistd.h>
#include <minix/com.h>
+#include "param.h"
/* Some devices may or may not be there in the next table. */
#define DT(enable, opcl, io, driver, flags) \
-------------- -------- ------ ----------- ----- ------ ----
*/
struct dmap dmap[NR_DEVICES] = {
- DT(1, no_dev, 0, 0, 0) /* 0 = not used */
- DT(1, gen_opcl, gen_io, MEMORY, 0) /* 1 = /dev/mem */
- DT(ENABLE_FLOPPY, gen_opcl, gen_io, FLOPPY, 0) /* 2 = /dev/fd0 */
- DT(NR_CTRLRS >= 1, gen_opcl, gen_io, CTRLR(0), DMAP_MUTABLE) /* 3 = /dev/c0 */
-#if ENABLE_USER_TTY
- DT(1, tty_opcl, gen_io, TERMINAL, 0) /* 4 = /dev/tty00 */
- DT(1, ctty_opcl,ctty_io,TERMINAL, 0) /* 5 = /dev/tty */
-#else
- DT(1, tty_opcl, gen_io, TTY, 0) /* 4 = /dev/tty00 */
- DT(1, ctty_opcl,ctty_io,TTY, 0) /* 5 = /dev/tty */
-#endif
- DT(ENABLE_PRINTER, gen_opcl, gen_io, PRINTER, 0) /* 6 = /dev/lp */
+ DT(1, no_dev, 0, 0, 0) /* 0 = not used */
+ DT(1, gen_opcl, gen_io, MEMORY, 0) /* 1 = /dev/mem */
+ DT(ENABLE_FLOPPY, gen_opcl, gen_io, NONE, DMAP_MUTABLE) /* 2 = /dev/fd0 */
+ DT(NR_CTRLRS >= 1, gen_opcl, gen_io, CTRLR(0),DMAP_MUTABLE) /* 3 = /dev/c0 */
+ DT(1, tty_opcl, gen_io, TTY, 0) /* 4 = /dev/tty00 */
+ DT(1, ctty_opcl,ctty_io,TTY, 0) /* 5 = /dev/tty */
+ DT(ENABLE_PRINTER, gen_opcl, gen_io, NONE, DMAP_MUTABLE) /* 6 = /dev/lp */
#if (MACHINE == IBM_PC)
- DT(1, no_dev, 0, 0, DMAP_MUTABLE) /* 7 = /dev/ip */
- DT(NR_CTRLRS >= 2, gen_opcl, gen_io, CTRLR(1), DMAP_MUTABLE) /* 8 = /dev/c1 */
- DT(0, 0, 0, 0, DMAP_MUTABLE) /* 9 = not used */
- DT(NR_CTRLRS >= 3, gen_opcl, gen_io, CTRLR(2), DMAP_MUTABLE) /*10 = /dev/c2 */
- DT(0, 0, 0, 0, DMAP_MUTABLE) /*11 = not used */
- DT(NR_CTRLRS >= 4, gen_opcl, gen_io, CTRLR(3), DMAP_MUTABLE) /*12 = /dev/c3 */
- DT(ENABLE_SB16, gen_opcl, gen_io, NONE, 0) /*13 = /dev/audio */
- DT(ENABLE_SB16, gen_opcl, gen_io, NONE, 0) /*14 = /dev/mixer */
+ DT(1, no_dev, 0, 0, DMAP_MUTABLE) /* 7 = /dev/ip */
+ DT(NR_CTRLRS >= 2, gen_opcl, gen_io, CTRLR(1),DMAP_MUTABLE) /* 8 = /dev/c1 */
+ DT(0, 0, 0, 0, DMAP_MUTABLE) /* 9 = not used */
+ DT(NR_CTRLRS >= 3, gen_opcl, gen_io, CTRLR(2),DMAP_MUTABLE) /*10 = /dev/c2 */
+ DT(0, 0, 0, 0, DMAP_MUTABLE) /*11 = not used */
+ DT(NR_CTRLRS >= 4, gen_opcl, gen_io, CTRLR(3),DMAP_MUTABLE) /*12 = /dev/c3 */
+ DT(ENABLE_SB16, gen_opcl, gen_io, NONE, DMAP_MUTABLE) /*13 = /dev/audio */
+ DT(ENABLE_SB16, gen_opcl, gen_io, NONE, DMAP_MUTABLE) /*14 = /dev/mixer */
DT(1, gen_opcl, gen_io, LOG_PROC_NR, 0) /* 15 = /dev/klog */
#endif /* IBM_PC */
};
+
+/*===========================================================================*
+ * do_devctl *
+ *===========================================================================*/
+PUBLIC int do_devctl()
+{
+ int result;
+
+
+ switch(m_in.ctl_req) {
+ case DEV_MAP:
+ /* Try to update device mapping. */
+ result = map_driver(m_in.dev_nr, m_in.driver_nr, m_in.dev_style);
+ break;
+ case DEV_UNMAP:
+ result = ENOSYS;
+ break;
+ default:
+ result = EINVAL;
+ }
+ return(result);
+}
+
+
/*===========================================================================*
* map_driver *
*===========================================================================*/
-PUBLIC int map_driver(major, proc_nr, dev_style)
+PUBLIC int map_driver(major, proc_nr, style)
int major; /* major number of the device */
int proc_nr; /* process number of the driver */
-int dev_style; /* style of the device */
+int style; /* style of the device */
{
/* Set a new device driver mapping in the dmap table. Given that correct
* arguments are given, this only works if the entry is mutable and the
if (! isokprocnr(proc_nr)) return(EINVAL);
/* Try to update the entry. */
- switch (dev_style) {
+ switch (style) {
case STYLE_DEV: dp->dmap_opcl = gen_opcl; break;
case STYLE_TTY: dp->dmap_opcl = tty_opcl; break;
case STYLE_CLONE: dp->dmap_opcl = clone_opcl; break;
+++ /dev/null
-#ifndef _DMAP_H
-#define _DMAP_H
-
-#include <minix/config.h>
-#include <minix/ipc.h>
-
-/* Device table. This table is indexed by major device number. It provides
- * the link between major device numbers and the routines that process them.
- * The table can be update dynamically. The field 'dmap_flags' describe an
- * entry's current status and determines what control options are possible.
- */
-#define DMAP_MUTABLE 0x01 /* mapping can be overtaken */
-#define DMAP_BUSY 0x02 /* driver busy with request */
-
-enum dev_style { STYLE_DEV, STYLE_NDEV, STYLE_TTY, STYLE_CLONE };
-
-extern struct dmap {
- int _PROTOTYPE ((*dmap_opcl), (int, Dev_t, int, int) );
- void _PROTOTYPE ((*dmap_io), (int, message *) );
- int dmap_driver;
- int dmap_flags;
-} dmap[];
-
-
-#endif /* _DMAP_H */
#include <sys/types.h>
#include <minix/const.h>
#include <minix/type.h>
+#include <minix/dmap.h>
#include <limits.h>
#include <errno.h>
#include <minix/keymap.h>
#include <minix/const.h>
#include "buf.h"
-#include "dmap.h"
#include "file.h"
#include "fproc.h"
#include "inode.h"
super_user = (fp->fp_effuid == SU_UID ? TRUE : FALSE); /* su? */
/* Check for special control messages first. */
- if (call_nr == SYS_EVENT) {
+ if (call_nr == SYS_SIG) {
sigset = m_in.NOTIFY_ARG;
if (sigismember(&sigset, SIGKSTOP)) {
do_sync();
printf("FS, warning illegal %d system call by %d\n", call_nr, who);
} else if (fp->fp_pid == PID_FREE) {
error = ENOSYS;
- printf("FS, bad process, who = %d\n", who);
+ printf("FS, bad process, who = %d, call_nr = %d\n", who, call_nr);
} else {
error = (*call_vec[call_nr])();
}
#include "file.h"
#include "fproc.h"
#include "inode.h"
-#include "dmap.h"
#include "param.h"
#include "super.h"
#include <minix/com.h>
#include <sys/stat.h>
#include "buf.h"
-#include "dmap.h"
#include "file.h"
#include "fproc.h"
#include "inode.h"
#include <minix/callnr.h>
#include <minix/com.h>
#include "buf.h"
-#include "dmap.h"
#include "file.h"
#include "fproc.h"
#include "inode.h"
#define pathname m3_ca1
#define pid m1_i3
#define pro m1_i1
+#define ctl_req m4_l1
+#define driver_nr m4_l2
+#define dev_nr m4_l3
+#define dev_style m4_l4
#define rd_only m1_i3
#define real_user_id m1_i2
#define request m1_i2
#include <minix/com.h>
#include <sys/select.h>
#include <sys/time.h>
-#include "dmap.h"
#include "file.h"
#include "fproc.h"
#include "inode.h"
off_t pos, int bytes, int flags) );
_PROTOTYPE( int gen_opcl, (int op, Dev_t dev, int proc, int flags) );
_PROTOTYPE( void gen_io, (int task_nr, message *mess_ptr) );
-_PROTOTYPE( int no_dev, (int op, Dev_t dev, int proc, int flags) );
+_PROTOTYPE( int no_dev, (int op, Dev_t dev, int proc, int flags) );
_PROTOTYPE( int tty_opcl, (int op, Dev_t dev, int proc, int flags) );
_PROTOTYPE( int ctty_opcl, (int op, Dev_t dev, int proc, int flags) );
_PROTOTYPE( int clone_opcl, (int op, Dev_t dev, int proc, int flags) );
_PROTOTYPE( void ctty_io, (int task_nr, message *mess_ptr) );
_PROTOTYPE( int do_ioctl, (void) );
_PROTOTYPE( int do_setsid, (void) );
-_PROTOTYPE( void dev_status, (message *) );
+_PROTOTYPE( void dev_status, (message *) );
/* dmp.c */
_PROTOTYPE( int do_fkey_pressed, (void) );
/* dmap.c */
+_PROTOTYPE( int do_devctl, (void) );
_PROTOTYPE( void map_controllers, (void) );
_PROTOTYPE( int map_driver, (int major, int proc_nr, int dev_style) );
/* timers.c */
_PROTOTYPE( void fs_set_timer, (timer_t *tp, int delta, tmr_func_t watchdog, int arg));
-_PROTOTYPE( void fs_expire_timers, (clock_t now));
-_PROTOTYPE( void fs_cancel_timer, (timer_t *tp));
-_PROTOTYPE( void fs_init_timer, (timer_t *tp));
+_PROTOTYPE( void fs_expire_timers, (clock_t now) );
+_PROTOTYPE( void fs_cancel_timer, (timer_t *tp) );
+_PROTOTYPE( void fs_init_timer, (timer_t *tp) );
/* cdprobe.c */
-_PROTOTYPE( int cdprobe, (void));
+_PROTOTYPE( int cdprobe, (void) );
#define DEBUG_SELECT 0
#include "fs.h"
-#include "dmap.h"
#include "select.h"
#include "file.h"
#include "inode.h"
do_cmostime, /* 78 = cmostime */
do_getsysinfo, /* 79 = getsysinfo */
no_sys, /* 80 = unused */
- no_sys, /* 81 = unused */
+ do_devctl, /* 81 = devctl */
do_fstatfs, /* 82 = fstatfs */
no_sys, /* 83 = memalloc */
no_sys, /* 84 = memfree */
/* Our new identity as a server. */
this_proc = info.proc_nr;
#else /* Minix 3 */
+#if DEAD_CODE
if (svrctl(SYSSIGNON, (void *) NULL) == -1) pause();
+#endif
/* Our new identity as a server. */
- if (getprocnr(&this_proc) != OK)
+ if ((this_proc = getprocnr()) < 0)
ip_panic(( "unable to get own process nr\n"));
#endif
*/
#include "is.h"
-#include "../fs/dmap.h"
#include "../fs/const.h"
#include "../fs/fproc.h"
+#include <minix/dmap.h>
PUBLIC struct fproc fproc[NR_PROCS];
p_rts_flags_str(rp->p_rts_flags));
if (rp->p_rts_flags & (SENDING|RECEIVING)) {
printf(" %-7.7s", proc_name(rp->p_getfrom));
- } else
- if (rp->p_rts_flags == 0) {
- printf(" ");
- }
+ }
printf("\n");
}
if (rp == END_PROC_ADDR) rp = BEG_PROC_ADDR; else printf("--more--\r");
extern int errno; /* error number set by system library */
/* Declare some local functions. */
-FORWARD _PROTOTYPE(void init_server, (void) );
+FORWARD _PROTOTYPE(void init_server, (int argc, char **argv) );
+FORWARD _PROTOTYPE(void exit_server, (void) );
FORWARD _PROTOTYPE(void get_work, (void) );
FORWARD _PROTOTYPE(void reply, (int whom, int result) );
+
/*===========================================================================*
* main *
*===========================================================================*/
-PUBLIC void main(void)
+PUBLIC void main(int argc, char **argv)
{
/* This is the main routine of this service. The main loop consists of
* three major activities: getting new work, processing the work, and
* 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();
-
- /* Main loop - get work and do it, forever. */
- while (TRUE) {
-
- /* Wait for incoming message, sets 'callnr' and 'who'. */
- get_work();
-
- switch (callnr) {
- case SYS_EVENT:
- sigset = (sigset_t) m_in.NOTIFY_ARG;
- if (sigismember(&sigset, SIGTERM)) {
- exit(3);
- /* nothing to do on shutdown */
- }
- if (sigismember(&sigset, SIGKSTOP)) {
- /* nothing to do on shutdown */
- }
- continue;
- case FKEY_PRESSED:
- result = do_fkey_pressed(&m_in);
- break;
- default: {
- printf("Warning, IS got unexpected request %d from %d\n",
- m_in.m_type, m_in.m_source);
- result = EINVAL;
- }
- }
-
- /* Finally send reply message, unless disabled. */
- if (result != EDONTREPLY) {
- reply(who, result);
- }
- }
+ int result;
+ sigset_t sigset;
+
+ /* Initialize the server, then go to work. */
+ init_server(argc, argv);
+
+ /* Main loop - get work and do it, forever. */
+ while (TRUE) {
+
+ /* Wait for incoming message, sets 'callnr' and 'who'. */
+ get_work();
+
+ switch (callnr) {
+ case SYS_SIG:
+ sigset = (sigset_t) m_in.NOTIFY_ARG;
+ if (sigismember(&sigset,SIGTERM) || sigismember(&sigset,SIGKSTOP)) {
+ exit_server();
+ }
+ continue;
+ case FKEY_PRESSED:
+ result = do_fkey_pressed(&m_in);
+ break;
+ default:
+ report("IS","warning, got illegal request from %d\n", m_in.m_source);
+ result = EINVAL;
+ }
+
+ /* Finally send reply message, unless disabled. */
+ if (result != EDONTREPLY) {
+ reply(who, result);
+ }
+ }
}
/*===========================================================================*
* init_server *
*===========================================================================*/
-PRIVATE void init_server()
+PRIVATE void init_server(int argc, char **argv)
{
/* Initialize the information service. */
int fkeys, sfkeys;
int i, s;
+#if DEAD_CODE
struct sigaction sigact;
/* 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)
+ if (sigaction(SIGTERM, &sigact, NULL) < 0)
report("IS","warning, sigaction() failed", errno);
+#endif
- /* Set key mappings. IS takes all of F1-F12 and Shift+F1-F6 . */
+ /* Set key mappings. IS takes all of F1-F12 and Shift+F1-F6. */
fkeys = sfkeys = 0;
for (i=1; i<=12; i++) bit_set(fkeys, i);
for (i=1; i<= 6; i++) bit_set(sfkeys, i);
if ((s=fkey_map(&fkeys, &sfkeys)) != OK)
- report("IS", "warning, sendrec failed:", s);
+ report("IS", "warning, fkey_map failed:", s);
}
+/*===========================================================================*
+ * exit_server *
+ *===========================================================================*/
+PRIVATE void exit_server()
+{
+/* Shut down the information service. */
+ int fkeys, sfkeys;
+ int i,s;
+
+ /* Release the function key mappings requested in init_server().
+ * IS took all of F1-F12 and Shift+F1-F6.
+ */
+ fkeys = sfkeys = 0;
+ for (i=1; i<=12; i++) bit_set(fkeys, i);
+ for (i=1; i<= 6; i++) bit_set(sfkeys, i);
+ if ((s=fkey_unmap(&fkeys, &sfkeys)) != OK)
+ report("IS", "warning, unfkey_map failed:", s);
+
+ /* Done. Now exit. */
+ exit(0);
+}
+
+
/*===========================================================================*
* get_work *
*===========================================================================*/
/* Function prototypes. */
/* main.c */
-_PROTOTYPE( void main, (void) );
+_PROTOTYPE( void main, (int argc, char **argv) );
/* dmp.c */
_PROTOTYPE( int do_fkey_pressed, (message *m) );
sys_newmap(child_nr, rmc->mp_seg);
/* Reply to child to wake it up. */
- setreply(child_nr, 0);
- return(new_pid); /* child's pid */
+ setreply(child_nr, 0); /* only parent gets details */
+ rmp->mp_reply.procnr = child_nr; /* child's process number */
+ return(new_pid); /* child's pid */
}
if (call_nr == SYN_ALARM) {
pm_expire_timers(m_in.NOTIFY_TIMESTAMP);
result = SUSPEND; /* don't reply */
- } else if (call_nr == SYS_EVENT) { /* signals pending */
+ } else if (call_nr == SYS_SIG) { /* signals pending */
sigset = m_in.NOTIFY_ARG;
if (sigismember(&sigset, SIGKSIG)) {
(void) ksig_pending();
static char core_sigs[] = { SIGQUIT, SIGILL, SIGTRAP, SIGABRT,
SIGEMT, SIGFPE, SIGUSR1, SIGSEGV, SIGUSR2 };
static char ign_sigs[] = { SIGCHLD };
+ static int protected[] = {PM_PROC_NR, FS_PROC_NR, SM_PROC_NR,
+ TTY, AT_WINI, MEMORY};
register struct mproc *rmp;
register char *sig_ptr;
phys_clicks total_clicks, minix_clicks, free_clicks;
rmp->mp_parent = PM_PROC_NR;
rmp->mp_flags |= IN_USE;
rmp->mp_nice = 0;
- sigemptyset(&rmp->mp_ignore);
}
else { /* system process */
rmp->mp_pid = get_free_pid();
rmp->mp_parent = SM_PROC_NR;
rmp->mp_flags |= IN_USE | DONT_SWAP | PRIV_PROC;
- sigfillset(&rmp->mp_ignore);
}
+ sigemptyset(&rmp->mp_ignore);
sigemptyset(&rmp->mp_sigmask);
sigemptyset(&rmp->mp_catch);
sigemptyset(&rmp->mp_sig2mess);
}
}
- /* PM is somewhat special. Override some details. */
- sigfillset(&mproc[PM_PROC_NR].mp_ignore); /* guard against signals */
+ /* Override some details. PM is somewhat special. */
mproc[PM_PROC_NR].mp_pid = PM_PID; /* magically override pid */
mproc[PM_PROC_NR].mp_parent = PM_PROC_NR; /* PM doesn't have parent */
+ for (i=0; i<sizeof(protected)/sizeof(int); i++)
+ sigfillset(&mproc[i].mp_ignore); /* guard against signals */
/* Tell FS that no more system processes follow and synchronize. */
int key_len;
int s;
- if (m_in.namelen > 0) { /* lookup process by name */
+ if (m_in.pid >= 0) { /* lookup process by pid */
+ for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++) {
+ if ((rmp->mp_flags & IN_USE) && (rmp->mp_pid==m_in.pid)) {
+ mp->mp_reply.procnr = (int) (rmp - mproc);
+ return(OK);
+ }
+ }
+ return(ESRCH);
+ } else if (m_in.namelen > 0) { /* lookup process by name */
key_len = MIN(m_in.namelen, PROC_NAME_LEN);
if (OK != (s=sys_datacopy(who, (vir_bytes) m_in.addr,
SELF, (vir_bytes) search_key, key_len)))
}
}
return(ESRCH);
- }
- else { /* return own process number */
+ } else { /* return own process number */
mp->mp_reply.procnr = who;
}
return(OK);
#define exec_len m1_i1
#define func m6_f1
#define grp_id m1_i1
-#define namelen m1_i1
+#define namelen m1_i2
#define pid m1_i1
#define procnr m1_i1
#define seconds m1_i1
# Makefile for System Process Manager (SM)
SERVER = sm
+UTIL = service
# directories
u = /usr
CC = exec cc
CFLAGS = -I$i
LDFLAGS = -i
+UTIL_LIBS = -lsys
LIBS = -lsys -lsysutil
+UTIL_OBJ = service.o
OBJ = sm.o manager.o
# build local binary
-all build: $(SERVER)
+all build: $(SERVER) $(UTIL)
+$(UTIL): $(UTIL_OBJ)
+ $(CC) -o $@ $(LDFLAGS) $(UTIL_OBJ) $(UTIL_LIBS)
$(SERVER): $(OBJ)
$(CC) -o $@ $(LDFLAGS) $(OBJ) $(LIBS)
-# install -S 256w $@
# install with other servers
-install: /usr/sbin/$(SERVER)
+install: /bin/$(UTIL) /usr/sbin/$(SERVER)
+/bin/$(UTIL): $(UTIL)
+ install -c $? $@
/usr/sbin/$(SERVER): $(SERVER)
install -o root -c $? $@
-# install -o root -cs $? $@
# clean up local files
clean:
- rm -f $(SERVER) *.o *.bak
+ rm -f $(UTIL) $(SERVER) *.o *.bak
depend:
/usr/bin/mkdep "$(CC) -E $(CPPFLAGS)" *.c > .depend
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <minix/dmap.h>
extern int errno;
-#define EXEC_FAILED 49 /* recognizable exit status */
+#define EXEC_FAILED 49 /* arbitrary, recognizable status */
+#define MAX_PATH_LEN 256 /* maximum path string length */
+#define MAX_ARGS_LEN 4096 /* maximum argument string length */
+#define MAX_ARG_COUNT 1 /* parsed arguments count */
+
+PRIVATE char command[MAX_PATH_LEN+1];
+PRIVATE char arg_buf[MAX_ARGS_LEN+1];
/*===========================================================================*
* do_start *
*===========================================================================*/
PUBLIC int do_start(message *m_ptr)
{
+ message m;
+ int child_proc_nr;
+ int major_nr;
+ enum dev_style dev_style;
pid_t child_pid;
- char command[255] = "/usr/sbin/is";
+ char *args[MAX_ARG_COUNT+1];
+ int s;
/* Obtain command name and parameters. */
+ if (m_ptr->SRV_PATH_LEN > MAX_PATH_LEN) return(E2BIG);
+ if (OK != (s=sys_datacopy(m_ptr->m_source, (vir_bytes) m_ptr->SRV_PATH_ADDR,
+ SELF, (vir_bytes) command, m_ptr->SRV_PATH_LEN))) return(s);
+ command[m_ptr->SRV_PATH_LEN] = '\0';
+ if (command[0] != '/') return(EINVAL);
+
+ if (m_ptr->SRV_ARGS_LEN > 0) {
+ if (m_ptr->SRV_ARGS_LEN > MAX_ARGS_LEN) return(E2BIG);
+ if (OK != (s=sys_datacopy(m_ptr->m_source, (vir_bytes) m_ptr->SRV_ARGS_ADDR,
+ SELF, (vir_bytes) arg_buf, m_ptr->SRV_ARGS_LEN))) return(s);
+ arg_buf[m_ptr->SRV_ARGS_LEN] = '\0';
+ args[0] = &arg_buf[0];
+ args[1] = NULL;
+ } else {
+ args[0] = NULL;
+ }
+ /* Now try to execute the new system service. Fork a new process. The child
+ * process will be inhibited from running by the NO_PRIV flag. Only let the
+ * child run once its privileges have been set by the parent.
+ */
+ if ((s = _taskcall(PM_PROC_NR, FORK, &m)) < 0) /* use raw interface */
+ report("SM", "_taskcall to PM failed", s); /* to get both */
+ child_pid = m.m_type; /* - child's pid */
+ child_proc_nr = m.PR_PROC_NR; /* - process nr */
- /* Now try to execute the new system service. */
- child_pid = fork(); /* normal POSIX fork */
- switch(child_pid) {
- case 0: /* child process, start system service */
- execve(command, NULL, NULL); /* POSIX exec */
+ /* Now branch for parent and child process, and check for error. */
+ switch(child_pid) { /* see fork(2) */
+ case 0: /* child process */
+ execve(command, args, NULL); /* POSIX exec */
report("SM", "warning, exec() failed", errno); /* shouldn't happen */
exit(EXEC_FAILED); /* terminate child */
break;
- case -1: /* fork failed, report error */
+ case -1: /* fork failed */
report("SM", "warning, fork() failed", errno); /* shouldn't happen */
return(errno);
- default: /* parent process */
- report("SM", "new process forked, pid", child_pid);
+ default: /* parent process */
+ if ((major_nr = m_ptr->SRV_DEV_MAJOR) > 0) { /* set driver map */
+ dev_style = STYLE_DEV;
+ if ((s=mapdriver(child_proc_nr, major_nr, dev_style)) < 0) {
+ report("SM", "couldn't map driver", errno);
+ }
+ }
+ if ((s = _taskcall(SYSTEM, SYS_PRIVCTL, &m)) < 0) /* set privileges */
+ report("SM", "_taskcall to SYSTEM failed", s); /* to let child run */
+#if DEAD_CODE
+ printf("SM: started '%s %s', major %d, pid %d, proc_nr %d",
+ command, arg_buf, major_nr, child_pid, child_proc_nr);
+#endif
/* update tables */
}
return(OK);
get_work();
switch (callnr) {
- case SYS_EVENT:
+ case SYS_SIG:
/* Signals are passed by means of a notification message from SYSTEM.
* Extract the map of pending signals from the notification argument.
*/
/* Nothing to do on shutdown. */
}
continue;
- case START_SERVICE:
+ case SRV_UP:
result = do_start(&m_in);
break;
- case STOP_SERVICE:
+ case SRV_DOWN:
result = do_stop(&m_in);
break;
default: