diff options
Diffstat (limited to 'proc/pgrp.c')
-rw-r--r-- | proc/pgrp.c | 115 |
1 files changed, 66 insertions, 49 deletions
diff --git a/proc/pgrp.c b/proc/pgrp.c index 224f7e52..2d6ca93a 100644 --- a/proc/pgrp.c +++ b/proc/pgrp.c @@ -1,5 +1,5 @@ -/* Session and process group manipulation - Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc. +/* Session and process group manipulation + Copyright (C) 1992,93,94,95,96,99,2001,02 Free Software Foundation, Inc. This file is part of the GNU Hurd. @@ -8,7 +8,7 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. -The GNU Hurd is distributed in the hope that it will be useful, +The GNU Hurd is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -25,6 +25,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <sys/errno.h> #include <stdlib.h> #include <signal.h> +#include <assert.h> #include "proc.h" #include "process_S.h" @@ -37,19 +38,22 @@ new_pgrp (pid_t pgid, struct session *sess) { struct pgrp *pg; - + pg = malloc (sizeof (struct pgrp)); + if (! pg) + return NULL; + pg->pg_plist = 0; pg->pg_pgid = pgid; pg->pg_orphcnt = 0; - + pg->pg_session = sess; pg->pg_next = sess->s_pgrps; if (pg->pg_next) pg->pg_next->pg_prevp = &pg->pg_next; sess->s_pgrps = pg; pg->pg_prevp = &sess->s_pgrps; - + add_pgrp_to_hash (pg); return pg; } @@ -59,14 +63,17 @@ static inline struct session * new_session (struct proc *p) { struct session *sess; - + sess = malloc (sizeof (struct session)); + if (! sess) + return NULL; + sess->s_sid = p->p_pid; sess->s_pgrps = 0; sess->s_sessionid = MACH_PORT_NULL; add_session_to_hash (sess); - + return sess; } @@ -93,21 +100,21 @@ free_pgrp (struct pgrp *pg) remove_pgrp_from_hash (pg); free (pg); } - -/* Implement proc_setsid as described in <hurd/proc.defs>. */ + +/* Implement proc_setsid as described in <hurd/process.defs>. */ kern_return_t S_proc_setsid (struct proc *p) { struct session *sess; - + if (!p) return EOPNOTSUPP; - + if (p->p_pgrp->pg_pgid == p->p_pid || pgrp_find (p->p_pid)) return EPERM; - + leave_pgrp (p); - + sess = new_session (p); p->p_pgrp= new_pgrp (p->p_pid, sess); join_pgrp (p); @@ -120,14 +127,15 @@ void boot_setsid (struct proc *p) { struct session *sess; - + sess = new_session (p); p->p_pgrp = new_pgrp (p->p_pid, sess); + assert (p->p_pgrp); join_pgrp (p); return; } -/* Implement proc_getsid as described in <hurd/proc.defs>. */ +/* Implement proc_getsid as described in <hurd/process.defs>. */ kern_return_t S_proc_getsid (struct proc *callerp, pid_t pid, @@ -143,12 +151,12 @@ S_proc_getsid (struct proc *callerp, return 0; } -/* Implement proc_getsessionpids as described in <hurd/proc.defs>. */ +/* Implement proc_getsessionpids as described in <hurd/process.defs>. */ kern_return_t S_proc_getsessionpids (struct proc *callerp, pid_t sid, pid_t **pids, - u_int *npidsp) + size_t *npidsp) { int count; struct pgrp *pg; @@ -156,13 +164,13 @@ S_proc_getsessionpids (struct proc *callerp, struct session *s; pid_t *pp = *pids; u_int npids = *npidsp; - + /* No need to check CALLERP; we don't use it. */ s = session_find (sid); if (!s) return ESRCH; - + count = 0; for (pg = s->s_pgrps; pg; pg = pg->pg_next) for (p = pg->pg_plist; p; p = p->p_gnext) @@ -170,12 +178,15 @@ S_proc_getsessionpids (struct proc *callerp, if (++count <= npids) *pp++ = p->p_pid; } - + if (count > npids) /* They didn't all fit */ { - vm_allocate (mach_task_self (), (vm_address_t *)pids, - count * sizeof (pid_t), 1); + *pids = mmap (0, count * sizeof (pid_t), PROT_READ|PROT_WRITE, + MAP_ANON, 0, 0); + if (*pids == MAP_FAILED) + return errno; + pp = *pids; for (pg = s->s_pgrps; pg; pg = pg->pg_next) for (p = pg->pg_plist; p; p = p->p_gnext) @@ -192,14 +203,14 @@ kern_return_t S_proc_getsessionpgids (struct proc *callerp, pid_t sid, pid_t **pgids, - u_int *npgidsp) + size_t *npgidsp) { int count; struct pgrp *pg; struct session *s; pid_t *pp = *pgids; int npgids = *npgidsp; - + /* No need to check CALLERP; we don't use it. */ s = session_find (sid); @@ -210,12 +221,15 @@ S_proc_getsessionpgids (struct proc *callerp, for (pg = s->s_pgrps; pg; pg = pg->pg_next) if (++count <= npgids) *pp++ = pg->pg_pgid; - + if (count > npgids) /* They didn't all fit. */ { - vm_allocate (mach_task_self (), (vm_address_t *)pgids, - count * sizeof (pid_t), 1); + *pgids = mmap (0, count * sizeof (pid_t), PROT_READ|PROT_WRITE, + MAP_ANON, 0, 0); + if (*pgids == MAP_FAILED) + return errno; + pp = *pgids; for (pg = s->s_pgrps; pg; pg = pg->pg_next) *pp++ = pg->pg_pgid; @@ -230,14 +244,14 @@ kern_return_t S_proc_getpgrppids (struct proc *callerp, pid_t pgid, pid_t **pids, - u_int *npidsp) + size_t *npidsp) { struct proc *p; struct pgrp *pg; pid_t *pp = *pids; unsigned int npids = *npidsp, count; - + /* No need to check CALLERP; we don't use it. */ if (pgid == 0) @@ -253,12 +267,15 @@ S_proc_getpgrppids (struct proc *callerp, for (p = pg->pg_plist; p; p = p->p_gnext) if (++count <= npids) *pp++ = p->p_pid; - + if (count > npids) /* They didn't all fit. */ { - vm_allocate (mach_task_self (), (vm_address_t *)pids, - count * sizeof (pid_t), 1); + *pids = mmap (0, count * sizeof (pid_t), PROT_READ|PROT_WRITE, + MAP_ANON, 0, 0); + if (*pids == MAP_FAILED) + return errno; + pp = *pids; for (p = pg->pg_plist; p; p = p->p_gnext) *pp++ = p->p_pid; @@ -268,13 +285,13 @@ S_proc_getpgrppids (struct proc *callerp, return 0; } -/* Implement proc_getsidport as described in <hurd/proc.defs>. */ +/* Implement proc_getsidport as described in <hurd/process.defs>. */ kern_return_t S_proc_getsidport (struct proc *p, mach_port_t *sessport, mach_msg_type_name_t *sessport_type) { error_t err = 0; - + if (!p) return EOPNOTSUPP; @@ -291,7 +308,7 @@ S_proc_getsidport (struct proc *p, return err; } -/* Implement proc_setpgrp as described in <hurd/proc.defs>. */ +/* Implement proc_setpgrp as described in <hurd/process.defs>. */ kern_return_t S_proc_setpgrp (struct proc *callerp, pid_t pid, @@ -299,7 +316,7 @@ S_proc_setpgrp (struct proc *callerp, { struct proc *p; struct pgrp *pg; - + if (!callerp) return EOPNOTSUPP; @@ -307,10 +324,10 @@ S_proc_setpgrp (struct proc *callerp, if (!p || (p != callerp && p->p_parent != callerp)) return ESRCH; - + if (p->p_parent == callerp && p->p_exec) return EACCES; - + if (!pgid) pgid = p->p_pid; pg = pgrp_find (pgid); @@ -320,7 +337,7 @@ S_proc_setpgrp (struct proc *callerp, || ((pgid != p->p_pid && (!pg || pg->pg_session != callerp->p_pgrp->pg_session)))) return EPERM; - + if (p->p_pgrp != pg) { leave_pgrp (p); @@ -330,11 +347,11 @@ S_proc_setpgrp (struct proc *callerp, else nowait_msg_proc_newids (p->p_msgport, p->p_task, p->p_parent->p_pid, pg->pg_pgid, !pg->pg_orphcnt); - + return 0; } -/* Implement proc_getpgrp as described in <hurd/proc.defs>. */ +/* Implement proc_getpgrp as described in <hurd/process.defs>. */ kern_return_t S_proc_getpgrp (struct proc *callerp, pid_t pid, @@ -343,17 +360,17 @@ S_proc_getpgrp (struct proc *callerp, struct proc *p = pid_find (pid); /* No need to check CALLERP; we don't use it. */ - + if (!p) return ESRCH; - + if (p->p_pgrp) *pgid = p->p_pgrp->pg_pgid; - + return 0; } -/* Implement proc_mark_exec as described in <hurd/proc.defs>. */ +/* Implement proc_mark_exec as described in <hurd/process.defs>. */ kern_return_t S_proc_mark_exec (struct proc *p) { @@ -375,7 +392,7 @@ leave_pgrp (struct proc *p) *p->p_gprevp = p->p_gnext; if (p->p_gnext) p->p_gnext->p_gprevp = p->p_gprevp; - + /* If we were the last member of our pgrp, free it */ if (!pg->pg_plist) free_pgrp (pg); @@ -387,7 +404,7 @@ leave_pgrp (struct proc *p) an orphaned process group -- do the orphaning gook */ struct proc *ip; int dosignal = 0; - + for (ip = pg->pg_plist; ip; ip = ip->p_gnext) { if (ip->p_stopped) @@ -418,7 +435,7 @@ join_pgrp (struct proc *p) if (pg->pg_plist) pg->pg_plist->p_gprevp = &p->p_gnext; pg->pg_plist = p; - + origorphcnt = !!pg->pg_orphcnt; if (p->p_parent->p_pgrp != pg && p->p_parent->p_pgrp->pg_session == pg->pg_session) |