]> granicus.if.org Git - strace/blob - file.c
1ecf85bd13694471414639d0c51f388b04e6a25e
[strace] / file.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 <dirent.h>
35 #ifdef linux
36 #define dirent kernel_dirent
37 #include <linux/types.h>
38 #include <linux/dirent.h>
39 #undef dirent
40 #else
41 #define kernel_dirent dirent
42 #endif
43
44 #ifdef linux
45 #  ifdef LINUXSPARC
46 struct stat {
47         unsigned short  st_dev;
48         unsigned int    st_ino;
49         unsigned short  st_mode;
50         short           st_nlink;
51         unsigned short  st_uid;
52         unsigned short  st_gid;
53         unsigned short  st_rdev;
54         unsigned int    st_size;
55         int             st_atime;
56         unsigned int    __unused1;
57         int             st_mtime;
58         unsigned int    __unused2;
59         int             st_ctime;
60         unsigned int    __unused3;
61         int             st_blksize;
62         int             st_blocks;
63         unsigned int    __unused4[2];
64 };
65 #    define stat kernel_stat
66 #    include <asm/stat.h>
67 #    undef stat
68 #  else
69 #    undef dev_t
70 #    undef ino_t
71 #    undef mode_t
72 #    undef nlink_t
73 #    undef uid_t
74 #    undef gid_t
75 #    undef off_t
76 #    undef loff_t
77
78 #    define dev_t __kernel_dev_t
79 #    define ino_t __kernel_ino_t
80 #    define mode_t __kernel_mode_t
81 #    define nlink_t __kernel_nlink_t
82 #    define uid_t __kernel_uid_t
83 #    define gid_t __kernel_gid_t
84 #    define off_t __kernel_off_t
85 #    define loff_t __kernel_loff_t
86
87 #    include <asm/stat.h>
88
89 #    undef dev_t
90 #    undef ino_t
91 #    undef mode_t
92 #    undef nlink_t
93 #    undef uid_t
94 #    undef gid_t
95 #    undef off_t
96 #    undef loff_t
97
98 #    define dev_t dev_t
99 #    define ino_t ino_t
100 #    define mode_t mode_t
101 #    define nlink_t nlink_t
102 #    define uid_t uid_t
103 #    define gid_t gid_t
104 #    define off_t off_t
105 #    define loff_t loff_t
106 #  endif
107 #  define stat libc_stat
108 #  include <sys/stat.h>
109 #  undef stat
110 #else
111 #  include <sys/stat.h>
112 #endif
113
114 #include <fcntl.h>
115
116 #ifdef SVR4
117 #  include <sys/cred.h>
118 #endif /* SVR4 */
119
120 #include <sys/vfs.h>
121
122 #ifdef MAJOR_IN_SYSMACROS
123 #include <sys/sysmacros.h>
124 #endif
125
126 #ifdef MAJOR_IN_MKDEV
127 #include <sys/mkdev.h>
128 #endif
129
130 #ifdef HAVE_SYS_ASYNCH_H
131 #include <sys/asynch.h>
132 #endif
133
134 #ifdef SUNOS4
135 #include <ustat.h>
136 #endif
137
138 /*
139  * This is a really dirty trick but it should always work.  Traditional
140  * Unix says r/w/rw are 0/1/2, so we make them true flags 1/2/3 by
141  * adding 1.  Just remember to add 1 to any arg decoded with openmodes.
142  */
143 struct xlat openmodes[] = {
144         { O_RDWR+1,     "O_RDWR"        },
145         { O_RDONLY+1,   "O_RDONLY"      },
146         { O_WRONLY+1,   "O_WRONLY"      },
147         { O_NONBLOCK,   "O_NONBLOCK"    },
148         { O_APPEND,     "O_APPEND"      },
149         { O_CREAT,      "O_CREAT"       },
150         { O_TRUNC,      "O_TRUNC"       },
151         { O_EXCL,       "O_EXCL"        },
152         { O_NOCTTY,     "O_NOCTTY"      },
153 #ifdef O_SYNC
154         { O_SYNC,       "O_SYNC"        },
155 #endif
156 #ifdef O_ASYNC
157         { O_ASYNC,      "O_ASYNC"       },
158 #endif
159 #ifdef O_DSYNC
160         { O_DSYNC,      "O_DSYNC"       },
161 #endif
162 #ifdef O_RSYNC
163         { O_RSYNC,      "O_RSYNC"       },
164 #endif
165 #ifdef O_NDELAY
166         { O_NDELAY,     "O_NDELAY"      },
167 #endif
168 #ifdef O_PRIV
169         { O_PRIV,       "O_PRIV"        },
170 #endif
171 #ifdef O_DIRECT
172    { O_DIRECT, "O_DIRECT"  },
173 #endif
174 #ifdef O_LARGEFILE
175    { O_LARGEFILE,  "O_LARGEFILE"   },
176 #endif
177 #ifdef O_DIRECTORY
178    { O_DIRECTORY,  "O_DIRECTORY"   },
179 #endif
180
181 #ifdef FNDELAY
182         { FNDELAY,      "FNDELAY"       },
183 #endif
184 #ifdef FAPPEND
185         { FAPPEND,      "FAPPEND"       },
186 #endif
187 #ifdef FMARK
188         { FMARK,        "FMARK"         },
189 #endif
190 #ifdef FDEFER
191         { FDEFER,       "FDEFER"        },
192 #endif
193 #ifdef FASYNC
194         { FASYNC,       "FASYNC"        },
195 #endif
196 #ifdef FSHLOCK
197         { FSHLOCK,      "FSHLOCK"       },
198 #endif
199 #ifdef FEXLOCK
200         { FEXLOCK,      "FEXLOCK"       },
201 #endif
202 #ifdef FCREAT
203         { FCREAT,       "FCREAT"        },
204 #endif
205 #ifdef FTRUNC
206         { FTRUNC,       "FTRUNC"        },
207 #endif
208 #ifdef FEXCL
209         { FEXCL,        "FEXCL"         },
210 #endif
211 #ifdef FNBIO
212         { FNBIO,        "FNBIO"         },
213 #endif
214 #ifdef FSYNC
215         { FSYNC,        "FSYNC"         },
216 #endif
217 #ifdef FNOCTTY
218         { FNOCTTY,      "FNOCTTY"       },
219 #endif
220         { 0,            NULL            },
221 };
222
223 int
224 sys_open(tcp)
225 struct tcb *tcp;
226 {
227         if (entering(tcp)) {
228                 printpath(tcp, tcp->u_arg[0]);
229                 tprintf(", ");
230                 /* flags */
231                 printflags(openmodes, tcp->u_arg[1] + 1);
232                 if (tcp->u_arg[1] & O_CREAT) {
233                         /* mode */
234                         tprintf(", %#lo", tcp->u_arg[2]);
235                 }
236         }
237         return 0;
238 }
239
240 #ifdef LINUXSPARC
241 struct xlat openmodessol[] = {
242         { 0,            "O_RDWR"        },
243         { 1,            "O_RDONLY"      },
244         { 2,            "O_WRONLY"      },
245         { 0x80,         "O_NONBLOCK"    },
246         { 8,            "O_APPEND"      },
247         { 0x100,        "O_CREAT"       },
248         { 0x200,        "O_TRUNC"       },
249         { 0x400,        "O_EXCL"        },
250         { 0x800,        "O_NOCTTY"      },
251         { 0x10,         "O_SYNC"        },
252         { 0x40,         "O_DSYNC"       },
253         { 0x8000,       "O_RSYNC"       },
254         { 4,            "O_NDELAY"      },
255         { 0x1000,       "O_PRIV"        },
256         { 0,            NULL            },
257 };
258
259 int
260 solaris_open(tcp)
261 struct tcb *tcp;
262 {
263         if (entering(tcp)) {
264                 printpath(tcp, tcp->u_arg[0]);
265                 tprintf(", ");
266                 /* flags */
267                 printflags(openmodessol, tcp->u_arg[1] + 1);
268                 if (tcp->u_arg[1] & 0x100) {
269                         /* mode */
270                         tprintf(", %#lo", tcp->u_arg[2]);
271                 }
272         }
273         return 0;
274 }
275
276 #endif
277
278 int
279 sys_creat(tcp)
280 struct tcb *tcp;
281 {
282         if (entering(tcp)) {
283                 printpath(tcp, tcp->u_arg[0]);
284                 tprintf(", %#lo", tcp->u_arg[1]);
285         }
286         return 0;
287 }
288
289 static struct xlat access_flags[] = {
290         { F_OK,         "F_OK",         },
291         { R_OK,         "R_OK"          },
292         { W_OK,         "W_OK"          },
293         { X_OK,         "X_OK"          },
294 #ifdef EFF_ONLY_OK
295         { EFF_ONLY_OK,  "EFF_ONLY_OK"   },
296 #endif
297 #ifdef EX_OK
298         { EX_OK,        "EX_OK"         },
299 #endif
300         { 0,            NULL            },
301 };
302
303 int
304 sys_access(tcp)
305 struct tcb *tcp;
306 {
307         if (entering(tcp)) {
308                 printpath(tcp, tcp->u_arg[0]);
309                 tprintf(", ");
310                 printflags(access_flags, tcp->u_arg[1]);
311         }
312         return 0;
313 }
314
315 int
316 sys_umask(tcp)
317 struct tcb *tcp;
318 {
319         if (entering(tcp)) {
320                 tprintf("%#lo", tcp->u_arg[0]);
321         }
322         return RVAL_OCTAL;
323 }
324
325 static struct xlat whence[] = {
326         { SEEK_SET,     "SEEK_SET"      },
327         { SEEK_CUR,     "SEEK_CUR"      },
328         { SEEK_END,     "SEEK_END"      },
329         { 0,            NULL            },
330 };
331
332 int
333 sys_lseek(tcp)
334 struct tcb *tcp;
335 {
336         if (entering(tcp)) {
337                 tprintf("%ld, ", tcp->u_arg[0]);
338                 if (tcp->u_arg[2] == SEEK_SET)
339                         tprintf("%lu, ", tcp->u_arg[1]);
340                 else
341                         tprintf("%ld, ", tcp->u_arg[1]);
342                 printxval(whence, tcp->u_arg[2], "SEEK_???");
343         }
344         return RVAL_UDECIMAL;
345 }
346
347 #ifdef linux
348 int
349 sys_llseek (tcp)
350 struct tcb *tcp;
351 {
352     if (entering(tcp)) {
353         if (tcp->u_arg[4] == SEEK_SET)
354             tprintf("%ld, %llu, ", tcp->u_arg[0],
355                     (((long long int) tcp->u_arg[1]) << 32
356                      | (unsigned long long) tcp->u_arg[2]));
357         else
358             tprintf("%ld, %lld, ", tcp->u_arg[0],
359                     (((long long int) tcp->u_arg[1]) << 32
360                      | (unsigned long long) tcp->u_arg[2]));
361     }
362     else {
363         long long int off;
364         if (syserror(tcp) || umove(tcp, tcp->u_arg[3], &off) < 0)
365             tprintf("%#lx, ", tcp->u_arg[3]);
366         else
367             tprintf("[%llu], ", off);
368         printxval(whence, tcp->u_arg[4], "SEEK_???");
369     }
370     return 0;
371 }
372 #endif
373
374 int
375 sys_truncate(tcp)
376 struct tcb *tcp;
377 {
378         if (entering(tcp)) {
379                 printpath(tcp, tcp->u_arg[0]);
380                 tprintf(", %lu", tcp->u_arg[1]);
381         }
382         return 0;
383 }
384
385 int
386 sys_ftruncate(tcp)
387 struct tcb *tcp;
388 {
389         if (entering(tcp)) {
390                 tprintf("%ld, %lu", tcp->u_arg[0], tcp->u_arg[1]);
391         }
392         return 0;
393 }
394
395 /* several stats */
396
397 static struct xlat modetypes[] = {
398         { S_IFREG,      "S_IFREG"       },
399         { S_IFSOCK,     "S_IFSOCK"      },
400         { S_IFIFO,      "S_IFIFO"       },
401         { S_IFLNK,      "S_IFLNK"       },
402         { S_IFDIR,      "S_IFDIR"       },
403         { S_IFBLK,      "S_IFBLK"       },
404         { S_IFCHR,      "S_IFCHR"       },
405         { 0,            NULL            },
406 };
407
408 static char *
409 sprintmode(mode)
410 int mode;
411 {
412         static char buf[64];
413         char *s;
414
415         if ((mode & S_IFMT) == 0)
416                 s = "";
417         else if ((s = xlookup(modetypes, mode & S_IFMT)) == NULL) {
418                 sprintf(buf, "%#o", mode);
419                 return buf;
420         }
421         sprintf(buf, "%s%s%s%s", s,
422                 (mode & S_ISUID) ? "|S_ISUID" : "",
423                 (mode & S_ISGID) ? "|S_ISGID" : "",
424                 (mode & S_ISVTX) ? "|S_ISVTX" : "");
425         mode &= ~(S_IFMT|S_ISUID|S_ISGID|S_ISVTX);
426         if (mode)
427                 sprintf(buf + strlen(buf), "|%#o", mode);
428         s = (*buf == '|') ? buf + 1 : buf;
429         return *s ? s : "0";
430 }
431
432 static char *
433 sprinttime(t)
434 time_t t;
435 {
436         struct tm *tmp;
437         static char buf[32];
438
439         if (t == 0) {
440                 sprintf(buf, "0");
441                 return buf;
442         }
443         tmp = localtime(&t);
444         sprintf(buf, "%02d/%02d/%02d-%02d:%02d:%02d",
445                 tmp->tm_year, tmp->tm_mon + 1, tmp->tm_mday,
446                 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
447         return buf;
448 }
449
450 #ifdef LINUXSPARC
451 typedef struct {
452         int     tv_sec;
453         int     tv_nsec;
454 } timestruct_t;
455
456 struct solstat {
457         unsigned        st_dev;
458         int             st_pad1[3];     /* network id */
459         unsigned        st_ino;
460         unsigned        st_mode;
461         unsigned        st_nlink;
462         unsigned        st_uid;
463         unsigned        st_gid;
464         unsigned        st_rdev;
465         int             st_pad2[2];
466         int             st_size;
467         int             st_pad3;        /* st_size, off_t expansion */
468         timestruct_t    st_atime;
469         timestruct_t    st_mtime;
470         timestruct_t    st_ctime;
471         int             st_blksize;
472         int             st_blocks;
473         char            st_fstype[16];
474         int             st_pad4[8];     /* expansion area */
475 };
476
477 static void
478 printstatsol(tcp, addr)
479 struct tcb *tcp;
480 int addr;
481 {
482         struct solstat statbuf;
483
484         if (!addr) {
485                 tprintf("NULL");
486                 return;
487         }
488         if (syserror(tcp) || !verbose(tcp)) {
489                 tprintf("%#x", addr);
490                 return;
491         }
492         if (umove(tcp, addr, &statbuf) < 0) {
493                 tprintf("{...}");
494                 return;
495         }
496         if (!abbrev(tcp)) {
497                 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%lu, st_mode=%s, ",
498                         (unsigned long) ((statbuf.st_dev >> 18) & 0x3fff),
499                         (unsigned long) (statbuf.st_dev & 0x3ffff),
500                         (unsigned long) statbuf.st_ino,
501                         sprintmode(statbuf.st_mode));
502                 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
503                         (unsigned long) statbuf.st_nlink,
504                         (unsigned long) statbuf.st_uid,
505                         (unsigned long) statbuf.st_gid);
506                 tprintf("st_blksize=%lu, ", (unsigned long) statbuf.st_blksize);
507                 tprintf("st_blocks=%lu, ", (unsigned long) statbuf.st_blocks);
508         }
509         else
510                 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
511         switch (statbuf.st_mode & S_IFMT) {
512         case S_IFCHR: case S_IFBLK:
513                 tprintf("st_rdev=makedev(%lu, %lu), ",
514                         (unsigned long) ((statbuf.st_rdev >> 18) & 0x3fff),
515                         (unsigned long) (statbuf.st_rdev & 0x3ffff));
516                 break;
517         default:
518                 tprintf("st_size=%u, ", statbuf.st_size);
519                 break;
520         }
521         if (!abbrev(tcp)) {
522                 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
523                 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
524                 tprintf("st_ctime=%s}", sprinttime(statbuf.st_ctime));
525         }
526         else
527                 tprintf("...}");
528 }
529 #endif /* LINUXSPARC */
530
531 static void
532 realprintstat(tcp, statbuf)
533 struct tcb *tcp;
534 struct stat *statbuf;
535 {
536     if (!abbrev(tcp)) {
537             tprintf("{st_dev=makedev(%lu, %lu), st_ino=%lu, st_mode=%s, ",
538                     (unsigned long) major(statbuf->st_dev),
539                     (unsigned long) minor(statbuf->st_dev),
540                     (unsigned long) statbuf->st_ino,
541                     sprintmode(statbuf->st_mode));
542             tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
543                     (unsigned long) statbuf->st_nlink,
544                     (unsigned long) statbuf->st_uid,
545                     (unsigned long) statbuf->st_gid);
546 #ifdef HAVE_ST_BLKSIZE
547             tprintf("st_blksize=%lu, ", (unsigned long) statbuf->st_blksize);
548 #endif /* HAVE_ST_BLKSIZE */
549 #ifdef HAVE_ST_BLOCKS
550             tprintf("st_blocks=%lu, ", (unsigned long) statbuf->st_blocks);
551 #endif /* HAVE_ST_BLOCKS */
552     }
553     else
554             tprintf("{st_mode=%s, ", sprintmode(statbuf->st_mode));
555     switch (statbuf->st_mode & S_IFMT) {
556     case S_IFCHR: case S_IFBLK:
557 #ifdef HAVE_ST_RDEV
558             tprintf("st_rdev=makedev(%lu, %lu), ",
559                     (unsigned long) major(statbuf->st_rdev),
560                     (unsigned long) minor(statbuf->st_rdev));
561 #else /* !HAVE_ST_RDEV */
562             tprintf("st_size=makedev(%lu, %lu), ",
563                     (unsigned long) major(statbuf->st_size),
564                     (unsigned long) minor(statbuf->st_size));
565 #endif /* !HAVE_ST_RDEV */
566             break;
567     default:
568             tprintf("st_size=%lu, ", statbuf->st_size);
569             break;
570     }
571     if (!abbrev(tcp)) {
572             tprintf("st_atime=%s, ", sprinttime(statbuf->st_atime));
573             tprintf("st_mtime=%s, ", sprinttime(statbuf->st_mtime));
574             tprintf("st_ctime=%s}", sprinttime(statbuf->st_ctime));
575     }
576     else
577             tprintf("...}");
578 }
579
580
581 static void
582 printstat(tcp, addr)
583 struct tcb *tcp;
584 int addr;
585 {
586         struct stat statbuf;
587
588 #ifdef LINUXSPARC
589         if (current_personality == 1) {
590                 printstatsol(tcp, addr);
591                 return;
592         }
593 #endif /* LINUXSPARC */
594
595         if (!addr) {
596                 tprintf("NULL");
597                 return;
598         }
599         if (syserror(tcp) || !verbose(tcp)) {
600                 tprintf("%#x", addr);
601                 return;
602         }
603         if (umove(tcp, addr, &statbuf) < 0) {
604                 tprintf("{...}");
605                 return;
606         }
607
608         realprintstat(tcp, &statbuf);
609 }
610
611 #ifdef linux
612 static void
613 convertoldstat(oldbuf, newbuf)
614 const struct __old_kernel_stat *oldbuf;
615 struct stat *newbuf;
616 {
617     newbuf->st_dev=oldbuf->st_dev;
618     newbuf->st_ino=oldbuf->st_ino;
619     newbuf->st_mode=oldbuf->st_mode;
620     newbuf->st_nlink=oldbuf->st_nlink;
621     newbuf->st_uid=oldbuf->st_uid;
622     newbuf->st_gid=oldbuf->st_gid;
623     newbuf->st_rdev=oldbuf->st_rdev;
624     newbuf->st_size=oldbuf->st_size;
625     newbuf->st_atime=oldbuf->st_atime;
626     newbuf->st_mtime=oldbuf->st_mtime;
627     newbuf->st_ctime=oldbuf->st_ctime;
628     newbuf->st_blksize=0;       /* not supported in old_stat */
629     newbuf->st_blocks=0;                /* not supported in old_stat */
630 }
631 #endif
632
633
634 #ifdef linux
635 static void
636 printoldstat(tcp, addr)
637 struct tcb *tcp;
638 int addr;
639 {
640         struct __old_kernel_stat statbuf;
641         struct stat newstatbuf;
642
643 #ifdef LINUXSPARC
644         if (current_personality == 1) {
645                 printstatsol(tcp, addr);
646                 return;
647         }
648 #endif /* LINUXSPARC */
649
650         if (!addr) {
651                 tprintf("NULL");
652                 return;
653         }
654         if (syserror(tcp) || !verbose(tcp)) {
655                 tprintf("%#x", addr);
656                 return;
657         }
658         if (umove(tcp, addr, &statbuf) < 0) {
659                 tprintf("{...}");
660                 return;
661         }
662
663         convertoldstat(&statbuf, &newstatbuf);
664         realprintstat(tcp, &newstatbuf);
665 }
666 #endif
667
668
669 int
670 sys_stat(tcp)
671 struct tcb *tcp;
672 {
673         if (entering(tcp)) {
674                 printpath(tcp, tcp->u_arg[0]);
675                 tprintf(", ");
676         } else {
677                 printstat(tcp, tcp->u_arg[1]);
678         }
679         return 0;
680 }
681
682 #ifdef linux
683 int
684 sys_oldstat(tcp)
685 struct tcb *tcp;
686 {
687         if (entering(tcp)) {
688                 printpath(tcp, tcp->u_arg[0]);
689                 tprintf(", ");
690         } else {
691                 printoldstat(tcp, tcp->u_arg[1]);
692         }
693         return 0;
694 }
695 #endif
696
697 int
698 sys_fstat(tcp)
699 struct tcb *tcp;
700 {
701         if (entering(tcp))
702                 tprintf("%ld, ", tcp->u_arg[0]);
703         else {
704                 printstat(tcp, tcp->u_arg[1]);
705         }
706         return 0;
707 }
708
709 #ifdef linux
710 int
711 sys_oldfstat(tcp)
712 struct tcb *tcp;
713 {
714         if (entering(tcp))
715                 tprintf("%ld, ", tcp->u_arg[0]);
716         else {
717                 printoldstat(tcp, tcp->u_arg[1]);
718         }
719         return 0;
720 }
721 #endif
722
723 int
724 sys_lstat(tcp)
725 struct tcb *tcp;
726 {
727         if (entering(tcp)) {
728                 printpath(tcp, tcp->u_arg[0]);
729                 tprintf(", ");
730         } else {
731                 printstat(tcp, tcp->u_arg[1]);
732         }
733         return 0;
734 }
735
736 #ifdef linux
737 int
738 sys_oldlstat(tcp)
739 struct tcb *tcp;
740 {
741         if (entering(tcp)) {
742                 printpath(tcp, tcp->u_arg[0]);
743                 tprintf(", ");
744         } else {
745                 printoldstat(tcp, tcp->u_arg[1]);
746         }
747         return 0;
748 }
749 #endif
750
751
752 #if defined(SVR4) || defined(LINUXSPARC)
753
754 int
755 sys_xstat(tcp)
756 struct tcb *tcp;
757 {
758         if (entering(tcp)) {
759                 tprintf("%ld, ", tcp->u_arg[0]);
760                 printpath(tcp, tcp->u_arg[1]);
761                 tprintf(", ");
762         } else {
763                 printstat(tcp, tcp->u_arg[2]);
764         }
765         return 0;
766 }
767
768 int
769 sys_fxstat(tcp)
770 struct tcb *tcp;
771 {
772         if (entering(tcp))
773                 tprintf("%ld, %ld, ", tcp->u_arg[0], tcp->u_arg[1]);
774         else {
775                 printstat(tcp, tcp->u_arg[2]);
776         }
777         return 0;
778 }
779
780 int
781 sys_lxstat(tcp)
782 struct tcb *tcp;
783 {
784         if (entering(tcp)) {
785                 tprintf("%ld, ", tcp->u_arg[0]);
786                 printpath(tcp, tcp->u_arg[1]);
787                 tprintf(", ");
788         } else {
789                 printstat(tcp, tcp->u_arg[2]);
790         }
791         return 0;
792 }
793
794 int
795 sys_xmknod(tcp)
796 struct tcb *tcp;
797 {
798         int mode = tcp->u_arg[2];
799
800         if (entering(tcp)) {
801                 tprintf("%ld, ", tcp->u_arg[0]);
802                 printpath(tcp, tcp->u_arg[1]);
803                 tprintf(", %s", sprintmode(mode));
804                 switch (mode & S_IFMT) {
805                 case S_IFCHR: case S_IFBLK:
806 #ifdef LINUXSPARC
807                         tprintf(", makedev(%lu, %lu)",
808                                 (unsigned long) ((tcp->u_arg[3] >> 18) & 0x3fff),
809                                 (unsigned long) (tcp->u_arg[3] & 0x3ffff));
810 #else           
811                         tprintf(", makedev(%lu, %lu)",
812                                 (unsigned long) major(tcp->u_arg[3]),
813                                 (unsigned long) minor(tcp->u_arg[3]));
814 #endif                          
815                         break;
816                 default:
817                         break;
818                 }
819         }
820         return 0;
821 }
822
823 #ifdef HAVE_SYS_ACL_H
824
825 #include <sys/acl.h>
826
827 struct xlat aclcmds[] = {
828 #ifdef SETACL
829         { SETACL,       "SETACL"        },
830 #endif
831 #ifdef GETACL
832         { GETACL,       "GETACL"        },
833 #endif
834 #ifdef GETACLCNT
835         { GETACLCNT,    "GETACLCNT"     },
836 #endif
837 #ifdef ACL_GET
838         { ACL_GET,      "ACL_GET"       },
839 #endif  
840 #ifdef ACL_SET
841         { ACL_SET,      "ACL_SET"       },
842 #endif  
843 #ifdef ACL_CNT
844         { ACL_CNT,      "ACL_CNT"       },
845 #endif  
846         { 0,            NULL            },
847 };
848
849 int
850 sys_acl(tcp)
851 struct tcb *tcp;
852 {
853         if (entering(tcp)) {
854                 printpath(tcp, tcp->u_arg[0]);
855                 tprintf(", ");
856                 printxval(aclcmds, tcp->u_arg[1], "???ACL???");
857                 tprintf(", %ld", tcp->u_arg[2]);
858                 /*
859                  * FIXME - dump out the list of aclent_t's pointed to
860                  * by "tcp->u_arg[3]" if it's not NULL.
861                  */
862                 if (tcp->u_arg[3])
863                         tprintf(", %#lx", tcp->u_arg[3]);
864                 else
865                         tprintf(", NULL");
866         }
867         return 0;
868 }
869
870
871 int
872 sys_facl(tcp)
873 struct tcb *tcp;
874 {
875         if (entering(tcp)) {
876                 tprintf("%ld, ", tcp->u_arg[0]);
877                 printxval(aclcmds, tcp->u_arg[1], "???ACL???");
878                 tprintf(", %ld", tcp->u_arg[2]);
879                 /*
880                  * FIXME - dump out the list of aclent_t's pointed to
881                  * by "tcp->u_arg[3]" if it's not NULL.
882                  */
883                 if (tcp->u_arg[3])
884                         tprintf(", %#lx", tcp->u_arg[3]);
885                 else
886                         tprintf(", NULL");
887         }
888         return 0;
889 }
890
891
892 struct xlat aclipc[] = {
893 #ifdef IPC_SHM
894         { IPC_SHM,      "IPC_SHM"       },
895 #endif  
896 #ifdef IPC_SEM
897         { IPC_SEM,      "IPC_SEM"       },
898 #endif  
899 #ifdef IPC_MSG
900         { IPC_MSG,      "IPC_MSG"       },
901 #endif  
902         { 0,            NULL            },
903 };
904
905
906 int
907 sys_aclipc(tcp)
908 struct tcb *tcp;
909 {
910         if (entering(tcp)) {
911                 printxval(aclipc, tcp->u_arg[0], "???IPC???");
912                 tprintf(", %#lx, ", tcp->u_arg[1]);
913                 printxval(aclcmds, tcp->u_arg[2], "???ACL???");
914                 tprintf(", %ld", tcp->u_arg[3]);
915                 /*
916                  * FIXME - dump out the list of aclent_t's pointed to
917                  * by "tcp->u_arg[4]" if it's not NULL.
918                  */
919                 if (tcp->u_arg[4])
920                         tprintf(", %#lx", tcp->u_arg[4]);
921                 else
922                         tprintf(", NULL");
923         }
924         return 0;
925 }
926
927
928
929 #endif /* HAVE_SYS_ACL_H */
930
931 #endif /* SVR4 || LINUXSPARC */
932
933 #ifdef linux
934
935 static struct xlat fsmagic[] = {
936         { 0xef51,       "EXT2_OLD_SUPER_MAGIC"  },
937         { 0xef53,       "EXT2_SUPER_MAGIC"      },
938         { 0x137d,       "EXT_SUPER_MAGIC"       },
939         { 0x9660,       "ISOFS_SUPER_MAGIC"     },
940         { 0x137f,       "MINIX_SUPER_MAGIC"     },
941         { 0x138f,       "MINIX_SUPER_MAGIC2"    },
942         { 0x2468,       "MINIX2_SUPER_MAGIC"    },
943         { 0x2478,       "MINIX2_SUPER_MAGIC2"   },
944         { 0x4d44,       "MSDOS_SUPER_MAGIC"     },
945         { 0x6969,       "NFS_SUPER_MAGIC"       },
946         { 0x9fa0,       "PROC_SUPER_MAGIC"      },
947         { 0x012fd16d,   "XIAFS_SUPER_MAGIC"     },
948         { 0,            NULL                    },
949 };
950
951 #endif /* linux */
952
953 #ifndef SVR4
954
955 static char *
956 sprintfstype(magic)
957 int magic;
958 {
959         static char buf[32];
960 #ifdef linux
961         char *s;
962
963         s = xlookup(fsmagic, magic);
964         if (s) {
965                 sprintf(buf, "\"%s\"", s);
966                 return buf;
967         }
968 #endif /* linux */
969         sprintf(buf, "%#x", magic);
970         return buf;
971 }
972
973 static void
974 printstatfs(tcp, addr)
975 struct tcb *tcp;
976 long addr;
977 {
978         struct statfs statbuf;
979
980         if (syserror(tcp) || !verbose(tcp)) {
981                 tprintf("%#lx", addr);
982                 return;
983         }
984         if (umove(tcp, addr, &statbuf) < 0) {
985                 tprintf("{...}");
986                 return;
987         }
988 #ifdef ALPHA
989
990         tprintf("{f_type=%s, f_fbsize=%u, f_blocks=%u, f_bfree=%u, ",
991                 sprintfstype(statbuf.f_type),
992                 statbuf.f_bsize, statbuf.f_blocks, statbuf.f_bfree);
993         tprintf("f_bavail=%u, f_files=%u, f_ffree=%u, f_namelen=%u",
994                 statbuf.f_bavail,statbuf.f_files, statbuf.f_ffree, statbuf.f_namelen);
995 #else /* !ALPHA */
996         tprintf("{f_type=%s, f_bsize=%lu, f_blocks=%lu, f_bfree=%lu, ",
997                 sprintfstype(statbuf.f_type),
998                 (unsigned long)statbuf.f_bsize,
999                 (unsigned long)statbuf.f_blocks,
1000                 (unsigned long)statbuf.f_bfree);
1001         tprintf("f_files=%lu, f_ffree=%lu",
1002                 (unsigned long)statbuf.f_files,
1003                 (unsigned long)statbuf.f_ffree);
1004 #ifdef linux
1005         tprintf(", f_namelen=%lu", (unsigned long)statbuf.f_namelen);
1006 #endif /* linux */
1007 #endif /* !ALPHA */
1008         tprintf("}");
1009 }
1010
1011 int
1012 sys_statfs(tcp)
1013 struct tcb *tcp;
1014 {
1015         if (entering(tcp)) {
1016                 printpath(tcp, tcp->u_arg[0]);
1017                 tprintf(", ");
1018         } else {
1019                 printstatfs(tcp, tcp->u_arg[1]);
1020         }
1021         return 0;
1022 }
1023
1024 int
1025 sys_fstatfs(tcp)
1026 struct tcb *tcp;
1027 {
1028         if (entering(tcp)) {
1029                 tprintf("%lu, ", tcp->u_arg[0]);
1030         } else {
1031                 printstatfs(tcp, tcp->u_arg[1]);
1032         }
1033         return 0;
1034 }
1035
1036 #if defined(linux) && defined(__alpha)
1037
1038 int
1039 osf_statfs(tcp)
1040 struct tcb *tcp;
1041 {
1042         if (entering(tcp)) {
1043                 printpath(tcp, tcp->u_arg[0]);
1044                 tprintf(", ");
1045         } else {
1046                 printstatfs(tcp, tcp->u_arg[1]);
1047                 tprintf(", %lu", tcp->u_arg[2]);
1048         }
1049         return 0;
1050 }
1051
1052 int
1053 osf_fstatfs(tcp)
1054 struct tcb *tcp;
1055 {
1056         if (entering(tcp)) {
1057                 tprintf("%lu, ", tcp->u_arg[0]);
1058         } else {
1059                 printstatfs(tcp, tcp->u_arg[1]);
1060                 tprintf(", %lu", tcp->u_arg[2]);
1061         }
1062         return 0;
1063 }
1064 #endif /* linux && __alpha */
1065
1066 #endif /* !SVR4 */
1067
1068 #ifdef SUNOS4
1069
1070 int
1071 sys_ustat(tcp)
1072 struct tcb *tcp;
1073 {
1074         struct ustat statbuf;
1075
1076         if (entering(tcp)) {
1077                 tprintf("makedev(%lu, %lu), ",
1078                                 (long) major(tcp->u_arg[0]),
1079                                 (long) minor(tcp->u_arg[0]));
1080         }
1081         else {
1082                 if (syserror(tcp) || !verbose(tcp))
1083                         tprintf("%#lx", tcp->u_arg[1]);
1084                 else if (umove(tcp, tcp->u_arg[1], &statbuf) < 0)
1085                         tprintf("{...}");
1086                 else {
1087                         tprintf("{f_tfree=%lu, f_tinode=%lu, ",
1088                                 statbuf.f_tfree, statbuf.f_tinode);
1089                         tprintf("f_fname=\"%.*s\", ",
1090                                 (int) sizeof(statbuf.f_fname),
1091                                 statbuf.f_fname);
1092                         tprintf("f_fpack=\"%.*s\"}",
1093                                 (int) sizeof(statbuf.f_fpack),
1094                                 statbuf.f_fpack);
1095                 }
1096         }
1097         return 0;
1098 }
1099
1100 #endif /* SUNOS4 */
1101
1102 /* directory */
1103 int
1104 sys_chdir(tcp)
1105 struct tcb *tcp;
1106 {
1107         if (entering(tcp)) {
1108                 printpath(tcp, tcp->u_arg[0]);
1109         }
1110         return 0;
1111 }
1112
1113 int
1114 sys_mkdir(tcp)
1115 struct tcb *tcp;
1116 {
1117         if (entering(tcp)) {
1118                 printpath(tcp, tcp->u_arg[0]);
1119                 tprintf(", %#lo", tcp->u_arg[1]);
1120         }
1121         return 0;
1122 }
1123
1124 int
1125 sys_rmdir(tcp)
1126 struct tcb *tcp;
1127 {
1128         if (entering(tcp)) {
1129                 printpath(tcp, tcp->u_arg[0]);
1130         }
1131         return 0;
1132 }
1133
1134 int
1135 sys_fchdir(tcp)
1136 struct tcb *tcp;
1137 {
1138         if (entering(tcp)) {
1139                 tprintf("%ld", tcp->u_arg[0]);
1140         }
1141         return 0;
1142 }
1143
1144 int
1145 sys_chroot(tcp)
1146 struct tcb *tcp;
1147 {
1148         if (entering(tcp)) {
1149                 printpath(tcp, tcp->u_arg[0]);
1150         }
1151         return 0;
1152 }
1153
1154 int
1155 sys_fchroot(tcp)
1156 struct tcb *tcp;
1157 {
1158         if (entering(tcp)) {
1159                 tprintf("%ld", tcp->u_arg[0]);
1160         }
1161         return 0;
1162 }
1163
1164 int
1165 sys_link(tcp)
1166 struct tcb *tcp;
1167 {
1168         if (entering(tcp)) {
1169                 printpath(tcp, tcp->u_arg[0]);
1170                 tprintf(", ");
1171                 printpath(tcp, tcp->u_arg[1]);
1172         }
1173         return 0;
1174 }
1175
1176 int
1177 sys_unlink(tcp)
1178 struct tcb *tcp;
1179 {
1180         if (entering(tcp)) {
1181                 printpath(tcp, tcp->u_arg[0]);
1182         }
1183         return 0;
1184 }
1185
1186 int
1187 sys_symlink(tcp)
1188 struct tcb *tcp;
1189 {
1190         if (entering(tcp)) {
1191                 printpath(tcp, tcp->u_arg[0]);
1192                 tprintf(", ");
1193                 printpath(tcp, tcp->u_arg[1]);
1194         }
1195         return 0;
1196 }
1197
1198 int
1199 sys_readlink(tcp)
1200 struct tcb *tcp;
1201 {
1202         if (entering(tcp)) {
1203                 printpath(tcp, tcp->u_arg[0]);
1204                 tprintf(", ");
1205         } else {
1206                 if (syserror(tcp))
1207                         tprintf("%#lx", tcp->u_arg[1]);
1208                 else
1209                         printpathn(tcp, tcp->u_arg[1], tcp->u_rval);
1210                 tprintf(", %lu", tcp->u_arg[2]);
1211         }
1212         return 0;
1213 }
1214
1215 int
1216 sys_rename(tcp)
1217 struct tcb *tcp;
1218 {
1219         if (entering(tcp)) {
1220                 printpath(tcp, tcp->u_arg[0]);
1221                 tprintf(", ");
1222                 printpath(tcp, tcp->u_arg[1]);
1223         }
1224         return 0;
1225 }
1226
1227 int
1228 sys_chown(tcp)
1229 struct tcb *tcp;
1230 {
1231         if (entering(tcp)) {
1232                 printpath(tcp, tcp->u_arg[0]);
1233                 tprintf(", %lu, %lu", tcp->u_arg[1], tcp->u_arg[2]);
1234         }
1235         return 0;
1236 }
1237
1238 int
1239 sys_fchown(tcp)
1240 struct tcb *tcp;
1241 {
1242         if (entering(tcp)) {
1243                 tprintf("%ld, %lu, %lu",
1244                         tcp->u_arg[0], tcp->u_arg[1], tcp->u_arg[2]);
1245         }
1246         return 0;
1247 }
1248
1249 int
1250 sys_chmod(tcp)
1251 struct tcb *tcp;
1252 {
1253         if (entering(tcp)) {
1254                 printpath(tcp, tcp->u_arg[0]);
1255                 tprintf(", %#lo", tcp->u_arg[1]);
1256         }
1257         return 0;
1258 }
1259
1260 int
1261 sys_fchmod(tcp)
1262 struct tcb *tcp;
1263 {
1264         if (entering(tcp)) {
1265                 tprintf("%ld, %#lo", tcp->u_arg[0], tcp->u_arg[1]);
1266         }
1267         return 0;
1268 }
1269
1270 #ifdef ALPHA
1271 int
1272 sys_osf_utimes(tcp)
1273 struct tcb *tcp;
1274 {
1275     if (entering(tcp)) {
1276         printpath(tcp, tcp->u_arg[0]);
1277         tprintf(", ");
1278         printtv32(tcp, tcp->u_arg[1]);
1279     }
1280     return 0;
1281 }
1282 #endif
1283
1284 int
1285 sys_utimes(tcp)
1286 struct tcb *tcp;
1287 {
1288         if (entering(tcp)) {
1289                 printpath(tcp, tcp->u_arg[0]);
1290                 tprintf(", ");
1291                 printtv(tcp, tcp->u_arg[1]);
1292         }
1293         return 0;
1294 }
1295
1296 int
1297 sys_utime(tcp)
1298 struct tcb *tcp;
1299 {
1300         long ut[2];
1301
1302         if (entering(tcp)) {
1303                 printpath(tcp, tcp->u_arg[0]);
1304                 tprintf(", ");
1305                 if (!tcp->u_arg[1])
1306                         tprintf("NULL");
1307                 else if (!verbose(tcp))
1308                         tprintf("%#lx", tcp->u_arg[1]);
1309                 else if (umoven(tcp, tcp->u_arg[1], sizeof ut,
1310                     (char *) ut) < 0)
1311                         tprintf("[?, ?]");
1312                 else {
1313                         tprintf("[%s,", sprinttime(ut[0]));
1314                         tprintf(" %s]", sprinttime(ut[1]));
1315                 }
1316         }
1317         return 0;
1318 }
1319
1320 int
1321 sys_mknod(tcp)
1322 struct tcb *tcp;
1323 {
1324         int mode = tcp->u_arg[1];
1325
1326         if (entering(tcp)) {
1327                 printpath(tcp, tcp->u_arg[0]);
1328                 tprintf(", %s", sprintmode(mode));
1329                 switch (mode & S_IFMT) {
1330                 case S_IFCHR: case S_IFBLK:
1331 #ifdef LINUXSPARC
1332                         if (current_personality == 1)
1333                         tprintf(", makedev(%lu, %lu)",
1334                                 (unsigned long) ((tcp->u_arg[2] >> 18) & 0x3fff),
1335                                 (unsigned long) (tcp->u_arg[2] & 0x3ffff));
1336                         else
1337 #endif  
1338                         tprintf(", makedev(%lu, %lu)",
1339                                 (unsigned long) major(tcp->u_arg[2]),
1340                                 (unsigned long) minor(tcp->u_arg[2]));
1341                         break;
1342                 default:
1343                         break;
1344                 }
1345         }
1346         return 0;
1347 }
1348
1349 int
1350 sys_mkfifo(tcp)
1351 struct tcb *tcp;
1352 {
1353         if (entering(tcp)) {
1354                 printpath(tcp, tcp->u_arg[0]);
1355                 tprintf(", %#lo", tcp->u_arg[1]);
1356         }
1357         return 0;
1358 }
1359
1360 int
1361 sys_fsync(tcp)
1362 struct tcb *tcp;
1363 {
1364         if (entering(tcp)) {
1365                 tprintf("%ld", tcp->u_arg[0]);
1366         }
1367         return 0;
1368 }
1369
1370 #ifdef linux
1371
1372 static void
1373 printdir(tcp, addr)
1374 struct tcb *tcp;
1375 long addr;
1376 {
1377         struct dirent d;
1378
1379         if (!verbose(tcp)) {
1380                 tprintf("%#lx", addr);
1381                 return;
1382         }
1383         if (umove(tcp, addr, &d) < 0) {
1384                 tprintf("{...}");
1385                 return;
1386         }
1387         tprintf("{d_ino=%ld, ", (unsigned long) d.d_ino);
1388         tprintf("d_name=");
1389         printpathn(tcp, (long) ((struct dirent *) addr)->d_name, d.d_reclen);
1390         tprintf("}");
1391 }
1392
1393 int
1394 sys_readdir(tcp)
1395 struct tcb *tcp;
1396 {
1397         if (entering(tcp)) {
1398                 tprintf("%lu, ", tcp->u_arg[0]);
1399         } else {
1400                 if (syserror(tcp) || tcp->u_rval == 0 || !verbose(tcp))
1401                         tprintf("%#lx", tcp->u_arg[1]);
1402                 else
1403                         printdir(tcp, tcp->u_arg[1]);
1404                 /* Not much point in printing this out, it is always 1. */
1405                 if (tcp->u_arg[2] != 1)
1406                         tprintf(", %lu", tcp->u_arg[2]);
1407         }
1408         return 0;
1409 }
1410
1411 #endif /* linux */
1412
1413 int
1414 sys_getdents(tcp)
1415 struct tcb *tcp;
1416 {
1417         int i, len, dents = 0;
1418         char *buf;
1419
1420         if (entering(tcp)) {
1421                 tprintf("%lu, ", tcp->u_arg[0]);
1422                 return 0;
1423         }
1424         if (syserror(tcp) || !verbose(tcp)) {
1425                 tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
1426                 return 0;
1427         }
1428         len = tcp->u_rval;
1429         if ((buf = malloc(len)) == NULL) {
1430                 tprintf("out of memory\n");
1431                 return 0;
1432         }
1433         if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
1434                 tprintf("{...}, %lu", tcp->u_arg[2]);
1435                 free(buf);
1436                 return 0;
1437         }
1438         if (!abbrev(tcp))
1439                 tprintf("{");
1440         for (i = 0; i < len;) {
1441                 struct kernel_dirent *d = (struct kernel_dirent *) &buf[i];
1442 #ifdef linux
1443                 if (!abbrev(tcp)) {
1444                         tprintf("%s{d_ino=%lu, d_off=%lu, ",
1445                                 i ? " " : "", d->d_ino, d->d_off);
1446                         tprintf("d_reclen=%u, d_name=\"%s\"}",
1447                                 d->d_reclen, d->d_name);
1448                 }
1449 #endif /* linux */
1450 #ifdef SVR4
1451                 if (!abbrev(tcp)) {
1452                         tprintf("%s{d_ino=%lu, d_off=%lu, ",
1453                                 i ? " " : "", d->d_ino, d->d_off);
1454                         tprintf("d_reclen=%u, d_name=\"%s\"}",
1455                                 d->d_reclen, d->d_name);
1456                 }
1457 #endif /* SVR4 */
1458 #ifdef SUNOS4
1459                 if (!abbrev(tcp)) {
1460                         tprintf("%s{d_off=%lu, d_fileno=%lu, d_reclen=%u, ",
1461                                 i ? " " : "", d->d_off, d->d_fileno,
1462                                 d->d_reclen);
1463                         tprintf("d_namlen=%u, d_name=\"%.*s\"}",
1464                                 d->d_namlen, d->d_namlen, d->d_name);
1465                 }
1466 #endif /* SUNOS4 */
1467                 i += d->d_reclen;
1468                 dents++;
1469         }
1470         if (!abbrev(tcp))
1471                 tprintf("}");
1472         else
1473                 tprintf("/* %u entries */", dents);
1474         tprintf(", %lu", tcp->u_arg[2]);
1475         free(buf);
1476         return 0;
1477 }
1478
1479 #ifdef linux
1480
1481 int
1482 sys_getcwd(tcp)
1483 struct tcb *tcp;
1484 {
1485     if (exiting(tcp)) {
1486         if (syserror(tcp))
1487             tprintf("%#lx", tcp->u_arg[0]);
1488         else
1489             printpathn(tcp, tcp->u_arg[0], tcp->u_rval - 1);
1490         tprintf(", %lu", tcp->u_arg[1]);
1491     }
1492     return 0;
1493 }
1494 #endif /* linux */
1495
1496 #ifdef HAVE_SYS_ASYNCH_H
1497
1498 int
1499 sys_aioread(tcp)
1500 struct tcb *tcp;
1501 {
1502         struct aio_result_t res;
1503
1504         if (entering(tcp)) {
1505                 tprintf("%lu, ", tcp->u_arg[0]);
1506         } else {
1507                 if (syserror(tcp))
1508                         tprintf("%#lx", tcp->u_arg[1]);
1509                 else
1510                         printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
1511                 tprintf(", %lu, %lu, ", tcp->u_arg[2], tcp->u_arg[3]);
1512                 printxval(whence, tcp->u_arg[4], "L_???");
1513                 if (syserror(tcp) || tcp->u_arg[5] == 0
1514                     || umove(tcp, tcp->u_arg[5], &res) < 0)
1515                         tprintf(", %#lx", tcp->u_arg[5]);
1516                 else
1517                         tprintf(", {aio_return %d aio_errno %d}",
1518                                 res.aio_return, res.aio_errno);
1519         }
1520         return 0;
1521 }
1522
1523 int
1524 sys_aiowrite(tcp)
1525 struct tcb *tcp;
1526 {
1527         struct aio_result_t res;
1528
1529         if (entering(tcp)) {
1530                 tprintf("%lu, ", tcp->u_arg[0]);
1531                 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
1532                 tprintf(", %lu, %lu, ", tcp->u_arg[2], tcp->u_arg[3]);
1533                 printxval(whence, tcp->u_arg[4], "L_???");
1534         }
1535         else {
1536                 if (tcp->u_arg[5] == 0)
1537                         tprintf(", NULL");
1538                 else if (syserror(tcp)
1539                     || umove(tcp, tcp->u_arg[5], &res) < 0)
1540                         tprintf(", %#lx", tcp->u_arg[5]);
1541                 else
1542                         tprintf(", {aio_return %d aio_errno %d}",
1543                                 res.aio_return, res.aio_errno);
1544         }
1545         return 0;
1546 }
1547
1548 int
1549 sys_aiowait(tcp)
1550 struct tcb *tcp;
1551 {
1552         if (entering(tcp))
1553                 printtv(tcp, tcp->u_arg[0]);
1554         return 0;
1555 }
1556
1557 int
1558 sys_aiocancel(tcp)
1559 struct tcb *tcp;
1560 {
1561         struct aio_result_t res;
1562
1563         if (exiting(tcp)) {
1564                 if (tcp->u_arg[0] == 0)
1565                         tprintf("NULL");
1566                 else if (syserror(tcp)
1567                     || umove(tcp, tcp->u_arg[0], &res) < 0)
1568                         tprintf("%#lx", tcp->u_arg[0]);
1569                 else
1570                         tprintf("{aio_return %d aio_errno %d}",
1571                                 res.aio_return, res.aio_errno);
1572         }
1573         return 0;
1574 }
1575
1576 #endif /* HAVE_SYS_ASYNCH_H */