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