/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#include <sys/ioctl.h>
#include <sys/tty.h>
#include <sys/signalvar.h>
+#include <sys/syslog.h>
/*
* Structure associated with user cacheing.
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.
*/
return (0);
return (1);
}
+/*
+ * Is p an inferior of t ?
+ */
+int
+isinferior(struct proc *p, register struct proc *t)
+{
+
+ /* if p==t they are not inferior */
+ if (p == t)
+ return(0);
+ for (; p != t; p = p->p_pptr)
+ if (p->p_pid == 0)
+ return (0);
+ return (1);
+}
/*
* Locate a process by number
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
*/
#endif
MALLOC_ZONE(pgrp, struct pgrp *, sizeof(struct pgrp), M_PGRP,
M_WAITOK);
- if ((np = pfind(savepid)) == NULL || np != p)
+ if ((np = pfind(savepid)) == NULL || np != p) {
+ FREE_ZONE(pgrp, sizeof(struct pgrp), M_PGRP);
return (ESRCH);
+ }
if (mksess) {
register struct session *sess;
MALLOC_ZONE(sess, struct session *,
sizeof(struct session), M_SESSION, M_WAITOK);
sess->s_leader = p;
+ sess->s_sid = p->p_pid;
sess->s_count = 1;
sess->s_ttyvp = NULL;
sess->s_ttyp = NULL;
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"
* 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;
* 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
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;
* hang-up all process in that group.
*/
static void
-orphanpg(pg)
- struct pgrp *pg;
+orphanpg(struct pgrp *pg)
{
register struct proc *p;
}
#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);
+}