]> granicus.if.org Git - strace/blob - proc.c
.
[strace] / proc.c
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
35 static 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
60 static 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
76 static 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
89 int
90 proc_ioctl(tcp, code, arg)
91 struct tcb *tcp;
92 int 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                         if (!printflags(proc_status_flags, status.pr_flags))
114                                 tprintf("0");
115                         if (status.pr_why) {
116                                 tprintf(", pr_why=");
117                                 printxval(proc_status_why, status.pr_why,
118                                           "PR_???");
119                         }
120                         switch (status.pr_why) {
121                         case PR_SIGNALLED:
122                         case PR_JOBCONTROL:
123                                 tprintf(", pr_what=");
124                                 printsignal(status.pr_what);
125                                 break;
126                         case PR_FAULTED:
127                                 tprintf(", pr_what=%d", status.pr_what);
128                                 break;
129                         case PR_SYSENTRY:
130                         case PR_SYSEXIT:
131                                 tprintf(", pr_what=SYS_%s",
132                                         sysent[status.pr_what].sys_name);
133                                 break;
134                         }
135                         tprintf(", ...}");
136                 }
137                 return 1;
138         case PIOCRUN:
139                 if (arg == 0)
140                         tprintf(", NULL");
141                 else if (umove(tcp, arg, &run) < 0)
142                         tprintf(", {...}");
143                 else {
144                         tprintf(", {pr_flags=");
145                         if (!printflags(proc_run_flags, run.pr_flags))
146                                 tprintf("0");
147                         tprintf(", ...}");
148                 }
149                 return 1;
150 #ifdef PIOCSET
151         case PIOCSET:
152         case PIOCRESET:
153                 if (umove(tcp, arg, &val) < 0)
154                         tprintf(", [?]");
155                 else {
156                         tprintf(", [");
157                         if (!printflags(proc_status_flags, val))
158                                 tprintf("0");
159                         tprintf("]");
160                 }
161                 return 1;
162 #endif /* PIOCSET */
163         case PIOCKILL:
164         case PIOCUNKILL:
165                 /* takes a pointer to a signal */
166                 if (umove(tcp, arg, &val) < 0)
167                         tprintf(", [?]");
168                 else {
169                         tprintf(", [");
170                         printsignal(val);
171                         tprintf("]");
172                 }
173                 return 1;
174         case PIOCSFORK:
175         case PIOCRFORK:
176         case PIOCSRLC:
177         case PIOCRRLC:
178                 /* doesn't take an arg */
179                 return 1;
180         default:
181                 /* ad naseum */
182                 return 0;
183         }
184 }
185
186 #endif /* HAVE_MP_PROCFS */
187 #endif /* SVR4 */
188
189 #ifdef FREEBSD
190 #include <sys/pioctl.h>
191
192 static const struct xlat proc_status_why[] = {
193         { S_EXEC,       "S_EXEC"        },
194         { S_SIG,        "S_SIG"         },
195         { S_SCE,        "S_SCE"         },
196         { S_SCX,        "S_SCX"         },
197         { S_CORE,       "S_CORE"        },
198         { S_EXIT,       "S_EXIT"        },
199         { 0,            NULL            }
200 };
201
202 static const struct xlat proc_status_flags[] = {
203         { PF_LINGER,    "PF_LINGER"     },
204         { PF_ISUGID,    "PF_ISUGID"     },
205         { 0,            NULL            }
206 };
207
208 int
209 proc_ioctl(tcp, code, arg)
210 struct tcb *tcp;
211 int code, arg;
212 {
213         int val;
214         struct procfs_status status;
215
216         if (entering(tcp))
217                 return 0;
218
219         switch (code) {
220         case PIOCSTATUS:
221         case PIOCWAIT:
222                 if (arg == 0)
223                         tprintf(", NULL");
224                 else if (syserror(tcp))
225                         tprintf(", %x", arg);
226                 else if (umove(tcp, arg, &status) < 0)
227                         tprintf(", {...}");
228                 else {
229                         tprintf(", {state=%d, flags=", status.state);
230                         if (!printflags(proc_status_flags, status.flags))
231                                 tprintf("0");
232                         tprintf(", events=");
233                         printflags(proc_status_why, status.events);
234                         tprintf(", why=");
235                         printxval(proc_status_why, status.why, "S_???");
236                         tprintf(", val=%lu}", status.val);
237                 }
238                 return 1;
239         case PIOCBIS:
240                 if (arg) {
241                         tprintf(", ");
242                         printflags(proc_status_why, arg);
243                 } else
244                         tprintf(", 0");
245                 return 1;
246                 return 1;
247         case PIOCSFL:
248                 if (arg) {
249                         tprintf(", ");
250                         printflags(proc_status_flags, arg);
251                 } else
252                         tprintf(", 0");
253                 return 1;
254         case PIOCGFL:
255                 if (syserror(tcp))
256                         tprintf(", %#x", arg);
257                 else if (umove(tcp, arg, &val) < 0)
258                         tprintf(", {...}");
259                 else {
260                         tprintf(", [");
261                         if (val)
262                                 printflags(proc_status_flags, val);
263                         else
264                                 tprintf("0");
265                         tprintf("]");
266                 }
267                 return 1;
268         default:
269                 /* ad naseum */
270                 return 0;
271         }
272 }
273 #endif