]> 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                         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
189 static 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
199 static const struct xlat proc_status_flags[] = {
200         { PF_LINGER,    "PF_LINGER"     },
201         { PF_ISUGID,    "PF_ISUGID"     },
202         { 0,            NULL            }
203 };
204
205 int
206 proc_ioctl(tcp, code, arg)
207 struct tcb *tcp;
208 int 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