X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/d7e50217d7adf6e52786a38bcaa4cd698cb9a79e..5eebf7385fedb1517b66b53c28e5aa6bb0a2be50:/bsd/kern/kern_proc.c diff --git a/bsd/kern/kern_proc.c b/bsd/kern/kern_proc.c index 125fde90a..2a4636217 100644 --- a/bsd/kern/kern_proc.c +++ b/bsd/kern/kern_proc.c @@ -3,22 +3,19 @@ * * @APPLE_LICENSE_HEADER_START@ * - * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. * * @APPLE_LICENSE_HEADER_END@ */ @@ -82,6 +79,7 @@ #include #include #include +#include /* * Structure associated with user cacheing. @@ -105,6 +103,11 @@ u_long pgrphash; struct proclist allproc; struct proclist zombproc; +/* Name to give to core files */ +__private_extern__ char corefilename[MAXPATHLEN+1] = {"/cores/core.%P"}; + +static void orphanpg(struct pgrp *pg); + /* * Initialize global process hashing structures. */ @@ -174,9 +177,7 @@ inferior(p) * Is p an inferior of t ? */ int -isinferior(p, t) - register struct proc *p; - register struct proc *t; +isinferior(struct proc *p, register struct proc *t) { /* if p==t they are not inferior */ @@ -206,6 +207,21 @@ pfind(pid) return (NULL); } +/* + * Locate a zombie by PID + */ +__private_extern__ struct proc * +pzfind(pid) + register pid_t pid; +{ + register struct proc *p; + + for (p = zombproc.lh_first; p != 0; p = p->p_list.le_next) + if (p->p_pid == pid) + return (p); + return (NULL); +} + /* * Locate a process group by number */ @@ -343,8 +359,6 @@ sessrele(sess) FREE_ZONE(sess, sizeof (struct session), M_SESSION); } -static void orphanpg(); - /* * Adjust pgrp jobc counters when specified process changes process group. * We count the number of processes in each process group that "qualify" @@ -356,10 +370,7 @@ static void orphanpg(); * entering == 1 => p is entering specified group. */ void -fixjobc(p, pgrp, entering) - register struct proc *p; - register struct pgrp *pgrp; - int entering; +fixjobc(struct proc *p, struct pgrp *pgrp, int entering) { register struct pgrp *hispgrp; register struct session *mysession = pgrp->pg_session; @@ -369,11 +380,12 @@ fixjobc(p, pgrp, entering) * group; if so, adjust count for p's process group. */ if ((hispgrp = p->p_pptr->p_pgrp) != pgrp && - hispgrp->pg_session == mysession) + hispgrp->pg_session == mysession) { if (entering) pgrp->pg_jobc++; else if (--pgrp->pg_jobc == 0) orphanpg(pgrp); + } /* * Check this process' children to see whether they qualify @@ -383,12 +395,13 @@ fixjobc(p, pgrp, entering) for (p = p->p_children.lh_first; p != 0; p = p->p_sibling.le_next) if ((hispgrp = p->p_pgrp) != pgrp && hispgrp->pg_session == mysession && - p->p_stat != SZOMB) + p->p_stat != SZOMB) { if (entering) hispgrp->pg_jobc++; else if (--hispgrp->pg_jobc == 0) orphanpg(hispgrp); } +} /* * A process group has become orphaned; @@ -396,8 +409,7 @@ fixjobc(p, pgrp, entering) * hang-up all process in that group. */ static void -orphanpg(pg) - struct pgrp *pg; +orphanpg(struct pgrp *pg) { register struct proc *p; @@ -441,7 +453,84 @@ pgrpdump() } #endif /* DEBUG */ -struct proc * current_proc_EXTERNAL() +/* XXX should be __private_extern__ */ +int +proc_is_classic(struct proc *p) +{ + return (p->p_flag & P_CLASSIC) ? 1 : 0; +} + +/* XXX Why does this function exist? Need to kill it off... */ +struct proc * +current_proc_EXTERNAL(void) { return (current_proc()); } + +/* + * proc_core_name(name, uid, pid) + * Expand the name described in corefilename, using name, uid, and pid. + * corefilename is a printf-like string, with three format specifiers: + * %N name of process ("name") + * %P process id (pid) + * %U user id (uid) + * For example, "%N.core" is the default; they can be disabled completely + * by using "/dev/null", or all core files can be stored in "/cores/%U/%N-%P". + * This is controlled by the sysctl variable kern.corefile (see above). + */ +__private_extern__ char * +proc_core_name(const char *name, uid_t uid, pid_t pid) +{ + const char *format, *appendstr; + char *temp; + char id_buf[11]; /* Buffer for pid/uid -- max 4B */ + size_t i, l, n; + + format = corefilename; + MALLOC(temp, char *, MAXPATHLEN, M_TEMP, M_NOWAIT | M_ZERO); + if (temp == NULL) + return (NULL); + for (i = 0, n = 0; n < MAXPATHLEN && format[i]; i++) { + switch (format[i]) { + case '%': /* Format character */ + i++; + switch (format[i]) { + case '%': + appendstr = "%"; + break; + case 'N': /* process name */ + appendstr = name; + break; + case 'P': /* process id */ + sprintf(id_buf, "%u", pid); + appendstr = id_buf; + break; + case 'U': /* user id */ + sprintf(id_buf, "%u", uid); + appendstr = id_buf; + break; + default: + appendstr = ""; + log(LOG_ERR, + "Unknown format character %c in `%s'\n", + format[i], format); + } + l = strlen(appendstr); + if ((n + l) >= MAXPATHLEN) + goto toolong; + bcopy(appendstr, temp + n, l); + n += l; + break; + default: + temp[n++] = format[i]; + } + } + if (format[i] != '\0') + goto toolong; + return (temp); +toolong: + log(LOG_ERR, "pid %ld (%s), uid (%lu): corename is too long\n", + (long)pid, name, (u_long)uid); + FREE(temp, M_TEMP); + return (NULL); +}