]> granicus.if.org Git - strace/blob - file.c
Cosmetic fixes, no code changes
[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  * 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 <dirent.h>
36
37 #ifdef LINUX
38 struct kernel_dirent {
39         unsigned long   d_ino;
40         unsigned long   d_off;
41         unsigned short  d_reclen;
42         char            d_name[1];
43 };
44 #else
45 # define kernel_dirent dirent
46 #endif
47
48 #ifdef LINUX
49 #  ifdef LINUXSPARC
50 struct stat {
51         unsigned short  st_dev;
52         unsigned int    st_ino;
53         unsigned short  st_mode;
54         short           st_nlink;
55         unsigned short  st_uid;
56         unsigned short  st_gid;
57         unsigned short  st_rdev;
58         unsigned int    st_size;
59         int             st_atime;
60         unsigned int    __unused1;
61         int             st_mtime;
62         unsigned int    __unused2;
63         int             st_ctime;
64         unsigned int    __unused3;
65         int             st_blksize;
66         int             st_blocks;
67         unsigned int    __unused4[2];
68 };
69 #if defined(SPARC64)
70 struct stat_sparc64 {
71         unsigned int    st_dev;
72         unsigned long   st_ino;
73         unsigned int    st_mode;
74         unsigned int    st_nlink;
75         unsigned int    st_uid;
76         unsigned int    st_gid;
77         unsigned int    st_rdev;
78         long            st_size;
79         long            st_atime;
80         long            st_mtime;
81         long            st_ctime;
82         long            st_blksize;
83         long            st_blocks;
84         unsigned long   __unused4[2];
85 };
86 #endif /* SPARC64 */
87 #    define stat kernel_stat
88 #    include <asm/stat.h>
89 #    undef stat
90 #  else
91 #    undef dev_t
92 #    undef ino_t
93 #    undef mode_t
94 #    undef nlink_t
95 #    undef uid_t
96 #    undef gid_t
97 #    undef off_t
98 #    undef loff_t
99
100 #    define dev_t __kernel_dev_t
101 #    define ino_t __kernel_ino_t
102 #    define mode_t __kernel_mode_t
103 #    define nlink_t __kernel_nlink_t
104 #    define uid_t __kernel_uid_t
105 #    define gid_t __kernel_gid_t
106 #    define off_t __kernel_off_t
107 #    define loff_t __kernel_loff_t
108
109 #    include <asm/stat.h>
110
111 #    undef dev_t
112 #    undef ino_t
113 #    undef mode_t
114 #    undef nlink_t
115 #    undef uid_t
116 #    undef gid_t
117 #    undef off_t
118 #    undef loff_t
119
120 #    define dev_t dev_t
121 #    define ino_t ino_t
122 #    define mode_t mode_t
123 #    define nlink_t nlink_t
124 #    define uid_t uid_t
125 #    define gid_t gid_t
126 #    define off_t off_t
127 #    define loff_t loff_t
128 #  endif
129 #  ifdef HPPA   /* asm-parisc/stat.h defines stat64 */
130 #    undef stat64
131 #  endif
132 #  define stat libc_stat
133 #  define stat64 libc_stat64
134 #  include <sys/stat.h>
135 #  undef stat
136 #  undef stat64
137    /* These might be macros. */
138 #  undef st_atime
139 #  undef st_mtime
140 #  undef st_ctime
141 #  ifdef HPPA
142 #    define stat64 hpux_stat64
143 #  endif
144 #else
145 #  include <sys/stat.h>
146 #endif
147
148 #include <fcntl.h>
149
150 #ifdef SVR4
151 #  include <sys/cred.h>
152 #endif /* SVR4 */
153
154 #ifdef HAVE_SYS_VFS_H
155 #include <sys/vfs.h>
156 #endif
157
158 #ifdef HAVE_LINUX_XATTR_H
159 #include <linux/xattr.h>
160 #elif defined linux
161 #define XATTR_CREATE 1
162 #define XATTR_REPLACE 2
163 #endif
164
165 #ifdef FREEBSD
166 #include <sys/param.h>
167 #include <sys/mount.h>
168 #include <sys/stat.h>
169 #endif
170
171 #if _LFS64_LARGEFILE && (defined(LINUX) || defined(SVR4))
172 # ifdef HAVE_INTTYPES_H
173 #  include <inttypes.h>
174 # else
175 #  define PRId64 "lld"
176 #  define PRIu64 "llu"
177 # endif
178 #endif
179
180 #if HAVE_LONG_LONG_OFF_T
181 /*
182  * Ugly hacks for systems that have typedef long long off_t
183  */
184
185 #define stat64 stat
186 #define HAVE_STAT64 1   /* Ugly hack */
187
188 #define sys_stat64      sys_stat
189 #define sys_fstat64     sys_fstat
190 #define sys_lstat64     sys_lstat
191 #define sys_lseek64     sys_lseek
192 #define sys_truncate64  sys_truncate
193 #define sys_ftruncate64 sys_ftruncate
194 #endif
195
196 #ifdef MAJOR_IN_SYSMACROS
197 #include <sys/sysmacros.h>
198 #endif
199
200 #ifdef MAJOR_IN_MKDEV
201 #include <sys/mkdev.h>
202 #endif
203
204 #ifdef HAVE_SYS_ASYNCH_H
205 #include <sys/asynch.h>
206 #endif
207
208 #ifdef SUNOS4
209 #include <ustat.h>
210 #endif
211
212 const struct xlat open_access_modes[] = {
213         { O_RDONLY,     "O_RDONLY"      },
214         { O_WRONLY,     "O_WRONLY"      },
215         { O_RDWR,       "O_RDWR"        },
216 #ifdef O_ACCMODE
217         { O_ACCMODE,    "O_ACCMODE"     },
218 #endif
219         { 0,            NULL            },
220 };
221
222 const struct xlat open_mode_flags[] = {
223         { O_CREAT,      "O_CREAT"       },
224         { O_EXCL,       "O_EXCL"        },
225         { O_NOCTTY,     "O_NOCTTY"      },
226         { O_TRUNC,      "O_TRUNC"       },
227         { O_APPEND,     "O_APPEND"      },
228         { O_NONBLOCK,   "O_NONBLOCK"    },
229 #ifdef O_SYNC
230         { O_SYNC,       "O_SYNC"        },
231 #endif
232 #ifdef O_ASYNC
233         { O_ASYNC,      "O_ASYNC"       },
234 #endif
235 #ifdef O_DSYNC
236         { O_DSYNC,      "O_DSYNC"       },
237 #endif
238 #ifdef O_RSYNC
239         { O_RSYNC,      "O_RSYNC"       },
240 #endif
241 #if defined(O_NDELAY) && (O_NDELAY != O_NONBLOCK)
242         { O_NDELAY,     "O_NDELAY"      },
243 #endif
244 #ifdef O_PRIV
245         { O_PRIV,       "O_PRIV"        },
246 #endif
247 #ifdef O_DIRECT
248         { O_DIRECT,     "O_DIRECT"      },
249 #endif
250 #ifdef O_LARGEFILE
251 # if O_LARGEFILE == 0           /* biarch platforms in 64-bit mode */
252 #  undef O_LARGEFILE
253 #  ifdef SPARC64
254 #   define O_LARGEFILE  0x40000
255 #  elif defined X86_64 || defined S390X
256 #   define O_LARGEFILE  0100000
257 #  endif
258 # endif
259 # ifdef O_LARGEFILE
260         { O_LARGEFILE,  "O_LARGEFILE"   },
261 # endif
262 #endif
263 #ifdef O_DIRECTORY
264         { O_DIRECTORY,  "O_DIRECTORY"   },
265 #endif
266 #ifdef O_NOFOLLOW
267         { O_NOFOLLOW,   "O_NOFOLLOW"    },
268 #endif
269 #ifdef O_NOATIME
270         { O_NOATIME,    "O_NOATIME"     },
271 #endif
272 #ifdef O_CLOEXEC
273         { O_CLOEXEC,    "O_CLOEXEC"     },
274 #endif
275
276 #ifdef FNDELAY
277         { FNDELAY,      "FNDELAY"       },
278 #endif
279 #ifdef FAPPEND
280         { FAPPEND,      "FAPPEND"       },
281 #endif
282 #ifdef FMARK
283         { FMARK,        "FMARK"         },
284 #endif
285 #ifdef FDEFER
286         { FDEFER,       "FDEFER"        },
287 #endif
288 #ifdef FASYNC
289         { FASYNC,       "FASYNC"        },
290 #endif
291 #ifdef FSHLOCK
292         { FSHLOCK,      "FSHLOCK"       },
293 #endif
294 #ifdef FEXLOCK
295         { FEXLOCK,      "FEXLOCK"       },
296 #endif
297 #ifdef FCREAT
298         { FCREAT,       "FCREAT"        },
299 #endif
300 #ifdef FTRUNC
301         { FTRUNC,       "FTRUNC"        },
302 #endif
303 #ifdef FEXCL
304         { FEXCL,        "FEXCL"         },
305 #endif
306 #ifdef FNBIO
307         { FNBIO,        "FNBIO"         },
308 #endif
309 #ifdef FSYNC
310         { FSYNC,        "FSYNC"         },
311 #endif
312 #ifdef FNOCTTY
313         { FNOCTTY,      "FNOCTTY"       },
314 #endif
315 #ifdef O_SHLOCK
316         { O_SHLOCK,     "O_SHLOCK"      },
317 #endif
318 #ifdef O_EXLOCK
319         { O_EXLOCK,     "O_EXLOCK"      },
320 #endif
321         { 0,            NULL            },
322 };
323
324 #ifdef LINUX
325
326 #ifndef AT_FDCWD
327 # define AT_FDCWD                -100
328 #endif
329
330 /* The fd is an "int", so when decoding x86 on x86_64, we need to force sign
331  * extension to get the right value.  We do this by declaring fd as int here.
332  */
333 static void
334 print_dirfd(struct tcb *tcp, int fd)
335 {
336         if (fd == AT_FDCWD)
337                 tprintf("AT_FDCWD, ");
338         else {
339                 printfd(tcp, fd);
340                 tprintf(", ");
341         }
342 }
343 #endif
344
345 /*
346  * Pity stpcpy() is not standardized...
347  */
348 static char *
349 str_append(char *dst, const char *src)
350 {
351         while ((*dst = *src++) != '\0')
352                 dst++;
353         return dst;
354 }
355
356 /*
357  * low bits of the open(2) flags define access mode,
358  * other bits are real flags.
359  */
360 const char *
361 sprint_open_modes(mode_t flags)
362 {
363         static char outstr[1024];
364         char *p;
365         char sep = 0;
366         const char *str;
367         const struct xlat *x;
368
369         p = str_append(outstr, "flags ");
370         str = xlookup(open_access_modes, flags & 3);
371         if (str) {
372                 p = str_append(p, str);
373                 flags &= ~3;
374                 if (!flags)
375                         return outstr;
376                 sep = '|';
377         }
378
379         for (x = open_mode_flags; x->str; x++) {
380                 if ((flags & x->val) == x->val) {
381                         if (sep)
382                                 *p++ = sep;
383                         p = str_append(p, x->str);
384                         flags &= ~x->val;
385                         if (!flags)
386                                 return outstr;
387                         sep = '|';
388                 }
389         }
390         /* flags is still nonzero */
391         if (sep)
392                 *p++ = sep;
393         sprintf(p, "%#x", flags);
394         return outstr;
395 }
396
397 void
398 tprint_open_modes(mode_t flags)
399 {
400         tprintf("%s", sprint_open_modes(flags) + sizeof("flags"));
401 }
402
403 static int
404 decode_open(struct tcb *tcp, int offset)
405 {
406         if (entering(tcp)) {
407                 printpath(tcp, tcp->u_arg[offset]);
408                 tprintf(", ");
409                 /* flags */
410                 tprint_open_modes(tcp->u_arg[offset + 1]);
411                 if (tcp->u_arg[offset + 1] & O_CREAT) {
412                         /* mode */
413                         tprintf(", %#lo", tcp->u_arg[offset + 2]);
414                 }
415         }
416         return 0;
417 }
418
419 int
420 sys_open(struct tcb *tcp)
421 {
422         return decode_open(tcp, 0);
423 }
424
425 #ifdef LINUX
426 int
427 sys_openat(struct tcb *tcp)
428 {
429         if (entering(tcp))
430                 print_dirfd(tcp, tcp->u_arg[0]);
431         return decode_open(tcp, 1);
432 }
433 #endif
434
435 #ifdef LINUXSPARC
436 static const struct xlat openmodessol[] = {
437         { 0,            "O_RDWR"        },
438         { 1,            "O_RDONLY"      },
439         { 2,            "O_WRONLY"      },
440         { 0x80,         "O_NONBLOCK"    },
441         { 8,            "O_APPEND"      },
442         { 0x100,        "O_CREAT"       },
443         { 0x200,        "O_TRUNC"       },
444         { 0x400,        "O_EXCL"        },
445         { 0x800,        "O_NOCTTY"      },
446         { 0x10,         "O_SYNC"        },
447         { 0x40,         "O_DSYNC"       },
448         { 0x8000,       "O_RSYNC"       },
449         { 4,            "O_NDELAY"      },
450         { 0x1000,       "O_PRIV"        },
451         { 0,            NULL            },
452 };
453
454 int
455 solaris_open(struct tcb *tcp)
456 {
457         if (entering(tcp)) {
458                 printpath(tcp, tcp->u_arg[0]);
459                 tprintf(", ");
460                 /* flags */
461                 printflags(openmodessol, tcp->u_arg[1] + 1, "O_???");
462                 if (tcp->u_arg[1] & 0x100) {
463                         /* mode */
464                         tprintf(", %#lo", tcp->u_arg[2]);
465                 }
466         }
467         return 0;
468 }
469
470 #endif
471
472 int
473 sys_creat(struct tcb *tcp)
474 {
475         if (entering(tcp)) {
476                 printpath(tcp, tcp->u_arg[0]);
477                 tprintf(", %#lo", tcp->u_arg[1]);
478         }
479         return 0;
480 }
481
482 static const struct xlat access_flags[] = {
483         { F_OK,         "F_OK",         },
484         { R_OK,         "R_OK"          },
485         { W_OK,         "W_OK"          },
486         { X_OK,         "X_OK"          },
487 #ifdef EFF_ONLY_OK
488         { EFF_ONLY_OK,  "EFF_ONLY_OK"   },
489 #endif
490 #ifdef EX_OK
491         { EX_OK,        "EX_OK"         },
492 #endif
493         { 0,            NULL            },
494 };
495
496 static int
497 decode_access(struct tcb *tcp, int offset)
498 {
499         if (entering(tcp)) {
500                 printpath(tcp, tcp->u_arg[offset]);
501                 tprintf(", ");
502                 printflags(access_flags, tcp->u_arg[offset + 1], "?_OK");
503         }
504         return 0;
505 }
506
507 int
508 sys_access(struct tcb *tcp)
509 {
510         return decode_access(tcp, 0);
511 }
512
513 #ifdef LINUX
514 int
515 sys_faccessat(struct tcb *tcp)
516 {
517         if (entering(tcp))
518                 print_dirfd(tcp, tcp->u_arg[0]);
519         return decode_access(tcp, 1);
520 }
521 #endif
522
523 int
524 sys_umask(struct tcb *tcp)
525 {
526         if (entering(tcp)) {
527                 tprintf("%#lo", tcp->u_arg[0]);
528         }
529         return RVAL_OCTAL;
530 }
531
532 static const struct xlat whence[] = {
533         { SEEK_SET,     "SEEK_SET"      },
534         { SEEK_CUR,     "SEEK_CUR"      },
535         { SEEK_END,     "SEEK_END"      },
536         { 0,            NULL            },
537 };
538
539 #ifndef HAVE_LONG_LONG_OFF_T
540 #if defined (LINUX_MIPSN32)
541 int
542 sys_lseek(struct tcb *tcp)
543 {
544         long long offset;
545         int _whence;
546
547         if (entering(tcp)) {
548                 printfd(tcp, tcp->u_arg[0]);
549                 tprintf(", ");
550                 offset = tcp->ext_arg[1];
551                 _whence = tcp->u_arg[2];
552                 if (_whence == SEEK_SET)
553                         tprintf("%llu, ", offset);
554                 else
555                         tprintf("%lld, ", offset);
556                 printxval(whence, _whence, "SEEK_???");
557         }
558         return RVAL_UDECIMAL;
559 }
560 #else /* !LINUX_MIPSN32 */
561 int
562 sys_lseek(struct tcb *tcp)
563 {
564         off_t offset;
565         int _whence;
566
567         if (entering(tcp)) {
568                 printfd(tcp, tcp->u_arg[0]);
569                 tprintf(", ");
570                 offset = tcp->u_arg[1];
571                 _whence = tcp->u_arg[2];
572                 if (_whence == SEEK_SET)
573                         tprintf("%lu, ", offset);
574                 else
575                         tprintf("%ld, ", offset);
576                 printxval(whence, _whence, "SEEK_???");
577         }
578         return RVAL_UDECIMAL;
579 }
580 #endif /* LINUX_MIPSN32 */
581 #endif
582
583 #ifdef LINUX
584 int
585 sys_llseek(struct tcb *tcp)
586 {
587         if (entering(tcp)) {
588                 printfd(tcp, tcp->u_arg[0]);
589                 /*
590                  * This one call takes explicitly two 32-bit arguments hi, lo,
591                  * rather than one 64-bit argument for which LONG_LONG works
592                  * appropriate for the native byte order.
593                  */
594                 if (tcp->u_arg[4] == SEEK_SET)
595                         tprintf(", %llu, ",
596                                 ((long long int) tcp->u_arg[1]) << 32 |
597                                 (unsigned long long) (unsigned) tcp->u_arg[2]);
598                 else
599                         tprintf(", %lld, ",
600                                 ((long long int) tcp->u_arg[1]) << 32 |
601                                 (unsigned long long) (unsigned) tcp->u_arg[2]);
602         }
603         else {
604                 long long int off;
605                 if (syserror(tcp) || umove(tcp, tcp->u_arg[3], &off) < 0)
606                         tprintf("%#lx, ", tcp->u_arg[3]);
607                 else
608                         tprintf("[%llu], ", off);
609                 printxval(whence, tcp->u_arg[4], "SEEK_???");
610         }
611         return 0;
612 }
613
614 int
615 sys_readahead(struct tcb *tcp)
616 {
617         if (entering(tcp)) {
618                 int argn;
619                 printfd(tcp, tcp->u_arg[0]);
620                 tprintf(", ");
621                 argn = printllval(tcp, "%lld", 1);
622                 tprintf(", %ld", tcp->u_arg[argn]);
623         }
624         return 0;
625 }
626 #endif
627
628 #if _LFS64_LARGEFILE || HAVE_LONG_LONG_OFF_T
629 int
630 sys_lseek64(struct tcb *tcp)
631 {
632         if (entering(tcp)) {
633                 int argn;
634                 printfd(tcp, tcp->u_arg[0]);
635                 tprintf(", ");
636                 if (tcp->u_arg[3] == SEEK_SET)
637                         argn = printllval(tcp, "%llu, ", 1);
638                 else
639                         argn = printllval(tcp, "%lld, ", 1);
640                 printxval(whence, tcp->u_arg[argn], "SEEK_???");
641         }
642         return RVAL_LUDECIMAL;
643 }
644 #endif
645
646 #ifndef HAVE_LONG_LONG_OFF_T
647 int
648 sys_truncate(struct tcb *tcp)
649 {
650         if (entering(tcp)) {
651                 printpath(tcp, tcp->u_arg[0]);
652                 tprintf(", %lu", tcp->u_arg[1]);
653         }
654         return 0;
655 }
656 #endif
657
658 #if _LFS64_LARGEFILE || HAVE_LONG_LONG_OFF_T
659 int
660 sys_truncate64(struct tcb *tcp)
661 {
662         if (entering(tcp)) {
663                 printpath(tcp, tcp->u_arg[0]);
664                 printllval(tcp, ", %llu", 1);
665         }
666         return 0;
667 }
668 #endif
669
670 #ifndef HAVE_LONG_LONG_OFF_T
671 int
672 sys_ftruncate(struct tcb *tcp)
673 {
674         if (entering(tcp)) {
675                 printfd(tcp, tcp->u_arg[0]);
676                 tprintf(", %lu", tcp->u_arg[1]);
677         }
678         return 0;
679 }
680 #endif
681
682 #if _LFS64_LARGEFILE || HAVE_LONG_LONG_OFF_T
683 int
684 sys_ftruncate64(struct tcb *tcp)
685 {
686         if (entering(tcp)) {
687                 printfd(tcp, tcp->u_arg[0]);
688                 tprintf(", ");
689                 printllval(tcp, "%llu", 1);
690         }
691         return 0;
692 }
693 #endif
694
695 /* several stats */
696
697 static const struct xlat modetypes[] = {
698         { S_IFREG,      "S_IFREG"       },
699         { S_IFSOCK,     "S_IFSOCK"      },
700         { S_IFIFO,      "S_IFIFO"       },
701         { S_IFLNK,      "S_IFLNK"       },
702         { S_IFDIR,      "S_IFDIR"       },
703         { S_IFBLK,      "S_IFBLK"       },
704         { S_IFCHR,      "S_IFCHR"       },
705         { 0,            NULL            },
706 };
707
708 static const char *
709 sprintmode(int mode)
710 {
711         static char buf[64];
712         const char *s;
713
714         if ((mode & S_IFMT) == 0)
715                 s = "";
716         else if ((s = xlookup(modetypes, mode & S_IFMT)) == NULL) {
717                 sprintf(buf, "%#o", mode);
718                 return buf;
719         }
720         sprintf(buf, "%s%s%s%s", s,
721                 (mode & S_ISUID) ? "|S_ISUID" : "",
722                 (mode & S_ISGID) ? "|S_ISGID" : "",
723                 (mode & S_ISVTX) ? "|S_ISVTX" : "");
724         mode &= ~(S_IFMT|S_ISUID|S_ISGID|S_ISVTX);
725         if (mode)
726                 sprintf(buf + strlen(buf), "|%#o", mode);
727         s = (*buf == '|') ? buf + 1 : buf;
728         return *s ? s : "0";
729 }
730
731 static char *
732 sprinttime(time_t t)
733 {
734         struct tm *tmp;
735         static char buf[32];
736
737         if (t == 0) {
738                 strcpy(buf, "0");
739                 return buf;
740         }
741         if ((tmp = localtime(&t)))
742                 snprintf(buf, sizeof buf, "%02d/%02d/%02d-%02d:%02d:%02d",
743                         tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
744                         tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
745         else
746                 snprintf(buf, sizeof buf, "%lu", (unsigned long) t);
747
748         return buf;
749 }
750
751 #ifdef LINUXSPARC
752 typedef struct {
753         int     tv_sec;
754         int     tv_nsec;
755 } timestruct_t;
756
757 struct solstat {
758         unsigned        st_dev;
759         int             st_pad1[3];     /* network id */
760         unsigned        st_ino;
761         unsigned        st_mode;
762         unsigned        st_nlink;
763         unsigned        st_uid;
764         unsigned        st_gid;
765         unsigned        st_rdev;
766         int             st_pad2[2];
767         int             st_size;
768         int             st_pad3;        /* st_size, off_t expansion */
769         timestruct_t    st_atime;
770         timestruct_t    st_mtime;
771         timestruct_t    st_ctime;
772         int             st_blksize;
773         int             st_blocks;
774         char            st_fstype[16];
775         int             st_pad4[8];     /* expansion area */
776 };
777
778 static void
779 printstatsol(struct tcb *tcp, long addr)
780 {
781         struct solstat statbuf;
782
783         if (umove(tcp, addr, &statbuf) < 0) {
784                 tprintf("{...}");
785                 return;
786         }
787         if (!abbrev(tcp)) {
788                 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%lu, st_mode=%s, ",
789                         (unsigned long) ((statbuf.st_dev >> 18) & 0x3fff),
790                         (unsigned long) (statbuf.st_dev & 0x3ffff),
791                         (unsigned long) statbuf.st_ino,
792                         sprintmode(statbuf.st_mode));
793                 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
794                         (unsigned long) statbuf.st_nlink,
795                         (unsigned long) statbuf.st_uid,
796                         (unsigned long) statbuf.st_gid);
797                 tprintf("st_blksize=%lu, ", (unsigned long) statbuf.st_blksize);
798                 tprintf("st_blocks=%lu, ", (unsigned long) statbuf.st_blocks);
799         }
800         else
801                 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
802         switch (statbuf.st_mode & S_IFMT) {
803         case S_IFCHR: case S_IFBLK:
804                 tprintf("st_rdev=makedev(%lu, %lu), ",
805                         (unsigned long) ((statbuf.st_rdev >> 18) & 0x3fff),
806                         (unsigned long) (statbuf.st_rdev & 0x3ffff));
807                 break;
808         default:
809                 tprintf("st_size=%u, ", statbuf.st_size);
810                 break;
811         }
812         if (!abbrev(tcp)) {
813                 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime.tv_sec));
814                 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime.tv_sec));
815                 tprintf("st_ctime=%s}", sprinttime(statbuf.st_ctime.tv_sec));
816         }
817         else
818                 tprintf("...}");
819 }
820
821 #if defined (SPARC64)
822 static void
823 printstat_sparc64(struct tcb *tcp, long addr)
824 {
825         struct stat_sparc64 statbuf;
826
827         if (umove(tcp, addr, &statbuf) < 0) {
828                 tprintf("{...}");
829                 return;
830         }
831
832         if (!abbrev(tcp)) {
833                 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%lu, st_mode=%s, ",
834                         (unsigned long) major(statbuf.st_dev),
835                         (unsigned long) minor(statbuf.st_dev),
836                         (unsigned long) statbuf.st_ino,
837                         sprintmode(statbuf.st_mode));
838                 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
839                         (unsigned long) statbuf.st_nlink,
840                         (unsigned long) statbuf.st_uid,
841                         (unsigned long) statbuf.st_gid);
842                 tprintf("st_blksize=%lu, ",
843                         (unsigned long) statbuf.st_blksize);
844                 tprintf("st_blocks=%lu, ",
845                         (unsigned long) statbuf.st_blocks);
846         }
847         else
848                 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
849         switch (statbuf.st_mode & S_IFMT) {
850         case S_IFCHR: case S_IFBLK:
851                 tprintf("st_rdev=makedev(%lu, %lu), ",
852                         (unsigned long) major(statbuf.st_rdev),
853                         (unsigned long) minor(statbuf.st_rdev));
854                 break;
855         default:
856                 tprintf("st_size=%lu, ", statbuf.st_size);
857                 break;
858         }
859         if (!abbrev(tcp)) {
860                 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
861                 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
862                 tprintf("st_ctime=%s", sprinttime(statbuf.st_ctime));
863                 tprintf("}");
864         }
865         else
866                 tprintf("...}");
867 }
868 #endif /* SPARC64 */
869 #endif /* LINUXSPARC */
870
871 #if defined LINUX && defined POWERPC64
872 struct stat_powerpc32 {
873         unsigned int    st_dev;
874         unsigned int    st_ino;
875         unsigned int    st_mode;
876         unsigned short  st_nlink;
877         unsigned int    st_uid;
878         unsigned int    st_gid;
879         unsigned int    st_rdev;
880         unsigned int    st_size;
881         unsigned int    st_blksize;
882         unsigned int    st_blocks;
883         unsigned int    st_atime;
884         unsigned int    st_atime_nsec;
885         unsigned int    st_mtime;
886         unsigned int    st_mtime_nsec;
887         unsigned int    st_ctime;
888         unsigned int    st_ctime_nsec;
889         unsigned int    __unused4;
890         unsigned int    __unused5;
891 };
892
893 static void
894 printstat_powerpc32(struct tcb *tcp, long addr)
895 {
896         struct stat_powerpc32 statbuf;
897
898         if (umove(tcp, addr, &statbuf) < 0) {
899                 tprintf("{...}");
900                 return;
901         }
902
903         if (!abbrev(tcp)) {
904                 tprintf("{st_dev=makedev(%u, %u), st_ino=%u, st_mode=%s, ",
905                         major(statbuf.st_dev), minor(statbuf.st_dev),
906                         statbuf.st_ino,
907                         sprintmode(statbuf.st_mode));
908                 tprintf("st_nlink=%u, st_uid=%u, st_gid=%u, ",
909                         statbuf.st_nlink, statbuf.st_uid, statbuf.st_gid);
910                 tprintf("st_blksize=%u, ", statbuf.st_blksize);
911                 tprintf("st_blocks=%u, ", statbuf.st_blocks);
912         }
913         else
914                 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
915         switch (statbuf.st_mode & S_IFMT) {
916         case S_IFCHR: case S_IFBLK:
917                 tprintf("st_rdev=makedev(%lu, %lu), ",
918                         (unsigned long) major(statbuf.st_rdev),
919                         (unsigned long) minor(statbuf.st_rdev));
920                 break;
921         default:
922                 tprintf("st_size=%u, ", statbuf.st_size);
923                 break;
924         }
925         if (!abbrev(tcp)) {
926                 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
927                 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
928                 tprintf("st_ctime=%s", sprinttime(statbuf.st_ctime));
929                 tprintf("}");
930         }
931         else
932                 tprintf("...}");
933 }
934 #endif /* LINUX && POWERPC64 */
935
936 static const struct xlat fileflags[] = {
937 #ifdef FREEBSD
938         { UF_NODUMP,    "UF_NODUMP"     },
939         { UF_IMMUTABLE, "UF_IMMUTABLE"  },
940         { UF_APPEND,    "UF_APPEND"     },
941         { UF_OPAQUE,    "UF_OPAQUE"     },
942         { UF_NOUNLINK,  "UF_NOUNLINK"   },
943         { SF_ARCHIVED,  "SF_ARCHIVED"   },
944         { SF_IMMUTABLE, "SF_IMMUTABLE"  },
945         { SF_APPEND,    "SF_APPEND"     },
946         { SF_NOUNLINK,  "SF_NOUNLINK"   },
947 #elif UNIXWARE >= 2
948 #ifdef _S_ISMLD
949         { _S_ISMLD,     "_S_ISMLD"      },
950 #endif
951 #ifdef _S_ISMOUNTED
952         { _S_ISMOUNTED, "_S_ISMOUNTED"  },
953 #endif
954 #endif
955         { 0,            NULL            },
956 };
957
958 #ifdef FREEBSD
959 int
960 sys_chflags(struct tcb *tcp)
961 {
962         if (entering(tcp)) {
963                 printpath(tcp, tcp->u_arg[0]);
964                 tprintf(", ");
965                 printflags(fileflags, tcp->u_arg[1], "UF_???");
966         }
967         return 0;
968 }
969
970 int
971 sys_fchflags(struct tcb *tcp)
972 {
973         if (entering(tcp)) {
974                 tprintf("%ld, ", tcp->u_arg[0]);
975                 printflags(fileflags, tcp->u_arg[1], "UF_???");
976         }
977         return 0;
978 }
979 #endif
980
981 #ifndef HAVE_LONG_LONG_OFF_T
982 static void
983 realprintstat(struct tcb *tcp, struct stat *statbuf)
984 {
985         if (!abbrev(tcp)) {
986                 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%lu, st_mode=%s, ",
987                         (unsigned long) major(statbuf->st_dev),
988                         (unsigned long) minor(statbuf->st_dev),
989                         (unsigned long) statbuf->st_ino,
990                         sprintmode(statbuf->st_mode));
991                 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
992                         (unsigned long) statbuf->st_nlink,
993                         (unsigned long) statbuf->st_uid,
994                         (unsigned long) statbuf->st_gid);
995 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
996                 tprintf("st_blksize=%lu, ", (unsigned long) statbuf->st_blksize);
997 #endif
998 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
999                 tprintf("st_blocks=%lu, ", (unsigned long) statbuf->st_blocks);
1000 #endif
1001         }
1002         else
1003                 tprintf("{st_mode=%s, ", sprintmode(statbuf->st_mode));
1004         switch (statbuf->st_mode & S_IFMT) {
1005         case S_IFCHR: case S_IFBLK:
1006 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1007                 tprintf("st_rdev=makedev(%lu, %lu), ",
1008                         (unsigned long) major(statbuf->st_rdev),
1009                         (unsigned long) minor(statbuf->st_rdev));
1010 #else /* !HAVE_STRUCT_STAT_ST_RDEV */
1011                 tprintf("st_size=makedev(%lu, %lu), ",
1012                         (unsigned long) major(statbuf->st_size),
1013                         (unsigned long) minor(statbuf->st_size));
1014 #endif /* !HAVE_STRUCT_STAT_ST_RDEV */
1015                 break;
1016         default:
1017                 tprintf("st_size=%lu, ", (unsigned long) statbuf->st_size);
1018                 break;
1019         }
1020         if (!abbrev(tcp)) {
1021                 tprintf("st_atime=%s, ", sprinttime(statbuf->st_atime));
1022                 tprintf("st_mtime=%s, ", sprinttime(statbuf->st_mtime));
1023                 tprintf("st_ctime=%s", sprinttime(statbuf->st_ctime));
1024 #if HAVE_STRUCT_STAT_ST_FLAGS
1025                 tprintf(", st_flags=");
1026                 printflags(fileflags, statbuf->st_flags, "UF_???");
1027 #endif
1028 #if HAVE_STRUCT_STAT_ST_ACLCNT
1029                 tprintf(", st_aclcnt=%d", statbuf->st_aclcnt);
1030 #endif
1031 #if HAVE_STRUCT_STAT_ST_LEVEL
1032                 tprintf(", st_level=%ld", statbuf->st_level);
1033 #endif
1034 #if HAVE_STRUCT_STAT_ST_FSTYPE
1035                 tprintf(", st_fstype=%.*s",
1036                         (int) sizeof statbuf->st_fstype, statbuf->st_fstype);
1037 #endif
1038 #if HAVE_STRUCT_STAT_ST_GEN
1039                 tprintf(", st_gen=%u", statbuf->st_gen);
1040 #endif
1041                 tprintf("}");
1042         }
1043         else
1044                 tprintf("...}");
1045 }
1046
1047
1048 static void
1049 printstat(struct tcb *tcp, long addr)
1050 {
1051         struct stat statbuf;
1052
1053         if (!addr) {
1054                 tprintf("NULL");
1055                 return;
1056         }
1057         if (syserror(tcp) || !verbose(tcp)) {
1058                 tprintf("%#lx", addr);
1059                 return;
1060         }
1061
1062 #ifdef LINUXSPARC
1063         if (current_personality == 1) {
1064                 printstatsol(tcp, addr);
1065                 return;
1066         }
1067 #ifdef SPARC64
1068         else if (current_personality == 2) {
1069                 printstat_sparc64(tcp, addr);
1070                 return;
1071         }
1072 #endif
1073 #endif /* LINUXSPARC */
1074
1075 #if defined LINUX && defined POWERPC64
1076         if (current_personality == 1) {
1077                 printstat_powerpc32(tcp, addr);
1078                 return;
1079         }
1080 #endif
1081
1082         if (umove(tcp, addr, &statbuf) < 0) {
1083                 tprintf("{...}");
1084                 return;
1085         }
1086
1087         realprintstat(tcp, &statbuf);
1088 }
1089 #endif  /* !HAVE_LONG_LONG_OFF_T */
1090
1091 #if !defined HAVE_STAT64 && defined LINUX && defined X86_64
1092 /*
1093  * Linux x86_64 has unified `struct stat' but its i386 biarch needs
1094  * `struct stat64'.  Its <asm-i386/stat.h> definition expects 32-bit `long'.
1095  * <linux/include/asm-x86_64/ia32.h> is not in the public includes set.
1096  * __GNUC__ is needed for the required __attribute__ below.
1097  */
1098 struct stat64 {
1099         unsigned long long      st_dev;
1100         unsigned char   __pad0[4];
1101         unsigned int    __st_ino;
1102         unsigned int    st_mode;
1103         unsigned int    st_nlink;
1104         unsigned int    st_uid;
1105         unsigned int    st_gid;
1106         unsigned long long      st_rdev;
1107         unsigned char   __pad3[4];
1108         long long       st_size;
1109         unsigned int    st_blksize;
1110         unsigned long long      st_blocks;
1111         unsigned int    st_atime;
1112         unsigned int    st_atime_nsec;
1113         unsigned int    st_mtime;
1114         unsigned int    st_mtime_nsec;
1115         unsigned int    st_ctime;
1116         unsigned int    st_ctime_nsec;
1117         unsigned long long      st_ino;
1118 } __attribute__((packed));
1119 # define HAVE_STAT64    1
1120 # define STAT64_SIZE    96
1121 #endif
1122
1123 #ifdef HAVE_STAT64
1124 static void
1125 printstat64(struct tcb *tcp, long addr)
1126 {
1127         struct stat64 statbuf;
1128
1129 #ifdef STAT64_SIZE
1130         (void) sizeof(char[sizeof statbuf == STAT64_SIZE ? 1 : -1]);
1131 #endif
1132
1133         if (!addr) {
1134                 tprintf("NULL");
1135                 return;
1136         }
1137         if (syserror(tcp) || !verbose(tcp)) {
1138                 tprintf("%#lx", addr);
1139                 return;
1140         }
1141
1142 #ifdef LINUXSPARC
1143         if (current_personality == 1) {
1144                 printstatsol(tcp, addr);
1145                 return;
1146         }
1147 # ifdef SPARC64
1148         else if (current_personality == 2) {
1149                 printstat_sparc64(tcp, addr);
1150                 return;
1151         }
1152 # endif
1153 #endif /* LINUXSPARC */
1154
1155 #if defined LINUX && defined X86_64
1156         if (current_personality == 0) {
1157                 printstat(tcp, addr);
1158                 return;
1159         }
1160 #endif
1161
1162         if (umove(tcp, addr, &statbuf) < 0) {
1163                 tprintf("{...}");
1164                 return;
1165         }
1166
1167         if (!abbrev(tcp)) {
1168 #ifdef HAVE_LONG_LONG
1169                 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%llu, st_mode=%s, ",
1170 #else
1171                 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%lu, st_mode=%s, ",
1172 #endif
1173                         (unsigned long) major(statbuf.st_dev),
1174                         (unsigned long) minor(statbuf.st_dev),
1175 #ifdef HAVE_LONG_LONG
1176                         (unsigned long long) statbuf.st_ino,
1177 #else
1178                         (unsigned long) statbuf.st_ino,
1179 #endif
1180                         sprintmode(statbuf.st_mode));
1181                 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
1182                         (unsigned long) statbuf.st_nlink,
1183                         (unsigned long) statbuf.st_uid,
1184                         (unsigned long) statbuf.st_gid);
1185 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1186                 tprintf("st_blksize=%lu, ",
1187                         (unsigned long) statbuf.st_blksize);
1188 #endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
1189 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1190                 tprintf("st_blocks=%lu, ", (unsigned long) statbuf.st_blocks);
1191 #endif /* HAVE_STRUCT_STAT_ST_BLOCKS */
1192         }
1193         else
1194                 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
1195         switch (statbuf.st_mode & S_IFMT) {
1196         case S_IFCHR: case S_IFBLK:
1197 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1198                 tprintf("st_rdev=makedev(%lu, %lu), ",
1199                         (unsigned long) major(statbuf.st_rdev),
1200                         (unsigned long) minor(statbuf.st_rdev));
1201 #else /* !HAVE_STRUCT_STAT_ST_RDEV */
1202                 tprintf("st_size=makedev(%lu, %lu), ",
1203                         (unsigned long) major(statbuf.st_size),
1204                         (unsigned long) minor(statbuf.st_size));
1205 #endif /* !HAVE_STRUCT_STAT_ST_RDEV */
1206                 break;
1207         default:
1208 #ifdef HAVE_LONG_LONG
1209                 tprintf("st_size=%llu, ", (unsigned long long) statbuf.st_size);
1210 #else
1211                 tprintf("st_size=%lu, ", (unsigned long) statbuf.st_size);
1212 #endif
1213                 break;
1214         }
1215         if (!abbrev(tcp)) {
1216                 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
1217                 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
1218                 tprintf("st_ctime=%s", sprinttime(statbuf.st_ctime));
1219 #if HAVE_STRUCT_STAT_ST_FLAGS
1220                 tprintf(", st_flags=");
1221                 printflags(fileflags, statbuf.st_flags, "UF_???");
1222 #endif
1223 #if HAVE_STRUCT_STAT_ST_ACLCNT
1224                 tprintf(", st_aclcnt=%d", statbuf.st_aclcnt);
1225 #endif
1226 #if HAVE_STRUCT_STAT_ST_LEVEL
1227                 tprintf(", st_level=%ld", statbuf.st_level);
1228 #endif
1229 #if HAVE_STRUCT_STAT_ST_FSTYPE
1230                 tprintf(", st_fstype=%.*s",
1231                         (int) sizeof statbuf.st_fstype, statbuf.st_fstype);
1232 #endif
1233 #if HAVE_STRUCT_STAT_ST_GEN
1234                 tprintf(", st_gen=%u", statbuf.st_gen);
1235 #endif
1236                 tprintf("}");
1237         }
1238         else
1239                 tprintf("...}");
1240 }
1241 #endif /* HAVE_STAT64 */
1242
1243 #if defined(LINUX) && defined(HAVE_STRUCT___OLD_KERNEL_STAT)
1244 static void
1245 convertoldstat(const struct __old_kernel_stat *oldbuf, struct stat *newbuf)
1246 {
1247         newbuf->st_dev = oldbuf->st_dev;
1248         newbuf->st_ino = oldbuf->st_ino;
1249         newbuf->st_mode = oldbuf->st_mode;
1250         newbuf->st_nlink = oldbuf->st_nlink;
1251         newbuf->st_uid = oldbuf->st_uid;
1252         newbuf->st_gid = oldbuf->st_gid;
1253         newbuf->st_rdev = oldbuf->st_rdev;
1254         newbuf->st_size = oldbuf->st_size;
1255         newbuf->st_atime = oldbuf->st_atime;
1256         newbuf->st_mtime = oldbuf->st_mtime;
1257         newbuf->st_ctime = oldbuf->st_ctime;
1258         newbuf->st_blksize = 0; /* not supported in old_stat */
1259         newbuf->st_blocks = 0; /* not supported in old_stat */
1260 }
1261
1262
1263 static void
1264 printoldstat(struct tcb *tcp, long addr)
1265 {
1266         struct __old_kernel_stat statbuf;
1267         struct stat newstatbuf;
1268
1269         if (!addr) {
1270                 tprintf("NULL");
1271                 return;
1272         }
1273         if (syserror(tcp) || !verbose(tcp)) {
1274                 tprintf("%#lx", addr);
1275                 return;
1276         }
1277
1278 #ifdef LINUXSPARC
1279         if (current_personality == 1) {
1280                 printstatsol(tcp, addr);
1281                 return;
1282         }
1283 #endif /* LINUXSPARC */
1284
1285         if (umove(tcp, addr, &statbuf) < 0) {
1286                 tprintf("{...}");
1287                 return;
1288         }
1289
1290         convertoldstat(&statbuf, &newstatbuf);
1291         realprintstat(tcp, &newstatbuf);
1292 }
1293 #endif /* LINUX && !IA64 && !HPPA && !X86_64 && !S390 && !S390X */
1294
1295 #ifndef HAVE_LONG_LONG_OFF_T
1296 int
1297 sys_stat(struct tcb *tcp)
1298 {
1299         if (entering(tcp)) {
1300                 printpath(tcp, tcp->u_arg[0]);
1301                 tprintf(", ");
1302         } else {
1303                 printstat(tcp, tcp->u_arg[1]);
1304         }
1305         return 0;
1306 }
1307 #endif
1308
1309 int
1310 sys_stat64(struct tcb *tcp)
1311 {
1312 #ifdef HAVE_STAT64
1313         if (entering(tcp)) {
1314                 printpath(tcp, tcp->u_arg[0]);
1315                 tprintf(", ");
1316         } else {
1317                 printstat64(tcp, tcp->u_arg[1]);
1318         }
1319         return 0;
1320 #else
1321         return printargs(tcp);
1322 #endif
1323 }
1324
1325 #ifdef LINUX
1326 static const struct xlat fstatatflags[] = {
1327 #ifndef AT_SYMLINK_NOFOLLOW
1328 # define AT_SYMLINK_NOFOLLOW     0x100
1329 #endif
1330         { AT_SYMLINK_NOFOLLOW,  "AT_SYMLINK_NOFOLLOW"   },
1331         { 0,                    NULL                    },
1332 };
1333 #define utimensatflags fstatatflags
1334
1335 int
1336 sys_newfstatat(struct tcb *tcp)
1337 {
1338         if (entering(tcp)) {
1339                 print_dirfd(tcp, tcp->u_arg[0]);
1340                 printpath(tcp, tcp->u_arg[1]);
1341                 tprintf(", ");
1342         } else {
1343 #ifdef POWERPC64
1344                 if (current_personality == 0)
1345                         printstat(tcp, tcp->u_arg[2]);
1346                 else
1347                         printstat64(tcp, tcp->u_arg[2]);
1348 #elif defined HAVE_STAT64
1349                 printstat64(tcp, tcp->u_arg[2]);
1350 #else
1351                 printstat(tcp, tcp->u_arg[2]);
1352 #endif
1353                 tprintf(", ");
1354                 printflags(fstatatflags, tcp->u_arg[3], "AT_???");
1355         }
1356         return 0;
1357 }
1358 #endif
1359
1360 #if defined(LINUX) && defined(HAVE_STRUCT___OLD_KERNEL_STAT)
1361 int
1362 sys_oldstat(struct tcb *tcp)
1363 {
1364         if (entering(tcp)) {
1365                 printpath(tcp, tcp->u_arg[0]);
1366                 tprintf(", ");
1367         } else {
1368                 printoldstat(tcp, tcp->u_arg[1]);
1369         }
1370         return 0;
1371 }
1372 #endif /* LINUX && HAVE_STRUCT___OLD_KERNEL_STAT */
1373
1374 #ifndef HAVE_LONG_LONG_OFF_T
1375 int
1376 sys_fstat(struct tcb *tcp)
1377 {
1378         if (entering(tcp)) {
1379                 printfd(tcp, tcp->u_arg[0]);
1380                 tprintf(", ");
1381         } else {
1382                 printstat(tcp, tcp->u_arg[1]);
1383         }
1384         return 0;
1385 }
1386 #endif
1387
1388 int
1389 sys_fstat64(struct tcb *tcp)
1390 {
1391 #ifdef HAVE_STAT64
1392         if (entering(tcp)) {
1393                 printfd(tcp, tcp->u_arg[0]);
1394                 tprintf(", ");
1395         } else {
1396                 printstat64(tcp, tcp->u_arg[1]);
1397         }
1398         return 0;
1399 #else
1400         return printargs(tcp);
1401 #endif
1402 }
1403
1404 #if defined(LINUX) && defined(HAVE_STRUCT___OLD_KERNEL_STAT)
1405 int
1406 sys_oldfstat(struct tcb *tcp)
1407 {
1408         if (entering(tcp)) {
1409                 printfd(tcp, tcp->u_arg[0]);
1410                 tprintf(", ");
1411         } else {
1412                 printoldstat(tcp, tcp->u_arg[1]);
1413         }
1414         return 0;
1415 }
1416 #endif /* LINUX && HAVE_STRUCT___OLD_KERNEL_STAT */
1417
1418 #ifndef HAVE_LONG_LONG_OFF_T
1419 int
1420 sys_lstat(struct tcb *tcp)
1421 {
1422         if (entering(tcp)) {
1423                 printpath(tcp, tcp->u_arg[0]);
1424                 tprintf(", ");
1425         } else {
1426                 printstat(tcp, tcp->u_arg[1]);
1427         }
1428         return 0;
1429 }
1430 #endif
1431
1432 int
1433 sys_lstat64(struct tcb *tcp)
1434 {
1435 #ifdef HAVE_STAT64
1436         if (entering(tcp)) {
1437                 printpath(tcp, tcp->u_arg[0]);
1438                 tprintf(", ");
1439         } else {
1440                 printstat64(tcp, tcp->u_arg[1]);
1441         }
1442         return 0;
1443 #else
1444         return printargs(tcp);
1445 #endif
1446 }
1447
1448 #if defined(LINUX) && defined(HAVE_STRUCT___OLD_KERNEL_STAT)
1449 int
1450 sys_oldlstat(struct tcb *tcp)
1451 {
1452         if (entering(tcp)) {
1453                 printpath(tcp, tcp->u_arg[0]);
1454                 tprintf(", ");
1455         } else {
1456                 printoldstat(tcp, tcp->u_arg[1]);
1457         }
1458         return 0;
1459 }
1460 #endif /* LINUX && HAVE_STRUCT___OLD_KERNEL_STAT */
1461
1462
1463 #if defined(SVR4) || defined(LINUXSPARC)
1464
1465 int
1466 sys_xstat(struct tcb *tcp)
1467 {
1468         if (entering(tcp)) {
1469                 tprintf("%ld, ", tcp->u_arg[0]);
1470                 printpath(tcp, tcp->u_arg[1]);
1471                 tprintf(", ");
1472         } else {
1473 #ifdef _STAT64_VER
1474                 if (tcp->u_arg[0] == _STAT64_VER)
1475                         printstat64 (tcp, tcp->u_arg[2]);
1476                 else
1477 #endif
1478                 printstat(tcp, tcp->u_arg[2]);
1479         }
1480         return 0;
1481 }
1482
1483 int
1484 sys_fxstat(struct tcb *tcp)
1485 {
1486         if (entering(tcp))
1487                 tprintf("%ld, %ld, ", tcp->u_arg[0], tcp->u_arg[1]);
1488         else {
1489 #ifdef _STAT64_VER
1490                 if (tcp->u_arg[0] == _STAT64_VER)
1491                         printstat64 (tcp, tcp->u_arg[2]);
1492                 else
1493 #endif
1494                 printstat(tcp, tcp->u_arg[2]);
1495         }
1496         return 0;
1497 }
1498
1499 int
1500 sys_lxstat(struct tcb *tcp)
1501 {
1502         if (entering(tcp)) {
1503                 tprintf("%ld, ", tcp->u_arg[0]);
1504                 printpath(tcp, tcp->u_arg[1]);
1505                 tprintf(", ");
1506         } else {
1507 #ifdef _STAT64_VER
1508                 if (tcp->u_arg[0] == _STAT64_VER)
1509                         printstat64 (tcp, tcp->u_arg[2]);
1510                 else
1511 #endif
1512                 printstat(tcp, tcp->u_arg[2]);
1513         }
1514         return 0;
1515 }
1516
1517 int
1518 sys_xmknod(struct tcb *tcp)
1519 {
1520         int mode = tcp->u_arg[2];
1521
1522         if (entering(tcp)) {
1523                 tprintf("%ld, ", tcp->u_arg[0]);
1524                 printpath(tcp, tcp->u_arg[1]);
1525                 tprintf(", %s", sprintmode(mode));
1526                 switch (mode & S_IFMT) {
1527                 case S_IFCHR: case S_IFBLK:
1528 #ifdef LINUXSPARC
1529                         tprintf(", makedev(%lu, %lu)",
1530                                 (unsigned long) ((tcp->u_arg[3] >> 18) & 0x3fff),
1531                                 (unsigned long) (tcp->u_arg[3] & 0x3ffff));
1532 #else
1533                         tprintf(", makedev(%lu, %lu)",
1534                                 (unsigned long) major(tcp->u_arg[3]),
1535                                 (unsigned long) minor(tcp->u_arg[3]));
1536 #endif
1537                         break;
1538                 default:
1539                         break;
1540                 }
1541         }
1542         return 0;
1543 }
1544
1545 #ifdef HAVE_SYS_ACL_H
1546
1547 #include <sys/acl.h>
1548
1549 static const struct xlat aclcmds[] = {
1550 #ifdef SETACL
1551         { SETACL,       "SETACL"        },
1552 #endif
1553 #ifdef GETACL
1554         { GETACL,       "GETACL"        },
1555 #endif
1556 #ifdef GETACLCNT
1557         { GETACLCNT,    "GETACLCNT"     },
1558 #endif
1559 #ifdef ACL_GET
1560         { ACL_GET,      "ACL_GET"       },
1561 #endif
1562 #ifdef ACL_SET
1563         { ACL_SET,      "ACL_SET"       },
1564 #endif
1565 #ifdef ACL_CNT
1566         { ACL_CNT,      "ACL_CNT"       },
1567 #endif
1568         { 0,            NULL            },
1569 };
1570
1571 int
1572 sys_acl(struct tcb *tcp)
1573 {
1574         if (entering(tcp)) {
1575                 printpath(tcp, tcp->u_arg[0]);
1576                 tprintf(", ");
1577                 printxval(aclcmds, tcp->u_arg[1], "???ACL???");
1578                 tprintf(", %ld", tcp->u_arg[2]);
1579                 /*
1580                  * FIXME - dump out the list of aclent_t's pointed to
1581                  * by "tcp->u_arg[3]" if it's not NULL.
1582                  */
1583                 if (tcp->u_arg[3])
1584                         tprintf(", %#lx", tcp->u_arg[3]);
1585                 else
1586                         tprintf(", NULL");
1587         }
1588         return 0;
1589 }
1590
1591
1592 int
1593 sys_facl(struct tcb *tcp)
1594 {
1595         if (entering(tcp)) {
1596                 tprintf("%ld, ", tcp->u_arg[0]);
1597                 printxval(aclcmds, tcp->u_arg[1], "???ACL???");
1598                 tprintf(", %ld", tcp->u_arg[2]);
1599                 /*
1600                  * FIXME - dump out the list of aclent_t's pointed to
1601                  * by "tcp->u_arg[3]" if it's not NULL.
1602                  */
1603                 if (tcp->u_arg[3])
1604                         tprintf(", %#lx", tcp->u_arg[3]);
1605                 else
1606                         tprintf(", NULL");
1607         }
1608         return 0;
1609 }
1610
1611
1612 static const struct xlat aclipc[] = {
1613 #ifdef IPC_SHM
1614         { IPC_SHM,      "IPC_SHM"       },
1615 #endif
1616 #ifdef IPC_SEM
1617         { IPC_SEM,      "IPC_SEM"       },
1618 #endif
1619 #ifdef IPC_MSG
1620         { IPC_MSG,      "IPC_MSG"       },
1621 #endif
1622         { 0,            NULL            },
1623 };
1624
1625
1626 int
1627 sys_aclipc(struct tcb *tcp)
1628 {
1629         if (entering(tcp)) {
1630                 printxval(aclipc, tcp->u_arg[0], "???IPC???");
1631                 tprintf(", %#lx, ", tcp->u_arg[1]);
1632                 printxval(aclcmds, tcp->u_arg[2], "???ACL???");
1633                 tprintf(", %ld", tcp->u_arg[3]);
1634                 /*
1635                  * FIXME - dump out the list of aclent_t's pointed to
1636                  * by "tcp->u_arg[4]" if it's not NULL.
1637                  */
1638                 if (tcp->u_arg[4])
1639                         tprintf(", %#lx", tcp->u_arg[4]);
1640                 else
1641                         tprintf(", NULL");
1642         }
1643         return 0;
1644 }
1645
1646 #endif /* HAVE_SYS_ACL_H */
1647
1648 #endif /* SVR4 || LINUXSPARC */
1649
1650 #ifdef LINUX
1651
1652 static const struct xlat fsmagic[] = {
1653         { 0x73757245,   "CODA_SUPER_MAGIC"      },
1654         { 0x012ff7b7,   "COH_SUPER_MAGIC"       },
1655         { 0x1373,       "DEVFS_SUPER_MAGIC"     },
1656         { 0x1cd1,       "DEVPTS_SUPER_MAGIC"    },
1657         { 0x414A53,     "EFS_SUPER_MAGIC"       },
1658         { 0xef51,       "EXT2_OLD_SUPER_MAGIC"  },
1659         { 0xef53,       "EXT2_SUPER_MAGIC"      },
1660         { 0x137d,       "EXT_SUPER_MAGIC"       },
1661         { 0xf995e849,   "HPFS_SUPER_MAGIC"      },
1662         { 0x9660,       "ISOFS_SUPER_MAGIC"     },
1663         { 0x137f,       "MINIX_SUPER_MAGIC"     },
1664         { 0x138f,       "MINIX_SUPER_MAGIC2"    },
1665         { 0x2468,       "MINIX2_SUPER_MAGIC"    },
1666         { 0x2478,       "MINIX2_SUPER_MAGIC2"   },
1667         { 0x4d44,       "MSDOS_SUPER_MAGIC"     },
1668         { 0x564c,       "NCP_SUPER_MAGIC"       },
1669         { 0x6969,       "NFS_SUPER_MAGIC"       },
1670         { 0x9fa0,       "PROC_SUPER_MAGIC"      },
1671         { 0x002f,       "QNX4_SUPER_MAGIC"      },
1672         { 0x52654973,   "REISERFS_SUPER_MAGIC"  },
1673         { 0x02011994,   "SHMFS_SUPER_MAGIC"     },
1674         { 0x517b,       "SMB_SUPER_MAGIC"       },
1675         { 0x012ff7b6,   "SYSV2_SUPER_MAGIC"     },
1676         { 0x012ff7b5,   "SYSV4_SUPER_MAGIC"     },
1677         { 0x00011954,   "UFS_MAGIC"             },
1678         { 0x54190100,   "UFS_CIGAM"             },
1679         { 0x012ff7b4,   "XENIX_SUPER_MAGIC"     },
1680         { 0x012fd16d,   "XIAFS_SUPER_MAGIC"     },
1681         { 0x62656572,   "SYSFS_MAGIC"           },
1682         { 0,            NULL                    },
1683 };
1684
1685 #endif /* LINUX */
1686
1687 #ifndef SVR4
1688
1689 static const char *
1690 sprintfstype(int magic)
1691 {
1692         static char buf[32];
1693 #ifdef LINUX
1694         const char *s;
1695
1696         s = xlookup(fsmagic, magic);
1697         if (s) {
1698                 sprintf(buf, "\"%s\"", s);
1699                 return buf;
1700         }
1701 #endif /* LINUX */
1702         sprintf(buf, "%#x", magic);
1703         return buf;
1704 }
1705
1706 static void
1707 printstatfs(struct tcb *tcp, long addr)
1708 {
1709         struct statfs statbuf;
1710
1711         if (syserror(tcp) || !verbose(tcp)) {
1712                 tprintf("%#lx", addr);
1713                 return;
1714         }
1715         if (umove(tcp, addr, &statbuf) < 0) {
1716                 tprintf("{...}");
1717                 return;
1718         }
1719 #ifdef ALPHA
1720
1721         tprintf("{f_type=%s, f_fbsize=%u, f_blocks=%u, f_bfree=%u, ",
1722                 sprintfstype(statbuf.f_type),
1723                 statbuf.f_bsize, statbuf.f_blocks, statbuf.f_bfree);
1724         tprintf("f_bavail=%u, f_files=%u, f_ffree=%u, f_fsid={%d, %d}, f_namelen=%u",
1725                 statbuf.f_bavail, statbuf.f_files, statbuf.f_ffree,
1726                 statbuf.f_fsid.__val[0], statbuf.f_fsid.__val[1],
1727                 statbuf.f_namelen);
1728 #else /* !ALPHA */
1729         tprintf("{f_type=%s, f_bsize=%lu, f_blocks=%lu, f_bfree=%lu, ",
1730                 sprintfstype(statbuf.f_type),
1731                 (unsigned long)statbuf.f_bsize,
1732                 (unsigned long)statbuf.f_blocks,
1733                 (unsigned long)statbuf.f_bfree);
1734         tprintf("f_bavail=%lu, f_files=%lu, f_ffree=%lu, f_fsid={%d, %d}",
1735                 (unsigned long)statbuf.f_bavail,
1736                 (unsigned long)statbuf.f_files,
1737                 (unsigned long)statbuf.f_ffree,
1738                 statbuf.f_fsid.__val[0], statbuf.f_fsid.__val[1]);
1739 #ifdef LINUX
1740         tprintf(", f_namelen=%lu", (unsigned long)statbuf.f_namelen);
1741 #endif /* LINUX */
1742 #endif /* !ALPHA */
1743 #ifdef _STATFS_F_FRSIZE
1744         tprintf(", f_frsize=%lu", (unsigned long)statbuf.f_frsize);
1745 #endif
1746         tprintf("}");
1747 }
1748
1749 int
1750 sys_statfs(struct tcb *tcp)
1751 {
1752         if (entering(tcp)) {
1753                 printpath(tcp, tcp->u_arg[0]);
1754                 tprintf(", ");
1755         } else {
1756                 printstatfs(tcp, tcp->u_arg[1]);
1757         }
1758         return 0;
1759 }
1760
1761 int
1762 sys_fstatfs(struct tcb *tcp)
1763 {
1764         if (entering(tcp)) {
1765                 printfd(tcp, tcp->u_arg[0]);
1766                 tprintf(", ");
1767         } else {
1768                 printstatfs(tcp, tcp->u_arg[1]);
1769         }
1770         return 0;
1771 }
1772
1773 #if defined LINUX && defined HAVE_STATFS64
1774 static void
1775 printstatfs64(struct tcb *tcp, long addr)
1776 {
1777         struct statfs64 statbuf;
1778
1779         if (syserror(tcp) || !verbose(tcp)) {
1780                 tprintf("%#lx", addr);
1781                 return;
1782         }
1783         if (umove(tcp, addr, &statbuf) < 0) {
1784                 tprintf("{...}");
1785                 return;
1786         }
1787         tprintf("{f_type=%s, f_bsize=%llu, f_blocks=%llu, f_bfree=%llu, ",
1788                 sprintfstype(statbuf.f_type),
1789                 (unsigned long long)statbuf.f_bsize,
1790                 (unsigned long long)statbuf.f_blocks,
1791                 (unsigned long long)statbuf.f_bfree);
1792         tprintf("f_bavail=%llu, f_files=%llu, f_ffree=%llu, f_fsid={%d, %d}",
1793                 (unsigned long long)statbuf.f_bavail,
1794                 (unsigned long long)statbuf.f_files,
1795                 (unsigned long long)statbuf.f_ffree,
1796                 statbuf.f_fsid.__val[0], statbuf.f_fsid.__val[1]);
1797         tprintf(", f_namelen=%lu", (unsigned long)statbuf.f_namelen);
1798 #ifdef _STATFS_F_FRSIZE
1799         tprintf(", f_frsize=%llu", (unsigned long long)statbuf.f_frsize);
1800 #endif
1801         tprintf("}");
1802 }
1803
1804 int
1805 sys_statfs64(struct tcb *tcp)
1806 {
1807         if (entering(tcp)) {
1808                 printpath(tcp, tcp->u_arg[0]);
1809                 tprintf(", %lu, ", tcp->u_arg[1]);
1810         } else {
1811                 if (tcp->u_arg[1] == sizeof(struct statfs64))
1812                         printstatfs64(tcp, tcp->u_arg[2]);
1813                 else
1814                         tprintf("{???}");
1815         }
1816         return 0;
1817 }
1818
1819 int
1820 sys_fstatfs64(struct tcb *tcp)
1821 {
1822         if (entering(tcp)) {
1823                 printfd(tcp, tcp->u_arg[0]);
1824                 tprintf(", %lu, ", tcp->u_arg[1]);
1825         } else {
1826                 if (tcp->u_arg[1] == sizeof(struct statfs64))
1827                         printstatfs64(tcp, tcp->u_arg[2]);
1828                 else
1829                         tprintf("{???}");
1830         }
1831         return 0;
1832 }
1833 #endif
1834
1835 #if defined(LINUX) && defined(__alpha)
1836
1837 int
1838 osf_statfs(struct tcb *tcp)
1839 {
1840         if (entering(tcp)) {
1841                 printpath(tcp, tcp->u_arg[0]);
1842                 tprintf(", ");
1843         } else {
1844                 printstatfs(tcp, tcp->u_arg[1]);
1845                 tprintf(", %lu", tcp->u_arg[2]);
1846         }
1847         return 0;
1848 }
1849
1850 int
1851 osf_fstatfs(struct tcb *tcp)
1852 {
1853         if (entering(tcp)) {
1854                 tprintf("%lu, ", tcp->u_arg[0]);
1855         } else {
1856                 printstatfs(tcp, tcp->u_arg[1]);
1857                 tprintf(", %lu", tcp->u_arg[2]);
1858         }
1859         return 0;
1860 }
1861 #endif /* LINUX && __alpha */
1862
1863 #endif /* !SVR4 */
1864
1865 #ifdef SUNOS4
1866 int
1867 sys_ustat(struct tcb *tcp)
1868 {
1869         struct ustat statbuf;
1870
1871         if (entering(tcp)) {
1872                 tprintf("makedev(%lu, %lu), ",
1873                                 (long) major(tcp->u_arg[0]),
1874                                 (long) minor(tcp->u_arg[0]));
1875         }
1876         else {
1877                 if (syserror(tcp) || !verbose(tcp))
1878                         tprintf("%#lx", tcp->u_arg[1]);
1879                 else if (umove(tcp, tcp->u_arg[1], &statbuf) < 0)
1880                         tprintf("{...}");
1881                 else {
1882                         tprintf("{f_tfree=%lu, f_tinode=%lu, ",
1883                                 statbuf.f_tfree, statbuf.f_tinode);
1884                         tprintf("f_fname=\"%.*s\", ",
1885                                 (int) sizeof(statbuf.f_fname),
1886                                 statbuf.f_fname);
1887                         tprintf("f_fpack=\"%.*s\"}",
1888                                 (int) sizeof(statbuf.f_fpack),
1889                                 statbuf.f_fpack);
1890                 }
1891         }
1892         return 0;
1893 }
1894 #endif /* SUNOS4 */
1895
1896 int
1897 sys_pivotroot(struct tcb *tcp)
1898 {
1899         if (entering(tcp)) {
1900                 printpath(tcp, tcp->u_arg[0]);
1901                 tprintf(", ");
1902                 printpath(tcp, tcp->u_arg[1]);
1903         }
1904         return 0;
1905 }
1906
1907
1908 /* directory */
1909 int
1910 sys_chdir(struct tcb *tcp)
1911 {
1912         if (entering(tcp)) {
1913                 printpath(tcp, tcp->u_arg[0]);
1914         }
1915         return 0;
1916 }
1917
1918 static int
1919 decode_mkdir(struct tcb *tcp, int offset)
1920 {
1921         if (entering(tcp)) {
1922                 printpath(tcp, tcp->u_arg[offset]);
1923                 tprintf(", %#lo", tcp->u_arg[offset + 1]);
1924         }
1925         return 0;
1926 }
1927
1928 int
1929 sys_mkdir(struct tcb *tcp)
1930 {
1931         return decode_mkdir(tcp, 0);
1932 }
1933
1934 #ifdef LINUX
1935 int
1936 sys_mkdirat(struct tcb *tcp)
1937 {
1938         if (entering(tcp))
1939                 print_dirfd(tcp, tcp->u_arg[0]);
1940         return decode_mkdir(tcp, 1);
1941 }
1942 #endif
1943
1944 int
1945 sys_rmdir(struct tcb *tcp)
1946 {
1947         if (entering(tcp)) {
1948                 printpath(tcp, tcp->u_arg[0]);
1949         }
1950         return 0;
1951 }
1952
1953 int
1954 sys_fchdir(struct tcb *tcp)
1955 {
1956         if (entering(tcp)) {
1957                 printfd(tcp, tcp->u_arg[0]);
1958         }
1959         return 0;
1960 }
1961
1962 int
1963 sys_chroot(struct tcb *tcp)
1964 {
1965         if (entering(tcp)) {
1966                 printpath(tcp, tcp->u_arg[0]);
1967         }
1968         return 0;
1969 }
1970
1971 #if defined(SUNOS4) || defined(SVR4)
1972 int
1973 sys_fchroot(struct tcb *tcp)
1974 {
1975         if (entering(tcp)) {
1976                 printfd(tcp, tcp->u_arg[0]);
1977         }
1978         return 0;
1979 }
1980 #endif /* SUNOS4 || SVR4 */
1981
1982 int
1983 sys_link(struct tcb *tcp)
1984 {
1985         if (entering(tcp)) {
1986                 printpath(tcp, tcp->u_arg[0]);
1987                 tprintf(", ");
1988                 printpath(tcp, tcp->u_arg[1]);
1989         }
1990         return 0;
1991 }
1992
1993 #ifdef LINUX
1994 int
1995 sys_linkat(struct tcb *tcp)
1996 {
1997         if (entering(tcp)) {
1998                 print_dirfd(tcp, tcp->u_arg[0]);
1999                 printpath(tcp, tcp->u_arg[1]);
2000                 tprintf(", ");
2001                 print_dirfd(tcp, tcp->u_arg[2]);
2002                 printpath(tcp, tcp->u_arg[3]);
2003                 tprintf(", ");
2004                 printfd(tcp, tcp->u_arg[4]);
2005         }
2006         return 0;
2007 }
2008 #endif
2009
2010 int
2011 sys_unlink(struct tcb *tcp)
2012 {
2013         if (entering(tcp)) {
2014                 printpath(tcp, tcp->u_arg[0]);
2015         }
2016         return 0;
2017 }
2018
2019 #ifdef LINUX
2020 static const struct xlat unlinkatflags[] = {
2021 #ifndef AT_REMOVEDIR
2022 # define AT_REMOVEDIR            0x200
2023 #endif
2024         { AT_REMOVEDIR, "AT_REMOVEDIR"  },
2025         { 0,            NULL            },
2026 };
2027
2028 int
2029 sys_unlinkat(struct tcb *tcp)
2030 {
2031         if (entering(tcp)) {
2032                 print_dirfd(tcp, tcp->u_arg[0]);
2033                 printpath(tcp, tcp->u_arg[1]);
2034                 tprintf(", ");
2035                 printflags(unlinkatflags, tcp->u_arg[2], "AT_???");
2036         }
2037         return 0;
2038 }
2039 #endif
2040
2041 int
2042 sys_symlink(struct tcb *tcp)
2043 {
2044         if (entering(tcp)) {
2045                 printpath(tcp, tcp->u_arg[0]);
2046                 tprintf(", ");
2047                 printpath(tcp, tcp->u_arg[1]);
2048         }
2049         return 0;
2050 }
2051
2052 #ifdef LINUX
2053 int
2054 sys_symlinkat(struct tcb *tcp)
2055 {
2056         if (entering(tcp)) {
2057                 printpath(tcp, tcp->u_arg[0]);
2058                 tprintf(", ");
2059                 print_dirfd(tcp, tcp->u_arg[1]);
2060                 printpath(tcp, tcp->u_arg[2]);
2061         }
2062         return 0;
2063 }
2064 #endif
2065
2066 static int
2067 decode_readlink(struct tcb *tcp, int offset)
2068 {
2069         if (entering(tcp)) {
2070                 printpath(tcp, tcp->u_arg[offset]);
2071                 tprintf(", ");
2072         } else {
2073                 if (syserror(tcp))
2074                         tprintf("%#lx", tcp->u_arg[offset + 1]);
2075                 else
2076                         printpathn(tcp, tcp->u_arg[offset + 1], tcp->u_rval);
2077                 tprintf(", %lu", tcp->u_arg[offset + 2]);
2078         }
2079         return 0;
2080 }
2081
2082 int
2083 sys_readlink(struct tcb *tcp)
2084 {
2085         return decode_readlink(tcp, 0);
2086 }
2087
2088 #ifdef LINUX
2089 int
2090 sys_readlinkat(struct tcb *tcp)
2091 {
2092         if (entering(tcp))
2093                 print_dirfd(tcp, tcp->u_arg[0]);
2094         return decode_readlink(tcp, 1);
2095 }
2096 #endif
2097
2098 int
2099 sys_rename(struct tcb *tcp)
2100 {
2101         if (entering(tcp)) {
2102                 printpath(tcp, tcp->u_arg[0]);
2103                 tprintf(", ");
2104                 printpath(tcp, tcp->u_arg[1]);
2105         }
2106         return 0;
2107 }
2108
2109 #ifdef LINUX
2110 int
2111 sys_renameat(struct tcb *tcp)
2112 {
2113         if (entering(tcp)) {
2114                 print_dirfd(tcp, tcp->u_arg[0]);
2115                 printpath(tcp, tcp->u_arg[1]);
2116                 tprintf(", ");
2117                 print_dirfd(tcp, tcp->u_arg[2]);
2118                 printpath(tcp, tcp->u_arg[3]);
2119         }
2120         return 0;
2121 }
2122 #endif
2123
2124 int
2125 sys_chown(struct tcb *tcp)
2126 {
2127         if (entering(tcp)) {
2128                 printpath(tcp, tcp->u_arg[0]);
2129                 printuid(", ", tcp->u_arg[1]);
2130                 printuid(", ", tcp->u_arg[2]);
2131         }
2132         return 0;
2133 }
2134
2135 #ifdef LINUX
2136 int
2137 sys_fchownat(struct tcb *tcp)
2138 {
2139         if (entering(tcp)) {
2140                 print_dirfd(tcp, tcp->u_arg[0]);
2141                 printpath(tcp, tcp->u_arg[1]);
2142                 printuid(", ", tcp->u_arg[2]);
2143                 printuid(", ", tcp->u_arg[3]);
2144                 tprintf(", ");
2145                 printflags(fstatatflags, tcp->u_arg[4], "AT_???");
2146         }
2147         return 0;
2148 }
2149 #endif
2150
2151 int
2152 sys_fchown(struct tcb *tcp)
2153 {
2154         if (entering(tcp)) {
2155                 printfd(tcp, tcp->u_arg[0]);
2156                 printuid(", ", tcp->u_arg[1]);
2157                 printuid(", ", tcp->u_arg[2]);
2158         }
2159         return 0;
2160 }
2161
2162 static int
2163 decode_chmod(struct tcb *tcp, int offset)
2164 {
2165         if (entering(tcp)) {
2166                 printpath(tcp, tcp->u_arg[offset]);
2167                 tprintf(", %#lo", tcp->u_arg[offset + 1]);
2168         }
2169         return 0;
2170 }
2171
2172 int
2173 sys_chmod(struct tcb *tcp)
2174 {
2175         return decode_chmod(tcp, 0);
2176 }
2177
2178 #ifdef LINUX
2179 int
2180 sys_fchmodat(struct tcb *tcp)
2181 {
2182         if (entering(tcp))
2183                 print_dirfd(tcp, tcp->u_arg[0]);
2184         return decode_chmod(tcp, 1);
2185 }
2186 #endif
2187
2188 int
2189 sys_fchmod(struct tcb *tcp)
2190 {
2191         if (entering(tcp)) {
2192                 printfd(tcp, tcp->u_arg[0]);
2193                 tprintf(", %#lo", tcp->u_arg[1]);
2194         }
2195         return 0;
2196 }
2197
2198 #ifdef ALPHA
2199 int
2200 sys_osf_utimes(struct tcb *tcp)
2201 {
2202         if (entering(tcp)) {
2203                 printpath(tcp, tcp->u_arg[0]);
2204                 tprintf(", ");
2205                 printtv_bitness(tcp, tcp->u_arg[1], BITNESS_32,  0);
2206         }
2207         return 0;
2208 }
2209 #endif
2210
2211 static int
2212 decode_utimes(struct tcb *tcp, int offset, int special)
2213 {
2214         if (entering(tcp)) {
2215                 printpath(tcp, tcp->u_arg[offset]);
2216                 tprintf(", ");
2217                 if (tcp->u_arg[offset + 1] == 0)
2218                         tprintf("NULL");
2219                 else {
2220                         tprintf("{");
2221                         printtv_bitness(tcp, tcp->u_arg[offset + 1],
2222                                         BITNESS_CURRENT, special);
2223                         tprintf(", ");
2224                         printtv_bitness(tcp, tcp->u_arg[offset + 1]
2225                                         + sizeof(struct timeval),
2226                                         BITNESS_CURRENT, special);
2227                         tprintf("}");
2228                 }
2229         }
2230         return 0;
2231 }
2232
2233 int
2234 sys_utimes(struct tcb *tcp)
2235 {
2236         return decode_utimes(tcp, 0, 0);
2237 }
2238
2239 #ifdef LINUX
2240 int
2241 sys_futimesat(struct tcb *tcp)
2242 {
2243         if (entering(tcp))
2244                 print_dirfd(tcp, tcp->u_arg[0]);
2245         return decode_utimes(tcp, 1, 0);
2246 }
2247
2248 int
2249 sys_utimensat(struct tcb *tcp)
2250 {
2251         if (entering(tcp)) {
2252                 print_dirfd(tcp, tcp->u_arg[0]);
2253                 decode_utimes(tcp, 1, 1);
2254                 tprintf(", ");
2255                 printflags(utimensatflags, tcp->u_arg[3], "AT_???");
2256         }
2257         return 0;
2258 }
2259 #endif
2260
2261 int
2262 sys_utime(struct tcb *tcp)
2263 {
2264         union {
2265                 long utl[2];
2266                 int uti[2];
2267         } u;
2268
2269         if (entering(tcp)) {
2270                 printpath(tcp, tcp->u_arg[0]);
2271                 tprintf(", ");
2272                 if (!tcp->u_arg[1])
2273                         tprintf("NULL");
2274                 else if (!verbose(tcp))
2275                         tprintf("%#lx", tcp->u_arg[1]);
2276                 else if (umoven(tcp, tcp->u_arg[1],
2277                                 2 * personality_wordsize[current_personality],
2278                                 (char *) &u) < 0)
2279                         tprintf("[?, ?]");
2280                 else if (personality_wordsize[current_personality]
2281                          == sizeof u.utl[0]) {
2282                         tprintf("[%s,", sprinttime(u.utl[0]));
2283                         tprintf(" %s]", sprinttime(u.utl[1]));
2284                 }
2285                 else if (personality_wordsize[current_personality]
2286                          == sizeof u.uti[0]) {
2287                         tprintf("[%s,", sprinttime(u.uti[0]));
2288                         tprintf(" %s]", sprinttime(u.uti[1]));
2289                 }
2290                 else
2291                         abort();
2292         }
2293         return 0;
2294 }
2295
2296 static int
2297 decode_mknod(struct tcb *tcp, int offset)
2298 {
2299         int mode = tcp->u_arg[offset + 1];
2300
2301         if (entering(tcp)) {
2302                 printpath(tcp, tcp->u_arg[offset]);
2303                 tprintf(", %s", sprintmode(mode));
2304                 switch (mode & S_IFMT) {
2305                 case S_IFCHR: case S_IFBLK:
2306 #ifdef LINUXSPARC
2307                         if (current_personality == 1)
2308                         tprintf(", makedev(%lu, %lu)",
2309                                 (unsigned long) ((tcp->u_arg[offset + 2] >> 18) & 0x3fff),
2310                                 (unsigned long) (tcp->u_arg[offset + 2] & 0x3ffff));
2311                         else
2312 #endif
2313                         tprintf(", makedev(%lu, %lu)",
2314                                 (unsigned long) major(tcp->u_arg[offset + 2]),
2315                                 (unsigned long) minor(tcp->u_arg[offset + 2]));
2316                         break;
2317                 default:
2318                         break;
2319                 }
2320         }
2321         return 0;
2322 }
2323
2324 int
2325 sys_mknod(struct tcb *tcp)
2326 {
2327         return decode_mknod(tcp, 0);
2328 }
2329
2330 #ifdef LINUX
2331 int
2332 sys_mknodat(struct tcb *tcp)
2333 {
2334         if (entering(tcp))
2335                 print_dirfd(tcp, tcp->u_arg[0]);
2336         return decode_mknod(tcp, 1);
2337 }
2338 #endif
2339
2340 #ifdef FREEBSD
2341 int
2342 sys_mkfifo(struct tcb *tcp)
2343 {
2344         if (entering(tcp)) {
2345                 printpath(tcp, tcp->u_arg[0]);
2346                 tprintf(", %#lo", tcp->u_arg[1]);
2347         }
2348         return 0;
2349 }
2350 #endif /* FREEBSD */
2351
2352 int
2353 sys_fsync(struct tcb *tcp)
2354 {
2355         if (entering(tcp)) {
2356                 printfd(tcp, tcp->u_arg[0]);
2357         }
2358         return 0;
2359 }
2360
2361 #ifdef LINUX
2362
2363 static void
2364 printdir(struct tcb *tcp, long addr)
2365 {
2366         struct dirent d;
2367
2368         if (!verbose(tcp)) {
2369                 tprintf("%#lx", addr);
2370                 return;
2371         }
2372         if (umove(tcp, addr, &d) < 0) {
2373                 tprintf("{...}");
2374                 return;
2375         }
2376         tprintf("{d_ino=%ld, ", (unsigned long) d.d_ino);
2377         tprintf("d_name=");
2378         printpathn(tcp, (long) ((struct dirent *) addr)->d_name, d.d_reclen);
2379         tprintf("}");
2380 }
2381
2382 int
2383 sys_readdir(struct tcb *tcp)
2384 {
2385         if (entering(tcp)) {
2386                 printfd(tcp, tcp->u_arg[0]);
2387                 tprintf(", ");
2388         } else {
2389                 if (syserror(tcp) || tcp->u_rval == 0 || !verbose(tcp))
2390                         tprintf("%#lx", tcp->u_arg[1]);
2391                 else
2392                         printdir(tcp, tcp->u_arg[1]);
2393                 /* Not much point in printing this out, it is always 1. */
2394                 if (tcp->u_arg[2] != 1)
2395                         tprintf(", %lu", tcp->u_arg[2]);
2396         }
2397         return 0;
2398 }
2399
2400 #endif /* LINUX */
2401
2402 #if defined FREEBSD || defined LINUX
2403 static const struct xlat direnttypes[] = {
2404         { DT_UNKNOWN,   "DT_UNKNOWN"    },
2405         { DT_FIFO,      "DT_FIFO"       },
2406         { DT_CHR,       "DT_CHR"        },
2407         { DT_DIR,       "DT_DIR"        },
2408         { DT_BLK,       "DT_BLK"        },
2409         { DT_REG,       "DT_REG"        },
2410         { DT_LNK,       "DT_LNK"        },
2411         { DT_SOCK,      "DT_SOCK"       },
2412         { DT_WHT,       "DT_WHT"        },
2413         { 0,            NULL            },
2414 };
2415
2416 #endif
2417
2418 int
2419 sys_getdents(struct tcb *tcp)
2420 {
2421         int i, len, dents = 0;
2422         char *buf;
2423
2424         if (entering(tcp)) {
2425                 printfd(tcp, tcp->u_arg[0]);
2426                 tprintf(", ");
2427                 return 0;
2428         }
2429         if (syserror(tcp) || !verbose(tcp)) {
2430                 tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
2431                 return 0;
2432         }
2433         len = tcp->u_rval;
2434         buf = len ? malloc(len) : NULL;
2435         if (len && !buf) {
2436                 tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
2437                 fprintf(stderr, "out of memory\n");
2438                 return 0;
2439         }
2440         if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
2441                 tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
2442                 free(buf);
2443                 return 0;
2444         }
2445         if (!abbrev(tcp))
2446                 tprintf("{");
2447         for (i = 0; i < len;) {
2448                 struct kernel_dirent *d = (struct kernel_dirent *) &buf[i];
2449 #ifdef LINUX
2450                 if (!abbrev(tcp)) {
2451                         tprintf("%s{d_ino=%lu, d_off=%lu, ",
2452                                 i ? " " : "", d->d_ino, d->d_off);
2453                         tprintf("d_reclen=%u, d_name=\"%s\"}",
2454                                 d->d_reclen, d->d_name);
2455                 }
2456 #endif /* LINUX */
2457 #ifdef SVR4
2458                 if (!abbrev(tcp)) {
2459                         tprintf("%s{d_ino=%lu, d_off=%lu, ",
2460                                 i ? " " : "",
2461                                 (unsigned long) d->d_ino,
2462                                 (unsigned long) d->d_off);
2463                         tprintf("d_reclen=%u, d_name=\"%s\"}",
2464                                 d->d_reclen, d->d_name);
2465                 }
2466 #endif /* SVR4 */
2467 #ifdef SUNOS4
2468                 if (!abbrev(tcp)) {
2469                         tprintf("%s{d_off=%lu, d_fileno=%lu, d_reclen=%u, ",
2470                                 i ? " " : "", d->d_off, d->d_fileno,
2471                                 d->d_reclen);
2472                         tprintf("d_namlen=%u, d_name=\"%.*s\"}",
2473                                 d->d_namlen, d->d_namlen, d->d_name);
2474                 }
2475 #endif /* SUNOS4 */
2476 #ifdef FREEBSD
2477                 if (!abbrev(tcp)) {
2478                         tprintf("%s{d_fileno=%u, d_reclen=%u, d_type=",
2479                                 i ? " " : "", d->d_fileno, d->d_reclen);
2480                         printxval(direnttypes, d->d_type, "DT_???");
2481                         tprintf(", d_namlen=%u, d_name=\"%.*s\"}",
2482                                 d->d_namlen, d->d_namlen, d->d_name);
2483                 }
2484 #endif /* FREEBSD */
2485                 if (!d->d_reclen) {
2486                         tprintf("/* d_reclen == 0, problem here */");
2487                         break;
2488                 }
2489                 i += d->d_reclen;
2490                 dents++;
2491         }
2492         if (!abbrev(tcp))
2493                 tprintf("}");
2494         else
2495                 tprintf("/* %u entries */", dents);
2496         tprintf(", %lu", tcp->u_arg[2]);
2497         free(buf);
2498         return 0;
2499 }
2500
2501
2502 #if _LFS64_LARGEFILE
2503 int
2504 sys_getdents64(struct tcb *tcp)
2505 {
2506         int i, len, dents = 0;
2507         char *buf;
2508
2509         if (entering(tcp)) {
2510                 printfd(tcp, tcp->u_arg[0]);
2511                 tprintf(", ");
2512                 return 0;
2513         }
2514         if (syserror(tcp) || !verbose(tcp)) {
2515                 tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
2516                 return 0;
2517         }
2518         len = tcp->u_rval;
2519         buf = len ? malloc(len) : NULL;
2520         if (len && !buf) {
2521                 tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
2522                 fprintf(stderr, "out of memory\n");
2523                 return 0;
2524         }
2525         if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
2526                 tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
2527                 free(buf);
2528                 return 0;
2529         }
2530         if (!abbrev(tcp))
2531                 tprintf("{");
2532         for (i = 0; i < len;) {
2533                 struct dirent64 *d = (struct dirent64 *) &buf[i];
2534 #if defined(LINUX) || defined(SVR4)
2535                 if (!abbrev(tcp)) {
2536                         tprintf("%s{d_ino=%" PRIu64 ", d_off=%" PRId64 ", ",
2537                                 i ? " " : "",
2538                                 d->d_ino,
2539                                 d->d_off);
2540 #ifdef LINUX
2541                         tprintf("d_type=");
2542                         printxval(direnttypes, d->d_type, "DT_???");
2543                         tprintf(", ");
2544 #endif
2545                         tprintf("d_reclen=%u, d_name=\"%s\"}",
2546                                 d->d_reclen, d->d_name);
2547                 }
2548 #endif /* LINUX || SVR4 */
2549 #ifdef SUNOS4
2550                 if (!abbrev(tcp)) {
2551                         tprintf("%s{d_off=%lu, d_fileno=%lu, d_reclen=%u, ",
2552                                 i ? " " : "", d->d_off, d->d_fileno,
2553                                 d->d_reclen);
2554                         tprintf("d_namlen=%u, d_name=\"%.*s\"}",
2555                                 d->d_namlen, d->d_namlen, d->d_name);
2556                 }
2557 #endif /* SUNOS4 */
2558                 if (!d->d_reclen) {
2559                         tprintf("/* d_reclen == 0, problem here */");
2560                         break;
2561                 }
2562                 i += d->d_reclen;
2563                 dents++;
2564         }
2565         if (!abbrev(tcp))
2566                 tprintf("}");
2567         else
2568                 tprintf("/* %u entries */", dents);
2569         tprintf(", %lu", tcp->u_arg[2]);
2570         free(buf);
2571         return 0;
2572 }
2573 #endif
2574
2575 #ifdef FREEBSD
2576 int
2577 sys_getdirentries(struct tcb *tcp)
2578 {
2579         int i, len, dents = 0;
2580         long basep;
2581         char *buf;
2582
2583         if (entering(tcp)) {
2584                 printfd(tcp, tcp->u_arg[0]);
2585                 tprintf(", ");
2586                 return 0;
2587         }
2588         if (syserror(tcp) || !verbose(tcp)) {
2589                 tprintf("%#lx, %lu, %#lx", tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3]);
2590                 return 0;
2591         }
2592         len = tcp->u_rval;
2593         if ((buf = malloc(len)) == NULL) {
2594                 tprintf("%#lx, %lu, %#lx", tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3]);
2595                 fprintf(stderr, "out of memory\n");
2596                 return 0;
2597         }
2598         if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
2599                 tprintf("%#lx, %lu, %#lx", tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3]);
2600                 free(buf);
2601                 return 0;
2602         }
2603         if (!abbrev(tcp))
2604                 tprintf("{");
2605         for (i = 0; i < len;) {
2606                 struct kernel_dirent *d = (struct kernel_dirent *) &buf[i];
2607                 if (!abbrev(tcp)) {
2608                         tprintf("%s{d_fileno=%u, d_reclen=%u, d_type=",
2609                                 i ? " " : "", d->d_fileno, d->d_reclen);
2610                         printxval(direnttypes, d->d_type, "DT_???");
2611                         tprintf(", d_namlen=%u, d_name=\"%.*s\"}",
2612                                 d->d_namlen, d->d_namlen, d->d_name);
2613                 }
2614                 if (!d->d_reclen) {
2615                         tprintf("/* d_reclen == 0, problem here */");
2616                         break;
2617                 }
2618                 i += d->d_reclen;
2619                 dents++;
2620         }
2621         if (!abbrev(tcp))
2622                 tprintf("}");
2623         else
2624                 tprintf("/* %u entries */", dents);
2625         free(buf);
2626         tprintf(", %lu", tcp->u_arg[2]);
2627         if (umove(tcp, tcp->u_arg[3], &basep) < 0)
2628                 tprintf(", %#lx", tcp->u_arg[3]);
2629         else
2630                 tprintf(", [%lu]", basep);
2631         return 0;
2632 }
2633 #endif
2634
2635 #ifdef LINUX
2636 int
2637 sys_getcwd(struct tcb *tcp)
2638 {
2639         if (exiting(tcp)) {
2640                 if (syserror(tcp))
2641                         tprintf("%#lx", tcp->u_arg[0]);
2642                 else
2643                         printpathn(tcp, tcp->u_arg[0], tcp->u_rval - 1);
2644                 tprintf(", %lu", tcp->u_arg[1]);
2645         }
2646         return 0;
2647 }
2648 #endif /* LINUX */
2649
2650 #ifdef FREEBSD
2651 int
2652 sys___getcwd(struct tcb *tcp)
2653 {
2654         if (exiting(tcp)) {
2655                 if (syserror(tcp))
2656                         tprintf("%#lx", tcp->u_arg[0]);
2657                 else
2658                         printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
2659                 tprintf(", %lu", tcp->u_arg[1]);
2660         }
2661         return 0;
2662 }
2663 #endif
2664
2665 #ifdef HAVE_SYS_ASYNCH_H
2666
2667 int
2668 sys_aioread(struct tcb *tcp)
2669 {
2670         struct aio_result_t res;
2671
2672         if (entering(tcp)) {
2673                 tprintf("%lu, ", tcp->u_arg[0]);
2674         } else {
2675                 if (syserror(tcp))
2676                         tprintf("%#lx", tcp->u_arg[1]);
2677                 else
2678                         printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
2679                 tprintf(", %lu, %lu, ", tcp->u_arg[2], tcp->u_arg[3]);
2680                 printxval(whence, tcp->u_arg[4], "L_???");
2681                 if (syserror(tcp) || tcp->u_arg[5] == 0
2682                     || umove(tcp, tcp->u_arg[5], &res) < 0)
2683                         tprintf(", %#lx", tcp->u_arg[5]);
2684                 else
2685                         tprintf(", {aio_return %d aio_errno %d}",
2686                                 res.aio_return, res.aio_errno);
2687         }
2688         return 0;
2689 }
2690
2691 int
2692 sys_aiowrite(struct tcb *tcp)
2693 {
2694         struct aio_result_t res;
2695
2696         if (entering(tcp)) {
2697                 tprintf("%lu, ", tcp->u_arg[0]);
2698                 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
2699                 tprintf(", %lu, %lu, ", tcp->u_arg[2], tcp->u_arg[3]);
2700                 printxval(whence, tcp->u_arg[4], "L_???");
2701         }
2702         else {
2703                 if (tcp->u_arg[5] == 0)
2704                         tprintf(", NULL");
2705                 else if (syserror(tcp)
2706                     || umove(tcp, tcp->u_arg[5], &res) < 0)
2707                         tprintf(", %#lx", tcp->u_arg[5]);
2708                 else
2709                         tprintf(", {aio_return %d aio_errno %d}",
2710                                 res.aio_return, res.aio_errno);
2711         }
2712         return 0;
2713 }
2714
2715 int
2716 sys_aiowait(struct tcb *tcp)
2717 {
2718         if (entering(tcp))
2719                 printtv(tcp, tcp->u_arg[0]);
2720         return 0;
2721 }
2722
2723 int
2724 sys_aiocancel(struct tcb *tcp)
2725 {
2726         struct aio_result_t res;
2727
2728         if (exiting(tcp)) {
2729                 if (tcp->u_arg[0] == 0)
2730                         tprintf("NULL");
2731                 else if (syserror(tcp)
2732                     || umove(tcp, tcp->u_arg[0], &res) < 0)
2733                         tprintf("%#lx", tcp->u_arg[0]);
2734                 else
2735                         tprintf("{aio_return %d aio_errno %d}",
2736                                 res.aio_return, res.aio_errno);
2737         }
2738         return 0;
2739 }
2740
2741 #endif /* HAVE_SYS_ASYNCH_H */
2742
2743 static const struct xlat xattrflags[] = {
2744 #ifdef XATTR_CREATE
2745         { XATTR_CREATE,  "XATTR_CREATE" },
2746         { XATTR_REPLACE, "XATTR_REPLACE" },
2747 #endif
2748         { 0,             NULL }
2749 };
2750
2751 static void
2752 print_xattr_val(struct tcb *tcp, int failed,
2753                 unsigned long arg,
2754                 unsigned long insize,
2755                 unsigned long size)
2756 {
2757         if (!failed) {
2758                 unsigned long capacity = 4 * size + 1;
2759                 unsigned char *buf = (capacity < size) ? NULL : malloc(capacity);
2760                 if (buf == NULL || /* probably a bogus size argument */
2761                         umoven(tcp, arg, size, (char *) &buf[3 * size]) < 0) {
2762                         failed = 1;
2763                 }
2764                 else {
2765                         unsigned char *out = buf;
2766                         unsigned char *in = &buf[3 * size];
2767                         size_t i;
2768                         for (i = 0; i < size; ++i) {
2769                                 if (isprint(in[i]))
2770                                         *out++ = in[i];
2771                                 else {
2772 #define tohex(n) "0123456789abcdef"[n]
2773                                         *out++ = '\\';
2774                                         *out++ = 'x';
2775                                         *out++ = tohex(in[i] / 16);
2776                                         *out++ = tohex(in[i] % 16);
2777                                 }
2778                         }
2779                         /* Don't print terminating NUL if there is one.  */
2780                         if (i > 0 && in[i - 1] == '\0')
2781                                 out -= 4;
2782                         *out = '\0';
2783                         tprintf(", \"%s\", %ld", buf, insize);
2784                 }
2785                 free(buf);
2786         }
2787         if (failed)
2788                 tprintf(", 0x%lx, %ld", arg, insize);
2789 }
2790
2791 int
2792 sys_setxattr(struct tcb *tcp)
2793 {
2794         if (entering(tcp)) {
2795                 printpath(tcp, tcp->u_arg[0]);
2796                 tprintf(", ");
2797                 printstr(tcp, tcp->u_arg[1], -1);
2798                 print_xattr_val(tcp, 0, tcp->u_arg[2], tcp->u_arg[3], tcp->u_arg[3]);
2799                 tprintf(", ");
2800                 printflags(xattrflags, tcp->u_arg[4], "XATTR_???");
2801         }
2802         return 0;
2803 }
2804
2805 int
2806 sys_fsetxattr(struct tcb *tcp)
2807 {
2808         if (entering(tcp)) {
2809                 printfd(tcp, tcp->u_arg[0]);
2810                 tprintf(", ");
2811                 printstr(tcp, tcp->u_arg[1], -1);
2812                 print_xattr_val(tcp, 0, tcp->u_arg[2], tcp->u_arg[3], tcp->u_arg[3]);
2813                 tprintf(", ");
2814                 printflags(xattrflags, tcp->u_arg[4], "XATTR_???");
2815         }
2816         return 0;
2817 }
2818
2819 int
2820 sys_getxattr(struct tcb *tcp)
2821 {
2822         if (entering(tcp)) {
2823                 printpath(tcp, tcp->u_arg[0]);
2824                 tprintf(", ");
2825                 printstr(tcp, tcp->u_arg[1], -1);
2826         } else {
2827                 print_xattr_val(tcp, syserror(tcp), tcp->u_arg[2], tcp->u_arg[3],
2828                                 tcp->u_rval);
2829         }
2830         return 0;
2831 }
2832
2833 int
2834 sys_fgetxattr(struct tcb *tcp)
2835 {
2836         if (entering(tcp)) {
2837                 printfd(tcp, tcp->u_arg[0]);
2838                 tprintf(", ");
2839                 printstr(tcp, tcp->u_arg[1], -1);
2840         } else {
2841                 print_xattr_val(tcp, syserror(tcp), tcp->u_arg[2], tcp->u_arg[3],
2842                                 tcp->u_rval);
2843         }
2844         return 0;
2845 }
2846
2847 int
2848 sys_listxattr(struct tcb *tcp)
2849 {
2850         if (entering(tcp)) {
2851                 printpath(tcp, tcp->u_arg[0]);
2852         } else {
2853                 /* XXX Print value in format */
2854                 tprintf(", %p, %lu", (void *) tcp->u_arg[1], tcp->u_arg[2]);
2855         }
2856         return 0;
2857 }
2858
2859 int
2860 sys_flistxattr(struct tcb *tcp)
2861 {
2862         if (entering(tcp)) {
2863                 printfd(tcp, tcp->u_arg[0]);
2864         } else {
2865                 /* XXX Print value in format */
2866                 tprintf(", %p, %lu", (void *) tcp->u_arg[1], tcp->u_arg[2]);
2867         }
2868         return 0;
2869 }
2870
2871 int
2872 sys_removexattr(struct tcb *tcp)
2873 {
2874         if (entering(tcp)) {
2875                 printpath(tcp, tcp->u_arg[0]);
2876                 tprintf(", ");
2877                 printstr(tcp, tcp->u_arg[1], -1);
2878         }
2879         return 0;
2880 }
2881
2882 int
2883 sys_fremovexattr(struct tcb *tcp)
2884 {
2885         if (entering(tcp)) {
2886                 printfd(tcp, tcp->u_arg[0]);
2887                 tprintf(", ");
2888                 printstr(tcp, tcp->u_arg[1], -1);
2889         }
2890         return 0;
2891 }
2892
2893
2894 static const struct xlat advise[] = {
2895   { POSIX_FADV_NORMAL,          "POSIX_FADV_NORMAL"     },
2896   { POSIX_FADV_RANDOM,          "POSIX_FADV_RANDOM"     },
2897   { POSIX_FADV_SEQUENTIAL,      "POSIX_FADV_SEQUENTIAL" },
2898   { POSIX_FADV_WILLNEED,        "POSIX_FADV_WILLNEED"   },
2899   { POSIX_FADV_DONTNEED,        "POSIX_FADV_DONTNEED"   },
2900   { POSIX_FADV_NOREUSE,         "POSIX_FADV_NOREUSE"    },
2901   { 0,                          NULL                    }
2902 };
2903
2904
2905 #ifdef LINUX
2906 int
2907 sys_fadvise64(struct tcb *tcp)
2908 {
2909         if (entering(tcp)) {
2910                 int argn;
2911                 printfd(tcp, tcp->u_arg[0]);
2912                 tprintf(", ");
2913                 argn = printllval(tcp, "%lld", 1);
2914                 tprintf(", %ld, ", tcp->u_arg[argn++]);
2915                 printxval(advise, tcp->u_arg[argn], "POSIX_FADV_???");
2916         }
2917         return 0;
2918 }
2919 #endif
2920
2921
2922 int
2923 sys_fadvise64_64(struct tcb *tcp)
2924 {
2925         if (entering(tcp)) {
2926                 int argn;
2927                 printfd(tcp, tcp->u_arg[0]);
2928                 tprintf(", ");
2929 #if defined ARM || defined POWERPC
2930                 argn = printllval(tcp, "%lld, ", 2);
2931 #else
2932                 argn = printllval(tcp, "%lld, ", 1);
2933 #endif
2934                 argn = printllval(tcp, "%lld, ", argn);
2935 #if defined ARM || defined POWERPC
2936                 printxval(advise, tcp->u_arg[1], "POSIX_FADV_???");
2937 #else
2938                 printxval(advise, tcp->u_arg[argn], "POSIX_FADV_???");
2939 #endif
2940         }
2941         return 0;
2942 }
2943
2944 #ifdef LINUX
2945 static const struct xlat inotify_modes[] = {
2946         { 0x00000001,   "IN_ACCESS"     },
2947         { 0x00000002,   "IN_MODIFY"     },
2948         { 0x00000004,   "IN_ATTRIB"     },
2949         { 0x00000008,   "IN_CLOSE_WRITE"},
2950         { 0x00000010,   "IN_CLOSE_NOWRITE"},
2951         { 0x00000020,   "IN_OPEN"       },
2952         { 0x00000040,   "IN_MOVED_FROM" },
2953         { 0x00000080,   "IN_MOVED_TO"   },
2954         { 0x00000100,   "IN_CREATE"     },
2955         { 0x00000200,   "IN_DELETE"     },
2956         { 0x00000400,   "IN_DELETE_SELF"},
2957         { 0x00000800,   "IN_MOVE_SELF"  },
2958         { 0x00002000,   "IN_UNMOUNT"    },
2959         { 0x00004000,   "IN_Q_OVERFLOW" },
2960         { 0x00008000,   "IN_IGNORED"    },
2961         { 0x01000000,   "IN_ONLYDIR"    },
2962         { 0x02000000,   "IN_DONT_FOLLOW"},
2963         { 0x20000000,   "IN_MASK_ADD"   },
2964         { 0x40000000,   "IN_ISDIR"      },
2965         { 0x80000000,   "IN_ONESHOT"    },
2966         { 0,            NULL            }
2967 };
2968
2969 static const struct xlat inotify_init_flags[] = {
2970         { 0x00000800,   "IN_NONBLOCK"   },
2971         { 0x00080000,   "IN_CLOEXEC"    },
2972         { 0,            NULL            }
2973 };
2974
2975 int
2976 sys_inotify_add_watch(struct tcb *tcp)
2977 {
2978         if (entering(tcp)) {
2979                 printfd(tcp, tcp->u_arg[0]);
2980                 tprintf(", ");
2981                 printpath(tcp, tcp->u_arg[1]);
2982                 tprintf(", ");
2983                 printflags(inotify_modes, tcp->u_arg[2], "IN_???");
2984         }
2985         return 0;
2986 }
2987
2988 int
2989 sys_inotify_rm_watch(struct tcb *tcp)
2990 {
2991         if (entering(tcp)) {
2992                 printfd(tcp, tcp->u_arg[0]);
2993                 tprintf(", %ld", tcp->u_arg[1]);
2994         }
2995         return 0;
2996 }
2997
2998 int
2999 sys_inotify_init1(struct tcb *tcp)
3000 {
3001         if (entering(tcp))
3002                 printflags(inotify_init_flags, tcp->u_arg[0], "IN_???");
3003         return 0;
3004 }
3005
3006 int
3007 sys_fallocate(struct tcb *tcp)
3008 {
3009         if (entering(tcp)) {
3010                 int argn;
3011                 printfd(tcp, tcp->u_arg[0]);            /* fd */
3012                 tprintf(", ");
3013                 tprintf("%#lo, ", tcp->u_arg[1]);       /* mode */
3014                 argn = printllval(tcp, "%llu, ", 2);    /* offset */
3015                 printllval(tcp, "%llu", argn);          /* len */
3016         }
3017         return 0;
3018 }
3019 #endif