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