xref: /openbsd-src/gnu/usr.bin/binutils/gdb/proc-api.c (revision 11efff7f3ac2b3cfeff0c0cddc14294d9b3aca4f)
1b725ae77Skettenis /* Machine independent support for SVR4 /proc (process file system) for GDB.
2b725ae77Skettenis 
3b725ae77Skettenis    Copyright 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
4b725ae77Skettenis 
5b725ae77Skettenis    Written by Michael Snyder at Cygnus Solutions.
6b725ae77Skettenis    Based on work by Fred Fish, Stu Grossman, Geoff Noer, and others.
7b725ae77Skettenis 
8b725ae77Skettenis This file is part of GDB.
9b725ae77Skettenis 
10b725ae77Skettenis This program is free software; you can redistribute it and/or modify
11b725ae77Skettenis it under the terms of the GNU General Public License as published by
12b725ae77Skettenis the Free Software Foundation; either version 2 of the License, or
13b725ae77Skettenis (at your option) any later version.
14b725ae77Skettenis 
15b725ae77Skettenis This program is distributed in the hope that it will be useful,
16b725ae77Skettenis but WITHOUT ANY WARRANTY; without even the implied warranty of
17b725ae77Skettenis MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18b725ae77Skettenis GNU General Public License for more details.
19b725ae77Skettenis 
20b725ae77Skettenis You should have received a copy of the GNU General Public License
21b725ae77Skettenis along with this program; if not, write to the Free Software Foundation,
22b725ae77Skettenis Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
23b725ae77Skettenis 
24b725ae77Skettenis /*
25b725ae77Skettenis  * Pretty-print trace of api calls to the /proc api
26b725ae77Skettenis  * (ioctl or read/write calls).
27b725ae77Skettenis  *
28b725ae77Skettenis  */
29b725ae77Skettenis 
30b725ae77Skettenis #include "defs.h"
31b725ae77Skettenis #include "gdbcmd.h"
32b725ae77Skettenis #include "completer.h"
33b725ae77Skettenis 
34b725ae77Skettenis #if defined (NEW_PROC_API)
35b725ae77Skettenis #define _STRUCTURED_PROC 1
36b725ae77Skettenis #endif
37b725ae77Skettenis 
38b725ae77Skettenis #include <stdio.h>
39b725ae77Skettenis #include <sys/types.h>
40b725ae77Skettenis #include <sys/procfs.h>
41b725ae77Skettenis #ifdef HAVE_SYS_PROC_H
42b725ae77Skettenis #include <sys/proc.h>	/* for struct proc */
43b725ae77Skettenis #endif
44b725ae77Skettenis #ifdef HAVE_SYS_USER_H
45b725ae77Skettenis #include <sys/user.h>	/* for struct user */
46b725ae77Skettenis #endif
47b725ae77Skettenis #include <fcntl.h>	/* for O_RDWR etc. */
48b725ae77Skettenis #include "gdb_wait.h"
49b725ae77Skettenis 
50b725ae77Skettenis #include "proc-utils.h"
51b725ae77Skettenis 
52b725ae77Skettenis /*  Much of the information used in the /proc interface, particularly for
53b725ae77Skettenis     printing status information, is kept as tables of structures of the
54b725ae77Skettenis     following form.  These tables can be used to map numeric values to
55b725ae77Skettenis     their symbolic names and to a string that describes their specific use. */
56b725ae77Skettenis 
57b725ae77Skettenis struct trans {
58b725ae77Skettenis   long value;                   /* The numeric value */
59b725ae77Skettenis   char *name;                   /* The equivalent symbolic value */
60b725ae77Skettenis   char *desc;                   /* Short description of value */
61b725ae77Skettenis };
62b725ae77Skettenis 
63b725ae77Skettenis static int   procfs_trace    = 0;
64b725ae77Skettenis static FILE *procfs_file     = NULL;
65b725ae77Skettenis static char *procfs_filename = "procfs_trace";
66b725ae77Skettenis 
67b725ae77Skettenis static void
prepare_to_trace(void)68b725ae77Skettenis prepare_to_trace (void)
69b725ae77Skettenis {
70b725ae77Skettenis   if (procfs_trace)			/* if procfs tracing turned on */
71b725ae77Skettenis     if (procfs_file == NULL)		/* if output file not yet open */
72b725ae77Skettenis       if (procfs_filename != NULL)	/* if output filename known */
73b725ae77Skettenis 	procfs_file = fopen (procfs_filename, "a");	/* open output file */
74b725ae77Skettenis }
75b725ae77Skettenis 
76b725ae77Skettenis static void
set_procfs_trace_cmd(char * args,int from_tty,struct cmd_list_element * c)77b725ae77Skettenis set_procfs_trace_cmd (char *args, int from_tty, struct cmd_list_element *c)
78b725ae77Skettenis {
79b725ae77Skettenis #if 0	/* not sure what I might actually need to do here, if anything */
80b725ae77Skettenis   if (procfs_file)
81b725ae77Skettenis     fflush (procfs_file);
82b725ae77Skettenis #endif
83b725ae77Skettenis }
84b725ae77Skettenis 
85b725ae77Skettenis static void
set_procfs_file_cmd(char * args,int from_tty,struct cmd_list_element * c)86b725ae77Skettenis set_procfs_file_cmd (char *args, int from_tty, struct cmd_list_element *c)
87b725ae77Skettenis {
88b725ae77Skettenis   /* Just changed the filename for procfs tracing.
89b725ae77Skettenis      If a file was already open, close it.  */
90b725ae77Skettenis   if (procfs_file)
91b725ae77Skettenis     fclose (procfs_file);
92b725ae77Skettenis   procfs_file = NULL;
93b725ae77Skettenis }
94b725ae77Skettenis 
95b725ae77Skettenis 
96b725ae77Skettenis #ifndef NEW_PROC_API
97b725ae77Skettenis 
98b725ae77Skettenis static struct trans ioctl_table[] = {
99b725ae77Skettenis #ifdef PIOCACINFO			/* irix */
100b725ae77Skettenis   { PIOCACINFO,    "PIOCACINFO",   "get process account info" },
101b725ae77Skettenis #endif
102b725ae77Skettenis   { PIOCACTION,    "PIOCACTION",   "get signal action structs" },
103b725ae77Skettenis #ifdef PIOCARGUMENTS			/* osf */
104b725ae77Skettenis   { PIOCARGUMENTS, "PIOCARGUMENTS", "command line args" },
105b725ae77Skettenis #endif
106b725ae77Skettenis #ifdef PIOCAUXV				/* solaris aux vectors */
107b725ae77Skettenis   { PIOCAUXV,      "PIOCAUXV",     "get aux vector" },
108b725ae77Skettenis   { PIOCNAUXV,     "PIOCNAUXV",    "get number of aux vector entries" },
109b725ae77Skettenis #endif /* AUXV */
110b725ae77Skettenis   { PIOCCFAULT,    "PIOCCFAULT",   "clear current fault" },
111b725ae77Skettenis   { PIOCCRED,      "PIOCCRED",     "get process credentials" },
112b725ae77Skettenis #ifdef PIOCENEVCTRS			/* irix event counters */
113b725ae77Skettenis   { PIOCENEVCTRS,    "PIOCENEVCTRS",    "acquire and start event counters" },
114b725ae77Skettenis   { PIOCGETEVCTRL,   "PIOCGETEVCTRL",   "get control info of event counters" },
115b725ae77Skettenis   { PIOCGETEVCTRS,   "PIOCGETEVCTRS",   "dump event counters" },
116b725ae77Skettenis   { PIOCGETPREVCTRS, "PIOCGETPREVCTRS", "dump event counters & prusage info" },
117b725ae77Skettenis   { PIOCRELEVCTRS,   "PIOCRELEVCTRS",   "release/stop event counters" },
118b725ae77Skettenis   { PIOCSETEVCTRL,   "PIOCSETEVCTRL",   "set control info of event counters" },
119b725ae77Skettenis   { PIOCGETPTIMER,   "PIOCGETPTIMER",   "get process timers" },
120b725ae77Skettenis #endif	/* irix event counters */
121b725ae77Skettenis   { PIOCGENTRY,    "PIOCGENTRY",   "get traced syscall entry set" },
122b725ae77Skettenis #if defined (PIOCGETPR)
123b725ae77Skettenis   { PIOCGETPR,     "PIOCGETPR",    "read struct proc" },
124b725ae77Skettenis #endif
125b725ae77Skettenis #if defined (PIOCGETU)
126b725ae77Skettenis   { PIOCGETU,      "PIOCGETU",     "read user area" },
127b725ae77Skettenis #endif
128b725ae77Skettenis #if defined (PIOCGETUTK) && (defined(KERNEL) || defined(SHOW_UTT)) /* osf */
129b725ae77Skettenis   { PIOCGETUTK,  "PIOCGETUTK", "get the utask struct" },
130b725ae77Skettenis #endif
131b725ae77Skettenis   { PIOCGEXIT,     "PIOCGEXIT",    "get traced syscall exit  set" },
132b725ae77Skettenis   { PIOCGFAULT,    "PIOCGFAULT",   "get traced fault set" },
133b725ae77Skettenis #ifdef PIOCGFPCR			/* osf */
134b725ae77Skettenis   { PIOCGFPCR,     "PIOCGFPCR",    "get FP control register" },
135b725ae77Skettenis   { PIOCSFPCR,     "PIOCSFPCR",    "set FP conrtol register" },
136b725ae77Skettenis #endif
137b725ae77Skettenis   { PIOCGFPREG,    "PIOCGFPREG",   "get floating point registers" },
138b725ae77Skettenis   { PIOCGHOLD,     "PIOCGHOLD",    "get held signal set" },
139b725ae77Skettenis   { PIOCGREG,      "PIOCGREG",     "get general registers" },
140b725ae77Skettenis   { PIOCGROUPS,    "PIOCGROUPS",   "get supplementary groups" },
141b725ae77Skettenis #ifdef PIOCGSPCACT			/* osf */
142b725ae77Skettenis   { PIOCGSPCACT,   "PIOCGSPCACT",  "get special action" },
143b725ae77Skettenis   { PIOCSSPCACT,   "PIOCSSPCACT",  "set special action" },
144b725ae77Skettenis #endif
145b725ae77Skettenis   { PIOCGTRACE,    "PIOCGTRACE",   "get traced signal set" },
146b725ae77Skettenis #ifdef PIOCGWATCH			/* irix watchpoints */
147b725ae77Skettenis   { PIOCGWATCH,    "PIOCGWATCH",   "get watchpoint" },
148b725ae77Skettenis   { PIOCSWATCH,    "PIOCSWATCH",   "set watchpoint" },
149b725ae77Skettenis   { PIOCNWATCH,    "PIOCNWATCH",   "get number of watchpoints" },
150b725ae77Skettenis #endif	/* irix watchpoints */
151b725ae77Skettenis #ifdef PIOCGWIN				/* solaris sparc */
152b725ae77Skettenis   { PIOCGWIN,      "PIOCGWIN",     "get gwindows_t" },
153b725ae77Skettenis #endif
154b725ae77Skettenis #ifdef PIOCGXREG			/* solaris sparc extra regs */
155b725ae77Skettenis   { PIOCGXREGSIZE, "PIOCXREGSIZE", "get extra register state size" },
156b725ae77Skettenis   { PIOCGXREG,     "PIOCGXREG",    "get extra register state" },
157b725ae77Skettenis   { PIOCSXREG,     "PIOCSXREG",    "set extra register state" },
158b725ae77Skettenis #endif /* XREG */
159b725ae77Skettenis   { PIOCKILL,      "PIOCKILL",     "send signal" },
160b725ae77Skettenis #ifdef PIOCLDT				/* solaris i386 */
161b725ae77Skettenis   { PIOCLDT,       "PIOCLDT",      "get LDT" },
162b725ae77Skettenis   { PIOCNLDT,      "PIOCNLDT",     "get number of LDT entries" },
163b725ae77Skettenis #endif
164b725ae77Skettenis #ifdef PIOCLSTATUS			/* solaris and unixware */
165b725ae77Skettenis   { PIOCLSTATUS,   "PIOCLSTATUS",  "get status of all lwps" },
166b725ae77Skettenis   { PIOCLUSAGE,    "PIOCLUSAGE",   "get resource usage of all lwps" },
167b725ae77Skettenis   { PIOCOPENLWP,   "PIOCOPENLWP",  "get lwp file descriptor" },
168b725ae77Skettenis   { PIOCLWPIDS,    "PIOCLWPIDS",   "get lwp identifiers" },
169b725ae77Skettenis #endif /* LWP */
170b725ae77Skettenis   { PIOCMAP,       "PIOCMAP",      "get memory map information" },
171b725ae77Skettenis   { PIOCMAXSIG,    "PIOCMAXSIG",   "get max signal number" },
172b725ae77Skettenis   { PIOCNICE,      "PIOCNICE",     "set nice priority" },
173b725ae77Skettenis   { PIOCNMAP,      "PIOCNMAP",     "get number of memory mappings" },
174b725ae77Skettenis   { PIOCOPENM,     "PIOCOPENM",    "open mapped object for reading" },
175b725ae77Skettenis #ifdef PIOCOPENMOBS			/* osf */
176b725ae77Skettenis   { PIOCOPENMOBS,  "PIOCOPENMOBS", "open mapped object" },
177b725ae77Skettenis #endif
178b725ae77Skettenis #ifdef PIOCOPENPD	/* solaris */
179b725ae77Skettenis   { PIOCOPENPD,    "PIOCOPENPD",   "get page data file descriptor" },
180b725ae77Skettenis #endif
181b725ae77Skettenis   { PIOCPSINFO,    "PIOCPSINFO",   "get ps(1) information" },
182b725ae77Skettenis   { PIOCRESET,     "PIOCRESET",    "reset process flags" },
183b725ae77Skettenis   { PIOCRFORK,     "PIOCRFORK",    "reset inherit-on-fork flag" },
184b725ae77Skettenis   { PIOCRRLC,      "PIOCRRLC",     "reset run-on-last-close flag" },
185b725ae77Skettenis   { PIOCRUN,       "PIOCRUN",      "make process runnable" },
186b725ae77Skettenis #ifdef PIOCSAVECCNTRS			/* irix */
187b725ae77Skettenis   { PIOCSAVECCNTRS, "PIOCSAVECCNTRS", "parent gets child cntrs" },
188b725ae77Skettenis #endif
189b725ae77Skettenis   { PIOCSENTRY,    "PIOCSENTRY",   "set traced syscall entry set" },
190b725ae77Skettenis   { PIOCSET,       "PIOCSET",      "set process flags" },
191b725ae77Skettenis   { PIOCSEXIT,     "PIOCSEXIT",    "set traced syscall exit  set" },
192b725ae77Skettenis   { PIOCSFAULT,    "PIOCSFAULT",   "set traced fault set" },
193b725ae77Skettenis   { PIOCSFORK,     "PIOCSFORK",    "set inherit-on-fork flag" },
194b725ae77Skettenis   { PIOCSFPREG,    "PIOCSFPREG",   "set floating point registers" },
195b725ae77Skettenis   { PIOCSHOLD,     "PIOCSHOLD",    "set held signal set" },
196b725ae77Skettenis   { PIOCSREG,      "PIOCSREG",     "set general registers" },
197b725ae77Skettenis   { PIOCSRLC,      "PIOCSRLC",     "set run-on-last-close flag" },
198b725ae77Skettenis   { PIOCSSIG,      "PIOCSSIG",     "set current signal" },
199b725ae77Skettenis   { PIOCSTATUS,    "PIOCSTATUS",   "get process status" },
200b725ae77Skettenis   { PIOCSTOP,      "PIOCSTOP",     "post stop request" },
201b725ae77Skettenis   { PIOCSTRACE,    "PIOCSTRACE",   "set traced signal set" },
202b725ae77Skettenis   { PIOCUNKILL,    "PIOCUNKILL",   "delete a signal" },
203b725ae77Skettenis #ifdef PIOCUSAGE	/* solaris */
204b725ae77Skettenis   { PIOCUSAGE,     "PIOCUSAGE",    "get resource usage" },
205b725ae77Skettenis #endif
206b725ae77Skettenis   { PIOCWSTOP,     "PIOCWSTOP",    "wait for process to stop" },
207b725ae77Skettenis 
208b725ae77Skettenis #ifdef PIOCNTHR				/* osf threads */
209b725ae77Skettenis   { PIOCNTHR,      "PIOCNTHR",     "get thread count" },
210b725ae77Skettenis   { PIOCRTINH,     "PIOCRTINH",    "reset inherit-on-thread-creation" },
211b725ae77Skettenis   { PIOCSTINH,     "PIOCSTINH",    "set   inherit-on-thread-creation" },
212b725ae77Skettenis   { PIOCTLIST,     "PIOCTLIST",    "get thread ids" },
213b725ae77Skettenis   { PIOCXPTH,      "PIOCXPTH",     "translate port to thread handle" },
214b725ae77Skettenis   { PIOCTRUN,      "PIOCTRUN",     "make thread runnable" },
215b725ae77Skettenis   { PIOCTSTATUS,   "PIOCTSTATUS",  "get thread status" },
216b725ae77Skettenis   { PIOCTSTOP,     "PIOCTSTOP",    "stop a thread" },
217b725ae77Skettenis   /* ... TGTRACE TSTRACE TSSIG TKILL TUNKILL TCFAULT TGFAULT TSFAULT
218b725ae77Skettenis      TGFPREG TSFPREG TGREG TSREG TACTION TTERM TABRUN TGENTRY TSENTRY
219b725ae77Skettenis      TGEXIT TSEXIT TSHOLD ... thread functions */
220b725ae77Skettenis #endif /* osf threads */
221b725ae77Skettenis   { -1,            NULL,           NULL }
222b725ae77Skettenis };
223b725ae77Skettenis 
224b725ae77Skettenis int
ioctl_with_trace(int fd,long opcode,void * ptr,char * file,int line)225b725ae77Skettenis ioctl_with_trace (int fd, long opcode, void *ptr, char *file, int line)
226b725ae77Skettenis {
227b725ae77Skettenis   int i = 0;
228b725ae77Skettenis   int ret;
229b725ae77Skettenis   int arg1;
230b725ae77Skettenis 
231b725ae77Skettenis   prepare_to_trace ();
232b725ae77Skettenis 
233b725ae77Skettenis   if (procfs_trace)
234b725ae77Skettenis     {
235b725ae77Skettenis       for (i = 0; ioctl_table[i].name != NULL; i++)
236b725ae77Skettenis 	if (ioctl_table[i].value == opcode)
237b725ae77Skettenis 	  break;
238b725ae77Skettenis 
239b725ae77Skettenis       if (info_verbose)
240b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
241b725ae77Skettenis 		 "%s:%d -- ", file, line);
242b725ae77Skettenis       switch (opcode) {
243b725ae77Skettenis       case PIOCSET:
244b725ae77Skettenis 	arg1 = ptr ? *(long *) ptr : 0;
245b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
246b725ae77Skettenis 		 "ioctl (PIOCSET,   %s) %s\n",
247b725ae77Skettenis 		 arg1 == PR_FORK  ? "PR_FORK"  :
248b725ae77Skettenis 		 arg1 == PR_RLC   ? "PR_RLC"   :
249b725ae77Skettenis #ifdef PR_ASYNC
250b725ae77Skettenis 		 arg1 == PR_ASYNC ? "PR_ASYNC" :
251b725ae77Skettenis #endif
252b725ae77Skettenis 		 "<unknown flag>",
253b725ae77Skettenis 		 info_verbose ? ioctl_table[i].desc : "");
254b725ae77Skettenis 	break;
255b725ae77Skettenis       case PIOCRESET:
256b725ae77Skettenis 	arg1 = ptr ? *(long *) ptr : 0;
257b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
258b725ae77Skettenis 		 "ioctl (PIOCRESET, %s) %s\n",
259b725ae77Skettenis 		 arg1 == PR_FORK  ? "PR_FORK"  :
260b725ae77Skettenis 		 arg1 == PR_RLC   ? "PR_RLC"   :
261b725ae77Skettenis #ifdef PR_ASYNC
262b725ae77Skettenis 		 arg1 == PR_ASYNC ? "PR_ASYNC" :
263b725ae77Skettenis #endif
264b725ae77Skettenis 		 "<unknown flag>",
265b725ae77Skettenis 		 info_verbose ? ioctl_table[i].desc : "");
266b725ae77Skettenis 	break;
267b725ae77Skettenis       case PIOCSTRACE:
268b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
269b725ae77Skettenis 		 "ioctl (PIOCSTRACE) ");
270b725ae77Skettenis 	proc_prettyfprint_signalset (procfs_file ? procfs_file : stdout,
271b725ae77Skettenis 				     (sigset_t *) ptr, 0);
272b725ae77Skettenis 	break;
273b725ae77Skettenis       case PIOCSFAULT:
274b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
275b725ae77Skettenis 		 "ioctl (%s) ",
276b725ae77Skettenis 		 opcode == PIOCSFAULT ? "PIOCSFAULT" : "PIOCGFAULT");
277b725ae77Skettenis 	proc_prettyfprint_faultset (procfs_file ? procfs_file : stdout,
278b725ae77Skettenis 				    (fltset_t *) ptr, 0);
279b725ae77Skettenis 	break;
280b725ae77Skettenis       case PIOCSENTRY:
281b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
282b725ae77Skettenis 		 "ioctl (%s) ",
283b725ae77Skettenis 		 opcode == PIOCSENTRY ? "PIOCSENTRY" : "PIOCGENTRY");
284b725ae77Skettenis 	proc_prettyfprint_syscalls (procfs_file ? procfs_file : stdout,
285b725ae77Skettenis 				    (sysset_t *) ptr, 0);
286b725ae77Skettenis 	break;
287b725ae77Skettenis       case PIOCSEXIT:
288b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
289b725ae77Skettenis 		 "ioctl (%s) ",
290b725ae77Skettenis 		 opcode == PIOCSEXIT ? "PIOCSEXIT" : "PIOCGEXIT");
291b725ae77Skettenis 	proc_prettyfprint_syscalls (procfs_file ? procfs_file : stdout,
292b725ae77Skettenis 				    (sysset_t *) ptr, 0);
293b725ae77Skettenis 	break;
294b725ae77Skettenis       case PIOCSHOLD:
295b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
296b725ae77Skettenis 		 "ioctl (%s) ",
297b725ae77Skettenis 		 opcode == PIOCSHOLD ? "PIOCSHOLD" : "PIOCGHOLD");
298b725ae77Skettenis 	proc_prettyfprint_signalset (procfs_file ? procfs_file : stdout,
299b725ae77Skettenis 				     (sigset_t *) ptr, 0);
300b725ae77Skettenis 	break;
301b725ae77Skettenis       case PIOCSSIG:
302b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
303b725ae77Skettenis 		 "ioctl (PIOCSSIG) ");
304b725ae77Skettenis 	proc_prettyfprint_signal (procfs_file ? procfs_file : stdout,
305b725ae77Skettenis 				  ptr ? ((siginfo_t *) ptr)->si_signo : 0,
306b725ae77Skettenis 				  0);
307b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout, "\n");
308b725ae77Skettenis 	break;
309b725ae77Skettenis       case PIOCRUN:
310b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
311b725ae77Skettenis 		 "ioctl (PIOCRUN) ");
312b725ae77Skettenis 
313b725ae77Skettenis 	arg1 = ptr ? *(long *) ptr : 0;
314b725ae77Skettenis 	if (arg1 & PRCSIG)
315b725ae77Skettenis 	  fprintf (procfs_file ? procfs_file : stdout, "clearSig ");
316b725ae77Skettenis 	if (arg1 & PRCFAULT)
317b725ae77Skettenis 	  fprintf (procfs_file ? procfs_file : stdout, "clearFlt ");
318b725ae77Skettenis 	if (arg1 & PRSTRACE)
319b725ae77Skettenis 	  fprintf (procfs_file ? procfs_file : stdout, "setTrace ");
320b725ae77Skettenis 	if (arg1 & PRSHOLD)
321b725ae77Skettenis 	  fprintf (procfs_file ? procfs_file : stdout, "setHold ");
322b725ae77Skettenis 	if (arg1 & PRSFAULT)
323b725ae77Skettenis 	  fprintf (procfs_file ? procfs_file : stdout, "setFlt ");
324b725ae77Skettenis 	if (arg1 & PRSVADDR)
325b725ae77Skettenis 	  fprintf (procfs_file ? procfs_file : stdout, "setVaddr ");
326b725ae77Skettenis 	if (arg1 & PRSTEP)
327b725ae77Skettenis 	  fprintf (procfs_file ? procfs_file : stdout, "step ");
328b725ae77Skettenis 	if (arg1 & PRSABORT)
329b725ae77Skettenis 	  fprintf (procfs_file ? procfs_file : stdout, "syscallAbort ");
330b725ae77Skettenis 	if (arg1 & PRSTOP)
331b725ae77Skettenis 	  fprintf (procfs_file ? procfs_file : stdout, "stopReq ");
332b725ae77Skettenis 
333b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout, "\n");
334b725ae77Skettenis 	break;
335b725ae77Skettenis       case PIOCKILL:
336b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
337b725ae77Skettenis 		 "ioctl (PIOCKILL) ");
338b725ae77Skettenis 	proc_prettyfprint_signal (procfs_file ? procfs_file : stdout,
339b725ae77Skettenis 				  ptr ? *(long *) ptr : 0, 0);
340b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout, "\n");
341b725ae77Skettenis 	break;
342b725ae77Skettenis #ifdef PIOCSSPCACT
343b725ae77Skettenis       case PIOCSSPCACT:
344b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
345b725ae77Skettenis 		 "ioctl (PIOCSSPCACT) ");
346b725ae77Skettenis 	arg1 = ptr ? *(long *) ptr : 0;
347b725ae77Skettenis 	if (arg1 & PRFS_STOPFORK)
348b725ae77Skettenis 	  fprintf (procfs_file ? procfs_file : stdout, "stopFork ");
349b725ae77Skettenis 	if (arg1 & PRFS_STOPEXEC)
350b725ae77Skettenis 	  fprintf (procfs_file ? procfs_file : stdout, "stopExec ");
351b725ae77Skettenis 	if (arg1 & PRFS_STOPTERM)
352b725ae77Skettenis 	  fprintf (procfs_file ? procfs_file : stdout, "stopTerm ");
353b725ae77Skettenis 	if (arg1 & PRFS_STOPTCR)
354b725ae77Skettenis 	  fprintf (procfs_file ? procfs_file : stdout, "stopThreadCreate ");
355b725ae77Skettenis 	if (arg1 & PRFS_STOPTTERM)
356b725ae77Skettenis 	  fprintf (procfs_file ? procfs_file : stdout, "stopThreadTerm ");
357b725ae77Skettenis 	if (arg1 & PRFS_KOLC)
358b725ae77Skettenis 	  fprintf (procfs_file ? procfs_file : stdout, "killOnLastClose ");
359b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout, "\n");
360b725ae77Skettenis 	break;
361b725ae77Skettenis #endif /* PIOCSSPCACT */
362b725ae77Skettenis       default:
363b725ae77Skettenis 	if (ioctl_table[i].name)
364b725ae77Skettenis 	  fprintf (procfs_file ? procfs_file : stdout,
365b725ae77Skettenis 		   "ioctl (%s) %s\n",
366b725ae77Skettenis 		   ioctl_table[i].name,
367b725ae77Skettenis 		   info_verbose ? ioctl_table[i].desc : "");
368b725ae77Skettenis 	else
369b725ae77Skettenis 	  fprintf (procfs_file ? procfs_file : stdout,
370b725ae77Skettenis 		   "ioctl (<unknown %ld (0x%lx)) \n", opcode, opcode);
371b725ae77Skettenis 	break;
372b725ae77Skettenis       }
373b725ae77Skettenis       if (procfs_file)
374b725ae77Skettenis 	fflush (procfs_file);
375b725ae77Skettenis     }
376b725ae77Skettenis   errno = 0;
377b725ae77Skettenis   ret = ioctl (fd, opcode, ptr);
378b725ae77Skettenis   if (procfs_trace && ret < 0)
379b725ae77Skettenis     {
380b725ae77Skettenis       fprintf (procfs_file ? procfs_file : stdout,
381b725ae77Skettenis 	       "[ioctl (%s) FAILED! (%s)]\n",
382b725ae77Skettenis 	       ioctl_table[i].name != NULL ?
383b725ae77Skettenis 	       ioctl_table[i].name : "<unknown>",
384b725ae77Skettenis 	       safe_strerror (errno));
385b725ae77Skettenis       if (procfs_file)
386b725ae77Skettenis 	fflush (procfs_file);
387b725ae77Skettenis     }
388b725ae77Skettenis 
389b725ae77Skettenis   return ret;
390b725ae77Skettenis }
391b725ae77Skettenis 
392b725ae77Skettenis #else	/* NEW_PROC_API */
393b725ae77Skettenis 
394b725ae77Skettenis static struct trans rw_table[] = {
395b725ae77Skettenis #ifdef PCAGENT			/* solaris */
396b725ae77Skettenis   { PCAGENT,  "PCAGENT",  "create agent lwp with regs from argument" },
397b725ae77Skettenis #endif
398b725ae77Skettenis   { PCCFAULT, "PCCFAULT", "clear current fault" },
399b725ae77Skettenis #ifdef PCCSIG			/* solaris */
400b725ae77Skettenis   { PCCSIG,   "PCCSIG",   "clear current signal" },
401b725ae77Skettenis #endif
402b725ae77Skettenis #ifdef PCDSTOP			/* solaris */
403b725ae77Skettenis   { PCDSTOP,  "PCDSTOP",  "post stop request" },
404b725ae77Skettenis #endif
405b725ae77Skettenis   { PCKILL,   "PCKILL",   "post a signal" },
406b725ae77Skettenis #ifdef PCNICE			/* solaris */
407b725ae77Skettenis   { PCNICE,   "PCNICE",   "set nice priority" },
408b725ae77Skettenis #endif
409b725ae77Skettenis #ifdef PCREAD			/* solaris */
410b725ae77Skettenis   { PCREAD,   "PCREAD",   "read from the address space" },
411b725ae77Skettenis   { PCWRITE,  "PCWRITE",  "write to the address space" },
412b725ae77Skettenis #endif
413b725ae77Skettenis #ifdef PCRESET			/* unixware */
414b725ae77Skettenis   { PCRESET,  "PCRESET",  "unset modes" },
415b725ae77Skettenis #endif
416b725ae77Skettenis   { PCRUN,    "PCRUN",    "make process/lwp runnable" },
417b725ae77Skettenis #ifdef PCSASRS			/* solaris 2.7 only */
418b725ae77Skettenis   { PCSASRS,  "PCSASRS",  "set ancillary state registers" },
419b725ae77Skettenis #endif
420b725ae77Skettenis #ifdef PCSCRED			/* solaris */
421b725ae77Skettenis   { PCSCRED,  "PCSCRED",  "set process credentials" },
422b725ae77Skettenis #endif
423b725ae77Skettenis   { PCSENTRY, "PCSENTRY", "set traced syscall entry set" },
424b725ae77Skettenis   { PCSET,    "PCSET",    "set modes" },
425b725ae77Skettenis   { PCSEXIT,  "PCSEXIT",  "set traced syscall exit  set" },
426b725ae77Skettenis   { PCSFAULT, "PCSFAULT", "set traced fault set" },
427b725ae77Skettenis   { PCSFPREG, "PCSFPREG", "set floating point registers" },
428b725ae77Skettenis #ifdef PCSHOLD			/* solaris */
429b725ae77Skettenis   { PCSHOLD,  "PCSHOLD",  "set signal mask" },
430b725ae77Skettenis #endif
431b725ae77Skettenis   { PCSREG,   "PCSREG",   "set general registers" },
432b725ae77Skettenis   { PCSSIG,   "PCSSIG",   "set current signal" },
433b725ae77Skettenis   { PCSTOP,   "PCSTOP",   "post stop request and wait" },
434b725ae77Skettenis   { PCSTRACE, "PCSTRACE", "set traced signal set" },
435b725ae77Skettenis #ifdef PCSVADDR			/* solaris */
436b725ae77Skettenis   { PCSVADDR, "PCSVADDR", "set pc virtual address" },
437b725ae77Skettenis #endif
438b725ae77Skettenis #ifdef PCSXREG			/* solaris sparc only */
439b725ae77Skettenis   { PCSXREG,  "PCSXREG",  "set extra registers" },
440b725ae77Skettenis #endif
441b725ae77Skettenis #ifdef PCTWSTOP			/* solaris */
442b725ae77Skettenis   { PCTWSTOP, "PCTWSTOP", "wait for stop, with timeout arg" },
443b725ae77Skettenis #endif
444b725ae77Skettenis #ifdef PCUNKILL			/* solaris */
445b725ae77Skettenis   { PCUNKILL, "PCUNKILL", "delete a pending signal" },
446b725ae77Skettenis #endif
447b725ae77Skettenis #ifdef PCUNSET			/* solaris */
448b725ae77Skettenis   { PCUNSET,  "PCUNSET",  "unset modes" },
449b725ae77Skettenis #endif
450b725ae77Skettenis #ifdef PCWATCH			/* solaris */
451b725ae77Skettenis   { PCWATCH,  "PCWATCH",  "set/unset watched memory area" },
452b725ae77Skettenis #endif
453b725ae77Skettenis   { PCWSTOP,  "PCWSTOP",  "wait for process/lwp to stop, no timeout" },
454b725ae77Skettenis   { 0,        NULL,      NULL }
455b725ae77Skettenis };
456b725ae77Skettenis 
457b725ae77Skettenis static off_t lseek_offset;
458b725ae77Skettenis 
459b725ae77Skettenis int
write_with_trace(int fd,void * varg,size_t len,char * file,int line)460b725ae77Skettenis write_with_trace (int fd, void *varg, size_t len, char *file, int line)
461b725ae77Skettenis {
462b725ae77Skettenis   int i = ARRAY_SIZE (rw_table) - 1;
463b725ae77Skettenis   int ret;
464b725ae77Skettenis   procfs_ctl_t *arg = (procfs_ctl_t *) varg;
465b725ae77Skettenis 
466b725ae77Skettenis   prepare_to_trace ();
467b725ae77Skettenis   if (procfs_trace)
468b725ae77Skettenis     {
469b725ae77Skettenis       procfs_ctl_t opcode = arg[0];
470b725ae77Skettenis       for (i = 0; rw_table[i].name != NULL; i++)
471b725ae77Skettenis 	if (rw_table[i].value == opcode)
472b725ae77Skettenis 	  break;
473b725ae77Skettenis 
474b725ae77Skettenis       if (info_verbose)
475b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
476b725ae77Skettenis 		 "%s:%d -- ", file, line);
477b725ae77Skettenis       switch (opcode) {
478b725ae77Skettenis       case PCSET:
479b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
480b725ae77Skettenis 		 "write (PCSET,   %s) %s\n",
481b725ae77Skettenis 		 arg[1] == PR_FORK  ? "PR_FORK"  :
482b725ae77Skettenis 		 arg[1] == PR_RLC   ? "PR_RLC"   :
483b725ae77Skettenis #ifdef PR_ASYNC
484b725ae77Skettenis 		 arg[1] == PR_ASYNC ? "PR_ASYNC" :
485b725ae77Skettenis #endif
486b725ae77Skettenis 		 "<unknown flag>",
487b725ae77Skettenis 		 info_verbose ? rw_table[i].desc : "");
488b725ae77Skettenis 	break;
489b725ae77Skettenis #ifdef PCUNSET
490b725ae77Skettenis       case PCUNSET:
491b725ae77Skettenis #endif
492b725ae77Skettenis #ifdef PCRESET
493b725ae77Skettenis #if PCRESET != PCUNSET
494b725ae77Skettenis       case PCRESET:
495b725ae77Skettenis #endif
496b725ae77Skettenis #endif
497b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
498b725ae77Skettenis 		 "write (PCRESET, %s) %s\n",
499b725ae77Skettenis 		 arg[1] == PR_FORK  ? "PR_FORK"  :
500b725ae77Skettenis 		 arg[1] == PR_RLC   ? "PR_RLC"   :
501b725ae77Skettenis #ifdef PR_ASYNC
502b725ae77Skettenis 		 arg[1] == PR_ASYNC ? "PR_ASYNC" :
503b725ae77Skettenis #endif
504b725ae77Skettenis 		 "<unknown flag>",
505b725ae77Skettenis 		 info_verbose ? rw_table[i].desc : "");
506b725ae77Skettenis 	break;
507b725ae77Skettenis       case PCSTRACE:
508b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
509b725ae77Skettenis 		 "write (PCSTRACE) ");
510b725ae77Skettenis 	proc_prettyfprint_signalset (procfs_file ? procfs_file : stdout,
511b725ae77Skettenis 				     (sigset_t *) &arg[1], 0);
512b725ae77Skettenis 	break;
513b725ae77Skettenis       case PCSFAULT:
514b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
515b725ae77Skettenis 		 "write (PCSFAULT) ");
516b725ae77Skettenis 	proc_prettyfprint_faultset (procfs_file ? procfs_file : stdout,
517b725ae77Skettenis 				    (fltset_t *) &arg[1], 0);
518b725ae77Skettenis 	break;
519b725ae77Skettenis       case PCSENTRY:
520b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
521b725ae77Skettenis 		 "write (PCSENTRY) ");
522b725ae77Skettenis 	proc_prettyfprint_syscalls (procfs_file ? procfs_file : stdout,
523b725ae77Skettenis 				    (sysset_t *) &arg[1], 0);
524b725ae77Skettenis 	break;
525b725ae77Skettenis       case PCSEXIT:
526b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
527b725ae77Skettenis 		 "write (PCSEXIT) ");
528b725ae77Skettenis 	proc_prettyfprint_syscalls (procfs_file ? procfs_file : stdout,
529b725ae77Skettenis 				    (sysset_t *) &arg[1], 0);
530b725ae77Skettenis 	break;
531b725ae77Skettenis #ifdef PCSHOLD
532b725ae77Skettenis       case PCSHOLD:
533b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
534b725ae77Skettenis 		 "write (PCSHOLD) ");
535b725ae77Skettenis 	proc_prettyfprint_signalset (procfs_file ? procfs_file : stdout,
536b725ae77Skettenis 				     (sigset_t *) &arg[1], 0);
537b725ae77Skettenis 	break;
538b725ae77Skettenis #endif
539b725ae77Skettenis       case PCSSIG:
540b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
541b725ae77Skettenis 		 "write (PCSSIG) ");
542b725ae77Skettenis 	proc_prettyfprint_signal (procfs_file ? procfs_file : stdout,
543b725ae77Skettenis 				  arg[1] ? ((siginfo_t *) &arg[1])->si_signo
544b725ae77Skettenis 				         : 0,
545b725ae77Skettenis 				  0);
546b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout, "\n");
547b725ae77Skettenis 	break;
548b725ae77Skettenis       case PCRUN:
549b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
550b725ae77Skettenis 		 "write (PCRUN) ");
551b725ae77Skettenis 	if (arg[1] & PRCSIG)
552b725ae77Skettenis 	  fprintf (procfs_file ? procfs_file : stdout, "clearSig ");
553b725ae77Skettenis 	if (arg[1] & PRCFAULT)
554b725ae77Skettenis 	  fprintf (procfs_file ? procfs_file : stdout, "clearFlt ");
555b725ae77Skettenis 	if (arg[1] & PRSTEP)
556b725ae77Skettenis 	  fprintf (procfs_file ? procfs_file : stdout, "step ");
557b725ae77Skettenis #ifdef PRSABORT
558b725ae77Skettenis 	if (arg[1] & PRSABORT)
559b725ae77Skettenis 	  fprintf (procfs_file ? procfs_file : stdout, "syscallAbort ");
560b725ae77Skettenis #endif
561b725ae77Skettenis #ifdef PRSTOP
562b725ae77Skettenis 	if (arg[1] & PRSTOP)
563b725ae77Skettenis 	  fprintf (procfs_file ? procfs_file : stdout, "stopReq ");
564b725ae77Skettenis #endif
565b725ae77Skettenis 
566b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout, "\n");
567b725ae77Skettenis 	break;
568b725ae77Skettenis       case PCKILL:
569b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
570b725ae77Skettenis 		 "write (PCKILL) ");
571b725ae77Skettenis 	proc_prettyfprint_signal (procfs_file ? procfs_file : stdout,
572b725ae77Skettenis 				  arg[1], 0);
573b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout, "\n");
574b725ae77Skettenis 	break;
575b725ae77Skettenis       default:
576b725ae77Skettenis 	{
577b725ae77Skettenis 	  if (rw_table[i].name)
578b725ae77Skettenis 	    fprintf (procfs_file ? procfs_file : stdout,
579b725ae77Skettenis 		     "write (%s) %s\n",
580b725ae77Skettenis 		     rw_table[i].name,
581b725ae77Skettenis 		     info_verbose ? rw_table[i].desc : "");
582b725ae77Skettenis 	  else
583b725ae77Skettenis 	    {
584b725ae77Skettenis 	      if (lseek_offset != -1)
585b725ae77Skettenis 		fprintf (procfs_file ? procfs_file : stdout,
586b725ae77Skettenis 			 "write (<unknown>, %lud bytes at 0x%08lx) \n",
587b725ae77Skettenis 			 (unsigned long) len, (unsigned long) lseek_offset);
588b725ae77Skettenis 	      else
589b725ae77Skettenis 		fprintf (procfs_file ? procfs_file : stdout,
590b725ae77Skettenis 			 "write (<unknown>, %lud bytes) \n",
591b725ae77Skettenis 			 (unsigned long) len);
592b725ae77Skettenis 	    }
593b725ae77Skettenis 	  break;
594b725ae77Skettenis 	}
595b725ae77Skettenis       }
596b725ae77Skettenis       if (procfs_file)
597b725ae77Skettenis 	fflush (procfs_file);
598b725ae77Skettenis     }
599b725ae77Skettenis   errno = 0;
600b725ae77Skettenis   ret = write (fd, (void *) arg, len);
601b725ae77Skettenis   if (procfs_trace && ret != len)
602b725ae77Skettenis     {
603b725ae77Skettenis       fprintf (procfs_file ? procfs_file : stdout,
604b725ae77Skettenis 	       "[write (%s) FAILED! (%s)]\n",
605b725ae77Skettenis 	       rw_table[i].name != NULL ?
606b725ae77Skettenis 	       rw_table[i].name : "<unknown>",
607b725ae77Skettenis 	       safe_strerror (errno));
608b725ae77Skettenis       if (procfs_file)
609b725ae77Skettenis 	fflush (procfs_file);
610b725ae77Skettenis     }
611b725ae77Skettenis 
612b725ae77Skettenis   lseek_offset = -1;
613b725ae77Skettenis   return ret;
614b725ae77Skettenis }
615b725ae77Skettenis 
616b725ae77Skettenis off_t
lseek_with_trace(int fd,off_t offset,int whence,char * file,int line)617b725ae77Skettenis lseek_with_trace (int fd, off_t offset, int whence, char *file, int line)
618b725ae77Skettenis {
619b725ae77Skettenis   off_t ret;
620b725ae77Skettenis 
621b725ae77Skettenis   prepare_to_trace ();
622b725ae77Skettenis   errno = 0;
623b725ae77Skettenis   ret = lseek (fd, offset, whence);
624b725ae77Skettenis   lseek_offset = ret;
625b725ae77Skettenis   if (procfs_trace && (ret == -1 || errno != 0))
626b725ae77Skettenis     {
627b725ae77Skettenis       fprintf (procfs_file ? procfs_file : stdout,
628b725ae77Skettenis 	       "[lseek (0x%08lx) FAILED! (%s)]\n",
629b725ae77Skettenis 	       (unsigned long) offset, safe_strerror (errno));
630b725ae77Skettenis       if (procfs_file)
631b725ae77Skettenis 	fflush (procfs_file);
632b725ae77Skettenis     }
633b725ae77Skettenis 
634b725ae77Skettenis   return ret;
635b725ae77Skettenis }
636b725ae77Skettenis 
637b725ae77Skettenis #endif /* NEW_PROC_API */
638b725ae77Skettenis 
639b725ae77Skettenis int
open_with_trace(char * filename,int mode,char * file,int line)640b725ae77Skettenis open_with_trace (char *filename, int mode, char *file, int line)
641b725ae77Skettenis {
642b725ae77Skettenis   int ret;
643b725ae77Skettenis 
644b725ae77Skettenis   prepare_to_trace ();
645b725ae77Skettenis   errno = 0;
646b725ae77Skettenis   ret = open (filename, mode);
647b725ae77Skettenis   if (procfs_trace)
648b725ae77Skettenis     {
649b725ae77Skettenis       if (info_verbose)
650b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
651b725ae77Skettenis 		 "%s:%d -- ", file, line);
652b725ae77Skettenis 
653b725ae77Skettenis       if (errno)
654b725ae77Skettenis 	{
655b725ae77Skettenis 	  fprintf (procfs_file ? procfs_file : stdout,
656b725ae77Skettenis 		   "[open FAILED! (%s) line %d]\\n",
657b725ae77Skettenis 		   safe_strerror (errno), line);
658b725ae77Skettenis 	}
659b725ae77Skettenis       else
660b725ae77Skettenis 	{
661b725ae77Skettenis 	  fprintf (procfs_file ? procfs_file : stdout,
662b725ae77Skettenis 		   "%d = open (%s, ", ret, filename);
663b725ae77Skettenis 	  if (mode == O_RDONLY)
664b725ae77Skettenis 	    fprintf (procfs_file ? procfs_file : stdout, "O_RDONLY) %d\n",
665b725ae77Skettenis 		     line);
666b725ae77Skettenis 	  else if (mode == O_WRONLY)
667b725ae77Skettenis 	    fprintf (procfs_file ? procfs_file : stdout, "O_WRONLY) %d\n",
668b725ae77Skettenis 		     line);
669b725ae77Skettenis 	  else if (mode == O_RDWR)
670b725ae77Skettenis 	    fprintf (procfs_file ? procfs_file : stdout, "O_RDWR)   %d\n",
671b725ae77Skettenis 		     line);
672b725ae77Skettenis 	}
673b725ae77Skettenis       if (procfs_file)
674b725ae77Skettenis 	fflush (procfs_file);
675b725ae77Skettenis     }
676b725ae77Skettenis 
677b725ae77Skettenis   return ret;
678b725ae77Skettenis }
679b725ae77Skettenis 
680b725ae77Skettenis int
close_with_trace(int fd,char * file,int line)681b725ae77Skettenis close_with_trace (int fd, char *file, int line)
682b725ae77Skettenis {
683b725ae77Skettenis   int ret;
684b725ae77Skettenis 
685b725ae77Skettenis   prepare_to_trace ();
686b725ae77Skettenis   errno = 0;
687b725ae77Skettenis   ret = close (fd);
688b725ae77Skettenis   if (procfs_trace)
689b725ae77Skettenis     {
690b725ae77Skettenis       if (info_verbose)
691b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
692b725ae77Skettenis 		 "%s:%d -- ", file, line);
693b725ae77Skettenis       if (errno)
694b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
695b725ae77Skettenis 		 "[close FAILED! (%s)]\n", safe_strerror (errno));
696b725ae77Skettenis       else
697b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
698b725ae77Skettenis 		 "%d = close (%d)\n", ret, fd);
699b725ae77Skettenis       if (procfs_file)
700b725ae77Skettenis 	fflush (procfs_file);
701b725ae77Skettenis     }
702b725ae77Skettenis 
703b725ae77Skettenis   return ret;
704b725ae77Skettenis }
705b725ae77Skettenis 
706b725ae77Skettenis pid_t
wait_with_trace(int * wstat,char * file,int line)707b725ae77Skettenis wait_with_trace (int *wstat, char *file, int line)
708b725ae77Skettenis {
709b725ae77Skettenis   int ret, lstat = 0;
710b725ae77Skettenis 
711b725ae77Skettenis   prepare_to_trace ();
712b725ae77Skettenis   if (procfs_trace)
713b725ae77Skettenis     {
714b725ae77Skettenis       if (info_verbose)
715b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
716b725ae77Skettenis 		 "%s:%d -- ", file, line);
717b725ae77Skettenis       fprintf (procfs_file ? procfs_file : stdout,
718b725ae77Skettenis 	       "wait (line %d) ", line);
719b725ae77Skettenis       if (procfs_file)
720b725ae77Skettenis 	fflush (procfs_file);
721b725ae77Skettenis     }
722b725ae77Skettenis   errno = 0;
723b725ae77Skettenis   ret = wait (&lstat);
724b725ae77Skettenis   if (procfs_trace)
725b725ae77Skettenis     {
726b725ae77Skettenis       if (errno)
727b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
728b725ae77Skettenis 		 "[wait FAILED! (%s)]\n", safe_strerror (errno));
729b725ae77Skettenis       else
730b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
731b725ae77Skettenis 		 "returned pid %d, status 0x%x\n", ret, lstat);
732b725ae77Skettenis       if (procfs_file)
733b725ae77Skettenis 	fflush (procfs_file);
734b725ae77Skettenis     }
735b725ae77Skettenis   if (wstat)
736b725ae77Skettenis     *wstat = lstat;
737b725ae77Skettenis 
738b725ae77Skettenis   return ret;
739b725ae77Skettenis }
740b725ae77Skettenis 
741b725ae77Skettenis void
procfs_note(char * msg,char * file,int line)742b725ae77Skettenis procfs_note (char *msg, char *file, int line)
743b725ae77Skettenis {
744b725ae77Skettenis   prepare_to_trace ();
745b725ae77Skettenis   if (procfs_trace)
746b725ae77Skettenis     {
747b725ae77Skettenis       if (info_verbose)
748b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
749b725ae77Skettenis 		 "%s:%d -- ", file, line);
750b725ae77Skettenis       fprintf (procfs_file ? procfs_file : stdout, "%s", msg);
751b725ae77Skettenis       if (procfs_file)
752b725ae77Skettenis 	fflush (procfs_file);
753b725ae77Skettenis     }
754b725ae77Skettenis }
755b725ae77Skettenis 
756b725ae77Skettenis void
proc_prettyfprint_status(long flags,int why,int what,int thread)757b725ae77Skettenis proc_prettyfprint_status (long flags, int why, int what, int thread)
758b725ae77Skettenis {
759b725ae77Skettenis   prepare_to_trace ();
760b725ae77Skettenis   if (procfs_trace)
761b725ae77Skettenis     {
762b725ae77Skettenis       if (thread)
763b725ae77Skettenis 	fprintf (procfs_file ? procfs_file : stdout,
764b725ae77Skettenis 		 "Thread %d: ", thread);
765b725ae77Skettenis 
766b725ae77Skettenis       proc_prettyfprint_flags (procfs_file ? procfs_file : stdout,
767b725ae77Skettenis 			       flags, 0);
768b725ae77Skettenis 
769b725ae77Skettenis       if (flags & (PR_STOPPED | PR_ISTOP))
770b725ae77Skettenis 	proc_prettyfprint_why (procfs_file ? procfs_file : stdout,
771b725ae77Skettenis 			       why, what, 0);
772b725ae77Skettenis       if (procfs_file)
773b725ae77Skettenis 	fflush (procfs_file);
774b725ae77Skettenis     }
775b725ae77Skettenis }
776b725ae77Skettenis 
777b725ae77Skettenis 
778b725ae77Skettenis void
_initialize_proc_api(void)779b725ae77Skettenis _initialize_proc_api (void)
780b725ae77Skettenis {
781b725ae77Skettenis   struct cmd_list_element *c;
782b725ae77Skettenis 
783b725ae77Skettenis   c = add_set_cmd ("procfs-trace", no_class,
784b725ae77Skettenis 		   var_boolean, (char *) &procfs_trace,
785b725ae77Skettenis 		   "Set tracing for /proc api calls.\n", &setlist);
786b725ae77Skettenis 
787*11efff7fSkettenis   deprecated_add_show_from_set (c, &showlist);
788b725ae77Skettenis   set_cmd_sfunc (c, set_procfs_trace_cmd);
789b725ae77Skettenis   set_cmd_completer (c, filename_completer);
790b725ae77Skettenis 
791b725ae77Skettenis   c = add_set_cmd ("procfs-file", no_class, var_filename,
792b725ae77Skettenis 		   (char *) &procfs_filename,
793b725ae77Skettenis 		   "Set filename for /proc tracefile.\n", &setlist);
794b725ae77Skettenis 
795*11efff7fSkettenis   deprecated_add_show_from_set (c, &showlist);
796b725ae77Skettenis   set_cmd_sfunc (c, set_procfs_file_cmd);
797b725ae77Skettenis }
798