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