1/*
2 * Copyright (c) 1993, 1994, 1995 Rick Sladkey <jrs@world.std.com>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 *    derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 *	$Id$
28 */
29
30#include "defs.h"
31
32#ifdef SVR4
33#ifndef HAVE_MP_PROCFS
34
35static const struct xlat proc_status_flags[] = {
36	{ PR_STOPPED,	"PR_STOPPED"	},
37	{ PR_ISTOP,	"PR_ISTOP"	},
38	{ PR_DSTOP,	"PR_DSTOP"	},
39	{ PR_ASLEEP,	"PR_ASLEEP"	},
40	{ PR_FORK,	"PR_FORK"	},
41	{ PR_RLC,	"PR_RLC"	},
42	{ PR_PTRACE,	"PR_PTRACE"	},
43	{ PR_PCINVAL,	"PR_PCINVAL"	},
44	{ PR_ISSYS,	"PR_ISSYS"	},
45#ifdef PR_STEP
46	{ PR_STEP,	"PR_STEP"	},
47#endif
48#ifdef PR_KLC
49	{ PR_KLC,	"PR_KLC"	},
50#endif
51#ifdef PR_ASYNC
52	{ PR_ASYNC,	"PR_ASYNC"	},
53#endif
54#ifdef PR_PCOMPAT
55	{ PR_PCOMPAT,	"PR_PCOMPAT"	},
56#endif
57	{ 0,		NULL		},
58};
59
60static const struct xlat proc_status_why[] = {
61	{ PR_REQUESTED,	"PR_REQUESTED"	},
62	{ PR_SIGNALLED,	"PR_SIGNALLED"	},
63	{ PR_SYSENTRY,	"PR_SYSENTRY"	},
64	{ PR_SYSEXIT,	"PR_SYSEXIT"	},
65	{ PR_JOBCONTROL,"PR_JOBCONTROL"	},
66	{ PR_FAULTED,	"PR_FAULTED"	},
67#ifdef PR_SUSPENDED
68	{ PR_SUSPENDED,	"PR_SUSPENDED"	},
69#endif
70#ifdef PR_CHECKPOINT
71	{ PR_CHECKPOINT,"PR_CHECKPOINT"	},
72#endif
73	{ 0,		NULL		},
74};
75
76static const struct xlat proc_run_flags[] = {
77	{ PRCSIG,	"PRCSIG"	},
78	{ PRCFAULT,	"PRCFAULT"	},
79	{ PRSTRACE,	"PRSTRACE"	},
80	{ PRSHOLD,	"PRSHOLD"	},
81	{ PRSFAULT,	"PRSFAULT"	},
82	{ PRSVADDR,	"PRSVADDR"	},
83	{ PRSTEP,	"PRSTEP"	},
84	{ PRSABORT,	"PRSABORT"	},
85	{ PRSTOP,	"PRSTOP"	},
86	{ 0,		NULL		},
87};
88
89int
90proc_ioctl(tcp, code, arg)
91struct tcb *tcp;
92int code, arg;
93{
94	int val;
95	prstatus_t status;
96	prrun_t run;
97
98	if (entering(tcp))
99		return 0;
100
101	switch (code) {
102	case PIOCSTATUS:
103	case PIOCSTOP:
104	case PIOCWSTOP:
105		if (arg == 0)
106			tprintf(", NULL");
107		else if (syserror(tcp))
108			tprintf(", %#x", arg);
109		else if (umove(tcp, arg, &status) < 0)
110			tprintf(", {...}");
111		else {
112			tprintf(", {pr_flags=");
113			printflags(proc_status_flags, status.pr_flags, "PR_???");
114			if (status.pr_why) {
115				tprintf(", pr_why=");
116				printxval(proc_status_why, status.pr_why,
117					  "PR_???");
118			}
119			switch (status.pr_why) {
120			case PR_SIGNALLED:
121			case PR_JOBCONTROL:
122				tprintf(", pr_what=");
123				printsignal(status.pr_what);
124				break;
125			case PR_FAULTED:
126				tprintf(", pr_what=%d", status.pr_what);
127				break;
128			case PR_SYSENTRY:
129			case PR_SYSEXIT:
130				tprintf(", pr_what=SYS_%s",
131					sysent[status.pr_what].sys_name);
132				break;
133			}
134			tprintf(", ...}");
135		}
136		return 1;
137	case PIOCRUN:
138		if (arg == 0)
139			tprintf(", NULL");
140		else if (umove(tcp, arg, &run) < 0)
141			tprintf(", {...}");
142		else {
143			tprintf(", {pr_flags=");
144			printflags(proc_run_flags, run.pr_flags, "PR???");
145			tprintf(", ...}");
146		}
147		return 1;
148#ifdef PIOCSET
149	case PIOCSET:
150	case PIOCRESET:
151		if (umove(tcp, arg, &val) < 0)
152			tprintf(", [?]");
153		else {
154			tprintf(", [");
155			printflags(proc_status_flags, val, "PR_???");
156			tprintf("]");
157		}
158		return 1;
159#endif /* PIOCSET */
160	case PIOCKILL:
161	case PIOCUNKILL:
162		/* takes a pointer to a signal */
163		if (umove(tcp, arg, &val) < 0)
164			tprintf(", [?]");
165		else {
166			tprintf(", [");
167			printsignal(val);
168			tprintf("]");
169		}
170		return 1;
171	case PIOCSFORK:
172	case PIOCRFORK:
173	case PIOCSRLC:
174	case PIOCRRLC:
175		/* doesn't take an arg */
176		return 1;
177	default:
178		/* ad naseum */
179		return 0;
180	}
181}
182
183#endif /* HAVE_MP_PROCFS */
184#endif /* SVR4 */
185
186#ifdef FREEBSD
187#include <sys/pioctl.h>
188
189static const struct xlat proc_status_why[] = {
190	{ S_EXEC,	"S_EXEC"	},
191	{ S_SIG,	"S_SIG"		},
192	{ S_SCE,	"S_SCE"		},
193	{ S_SCX,	"S_SCX"		},
194	{ S_CORE,	"S_CORE"	},
195	{ S_EXIT,	"S_EXIT"	},
196	{ 0,		NULL		}
197};
198
199static const struct xlat proc_status_flags[] = {
200	{ PF_LINGER,	"PF_LINGER"	},
201	{ PF_ISUGID,	"PF_ISUGID"	},
202	{ 0,		NULL		}
203};
204
205int
206proc_ioctl(tcp, code, arg)
207struct tcb *tcp;
208int code, arg;
209{
210	int val;
211	struct procfs_status status;
212
213	if (entering(tcp))
214		return 0;
215
216	switch (code) {
217	case PIOCSTATUS:
218	case PIOCWAIT:
219		if (arg == 0)
220			tprintf(", NULL");
221		else if (syserror(tcp))
222			tprintf(", %x", arg);
223		else if (umove(tcp, arg, &status) < 0)
224			tprintf(", {...}");
225		else {
226			tprintf(", {state=%d, flags=", status.state);
227			printflags(proc_status_flags, status.flags, "PF_???");
228			tprintf(", events=");
229			printflags(proc_status_why, status.events, "S_???");
230			tprintf(", why=");
231			printxval(proc_status_why, status.why, "S_???");
232			tprintf(", val=%lu}", status.val);
233		}
234		return 1;
235	case PIOCBIS:
236		tprintf(", ");
237		printflags(proc_status_why, arg, "S_???");
238		return 1;
239		return 1;
240	case PIOCSFL:
241		tprintf(", ");
242		printflags(proc_status_flags, arg, "PF_???");
243		return 1;
244	case PIOCGFL:
245		if (syserror(tcp))
246			tprintf(", %#x", arg);
247		else if (umove(tcp, arg, &val) < 0)
248			tprintf(", {...}");
249		else {
250			tprintf(", [");
251			printflags(proc_status_flags, val, "PF_???");
252			tprintf("]");
253		}
254		return 1;
255	default:
256		/* ad naseum */
257		return 0;
258	}
259}
260#endif
261