1 /*
2  * Copyright (c) 1993 Jan-Simon Pendry
3  * Copyright (c) 1993
4  *	The Regents of the University of California.  All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * Jan-Simon Pendry.
8  *
9  * %sccs.include.redist.c%
10  *
11  *	@(#)procfs_status.c	8.3 (Berkeley) 02/17/94
12  *
13  * From:
14  *	$Id: procfs_status.c,v 3.1 1993/12/15 09:40:17 jsp Exp $
15  */
16 
17 #include <sys/param.h>
18 #include <sys/systm.h>
19 #include <sys/time.h>
20 #include <sys/kernel.h>
21 #include <sys/proc.h>
22 #include <sys/vnode.h>
23 #include <sys/ioctl.h>
24 #include <sys/tty.h>
25 #include <sys/resource.h>
26 #include <sys/resourcevar.h>
27 #include <miscfs/procfs/procfs.h>
28 
29 int
30 procfs_dostatus(curp, p, pfs, uio)
31 	struct proc *curp;
32 	struct proc *p;
33 	struct pfsnode *pfs;
34 	struct uio *uio;
35 {
36 	struct session *sess;
37 	struct tty *tp;
38 	struct ucred *cr;
39 	char *ps;
40 	char *sep;
41 	int pid, ppid, pgid, sid;
42 	int i;
43 	int xlen;
44 	int error;
45 	char psbuf[256];		/* XXX - conservative */
46 
47 	if (uio->uio_rw != UIO_READ)
48 		return (EOPNOTSUPP);
49 
50 	pid = p->p_pid;
51 	ppid = p->p_pptr ? p->p_pptr->p_pid : 0,
52 	pgid = p->p_pgrp->pg_id;
53 	sess = p->p_pgrp->pg_session;
54 	sid = sess->s_leader ? sess->s_leader->p_pid : 0;
55 
56 /* comm pid ppid pgid sid maj,min ctty,sldr start ut st wmsg uid groups ... */
57 
58 	ps = psbuf;
59 	bcopy(p->p_comm, ps, MAXCOMLEN);
60 	ps[MAXCOMLEN] = '\0';
61 	ps += strlen(ps);
62 	ps += sprintf(ps, " %d %d %d %d ", pid, ppid, pgid, sid);
63 
64 	if ((p->p_flag&P_CONTROLT) && (tp = sess->s_ttyp))
65 		ps += sprintf(ps, "%d,%d ", major(tp->t_dev), minor(tp->t_dev));
66 	else
67 		ps += sprintf(ps, "%d,%d ", -1, -1);
68 
69 	sep = "";
70 	if (sess->s_ttyvp) {
71 		ps += sprintf(ps, "%sctty", sep);
72 		sep = ",";
73 	}
74 	if (SESS_LEADER(p)) {
75 		ps += sprintf(ps, "%ssldr", sep);
76 		sep = ",";
77 	}
78 	if (*sep != ',')
79 		ps += sprintf(ps, "noflags");
80 
81 	if (p->p_flag & P_INMEM)
82 		ps += sprintf(ps, " %d,%d",
83 			p->p_stats->p_start.tv_sec,
84 			p->p_stats->p_start.tv_usec);
85 	else
86 		ps += sprintf(ps, " -1,-1");
87 
88 	{
89 		struct timeval ut, st;
90 
91 		calcru(p, &ut, &st, (void *) 0);
92 		ps += sprintf(ps, " %d,%d %d,%d",
93 			ut.tv_sec,
94 			ut.tv_usec,
95 			st.tv_sec,
96 			st.tv_usec);
97 	}
98 
99 	ps += sprintf(ps, " %s",
100 		(p->p_wchan && p->p_wmesg) ? p->p_wmesg : "nochan");
101 
102 	cr = p->p_ucred;
103 
104 	ps += sprintf(ps, " %d", cr->cr_uid, cr->cr_gid);
105 	for (i = 0; i < cr->cr_ngroups; i++)
106 		ps += sprintf(ps, ",%d", cr->cr_groups[i]);
107 	ps += sprintf(ps, "\n");
108 
109 	xlen = ps - psbuf;
110 	xlen -= uio->uio_offset;
111 	ps = psbuf + uio->uio_offset;
112 	xlen = min(xlen, uio->uio_resid);
113 	if (xlen <= 0)
114 		error = 0;
115 	else
116 		error = uiomove(ps, xlen, uio);
117 
118 	return (error);
119 }
120