diff --git a/sys/compat/darwin/darwin_sysctl.c b/sys/compat/darwin/darwin_sysctl.c index 84e5576aec4e..7ea2f9b514a2 100644 --- a/sys/compat/darwin/darwin_sysctl.c +++ b/sys/compat/darwin/darwin_sysctl.c @@ -1,4 +1,4 @@ -/* $NetBSD: darwin_sysctl.c,v 1.13 2003/07/10 14:47:34 manu Exp $ */ +/* $NetBSD: darwin_sysctl.c,v 1.14 2003/09/06 23:54:47 manu Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -37,22 +37,30 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: darwin_sysctl.c,v 1.13 2003/07/10 14:47:34 manu Exp $"); +__KERNEL_RCSID(0, "$NetBSD: darwin_sysctl.c,v 1.14 2003/09/06 23:54:47 manu Exp $"); #include #include #include #include #include +#include #include +#include #include #include +#include #include +#include + +#include + #include #include +#include #include #include #include @@ -77,6 +85,11 @@ static int darwin_machdep_sysctl static int darwin_user_sysctl (int *, u_int, void *, size_t *, void *, size_t, struct proc *); +static int darwin_sysctl_dokproc(int *, u_int, void *, size_t *); +static void darwin_fill_kproc(struct proc *, struct darwin_kinfo_proc *); +static void native_to_darwin_pflag(int *, int); +static int darwin_procargs(int *, u_int, void *, size_t *, struct proc *); + int darwin_sys___sysctl(struct lwp *l, void *v, register_t *retval) { @@ -206,7 +219,6 @@ darwin_kern_sysctl(name, nlen, oldp, oldlenp, newp, newlen, p) case DARWIN_KERN_HOSTID: case DARWIN_KERN_CLOCKRATE: case DARWIN_KERN_VNODE: - case DARWIN_KERN_PROC: case DARWIN_KERN_FILE: case DARWIN_KERN_PROF: case DARWIN_KERN_POSIX1: @@ -218,6 +230,15 @@ darwin_kern_sysctl(name, nlen, oldp, oldlenp, newp, newlen, p) case DARWIN_KERN_MAXPARTITIONS: return kern_sysctl(name, 1, oldp, oldlenp, newp, newlen, p); break; + + case DARWIN_KERN_PROCARGS: + return darwin_procargs(name + 1, nlen - 1, oldp, oldlenp, p); + break; + + case DARWIN_KERN_PROC: + return darwin_sysctl_dokproc(name, nlen, oldp, oldlenp); + break; + default: return EOPNOTSUPP; } @@ -430,3 +451,531 @@ darwin_sys_getpid(l, v, retval) return 0; } + +/* + * This is stolen from sys/kern/kern_sysctl.c:sysctl_doeproc() + */ +#define DARWIN_KERN_PROCSLOP (5 * sizeof(struct darwin_kinfo_proc)) + +static int +darwin_sysctl_dokproc(int *name, u_int namelen, void *vwhere, size_t *sizep) +{ + struct darwin_kinfo_proc kproc; + struct darwin_kinfo_proc *dp; + struct proc *p; + const struct proclist_desc *pd; + char *where, *dp2; + int type, op, arg; + u_int elem_size, elem_count; + size_t buflen, needed; + int error; + + dp = vwhere; + dp2 = where = vwhere; + buflen = where != NULL ? *sizep : 0; + error = 0; + needed = 0; + type = name[0]; + + if (type == DARWIN_KERN_PROC) { + if (namelen != 3 && + !(namelen == 2 && name[1] == DARWIN_KERN_PROC_ALL)) + return (EINVAL); + op = name[1]; + if (op != DARWIN_KERN_PROC_ALL) + arg = name[2]; + else + arg = 0; /* Quell compiler warning */ + elem_size = elem_count = 0; /* Ditto */ + } else { + if (namelen != 5) + return (EINVAL); + op = name[1]; + arg = name[2]; + elem_size = name[3]; + elem_count = name[4]; + } + + proclist_lock_read(); + + pd = proclists; +again: + for (p = LIST_FIRST(pd->pd_list); p != NULL; p = LIST_NEXT(p, p_list)) { + /* + * Skip embryonic processes. + */ + if (p->p_stat == SIDL) + continue; + /* + * TODO - make more efficient (see notes below). + * do by session. + */ + switch (op) { + + case DARWIN_KERN_PROC_PID: + /* could do this with just a lookup */ + if (p->p_pid != (pid_t)arg) + continue; + break; + + case DARWIN_KERN_PROC_PGRP: + /* could do this by traversing pgrp */ + if (p->p_pgrp->pg_id != (pid_t)arg) + continue; + break; + + case DARWIN_KERN_PROC_SESSION: + if (p->p_session->s_sid != (pid_t)arg) + continue; + break; + + case DARWIN_KERN_PROC_TTY: + if (arg == (int) KERN_PROC_TTY_REVOKE) { + if ((p->p_flag & P_CONTROLT) == 0 || + p->p_session->s_ttyp == NULL || + p->p_session->s_ttyvp != NULL) + continue; + } else if ((p->p_flag & P_CONTROLT) == 0 || + p->p_session->s_ttyp == NULL) { + continue; + } else if (p->p_session->s_ttyp->t_dev != + darwin_to_native_dev((dev_t)arg)) + continue; + break; + + case DARWIN_KERN_PROC_UID: + if (p->p_ucred->cr_uid != (uid_t)arg) + continue; + break; + + case DARWIN_KERN_PROC_RUID: + if (p->p_cred->p_ruid != (uid_t)arg) + continue; + break; + + case DARWIN_KERN_PROC_ALL: + /* allow everything */ + break; + + default: + error = EINVAL; + goto cleanup; + } + if (buflen >= sizeof(struct darwin_kinfo_proc)) { + darwin_fill_kproc(p, &kproc); + error = copyout((caddr_t)&kproc, dp, sizeof(kproc)); + if (error) + goto cleanup; + dp++; + buflen -= sizeof(struct darwin_kinfo_proc); + } + needed += sizeof(struct darwin_kinfo_proc); + } + pd++; + if (pd->pd_list != NULL) + goto again; + proclist_unlock_read(); + + if (where != NULL) { + *sizep = (caddr_t)dp - where; + if (needed > *sizep) + return (ENOMEM); + } else { + needed += DARWIN_KERN_PROCSLOP; + *sizep = needed; + } + return (0); + cleanup: + proclist_unlock_read(); + return (error); +} + +/* + * Native struct proc to Darin's struct kinfo_proc + */ +static void +darwin_fill_kproc(p, dkp) + struct proc *p; + struct darwin_kinfo_proc *dkp; +{ + struct lwp *l; + struct darwin_extern_proc *dep; + struct darwin_eproc *de; + + printf("fillkproc: pid %d\n", p->p_pid); + l = proc_representative_lwp(p); + (void)memset(dkp, 0, sizeof(*dkp)); + + dep = (struct darwin_extern_proc *)&dkp->kp_proc; + de = (struct darwin_eproc *)&dkp->kp_eproc; + + /* (ptr) dep->p_un */ + /* (ptr) dep->p_vmspace */ + /* (ptr) dep->p_sigacts */ + native_to_darwin_pflag(&dep->p_flag, p->p_flag); + dep->p_stat = p->p_stat; /* XXX Neary the same */ + dep->p_pid = p->p_pid; + dep->p_oppid = p->p_opptr->p_pid; + dep->p_dupfd = p->p_dupfd; + /* dep->userstack */ + /* dep->exit_thread */ + /* dep->p_debugger */ + /* dep->p_sigwait */ + dep->p_estcpu = p->p_estcpu; + dep->p_cpticks = p->p_cpticks; + dep->p_pctcpu = p->p_pctcpu; + /* (ptr) dep->p_wchan */ + /* (ptr) dep->p_wmesg */ + /* dep->p_swtime */ + /* dep->p_slptime */ + /* dep->p_realtimer */ + memcpy(&dep->p_rtime, &p->p_rtime, sizeof(p->p_rtime)); + dep->p_uticks = p->p_uticks; + dep->p_sticks = p->p_sticks; + dep->p_iticks = p->p_iticks; + dep->p_traceflag = p->p_traceflag; /* XXX */ + /* (ptr) dep->p_tracep */ + native_sigset13_to_sigset(&dep->p_siglist, + &p->p_sigctx.ps_siglist); + /* (ptr) dep->p_textvp */ + /* dep->p_holdcnt */ + native_sigset13_to_sigset(&dep->p_sigmask, + &p->p_sigctx.ps_sigmask); + native_sigset13_to_sigset(&dep->p_sigignore, + &p->p_sigctx.ps_sigignore); + native_sigset13_to_sigset(&dep->p_sigcatch, + &p->p_sigctx.ps_sigcatch); + dep->p_priority = l->l_priority; + dep->p_nice = p->p_nice; + (void)strlcpy(dep->p_comm, p->p_comm, DARWIN_MAXCOMLEN); + /* (ptr) dep->p_pgrp */ + /* (ptr) dep->p_addr */ + dep->p_xstat = p->p_xstat; + dep->p_acflag = p->p_acflag; /* XXX accounting flags */ + /* (ptr) dep->p_ru */ + + /* (ptr) */ de->e_paddr = (struct darwin_proc *)p; + /* (ptr) */ de->e_sess = + (struct darwin_session *)p->p_session; + de->e_pcred.pc_ruid = p->p_cred->p_ruid; + de->e_pcred.pc_svuid = p->p_cred->p_svuid; + de->e_pcred.pc_rgid = p->p_cred->p_rgid; + de->e_pcred.pc_svgid = p->p_cred->p_svgid; + de->e_pcred.pc_refcnt = p->p_cred->p_refcnt; + de->e_ucred.cr_ref = p->p_ucred->cr_ref; + de->e_ucred.cr_uid = p->p_ucred->cr_uid; + de->e_ucred.cr_ngroups = p->p_ucred->cr_ngroups; + (void)memcpy(de->e_ucred.cr_groups, + p->p_ucred->cr_groups, sizeof(gid_t) * DARWIN_NGROUPS); + de->e_vm.vm_refcnt = p->p_vmspace->vm_refcnt; + de->e_vm.vm_rssize = p->p_vmspace->vm_rssize; + de->e_vm.vm_swrss = p->p_vmspace->vm_swrss; + de->e_vm.vm_tsize = p->p_vmspace->vm_tsize; + de->e_vm.vm_dsize = p->p_vmspace->vm_dsize; + de->e_vm.vm_ssize = p->p_vmspace->vm_ssize; + de->e_vm.vm_taddr = p->p_vmspace->vm_taddr; + de->e_vm.vm_daddr = p->p_vmspace->vm_daddr; + de->e_vm.vm_maxsaddr = p->p_vmspace->vm_maxsaddr; + de->e_ppid = p->p_pptr->p_pid; + de->e_pgid = p->p_pgid; + de->e_jobc = p->p_pgrp->pg_jobc; + if ((p->p_flag & P_CONTROLT) && (p->p_session->s_ttyp != NULL)) { + de->e_tdev = + native_to_darwin_dev(p->p_session->s_ttyp->t_dev); + de->e_tpgid = p->p_session->s_ttyp->t_pgrp ? + p->p_session->s_ttyp->t_pgrp->pg_id : NO_PGID; + /* (ptr) */ de->e_tsess = (struct darwin_session *) + p->p_session->s_ttyp->t_session; + } else { + de->e_tdev = NODEV; + /* de->e_tpgid */ + /* (ptr) de->e_tsess */ + } + if (l->l_wmesg) + strlcpy(de->e_wmesg, l->l_wmesg, DARWIN_WMESGLEN); + de->e_xsize = 0; + de->e_xrssize = 0; + de->e_xccount = 0; + de->e_xswrss = 0; + de->e_flag = p->p_session->s_ttyvp ? DARWIN_EPROC_CTTY : 0; + + if (SESS_LEADER(p)) + de->e_flag |= DARWIN_EPROC_SLEADER; + (void)strlcpy(de->e_login, + p->p_session->s_login, DARWIN_COMAPT_MAXLOGNAME); + /* de->e_spare */ + + return; +} + +static void +native_to_darwin_pflag(dfp, bf) + int *dfp; + int bf; +{ + int df = 0; + + if (bf & P_ADVLOCK) + df |= DARWIN_P_ADVLOCK; + if (bf & P_CONTROLT) + df |= DARWIN_P_CONTROLT; + if (bf & P_NOCLDSTOP) + df |= DARWIN_P_NOCLDSTOP; + if (bf & P_PPWAIT) + df |= DARWIN_P_PPWAIT; + if (bf & P_PROFIL) + df |= DARWIN_P_PROFIL; + if (bf & P_SUGID) + df |= DARWIN_P_SUGID; + if (bf & P_SYSTEM) + df |= DARWIN_P_SYSTEM; + if (bf & P_TRACED) + df |= DARWIN_P_TRACED; + if (bf & P_WAITED) + df |= DARWIN_P_WAITED; + if (bf & P_WEXIT) + df |= DARWIN_P_WEXIT; + if (bf & P_EXEC) + df |= DARWIN_P_EXEC; + if (bf & P_OWEUPC) + df |= DARWIN_P_OWEUPC; + if (bf & P_FSTRACE) + df |= DARWIN_P_FSTRACE; + if (bf & P_NOCLDWAIT) + df |= DARWIN_P_NOCLDWAIT; + if (bf & P_NOCLDWAIT) + df |= DARWIN_P_NOCLDWAIT; + + *dfp = df; + return; +} + +/* Derived from sys/kern/kern_sysctl.c:sysctl_procargs() */ +static int +darwin_procargs(name, namelen, where, sizep, up) + int *name; + u_int namelen; + void *where; + size_t *sizep; + struct proc *up; +{ + struct ps_strings pss; + struct proc *p; + size_t len, upper_bound, xlen, i; + struct uio auio; + struct iovec aiov; + vaddr_t argv; + pid_t pid; + int nargv, nenv, nstr, error; + char *arg; + char *tmp; + + if (namelen != 1) + return (EINVAL); + pid = name[0]; + + /* check pid */ + if ((p = pfind(pid)) == NULL) + return (EINVAL); + + /* only root or same user change look at the environment */ + if (up->p_ucred->cr_uid != 0) { + if (up->p_cred->p_ruid != p->p_cred->p_ruid || + up->p_cred->p_ruid != p->p_cred->p_svuid) + return (EPERM); + } + + if (sizep != NULL && where == NULL) { + *sizep = ARG_MAX; /* XXX XXX XXX */ + return (0); + } + if (where == NULL || sizep == NULL) + return (EINVAL); + + /* + * Zombies don't have a stack, so we can't read their psstrings. + * System processes also don't have a user stack. + */ + if (P_ZOMBIE(p) || (p->p_flag & P_SYSTEM) != 0) + return (EINVAL); + + /* + * Lock the process down in memory. + */ + /* XXXCDC: how should locking work here? */ + if ((p->p_flag & P_WEXIT) || (p->p_vmspace->vm_refcnt < 1)) + return (EFAULT); + + p->p_vmspace->vm_refcnt++; /* XXX */ + + /* + * Allocate a temporary buffer to hold the arguments. + */ + arg = malloc(PAGE_SIZE, M_TEMP, M_WAITOK); + + /* + * Zero fill the destination buffer. + */ + (void)memset(arg, 0, PAGE_SIZE); + upper_bound = *sizep; + len = 0; + while (len < upper_bound) { + if (len + PAGE_SIZE > upper_bound) + xlen = len - upper_bound; + else + xlen = PAGE_SIZE; + + if ((error = copyout(arg, (char *)where + len, xlen)) != 0) + goto done; + + len += PAGE_SIZE; + } + + /* + * Read in the ps_strings structure. + */ + aiov.iov_base = &pss; + aiov.iov_len = sizeof(pss); + auio.uio_iov = &aiov; + auio.uio_iovcnt = 1; + auio.uio_offset = (vaddr_t)p->p_psstr; + auio.uio_resid = sizeof(pss); + auio.uio_segflg = UIO_SYSSPACE; + auio.uio_rw = UIO_READ; + auio.uio_procp = NULL; + if ((error = uvm_io(&p->p_vmspace->vm_map, &auio)) != 0) + goto done; + + /* + * Get argument vector address and length. Since we want to + * copy argv and env at the same time, we add their lengths. + */ + memcpy(&nargv, (char *)&pss + p->p_psnargv, sizeof(nargv)); + memcpy(&nenv, (char *)&pss + p->p_psnenv, sizeof(nargv)); + nstr = nargv + nenv; + memcpy(&tmp, (char *)&pss + p->p_psargv, sizeof(tmp)); + + auio.uio_offset = (off_t)(long)tmp; + aiov.iov_base = &argv; + aiov.iov_len = sizeof(argv); + auio.uio_iov = &aiov; + auio.uio_iovcnt = 1; + auio.uio_resid = sizeof(argv); + auio.uio_segflg = UIO_SYSSPACE; + auio.uio_rw = UIO_READ; + auio.uio_procp = NULL; + if ((error = uvm_io(&p->p_vmspace->vm_map, &auio)) != 0) + goto done; + + + /* + * Check the whole argument vector to discover its size + * We have to do this since Darwin's ps insist about having + * the data at the end of the buffer. + */ + len = 0; + upper_bound = *sizep; + for (; nstr != 0 && len < upper_bound; len += xlen) { + aiov.iov_base = arg; + aiov.iov_len = PAGE_SIZE; + auio.uio_iov = &aiov; + auio.uio_iovcnt = 1; + auio.uio_offset = argv + len; + xlen = PAGE_SIZE - ((argv + len) & PAGE_MASK); + auio.uio_resid = xlen; + auio.uio_segflg = UIO_SYSSPACE; + auio.uio_rw = UIO_READ; + auio.uio_procp = NULL; + error = uvm_io(&p->p_vmspace->vm_map, &auio); + if (error) + goto done; + + for (i = 0;i < xlen && nstr != 0; i++) { + if (arg[i] == '\0') + nstr--; /* one full string */ + } + + /* + * Make sure we don't reach the + * end of the user's buffer. + */ + if (len + i > upper_bound) + i = upper_bound - len; + + if (nstr == 0) { + len += i; + break; + } + } + + /* + * Try to keep one null word at the + * end, and align on a word boundary + */ + len = (((u_long)where + len - 5) & ~0x3UL) - (u_long)where; + len = upper_bound - len; + + /* + * Align to a word boundary, and copy the program name + */ + len = (((u_long)where + len - 1) & ~0x3UL) - (u_long)where; + len = len - strlen(p->p_comm); + if (len < 0) + len = 0; + + error = copyout(p->p_comm, (char *)where + len, strlen(p->p_comm) + 1); + if (error != 0) + goto done; + + len = len + strlen(p->p_comm); + len = (((u_long)where + len + 5) & ~0x3UL) - (u_long)where; + + /* + * Now copy in the actual argument vector, one page at a time, + * since we don't know how long the vector is (though, we do + * know how many NUL-terminated strings are in the vector). + */ + upper_bound = *sizep; + nstr = nargv + nenv; + for (; nstr != 0 && len < upper_bound; len += xlen) { + aiov.iov_base = arg; + aiov.iov_len = PAGE_SIZE; + auio.uio_iov = &aiov; + auio.uio_iovcnt = 1; + auio.uio_offset = argv + len; + xlen = PAGE_SIZE - ((argv + len) & PAGE_MASK); + auio.uio_resid = xlen; + auio.uio_segflg = UIO_SYSSPACE; + auio.uio_rw = UIO_READ; + auio.uio_procp = NULL; + error = uvm_io(&p->p_vmspace->vm_map, &auio); + if (error) + goto done; + + for (i = 0;i < xlen && nstr != 0; i++) { + if (arg[i] == '\0') + nstr--; /* one full string */ + } + + /* + * Make sure we don't copyout past the end of the user's + * buffer. + */ + if (len + i > upper_bound) + i = upper_bound - len; + + if ((error = copyout(arg, (char *)where + len, i)) != 0) + break; + + if (nstr == 0) { + len += i; + break; + } + } + +done: + uvmspace_free(p->p_vmspace); + + free(arg, M_TEMP); + return (error); +} diff --git a/sys/compat/darwin/darwin_sysctl.h b/sys/compat/darwin/darwin_sysctl.h index 9ef6975fbead..0764d257b000 100644 --- a/sys/compat/darwin/darwin_sysctl.h +++ b/sys/compat/darwin/darwin_sysctl.h @@ -1,4 +1,4 @@ -/* $NetBSD: darwin_sysctl.h,v 1.4 2003/06/29 22:29:15 fvdl Exp $ */ +/* $NetBSD: darwin_sysctl.h,v 1.5 2003/09/06 23:54:47 manu Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -39,6 +39,8 @@ #ifndef _DARWIN_SYSCTL_H_ #define _DARWIN_SYSCTL_H_ +#include + extern pid_t darwin_init_pid; #define EMUL_DARWIN_INIT_PID 1 @@ -215,4 +217,169 @@ int darwin_sysctl(int *, u_int, void *, #define DARWIN_CTL_DEBUG_VALUE 1 #define DARWIN_CTL_DEBUG_MAXID 20 + +/* For KERN_PROC */ +struct darwin_ucred { + u_long cr_ref; + uid_t cr_uid; + short cr_ngroups; +#define DARWIN_NGROUPS 16 + gid_t cr_groups[DARWIN_NGROUPS]; +}; + +struct darwin_pcred { + struct darwin_lock__bsd__ { + struct darwin_slock lk_interlock; + u_int lk_flags; + int lk_sharecount; + int lk_waitcount; + short lk_exclusivecount; +#undef lk_prio /* Defined in */ + short lk_prio; + char *lk_wmesg; +#undef lk_timo /* Defined in */ + int lk_timo; +#undef lk_lockholder /* Defined in */ + pid_t lk_lockholder; + void *lk_lockthread; + } pc_lock; + struct darwin_ucred *pc_ucred; + uid_t pc_ruid; + uid_t pc_svuid; + gid_t pc_rgid; + gid_t pc_svgid; + int pc_refcnt; +}; + +struct darwin_vmspace { + int vm_refcnt; + caddr_t vm_shm; + segsz_t vm_rssize; + segsz_t vm_swrss; + segsz_t vm_tsize; + segsz_t vm_dsize; + segsz_t vm_ssize; + caddr_t vm_taddr; + caddr_t vm_daddr; + caddr_t vm_maxsaddr; +}; + +struct darwin_extern_proc { + union { + struct { + struct darwin_proc *__p_forw; + struct darwin_proc *__p_back; + } p_st1; + struct timeval __p_starttime; + } p_un; + struct darwin_vmspace *p_vmspace; + struct darwin_sigacts *p_sigacts; + int p_flag; + char p_stat; + pid_t p_pid; + pid_t p_oppid; + int p_dupfd; + caddr_t user_stack; + void *exit_thread; + int p_debugger; + mach_boolean_t sigwait; + u_int p_estcpu; + int p_cpticks; + fixpt_t p_pctcpu; + void *p_wchan; + char *p_wmesg; + u_int p_swtime; + u_int p_slptime; + struct itimerval p_realtimer; + struct timeval p_rtime; + u_quad_t p_uticks; + u_quad_t p_sticks; + u_quad_t p_iticks; + int p_traceflag; + struct darwin_vnode *p_tracep; + int p_siglist; + struct darwin_vnode *p_textvp; + int p_holdcnt; + sigset13_t p_sigmask; + sigset13_t p_sigignore; + sigset13_t p_sigcatch; + u_char p_priority; + u_char p_usrpri; + char p_nice; +#define DARWIN_MAXCOMLEN 16 + char p_comm[DARWIN_MAXCOMLEN + 1]; + struct darwin_pgrp *p_pgrp; + struct darwin_user *p_addr; + u_short p_xstat; + u_short p_acflag; + struct darwin_rusage *p_ru; +}; + +struct darwin_kinfo_proc { + /* + * kp_proc is a struct darwin_extern_proc. + * Declaring struct darwin_extern_proc here causes an allignement + * on a word boundary. We replace it by a char array to avoid that. + */ + char kp_proc[196]; + struct darwin_eproc { + struct darwin_proc *e_paddr; + struct darwin_session *e_sess; + struct darwin_pcred e_pcred; + struct darwin_ucred e_ucred; + struct darwin_vmspace e_vm; + pid_t e_ppid; + pid_t e_pgid; + short e_jobc; + dev_t e_tdev; + pid_t e_tpgid; + struct darwin_session *e_tsess; +#define DARWIN_WMESGLEN 7 + char e_wmesg[DARWIN_WMESGLEN + 1]; + segsz_t e_xsize; + short e_xrssize; + short e_xccount; + short e_xswrss; + long e_flag; +#define DARWIN_EPROC_CTTY 0x01 +#define DARWIN_EPROC_SLEADER 0x02 +#define DARWIN_COMAPT_MAXLOGNAME 12 + char e_login[DARWIN_COMAPT_MAXLOGNAME]; + long e_spare[4]; + } kp_eproc; +}; + +/* p_flag for Darwin */ +#define DARWIN_P_ADVLOCK 0x00001 +#define DARWIN_P_CONTROLT 0x00002 +#define DARWIN_P_INMEM 0x00004 +#define DARWIN_P_NOCLDSTOP 0x00008 +#define DARWIN_P_PPWAIT 0x00010 +#define DARWIN_P_PROFIL 0x00020 +#define DARWIN_P_SELECT 0x00040 +#define DARWIN_P_SINTR 0x00080 +#define DARWIN_P_SUGID 0x00100 +#define DARWIN_P_SYSTEM 0x00200 +#define DARWIN_P_TIMEOUT 0x00400 +#define DARWIN_P_TRACED 0x00800 +#define DARWIN_P_WAITED 0x01000 +#define DARWIN_P_WEXIT 0x02000 +#define DARWIN_P_EXEC 0x04000 +#define DARWIN_P_OWEUPC 0x08000 +#define DARWIN_P_FSTRACE 0x10000 +#define DARWIN_P_SSTEP 0x20000 +#define DARWIN_P_WAITING 0x0040000 +#define DARWIN_P_KDEBUG 0x0080000 +#define DARWIN_P_TTYSLEEP 0x0100000 +#define DARWIN_P_REBOOT 0x0200000 +#define DARWIN_P_TBE 0x0400000 +#define DARWIN_P_SIGEXC 0x0800000 +#define DARWIN_P_BTRACE 0x1000000 +#define DARWIN_P_VFORK 0x2000000 +#define DARWIN_P_NOATTACH 0x4000000 +#define DARWIN_P_INVFORK 0x8000000 +#define DARWIN_P_NOSHLIB 0x10000000 +#define DARWIN_P_FORCEQUOTA 0x20000000 +#define DARWIN_P_NOCLDWAIT 0x40000000 + #endif /* _DARWIN_SYSCTL_H_ */