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