Created new devctl system call to FS. Moved dmap.h header to include/minix/.

Various updates to support dynamically starting servers and suppress output.
This commit is contained in:
Jorrit Herder 2005-08-02 15:29:17 +00:00
parent ab7c0a9926
commit f44725b777
25 changed files with 215 additions and 141 deletions

View file

@ -20,7 +20,6 @@
#include <fcntl.h>
#include <minix/callnr.h>
#include <minix/com.h>
#include "dmap.h"
#include "file.h"
#include "fproc.h"
#include "inode.h"

View file

@ -5,10 +5,10 @@
#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) \
@ -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;

View file

@ -1,25 +0,0 @@
#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 */

View file

@ -11,6 +11,7 @@
#include <sys/types.h>
#include <minix/const.h>
#include <minix/type.h>
#include <minix/dmap.h>
#include <limits.h>
#include <errno.h>

View file

@ -25,7 +25,6 @@ struct super_block; /* proto.h needs to know this */
#include <minix/keymap.h>
#include <minix/const.h>
#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])();
}

View file

@ -27,7 +27,6 @@
#include "file.h"
#include "fproc.h"
#include "inode.h"
#include "dmap.h"
#include "param.h"
#include "super.h"

View file

@ -10,7 +10,6 @@
#include <minix/com.h>
#include <sys/stat.h>
#include "buf.h"
#include "dmap.h"
#include "file.h"
#include "fproc.h"
#include "inode.h"

View file

@ -16,7 +16,6 @@
#include <minix/callnr.h>
#include <minix/com.h>
#include "buf.h"
#include "dmap.h"
#include "file.h"
#include "fproc.h"
#include "inode.h"

View file

@ -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

View file

@ -20,7 +20,6 @@
#include <minix/com.h>
#include <sys/select.h>
#include <sys/time.h>
#include "dmap.h"
#include "file.h"
#include "fproc.h"
#include "inode.h"

View file

@ -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) );

View file

@ -20,7 +20,6 @@
#define DEBUG_SELECT 0
#include "fs.h"
#include "dmap.h"
#include "select.h"
#include "file.h"
#include "inode.h"

View file

@ -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 */

View file

@ -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

View file

@ -9,9 +9,9 @@
*/
#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];

View file

@ -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");

View file

@ -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;
int result;
sigset_t sigset;
/* Initialize the server, then go to work. */
init_server();
/* Initialize the server, then go to work. */
init_server(argc, argv);
/* Main loop - get work and do it, forever. */
while (TRUE) {
/* Main loop - get work and do it, forever. */
while (TRUE) {
/* Wait for incoming message, sets 'callnr' and 'who'. */
get_work();
/* 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;
}
}
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);
}
}
/* 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 *
*===========================================================================*/

View file

@ -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) );

View file

@ -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 */
}

View file

@ -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<sizeof(protected)/sizeof(int); i++)
sigfillset(&mproc[i].mp_ignore); /* guard against signals */
/* Tell FS that no more system processes follow and synchronize. */

View file

@ -97,7 +97,15 @@ PUBLIC int do_getprocnr()
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)))
@ -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);

View file

@ -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

View file

@ -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

View file

@ -13,35 +13,81 @@
#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);
/* 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 */
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 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);

View file

@ -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: