From: Jorrit Herder Date: Tue, 2 Aug 2005 15:29:17 +0000 (+0000) Subject: Created new devctl system call to FS. Moved dmap.h header to include/minix/. X-Git-Tag: v3.1.0~481 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/Bv9ARM.ch09.html?a=commitdiff_plain;h=f44725b7778f394240afd377eff7f7899f8fb8d8;p=minix.git Created new devctl system call to FS. Moved dmap.h header to include/minix/. Various updates to support dynamically starting servers and suppress output. --- diff --git a/servers/fs/device.c b/servers/fs/device.c index f75ff9544..6c82c74b4 100644 --- a/servers/fs/device.c +++ b/servers/fs/device.c @@ -20,7 +20,6 @@ #include #include #include -#include "dmap.h" #include "file.h" #include "fproc.h" #include "inode.h" diff --git a/servers/fs/dmap.c b/servers/fs/dmap.c index 0abed3682..d6f668c1a 100644 --- a/servers/fs/dmap.c +++ b/servers/fs/dmap.c @@ -5,10 +5,10 @@ #include "fs.h" #include "fproc.h" -#include "dmap.h" #include #include #include +#include "param.h" /* Some devices may or may not be there in the next table. */ #define DT(enable, opcl, io, driver, flags) \ @@ -28,39 +28,58 @@ -------------- -------- ------ ----------- ----- ------ ---- */ 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 @@ -82,7 +101,7 @@ int dev_style; /* style of the device */ 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; diff --git a/servers/fs/dmap.h b/servers/fs/dmap.h deleted file mode 100644 index 2f82fe87a..000000000 --- a/servers/fs/dmap.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _DMAP_H -#define _DMAP_H - -#include -#include - -/* 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 */ diff --git a/servers/fs/fs.h b/servers/fs/fs.h index a47663f35..af5c6a48f 100644 --- a/servers/fs/fs.h +++ b/servers/fs/fs.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include diff --git a/servers/fs/main.c b/servers/fs/main.c index ada88206c..fc44250a2 100644 --- a/servers/fs/main.c +++ b/servers/fs/main.c @@ -25,7 +25,6 @@ struct super_block; /* proto.h needs to know this */ #include #include #include "buf.h" -#include "dmap.h" #include "file.h" #include "fproc.h" #include "inode.h" @@ -62,7 +61,7 @@ PUBLIC void main() 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(); @@ -85,7 +84,7 @@ PUBLIC void main() 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])(); } diff --git a/servers/fs/misc.c b/servers/fs/misc.c index 0167b2a89..704f66ff0 100644 --- a/servers/fs/misc.c +++ b/servers/fs/misc.c @@ -27,7 +27,6 @@ #include "file.h" #include "fproc.h" #include "inode.h" -#include "dmap.h" #include "param.h" #include "super.h" diff --git a/servers/fs/mount.c b/servers/fs/mount.c index cb58eba85..b7844abbb 100644 --- a/servers/fs/mount.c +++ b/servers/fs/mount.c @@ -10,7 +10,6 @@ #include #include #include "buf.h" -#include "dmap.h" #include "file.h" #include "fproc.h" #include "inode.h" diff --git a/servers/fs/open.c b/servers/fs/open.c index 9c93a13a1..ac1ccee21 100644 --- a/servers/fs/open.c +++ b/servers/fs/open.c @@ -16,7 +16,6 @@ #include #include #include "buf.h" -#include "dmap.h" #include "file.h" #include "fproc.h" #include "inode.h" diff --git a/servers/fs/param.h b/servers/fs/param.h index efd2f65cd..0a3255f8b 100644 --- a/servers/fs/param.h +++ b/servers/fs/param.h @@ -30,6 +30,10 @@ #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 diff --git a/servers/fs/pipe.c b/servers/fs/pipe.c index 48e79a9e5..d86568ce7 100644 --- a/servers/fs/pipe.c +++ b/servers/fs/pipe.c @@ -20,7 +20,6 @@ #include #include #include -#include "dmap.h" #include "file.h" #include "fproc.h" #include "inode.h" diff --git a/servers/fs/proto.h b/servers/fs/proto.h index 9fc1b4bea..6a7cc0d6e 100644 --- a/servers/fs/proto.h +++ b/servers/fs/proto.h @@ -34,19 +34,20 @@ _PROTOTYPE( int dev_io, (int op, Dev_t dev, int proc, void *buf, 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) ); @@ -190,9 +191,9 @@ _PROTOTYPE( int select_notified, (int major, int minor, int ops) ); /* 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) ); diff --git a/servers/fs/select.c b/servers/fs/select.c index 9765b5ddb..aefbf8816 100644 --- a/servers/fs/select.c +++ b/servers/fs/select.c @@ -20,7 +20,6 @@ #define DEBUG_SELECT 0 #include "fs.h" -#include "dmap.h" #include "select.h" #include "file.h" #include "inode.h" diff --git a/servers/fs/table.c b/servers/fs/table.c index 0a2909f4f..23129b6f1 100644 --- a/servers/fs/table.c +++ b/servers/fs/table.c @@ -98,7 +98,7 @@ PUBLIC _PROTOTYPE (int (*call_vec[]), (void) ) = { 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 */ diff --git a/servers/inet/inet.c b/servers/inet/inet.c index 1bbbb27a9..d033a567a 100644 --- a/servers/inet/inet.c +++ b/servers/inet/inet.c @@ -162,10 +162,12 @@ PUBLIC void main() /* 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 diff --git a/servers/is/dmp_fs.c b/servers/is/dmp_fs.c index 51cab0261..76a20fae1 100644 --- a/servers/is/dmp_fs.c +++ b/servers/is/dmp_fs.c @@ -9,9 +9,9 @@ */ #include "is.h" -#include "../fs/dmap.h" #include "../fs/const.h" #include "../fs/fproc.h" +#include PUBLIC struct fproc fproc[NR_PROCS]; diff --git a/servers/is/dmp_kernel.c b/servers/is/dmp_kernel.c index a600dfdc9..a532f6211 100644 --- a/servers/is/dmp_kernel.c +++ b/servers/is/dmp_kernel.c @@ -495,10 +495,7 @@ PUBLIC void proctab_dmp() 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"); diff --git a/servers/is/is.c b/servers/is/is.c index a57c4784d..e430800ff 100644 --- a/servers/is/is.c +++ b/servers/is/is.c @@ -22,57 +22,53 @@ int callnr; /* system call number */ 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); + } + } } @@ -81,28 +77,53 @@ PUBLIC void main(void) /*===========================================================================* * 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 * *===========================================================================*/ diff --git a/servers/is/proto.h b/servers/is/proto.h index efcba7f94..c79c8ec5c 100644 --- a/servers/is/proto.h +++ b/servers/is/proto.h @@ -1,7 +1,7 @@ /* Function prototypes. */ /* main.c */ -_PROTOTYPE( void main, (void) ); +_PROTOTYPE( void main, (int argc, char **argv) ); /* dmp.c */ _PROTOTYPE( int do_fkey_pressed, (message *m) ); diff --git a/servers/pm/forkexit.c b/servers/pm/forkexit.c index ea95e1e75..e396b6db0 100644 --- a/servers/pm/forkexit.c +++ b/servers/pm/forkexit.c @@ -101,8 +101,9 @@ PUBLIC int do_fork() 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 */ } diff --git a/servers/pm/main.c b/servers/pm/main.c index 555f7dec7..aeb38e27f 100644 --- a/servers/pm/main.c +++ b/servers/pm/main.c @@ -54,7 +54,7 @@ PUBLIC void main() 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(); @@ -145,6 +145,8 @@ PRIVATE void pm_init() 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; @@ -201,14 +203,13 @@ PRIVATE void pm_init() 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); @@ -229,10 +230,11 @@ PRIVATE void pm_init() } } - /* 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 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))) @@ -111,8 +119,7 @@ PUBLIC int do_getprocnr() } } return(ESRCH); - } - else { /* return own process number */ + } else { /* return own process number */ mp->mp_reply.procnr = who; } return(OK); diff --git a/servers/pm/param.h b/servers/pm/param.h index 38eba4444..839e1c85c 100644 --- a/servers/pm/param.h +++ b/servers/pm/param.h @@ -4,7 +4,7 @@ #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 diff --git a/servers/sm/Makefile b/servers/sm/Makefile index 71e332c9b..3258319d6 100644 --- a/servers/sm/Makefile +++ b/servers/sm/Makefile @@ -1,5 +1,6 @@ # Makefile for System Process Manager (SM) SERVER = sm +UTIL = service # directories u = /usr @@ -12,25 +13,29 @@ b = $i/ibm 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 diff --git a/servers/sm/manager.c b/servers/sm/manager.c index 3bb771d55..6af6a83f9 100644 --- a/servers/sm/manager.c +++ b/servers/sm/manager.c @@ -13,35 +13,81 @@ #include #include #include +#include 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); diff --git a/servers/sm/sm.c b/servers/sm/sm.c index fccb78174..9b520e691 100644 --- a/servers/sm/sm.c +++ b/servers/sm/sm.c @@ -43,7 +43,7 @@ PUBLIC void main(void) 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. */ @@ -63,10 +63,10 @@ PUBLIC void main(void) /* 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: