41 |
ihash_t proc_hash_table; |
ihash_t proc_hash_table; |
42 |
pthread_mutex_t proc_hash_lock = PTHREAD_MUTEX_INITIALIZER; |
pthread_mutex_t proc_hash_lock = PTHREAD_MUTEX_INITIALIZER; |
43 |
|
|
44 |
|
/* Hash table for process, indexed by PID. |
45 |
|
Hash table for process groups, indexed by group ID. |
46 |
|
Hash table for sessions, indexed by session ID. */ |
47 |
|
ihash_t proc_pidhash; |
48 |
|
ihash_t proc_pgrphash; |
49 |
|
ihash_t proc_sesshash; |
50 |
|
|
51 |
/* Tries to choose a new pid for a process. We return new pid, |
/* Tries to choose a new pid for a process. We return new pid, |
52 |
or zero if we for some reason fail to choose new id. */ |
or zero if we for some reason fail to choose new id. */ |
53 |
static int |
static int |
54 |
choose_pid (void) |
choose_pid (void) |
55 |
{ |
{ |
56 |
static pid_t pid_cnt = 2; |
pid_t pid; |
57 |
|
|
58 |
/* ??? implement some form of random-based pid selection. */ |
do |
59 |
return pid_cnt++; |
pid = random () & 0xffffff; |
60 |
|
while (pid_find (pid) || pid == 0); |
61 |
|
return pid; |
62 |
} |
} |
63 |
|
|
64 |
/* Chain process CHILD into children chain in PARENT. */ |
/* Chain process CHILD into children chain in PARENT. */ |
95 |
} |
} |
96 |
} |
} |
97 |
|
|
98 |
|
/* Check user id for process P. If it is equal |
99 |
|
to UID, return true, otherwize zero. */ |
100 |
|
int |
101 |
|
check_uid_p (struct proc *p, uid_t uid) |
102 |
|
{ |
103 |
|
if (p->p_ucred.cr_uid == uid || p->p_ucred.cr_uid == 0) |
104 |
|
return 1; |
105 |
|
return 0; |
106 |
|
} |
107 |
|
|
108 |
|
|
109 |
/* Exception raise function. EXC_PORT is the proc port, |
/* Exception raise function. EXC_PORT is the proc port, |
132 |
|
|
133 |
trace_printf ("--- GET EXCEPTION FROM PROCESS %d", p->p_pid); |
trace_printf ("--- GET EXCEPTION FROM PROCESS %d", p->p_pid); |
134 |
trace_printf ("--- should send signal %d", signum); |
trace_printf ("--- should send signal %d", signum); |
135 |
|
trace_printf ("--- exc %x code %x subcode %x", |
136 |
|
exception, code, subcode); |
137 |
|
|
138 |
return KERN_FAILURE; |
return KERN_FAILURE; |
139 |
} |
} |
140 |
|
|
241 |
return 0; |
return 0; |
242 |
} |
} |
243 |
|
|
244 |
/* Create a new dummy process. This process can only be used with |
/* Create startup process. This process can only be used with |
245 |
the exec syscall -- since we have no state for the process. */ |
the exec syscall -- since we have no state for the process. */ |
246 |
int |
int |
247 |
proc_dummy (struct proc **pp) |
proc_create_startup (struct proc **pp) |
248 |
{ |
{ |
249 |
|
static char *rootsname = "root"; |
250 |
struct proc *p; |
struct proc *p; |
251 |
int err; |
int err; |
252 |
|
|
279 |
|
|
280 |
p->p_pid = choose_pid (); |
p->p_pid = choose_pid (); |
281 |
*pp = p; |
*pp = p; |
282 |
|
|
283 |
|
p->p_loginleader = 1; |
284 |
|
p->p_login = malloc (sizeof (struct login) + strlen (rootsname) + 1); |
285 |
|
assert (p->p_login); |
286 |
|
|
287 |
|
p->p_login->l_refcnt = 1; |
288 |
|
strcpy (p->p_login->l_name, rootsname); |
289 |
|
|
290 |
|
boot_setsid (p); |
291 |
|
|
292 |
|
add_pid_to_hash (p); |
293 |
|
|
294 |
return 0; |
return 0; |
295 |
} |
} |
296 |
|
|
471 |
} |
} |
472 |
trace_printf ("done 4"); |
trace_printf ("done 4"); |
473 |
|
|
474 |
|
/* ??? */ |
475 |
|
p->p_login = parent->p_login; |
476 |
|
p->p_login->l_refcnt++; |
477 |
|
|
478 |
|
p->p_pgrp = parent->p_pgrp; |
479 |
|
join_pgrp (p); |
480 |
|
|
481 |
/* Inherit fields from the parent. */ |
/* Inherit fields from the parent. */ |
482 |
p->p_ucred = parent->p_ucred; |
p->p_ucred = parent->p_ucred; |
483 |
p->p_cwd = parent->p_cwd; /* ??? vhold */ |
p->p_cwd = parent->p_cwd; /* ??? vhold */ |
502 |
*child_port = p->p_pport; |
*child_port = p->p_pport; |
503 |
*pidp = p->p_pid; |
*pidp = p->p_pid; |
504 |
|
|
505 |
|
add_pid_to_hash (p); |
506 |
|
|
507 |
trace_printf ("spawning process %d", p->p_pid); |
trace_printf ("spawning process %d", p->p_pid); |
508 |
return 0; |
return 0; |
509 |
|
|
596 |
return 0; |
return 0; |
597 |
} |
} |
598 |
|
|
599 |
|
/* Set login name for process P to NAME. |
600 |
|
NAME_LEN is length of NAME string (including '\0'). */ |
601 |
|
int |
602 |
|
nova_S_proc_setlogin (struct proc *p, char *name, |
603 |
|
size_t name_len) |
604 |
|
{ |
605 |
|
struct login *l; |
606 |
|
|
607 |
|
if (! p) |
608 |
|
return EOPNOTSUPP; |
609 |
|
|
610 |
|
if (! check_uid_p (p, 0)) |
611 |
|
return EPERM; |
612 |
|
|
613 |
|
l = malloc (sizeof (struct login) + strlen (name) + 1); |
614 |
|
if (! l) |
615 |
|
return ENOMEM; |
616 |
|
strcpy (l->l_name, name); |
617 |
|
l->l_refcnt = 1; |
618 |
|
if (--p->p_login->l_refcnt) |
619 |
|
free (p->p_login); |
620 |
|
p->p_login = l; |
621 |
|
return 0; |
622 |
|
} |
623 |
|
|
624 |
|
/* Get login name for process P. Return name in NAME. */ |
625 |
|
int |
626 |
|
nova_S_proc_getlogin (struct proc *p, char *name, |
627 |
|
size_t *name_len) |
628 |
|
{ |
629 |
|
size_t len; |
630 |
|
|
631 |
|
if (! p) |
632 |
|
return EOPNOTSUPP; |
633 |
|
|
634 |
|
len = strlen (p->p_login->l_name); |
635 |
|
if (len > *name_len) |
636 |
|
len = *name_len; |
637 |
|
|
638 |
|
strncpy (name, p->p_login->l_name, len); |
639 |
|
*name_len = len; |
640 |
|
return 0; |
641 |
|
} |
642 |
|
|
643 |
|
/* Return user and group IDs for process P. */ |
644 |
|
int |
645 |
|
nova_S_proc_getids (struct proc *p, |
646 |
|
uid_t *uids, int *nuids, |
647 |
|
gid_t *gids, int *ngids) |
648 |
|
{ |
649 |
|
int i; |
650 |
|
|
651 |
|
if (! p) |
652 |
|
return EOPNOTSUPP; |
653 |
|
|
654 |
|
if (*nuids > 0) |
655 |
|
uids [0] = p->p_ucred.cr_uid; |
656 |
|
*nuids = 1; |
657 |
|
if (*ngids > 1) |
658 |
|
{ |
659 |
|
gids [0] = p->p_ucred.cr_gid; |
660 |
|
|
661 |
|
for (i = 1; i < p->p_ucred.cr_ngroups + 1 && i < *ngids; i++) |
662 |
|
gids [i] = p->p_ucred.cr_groups [i - 1]; |
663 |
|
*ngids = i; |
664 |
|
} |
665 |
|
return 0; |
666 |
|
} |
667 |
|
|