]> granicus.if.org Git - strace/blob - desc.c
Update sys_createmodule and sys_initmodule
[strace] / desc.c
1 /*
2  * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3  * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4  * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  *
29  *      $Id$
30  */
31
32 #include "defs.h"
33
34 #include <fcntl.h>
35 #include <sys/file.h>
36
37 static struct xlat fcntlcmds[] = {
38         { F_DUPFD,      "F_DUPFD"       },
39         { F_GETFD,      "F_GETFD"       },
40         { F_SETFD,      "F_SETFD"       },
41         { F_GETFL,      "F_GETFL"       },
42         { F_SETFL,      "F_SETFL"       },
43         { F_GETLK,      "F_GETLK"       },
44         { F_SETLK,      "F_SETLK"       },
45         { F_SETLKW,     "F_SETLKW"      },
46         { F_GETOWN,     "F_GETOWN"      },
47         { F_SETOWN,     "F_SETOWN"      },
48 #ifdef F_RSETLK
49         { F_RSETLK,     "F_RSETLK"      },
50 #endif
51 #ifdef F_RSETLKW
52         { F_RSETLKW,    "F_RSETLKW"     },
53 #endif
54 #ifdef F_RGETLK
55         { F_RGETLK,     "F_RGETLK"      },
56 #endif
57 #ifdef F_CNVT
58         { F_CNVT,       "F_CNVT"        },
59 #endif
60         { 0,            NULL            },
61 };
62
63 static struct xlat fdflags[] = {
64 #ifdef FD_CLOEXEC
65         { FD_CLOEXEC,   "FD_CLOEXEC"    },
66 #endif
67         { 0,            NULL            },
68 };
69
70 #ifdef LOCK_SH
71
72 static struct xlat flockcmds[] = {
73         { LOCK_SH,      "LOCK_SH"       },
74         { LOCK_EX,      "LOCK_EX"       },
75         { LOCK_NB,      "LOCK_NB"       },
76         { LOCK_UN,      "LOCK_UN"       },
77         { 0,            NULL            },
78 };
79
80 #endif /* LOCK_SH */
81
82 static struct xlat lockfcmds[] = {
83         { F_RDLCK,      "F_RDLCK"       },
84         { F_WRLCK,      "F_WRLCK"       },
85         { F_UNLCK,      "F_UNLCK"       },
86 #ifdef F_EXLCK
87         { F_EXLCK,      "F_EXLCK"       },
88 #endif
89 #ifdef F_SHLCK
90         { F_SHLCK,      "F_SHLCK"       },
91 #endif
92         { 0,            NULL            },
93 };
94
95 static struct xlat whence[] = {
96         { SEEK_SET,     "SEEK_SET"      },
97         { SEEK_CUR,     "SEEK_CUR"      },
98         { SEEK_END,     "SEEK_END"      },
99         { 0,            NULL            },
100 };
101
102 /* fcntl/lockf */
103 static void
104 printflock(tcp, addr, getlk)
105 struct tcb *tcp;
106 int addr;
107 int getlk;
108 {
109         struct flock fl;
110
111         if (umove(tcp, addr, &fl) < 0) {
112                 tprintf("{...}");
113                 return;
114         }
115         tprintf("{type=");
116         printxval(lockfcmds, fl.l_type, "F_???");
117         tprintf(", whence=");
118         printxval(whence, fl.l_whence, "SEEK_???");
119         tprintf(", start=%ld, len=%ld", fl.l_start, fl.l_len);
120         if (getlk)
121                 tprintf(", pid=%lu}", (unsigned long) fl.l_pid);
122         else
123                 tprintf("}");
124 }
125
126 static char *
127 sprintflags(xlat, flags)
128 struct xlat *xlat;
129 int flags;
130 {
131         static char outstr[1024];
132         char *sep;
133
134         strcpy(outstr, "flags ");
135         sep = "";
136         for (; xlat->str; xlat++) {
137                 if ((flags & xlat->val) == xlat->val) {
138                         sprintf(outstr + strlen(outstr),
139                                 "%s%s", sep, xlat->str);
140                         sep = "|";
141                         flags &= ~xlat->val;
142                 }
143         }
144         if (flags)
145                 sprintf(outstr + strlen(outstr),
146                         "%s%#x", sep, flags);
147         return outstr;
148 }
149
150 int
151 sys_fcntl(tcp)
152 struct tcb *tcp;
153 {
154         extern struct xlat openmodes[];
155
156         if (entering(tcp)) {
157                 tprintf("%ld, ", tcp->u_arg[0]);
158                 printxval(fcntlcmds, tcp->u_arg[1], "F_???");
159                 switch (tcp->u_arg[1]) {
160                 case F_SETFD:
161                         tprintf(", ");
162                         if (printflags(fdflags, tcp->u_arg[2]) == 0)
163                                 tprintf("0");
164                         break;
165                 case F_SETOWN: case F_DUPFD:
166                         tprintf(", %ld", tcp->u_arg[2]);
167                         break;
168                 case F_SETFL:
169                         tprintf(", ");
170                         if (printflags(openmodes, tcp->u_arg[2] + 1) == 0)
171                                 tprintf("0");
172                         break;
173                 case F_SETLK: case F_SETLKW:
174                         tprintf(", ");
175                         printflock(tcp, tcp->u_arg[2], 0);
176                         break;
177                 }
178         }
179         else {
180                 switch (tcp->u_arg[1]) {
181                 case F_DUPFD:
182                 case F_SETFD: case F_SETFL:
183                 case F_SETLK: case F_SETLKW:
184                 case F_SETOWN: case F_GETOWN:
185                         break;
186                 case F_GETFD:
187                         if (tcp->u_rval == 0)
188                                 return 0;
189                         tcp->auxstr = sprintflags(fdflags, tcp->u_rval);
190                         return RVAL_HEX|RVAL_STR;
191                 case F_GETFL:
192                         tcp->auxstr = sprintflags(openmodes, tcp->u_rval + 1);
193                         return RVAL_HEX|RVAL_STR;
194                 case F_GETLK:
195                         tprintf(", ");
196                         printflock(tcp, tcp->u_arg[2], 1);
197                         break;
198                 default:
199                         tprintf(", %#lx", tcp->u_arg[2]);
200                         break;
201                 }
202         }
203         return 0;
204 }
205
206 #ifdef LOCK_SH
207
208 int
209 sys_flock(tcp)
210 struct tcb *tcp;
211 {
212         if (entering(tcp)) {
213                 tprintf("%ld, ", tcp->u_arg[0]);
214                 if (!printflags(flockcmds, tcp->u_arg[1]))
215                         tprintf("LOCK_???");
216         }
217         return 0;
218 }
219 #endif /* LOCK_SH */
220
221 int
222 sys_close(tcp)
223 struct tcb *tcp;
224 {
225         if (entering(tcp)) {
226                 tprintf("%ld", tcp->u_arg[0]);
227         }
228         return 0;
229 }
230
231 int
232 sys_dup(tcp)
233 struct tcb *tcp;
234 {
235         if (entering(tcp)) {
236                 tprintf("%ld", tcp->u_arg[0]);
237         }
238         return 0;
239 }
240
241 int
242 sys_dup2(tcp)
243 struct tcb *tcp;
244 {
245         if (entering(tcp)) {
246                 tprintf("%ld, %ld", tcp->u_arg[0], tcp->u_arg[1]);
247         }
248         return 0;
249 }
250
251 int
252 sys_getdtablesize(tcp)
253 struct tcb *tcp;
254 {
255         return 0;
256 }
257
258 static int
259 decode_select(tcp, args)
260 struct tcb *tcp;
261 long *args;
262 {
263         int i, j, nfds;
264         fd_set fds;
265         struct timeval tv;
266         static char outstr[1024];
267         char *sep;
268         long arg;
269
270         if (entering(tcp)) {
271                 nfds = args[0];
272                 tprintf("%d", nfds);
273                 for (i = 0; i < 3; i++) {
274                         arg = args[i+1];
275                         if (arg == 0) {
276                                 tprintf(", NULL");
277                                 continue;
278                         }
279                         if (!verbose(tcp)) {
280                                 tprintf(", %#lx", arg);
281                                 continue;
282                         }
283                         if (umove(tcp, arg, &fds) < 0) {
284                                 tprintf(", [?]");
285                                 continue;
286                         }
287                         tprintf(", [");
288                         for (j = 0, sep = ""; j < nfds; j++) {
289                                 if (FD_ISSET(j, &fds)) {
290                                         tprintf("%s%u", sep, j);
291                                         sep = " ";
292                                 }
293                         }
294                         tprintf("]");
295                 }
296                 if (!args[4])
297                         tprintf(", NULL");
298                 else if (!verbose(tcp))
299                         tprintf(", %#lx", args[4]);
300                 else if (umove(tcp, args[4], &tv) < 0)
301                         tprintf(", {...}");
302                 else {
303                         tprintf(", {%lu, %lu}",
304                                 (long) tv.tv_sec, (long) tv.tv_usec);
305                 }
306         }
307         else {
308                 unsigned int cumlen = 0;
309                 char *sep = "";
310
311                 if (syserror(tcp))
312                         return 0;
313
314                 if ((nfds = tcp->u_rval) == 0) {
315                         tcp->auxstr = "Timeout";
316                         return RVAL_STR;
317                 }
318                 outstr[0] = '\0';
319                 for (i = 0; i < 3; i++) {
320                         int first = 1;
321                         char str[20];
322
323                         tcp->auxstr = outstr;
324                         arg = args[i+1];
325                         if (!arg || umove(tcp, arg, &fds) < 0)
326                                 continue;
327                         for (j = 0; j < args[0]; j++) {
328                                 if (FD_ISSET(j, &fds)) {
329                                         if (first) {
330                                                 sprintf(str, "%s%s [%u", sep,
331                                                         i == 0 ? "in" :
332                                                         i == 1 ? "out" :
333                                                         "except", j);
334                                                 first = 0;
335                                                 sep = ", ";
336                                         }
337                                         else
338                                                 sprintf(str, " %u", j);
339                                         cumlen += strlen(str);
340                                         if (cumlen < sizeof(outstr))
341                                                 strcat(outstr, str);
342                                         nfds--;
343                                 }
344                         }
345                         if (cumlen)
346                                 strcat(outstr, "]");
347                         if (nfds == 0)
348                                 break;
349                 }
350 #ifdef LINUX
351                 /* This contains no useful information on SunOS.  */
352                 if (args[4]) {
353                         char str[20];
354
355                         if (umove(tcp, args[4], &tv) >= 0)
356                                 sprintf(str, "%sleft {%lu, %lu}", sep,
357                                         (long) tv.tv_sec, (long) tv.tv_usec);
358                         if ((cumlen += strlen(str)) < sizeof(outstr))
359                                 strcat(outstr, str);
360                 }
361 #endif /* LINUX */
362                 return RVAL_STR;
363         }
364         return 0;
365 }
366
367 #ifdef LINUX
368
369 int
370 sys_oldselect(tcp)
371 struct tcb *tcp;
372 {
373         long args[5];
374
375         if (umoven(tcp, tcp->u_arg[0], sizeof args, (char *) args) < 0) {
376                 tprintf("[...]");
377                 return 0;
378         }
379         return decode_select(tcp, args);
380 }
381
382 #endif /* LINUX */
383
384 int
385 sys_select(tcp)
386 struct tcb *tcp;
387 {
388         long *args = tcp->u_arg;
389         return decode_select(tcp, args);
390 }