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