]> granicus.if.org Git - strace/blob - file.c
2004-10-19 Roland McGrath <roland@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 HAVE_LONG_LONG_OFF_T
172 /*
173  * Ugly hacks for systems that have typedef long long off_t
174  */
175
176 #define stat64 stat
177 #define HAVE_STAT64 1   /* Ugly hack */
178
179 #define sys_stat64      sys_stat
180 #define sys_fstat64     sys_fstat
181 #define sys_lstat64     sys_lstat
182 #define sys_lseek64     sys_lseek
183 #define sys_truncate64  sys_truncate
184 #define sys_ftruncate64 sys_ftruncate
185 #endif
186
187 #ifdef MAJOR_IN_SYSMACROS
188 #include <sys/sysmacros.h>
189 #endif
190
191 #ifdef MAJOR_IN_MKDEV
192 #include <sys/mkdev.h>
193 #endif
194
195 #ifdef HAVE_SYS_ASYNCH_H
196 #include <sys/asynch.h>
197 #endif
198
199 #ifdef SUNOS4
200 #include <ustat.h>
201 #endif
202
203 /*
204  * This is a really dirty trick but it should always work.  Traditional
205  * Unix says r/w/rw are 0/1/2, so we make them true flags 1/2/3 by
206  * adding 1.  Just remember to add 1 to any arg decoded with openmodes.
207  */
208 const struct xlat openmodes[] = {
209         { O_RDWR+1,     "O_RDWR"        },
210         { O_RDONLY+1,   "O_RDONLY"      },
211         { O_WRONLY+1,   "O_WRONLY"      },
212         { O_NONBLOCK,   "O_NONBLOCK"    },
213         { O_APPEND,     "O_APPEND"      },
214         { O_CREAT,      "O_CREAT"       },
215         { O_TRUNC,      "O_TRUNC"       },
216         { O_EXCL,       "O_EXCL"        },
217         { O_NOCTTY,     "O_NOCTTY"      },
218 #ifdef O_SYNC
219         { O_SYNC,       "O_SYNC"        },
220 #endif
221 #ifdef O_ASYNC
222         { O_ASYNC,      "O_ASYNC"       },
223 #endif
224 #ifdef O_DSYNC
225         { O_DSYNC,      "O_DSYNC"       },
226 #endif
227 #ifdef O_RSYNC
228         { O_RSYNC,      "O_RSYNC"       },
229 #endif
230 #ifdef O_NDELAY
231         { O_NDELAY,     "O_NDELAY"      },
232 #endif
233 #ifdef O_PRIV
234         { O_PRIV,       "O_PRIV"        },
235 #endif
236 #ifdef O_DIRECT
237         { O_DIRECT,     "O_DIRECT"      },
238 #endif
239 #ifdef O_LARGEFILE
240         { O_LARGEFILE,  "O_LARGEFILE"   },
241 #endif
242 #ifdef O_DIRECTORY
243         { O_DIRECTORY,  "O_DIRECTORY"   },
244 #endif
245 #ifdef O_NOFOLLOW
246         { O_NOFOLLOW,   "O_NOFOLLOW"    },
247 #endif
248
249 #ifdef FNDELAY
250         { FNDELAY,      "FNDELAY"       },
251 #endif
252 #ifdef FAPPEND
253         { FAPPEND,      "FAPPEND"       },
254 #endif
255 #ifdef FMARK
256         { FMARK,        "FMARK"         },
257 #endif
258 #ifdef FDEFER
259         { FDEFER,       "FDEFER"        },
260 #endif
261 #ifdef FASYNC
262         { FASYNC,       "FASYNC"        },
263 #endif
264 #ifdef FSHLOCK
265         { FSHLOCK,      "FSHLOCK"       },
266 #endif
267 #ifdef FEXLOCK
268         { FEXLOCK,      "FEXLOCK"       },
269 #endif
270 #ifdef FCREAT
271         { FCREAT,       "FCREAT"        },
272 #endif
273 #ifdef FTRUNC
274         { FTRUNC,       "FTRUNC"        },
275 #endif
276 #ifdef FEXCL
277         { FEXCL,        "FEXCL"         },
278 #endif
279 #ifdef FNBIO
280         { FNBIO,        "FNBIO"         },
281 #endif
282 #ifdef FSYNC
283         { FSYNC,        "FSYNC"         },
284 #endif
285 #ifdef FNOCTTY
286         { FNOCTTY,      "FNOCTTY"       },
287 #endif
288 #ifdef O_SHLOCK
289         { O_SHLOCK,     "O_SHLOCK"      },
290 #endif
291 #ifdef O_EXLOCK
292         { O_EXLOCK,     "O_EXLOCK"      },
293 #endif
294         { 0,            NULL            },
295 };
296
297 int
298 sys_open(tcp)
299 struct tcb *tcp;
300 {
301         if (entering(tcp)) {
302                 printpath(tcp, tcp->u_arg[0]);
303                 tprintf(", ");
304                 /* flags */
305                 printflags(openmodes, tcp->u_arg[1] + 1);
306                 if (tcp->u_arg[1] & O_CREAT) {
307                         /* mode */
308                         tprintf(", %#lo", tcp->u_arg[2]);
309                 }
310         }
311         return 0;
312 }
313
314 #ifdef LINUXSPARC
315 const struct xlat openmodessol[] = {
316         { 0,            "O_RDWR"        },
317         { 1,            "O_RDONLY"      },
318         { 2,            "O_WRONLY"      },
319         { 0x80,         "O_NONBLOCK"    },
320         { 8,            "O_APPEND"      },
321         { 0x100,        "O_CREAT"       },
322         { 0x200,        "O_TRUNC"       },
323         { 0x400,        "O_EXCL"        },
324         { 0x800,        "O_NOCTTY"      },
325         { 0x10,         "O_SYNC"        },
326         { 0x40,         "O_DSYNC"       },
327         { 0x8000,       "O_RSYNC"       },
328         { 4,            "O_NDELAY"      },
329         { 0x1000,       "O_PRIV"        },
330         { 0,            NULL            },
331 };
332
333 int
334 solaris_open(tcp)
335 struct tcb *tcp;
336 {
337         if (entering(tcp)) {
338                 printpath(tcp, tcp->u_arg[0]);
339                 tprintf(", ");
340                 /* flags */
341                 printflags(openmodessol, tcp->u_arg[1] + 1);
342                 if (tcp->u_arg[1] & 0x100) {
343                         /* mode */
344                         tprintf(", %#lo", tcp->u_arg[2]);
345                 }
346         }
347         return 0;
348 }
349
350 #endif
351
352 int
353 sys_creat(tcp)
354 struct tcb *tcp;
355 {
356         if (entering(tcp)) {
357                 printpath(tcp, tcp->u_arg[0]);
358                 tprintf(", %#lo", tcp->u_arg[1]);
359         }
360         return 0;
361 }
362
363 static const struct xlat access_flags[] = {
364         { F_OK,         "F_OK",         },
365         { R_OK,         "R_OK"          },
366         { W_OK,         "W_OK"          },
367         { X_OK,         "X_OK"          },
368 #ifdef EFF_ONLY_OK
369         { EFF_ONLY_OK,  "EFF_ONLY_OK"   },
370 #endif
371 #ifdef EX_OK
372         { EX_OK,        "EX_OK"         },
373 #endif
374         { 0,            NULL            },
375 };
376
377 int
378 sys_access(tcp)
379 struct tcb *tcp;
380 {
381         if (entering(tcp)) {
382                 printpath(tcp, tcp->u_arg[0]);
383                 tprintf(", ");
384                 printflags(access_flags, tcp->u_arg[1]);
385         }
386         return 0;
387 }
388
389 int
390 sys_umask(tcp)
391 struct tcb *tcp;
392 {
393         if (entering(tcp)) {
394                 tprintf("%#lo", tcp->u_arg[0]);
395         }
396         return RVAL_OCTAL;
397 }
398
399 static const struct xlat whence[] = {
400         { SEEK_SET,     "SEEK_SET"      },
401         { SEEK_CUR,     "SEEK_CUR"      },
402         { SEEK_END,     "SEEK_END"      },
403         { 0,            NULL            },
404 };
405
406 #ifndef HAVE_LONG_LONG_OFF_T
407 int
408 sys_lseek(tcp)
409 struct tcb *tcp;
410 {
411         off_t offset;
412         int _whence;
413
414         if (entering(tcp)) {
415                 tprintf("%ld, ", tcp->u_arg[0]);
416                 offset = tcp->u_arg[1];
417                 _whence = tcp->u_arg[2];
418                 if (_whence == SEEK_SET)
419                         tprintf("%lu, ", offset);
420                 else
421                         tprintf("%ld, ", offset);
422                 printxval(whence, _whence, "SEEK_???");
423         }
424         return RVAL_UDECIMAL;
425 }
426 #endif
427
428 #ifdef LINUX
429 int
430 sys_llseek (tcp)
431 struct tcb *tcp;
432 {
433     if (entering(tcp)) {
434         /*
435          * This one call takes explicitly two 32-bit arguments hi, lo,
436          * rather than one 64-bit argument for which LONG_LONG works
437          * appropriate for the native byte order.
438          */
439         if (tcp->u_arg[4] == SEEK_SET)
440             tprintf("%ld, %llu, ", tcp->u_arg[0],
441                     (((long long int) tcp->u_arg[1]) << 32
442                      | (unsigned long long) (unsigned) tcp->u_arg[2]));
443         else
444             tprintf("%ld, %lld, ", tcp->u_arg[0],
445                     (((long long int) tcp->u_arg[1]) << 32
446                      | (unsigned long long) (unsigned) tcp->u_arg[2]));
447     }
448     else {
449         long long int off;
450         if (syserror(tcp) || umove(tcp, tcp->u_arg[3], &off) < 0)
451             tprintf("%#lx, ", tcp->u_arg[3]);
452         else
453             tprintf("[%llu], ", off);
454         printxval(whence, tcp->u_arg[4], "SEEK_???");
455     }
456     return 0;
457 }
458
459 int
460 sys_readahead (tcp)
461 struct tcb *tcp;
462 {
463     if (entering(tcp)) {
464         tprintf("%ld, %lld, %ld", tcp->u_arg[0],
465 # if defined IA64 || defined X86_64 || defined ALPHA
466                 (long long int) tcp->u_arg[1], tcp->u_arg[2]
467 # else
468                 LONG_LONG(tcp->u_arg[1], tcp->u_arg[2]), tcp->u_arg[3]
469 # endif
470                 );
471     }
472     return 0;
473 }
474 #endif
475
476 #if _LFS64_LARGEFILE || HAVE_LONG_LONG_OFF_T
477 int
478 sys_lseek64 (tcp)
479 struct tcb *tcp;
480 {
481         if (entering(tcp)) {
482                 long long offset;
483                 ALIGN64 (tcp, 1);       /* FreeBSD aligns off_t args */
484                 offset = LONG_LONG(tcp->u_arg [1], tcp->u_arg[2]);
485                 if (tcp->u_arg[3] == SEEK_SET)
486                         tprintf("%ld, %llu, ", tcp->u_arg[0], offset);
487                 else
488                         tprintf("%ld, %lld, ", tcp->u_arg[0], offset);
489                 printxval(whence, tcp->u_arg[3], "SEEK_???");
490         }
491         return RVAL_LUDECIMAL;
492 }
493 #endif
494
495 #ifndef HAVE_LONG_LONG_OFF_T
496 int
497 sys_truncate(tcp)
498 struct tcb *tcp;
499 {
500         if (entering(tcp)) {
501                 printpath(tcp, tcp->u_arg[0]);
502                 tprintf(", %lu", tcp->u_arg[1]);
503         }
504         return 0;
505 }
506 #endif
507
508 #if _LFS64_LARGEFILE || HAVE_LONG_LONG_OFF_T
509 int
510 sys_truncate64(tcp)
511 struct tcb *tcp;
512 {
513         if (entering(tcp)) {
514                 ALIGN64 (tcp, 1);
515                 printpath(tcp, tcp->u_arg[0]);
516                 tprintf(", %llu", LONG_LONG(tcp->u_arg[1],tcp->u_arg[2]));
517         }
518         return 0;
519 }
520 #endif
521
522 #ifndef HAVE_LONG_LONG_OFF_T
523 int
524 sys_ftruncate(tcp)
525 struct tcb *tcp;
526 {
527         if (entering(tcp)) {
528                 tprintf("%ld, %lu", tcp->u_arg[0], tcp->u_arg[1]);
529         }
530         return 0;
531 }
532 #endif
533
534 #if _LFS64_LARGEFILE || HAVE_LONG_LONG_OFF_T
535 int
536 sys_ftruncate64(tcp)
537 struct tcb *tcp;
538 {
539         if (entering(tcp)) {
540                 ALIGN64 (tcp, 1);
541                 tprintf("%ld, %llu", tcp->u_arg[0],
542                         LONG_LONG(tcp->u_arg[1] ,tcp->u_arg[2]));
543         }
544         return 0;
545 }
546 #endif
547
548 /* several stats */
549
550 static const struct xlat modetypes[] = {
551         { S_IFREG,      "S_IFREG"       },
552         { S_IFSOCK,     "S_IFSOCK"      },
553         { S_IFIFO,      "S_IFIFO"       },
554         { S_IFLNK,      "S_IFLNK"       },
555         { S_IFDIR,      "S_IFDIR"       },
556         { S_IFBLK,      "S_IFBLK"       },
557         { S_IFCHR,      "S_IFCHR"       },
558         { 0,            NULL            },
559 };
560
561 static const char *
562 sprintmode(mode)
563 int mode;
564 {
565         static char buf[64];
566         const char *s;
567
568         if ((mode & S_IFMT) == 0)
569                 s = "";
570         else if ((s = xlookup(modetypes, mode & S_IFMT)) == NULL) {
571                 sprintf(buf, "%#o", mode);
572                 return buf;
573         }
574         sprintf(buf, "%s%s%s%s", s,
575                 (mode & S_ISUID) ? "|S_ISUID" : "",
576                 (mode & S_ISGID) ? "|S_ISGID" : "",
577                 (mode & S_ISVTX) ? "|S_ISVTX" : "");
578         mode &= ~(S_IFMT|S_ISUID|S_ISGID|S_ISVTX);
579         if (mode)
580                 sprintf(buf + strlen(buf), "|%#o", mode);
581         s = (*buf == '|') ? buf + 1 : buf;
582         return *s ? s : "0";
583 }
584
585 static char *
586 sprinttime(t)
587 time_t t;
588 {
589         struct tm *tmp;
590         static char buf[32];
591
592         if (t == 0) {
593                 sprintf(buf, "0");
594                 return buf;
595         }
596         tmp = localtime(&t);
597         sprintf(buf, "%02d/%02d/%02d-%02d:%02d:%02d",
598                 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
599                 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
600         return buf;
601 }
602
603 #ifdef LINUXSPARC
604 typedef struct {
605         int     tv_sec;
606         int     tv_nsec;
607 } timestruct_t;
608
609 struct solstat {
610         unsigned        st_dev;
611         int             st_pad1[3];     /* network id */
612         unsigned        st_ino;
613         unsigned        st_mode;
614         unsigned        st_nlink;
615         unsigned        st_uid;
616         unsigned        st_gid;
617         unsigned        st_rdev;
618         int             st_pad2[2];
619         int             st_size;
620         int             st_pad3;        /* st_size, off_t expansion */
621         timestruct_t    st_atime;
622         timestruct_t    st_mtime;
623         timestruct_t    st_ctime;
624         int             st_blksize;
625         int             st_blocks;
626         char            st_fstype[16];
627         int             st_pad4[8];     /* expansion area */
628 };
629
630 static void
631 printstatsol(tcp, addr)
632 struct tcb *tcp;
633 long addr;
634 {
635         struct solstat statbuf;
636
637         if (!addr) {
638                 tprintf("NULL");
639                 return;
640         }
641         if (syserror(tcp) || !verbose(tcp)) {
642                 tprintf("%#lx", addr);
643                 return;
644         }
645         if (umove(tcp, addr, &statbuf) < 0) {
646                 tprintf("{...}");
647                 return;
648         }
649         if (!abbrev(tcp)) {
650                 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%lu, st_mode=%s, ",
651                         (unsigned long) ((statbuf.st_dev >> 18) & 0x3fff),
652                         (unsigned long) (statbuf.st_dev & 0x3ffff),
653                         (unsigned long) statbuf.st_ino,
654                         sprintmode(statbuf.st_mode));
655                 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
656                         (unsigned long) statbuf.st_nlink,
657                         (unsigned long) statbuf.st_uid,
658                         (unsigned long) statbuf.st_gid);
659                 tprintf("st_blksize=%lu, ", (unsigned long) statbuf.st_blksize);
660                 tprintf("st_blocks=%lu, ", (unsigned long) statbuf.st_blocks);
661         }
662         else
663                 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
664         switch (statbuf.st_mode & S_IFMT) {
665         case S_IFCHR: case S_IFBLK:
666                 tprintf("st_rdev=makedev(%lu, %lu), ",
667                         (unsigned long) ((statbuf.st_rdev >> 18) & 0x3fff),
668                         (unsigned long) (statbuf.st_rdev & 0x3ffff));
669                 break;
670         default:
671                 tprintf("st_size=%u, ", statbuf.st_size);
672                 break;
673         }
674         if (!abbrev(tcp)) {
675                 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
676                 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
677                 tprintf("st_ctime=%s}", sprinttime(statbuf.st_ctime));
678         }
679         else
680                 tprintf("...}");
681 }
682
683 #if defined (SPARC64)
684 static void
685 printstat_sparc64(tcp, addr)
686 struct tcb *tcp;
687 long addr;
688 {
689         struct stat_sparc64 statbuf;
690
691         if (!addr) {
692                 tprintf("NULL");
693                 return;
694         }
695         if (syserror(tcp) || !verbose(tcp)) {
696                 tprintf("%#lx", addr);
697                 return;
698         }
699         if (umove(tcp, addr, &statbuf) < 0) {
700                 tprintf("{...}");
701                 return;
702         }
703
704         if (!abbrev(tcp)) {
705                 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%lu, st_mode=%s, ",
706                         (unsigned long) major(statbuf.st_dev),
707                         (unsigned long) minor(statbuf.st_dev),
708                         (unsigned long) statbuf.st_ino,
709                         sprintmode(statbuf.st_mode));
710                 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
711                         (unsigned long) statbuf.st_nlink,
712                         (unsigned long) statbuf.st_uid,
713                         (unsigned long) statbuf.st_gid);
714                 tprintf("st_blksize=%lu, ",
715                         (unsigned long) statbuf.st_blksize);
716                 tprintf("st_blocks=%lu, ",
717                         (unsigned long) statbuf.st_blocks);
718         }
719         else
720                 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
721         switch (statbuf.st_mode & S_IFMT) {
722         case S_IFCHR: case S_IFBLK:
723                 tprintf("st_rdev=makedev(%lu, %lu), ",
724                         (unsigned long) major(statbuf.st_rdev),
725                         (unsigned long) minor(statbuf.st_rdev));
726                 break;
727         default:
728                 tprintf("st_size=%lu, ", statbuf.st_size);
729                 break;
730         }
731         if (!abbrev(tcp)) {
732                 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
733                 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
734                 tprintf("st_ctime=%s", sprinttime(statbuf.st_ctime));
735                 tprintf("}");
736         }
737         else
738                 tprintf("...}");
739 }
740 #endif /* SPARC64 */
741 #endif /* LINUXSPARC */
742
743 const struct xlat fileflags[] = {
744 #ifdef FREEBSD
745         { UF_NODUMP,    "UF_NODUMP"     },
746         { UF_IMMUTABLE, "UF_IMMUTABLE"  },
747         { UF_APPEND,    "UF_APPEND"     },
748         { UF_OPAQUE,    "UF_OPAQUE"     },
749         { UF_NOUNLINK,  "UF_NOUNLINK"   },
750         { SF_ARCHIVED,  "SF_ARCHIVED"   },
751         { SF_IMMUTABLE, "SF_IMMUTABLE"  },
752         { SF_APPEND,    "SF_APPEND"     },
753         { SF_NOUNLINK,  "SF_NOUNLINK"   },
754 #elif UNIXWARE >= 2
755 #ifdef  _S_ISMLD
756         { _S_ISMLD,     "_S_ISMLD"      },
757 #endif
758 #ifdef  _S_ISMOUNTED
759         { _S_ISMOUNTED, "_S_ISMOUNTED"  },
760 #endif
761 #endif
762         { 0,            NULL            },
763 };
764
765 #ifdef FREEBSD
766 int
767 sys_chflags(tcp)
768 struct tcb *tcp;
769 {
770         if (entering(tcp)) {
771                 printpath(tcp, tcp->u_arg[0]);
772                 tprintf(", ");
773                 if (tcp->u_arg[1])
774                         printflags(fileflags, tcp->u_arg[1]);
775                 else
776                         tprintf("0");
777         }
778         return 0;
779 }
780
781 int
782 sys_fchflags(tcp)
783 struct tcb *tcp;
784 {
785         if (entering(tcp)) {
786                 tprintf("%ld, ", tcp->u_arg[0]);
787                 if (tcp->u_arg[1])
788                         printflags(fileflags, tcp->u_arg[1]);
789                 else
790                         tprintf("0");
791         }
792         return 0;
793 }
794 #endif
795
796 #ifndef HAVE_LONG_LONG_OFF_T
797 static void
798 realprintstat(tcp, statbuf)
799 struct tcb *tcp;
800 struct stat *statbuf;
801 {
802     if (!abbrev(tcp)) {
803             tprintf("{st_dev=makedev(%lu, %lu), st_ino=%lu, st_mode=%s, ",
804                     (unsigned long) major(statbuf->st_dev),
805                     (unsigned long) minor(statbuf->st_dev),
806                     (unsigned long) statbuf->st_ino,
807                     sprintmode(statbuf->st_mode));
808             tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
809                     (unsigned long) statbuf->st_nlink,
810                     (unsigned long) statbuf->st_uid,
811                     (unsigned long) statbuf->st_gid);
812 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
813             tprintf("st_blksize=%lu, ", (unsigned long) statbuf->st_blksize);
814 #endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
815 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
816             tprintf("st_blocks=%lu, ", (unsigned long) statbuf->st_blocks);
817 #endif /* HAVE_STRUCT_STAT_ST_BLOCKS */
818     }
819     else
820             tprintf("{st_mode=%s, ", sprintmode(statbuf->st_mode));
821     switch (statbuf->st_mode & S_IFMT) {
822     case S_IFCHR: case S_IFBLK:
823 #ifdef HAVE_STRUCT_STAT_ST_RDEV
824             tprintf("st_rdev=makedev(%lu, %lu), ",
825                     (unsigned long) major(statbuf->st_rdev),
826                     (unsigned long) minor(statbuf->st_rdev));
827 #else /* !HAVE_STRUCT_STAT_ST_RDEV */
828             tprintf("st_size=makedev(%lu, %lu), ",
829                     (unsigned long) major(statbuf->st_size),
830                     (unsigned long) minor(statbuf->st_size));
831 #endif /* !HAVE_STRUCT_STAT_ST_RDEV */
832             break;
833     default:
834             tprintf("st_size=%lu, ", statbuf->st_size);
835             break;
836     }
837     if (!abbrev(tcp)) {
838             tprintf("st_atime=%s, ", sprinttime(statbuf->st_atime));
839             tprintf("st_mtime=%s, ", sprinttime(statbuf->st_mtime));
840             tprintf("st_ctime=%s", sprinttime(statbuf->st_ctime));
841 #if HAVE_STRUCT_STAT_ST_FLAGS
842                 tprintf(", st_flags=");
843                 if (statbuf->st_flags) {
844                         printflags(fileflags, statbuf->st_flags);
845                 } else
846                         tprintf("0");
847 #endif
848 #if HAVE_STRUCT_STAT_ST_ACLCNT
849                 tprintf(", st_aclcnt=%d", statbuf->st_aclcnt);
850 #endif
851 #if HAVE_STRUCT_STAT_ST_LEVEL
852                 tprintf(", st_level=%ld", statbuf->st_level);
853 #endif
854 #if HAVE_STRUCT_STAT_ST_FSTYPE
855                 tprintf(", st_fstype=%.*s",
856                         (int) sizeof statbuf->st_fstype, statbuf->st_fstype);
857 #endif
858 #if HAVE_STRUCT_STAT_ST_GEN
859                 tprintf(", st_gen=%u", statbuf->st_gen);
860 #endif
861                 tprintf("}");
862     }
863     else
864             tprintf("...}");
865 }
866
867
868 static void
869 printstat(tcp, addr)
870 struct tcb *tcp;
871 long addr;
872 {
873         struct stat statbuf;
874
875 #ifdef LINUXSPARC
876         if (current_personality == 1) {
877                 printstatsol(tcp, addr);
878                 return;
879         }
880 #ifdef SPARC64
881         else if (current_personality == 2) {
882                 printstat_sparc64(tcp, addr);
883                 return;
884         }
885 #endif
886 #endif /* LINUXSPARC */
887
888         if (!addr) {
889                 tprintf("NULL");
890                 return;
891         }
892         if (syserror(tcp) || !verbose(tcp)) {
893                 tprintf("%#lx", addr);
894                 return;
895         }
896         if (umove(tcp, addr, &statbuf) < 0) {
897                 tprintf("{...}");
898                 return;
899         }
900
901         realprintstat(tcp, &statbuf);
902 }
903 #endif  /* !HAVE_LONG_LONG_OFF_T */
904
905 #ifdef HAVE_STAT64
906 static void
907 printstat64(tcp, addr)
908 struct tcb *tcp;
909 long addr;
910 {
911         struct stat64 statbuf;
912
913 #ifdef LINUXSPARC
914         if (current_personality == 1) {
915                 printstatsol(tcp, addr);
916                 return;
917         }
918 #ifdef SPARC64
919         else if (current_personality == 2) {
920                 printstat_sparc64(tcp, addr);
921                 return;
922         }
923 #endif
924 #endif /* LINUXSPARC */
925
926         if (!addr) {
927                 tprintf("NULL");
928                 return;
929         }
930         if (syserror(tcp) || !verbose(tcp)) {
931                 tprintf("%#lx", addr);
932                 return;
933         }
934         if (umove(tcp, addr, &statbuf) < 0) {
935                 tprintf("{...}");
936                 return;
937         }
938
939         if (!abbrev(tcp)) {
940 #ifdef HAVE_LONG_LONG
941                 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%llu, st_mode=%s, ",
942 #else
943                 tprintf("{st_dev=makedev(%lu, %lu), st_ino=%lu, st_mode=%s, ",
944 #endif
945                         (unsigned long) major(statbuf.st_dev),
946                         (unsigned long) minor(statbuf.st_dev),
947 #ifdef HAVE_LONG_LONG
948                         (unsigned long long) statbuf.st_ino,
949 #else
950                         (unsigned long) statbuf.st_ino,
951 #endif
952                         sprintmode(statbuf.st_mode));
953                 tprintf("st_nlink=%lu, st_uid=%lu, st_gid=%lu, ",
954                         (unsigned long) statbuf.st_nlink,
955                         (unsigned long) statbuf.st_uid,
956                         (unsigned long) statbuf.st_gid);
957 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
958                 tprintf("st_blksize=%lu, ",
959                         (unsigned long) statbuf.st_blksize);
960 #endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
961 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
962                 tprintf("st_blocks=%lu, ", (unsigned long) statbuf.st_blocks);
963 #endif /* HAVE_STRUCT_STAT_ST_BLOCKS */
964         }
965         else
966                 tprintf("{st_mode=%s, ", sprintmode(statbuf.st_mode));
967         switch (statbuf.st_mode & S_IFMT) {
968         case S_IFCHR: case S_IFBLK:
969 #ifdef HAVE_STRUCT_STAT_ST_RDEV
970                 tprintf("st_rdev=makedev(%lu, %lu), ",
971                         (unsigned long) major(statbuf.st_rdev),
972                         (unsigned long) minor(statbuf.st_rdev));
973 #else /* !HAVE_STRUCT_STAT_ST_RDEV */
974                 tprintf("st_size=makedev(%lu, %lu), ",
975                         (unsigned long) major(statbuf.st_size),
976                         (unsigned long) minor(statbuf.st_size));
977 #endif /* !HAVE_STRUCT_STAT_ST_RDEV */
978                 break;
979         default:
980                 tprintf("st_size=%llu, ", statbuf.st_size);
981                 break;
982         }
983         if (!abbrev(tcp)) {
984                 tprintf("st_atime=%s, ", sprinttime(statbuf.st_atime));
985                 tprintf("st_mtime=%s, ", sprinttime(statbuf.st_mtime));
986                 tprintf("st_ctime=%s", sprinttime(statbuf.st_ctime));
987 #if HAVE_STRUCT_STAT_ST_FLAGS
988                 tprintf(", st_flags=");
989                 if (statbuf.st_flags) {
990                         printflags(fileflags, statbuf.st_flags);
991                 } else
992                         tprintf("0");
993 #endif
994 #if HAVE_STRUCT_STAT_ST_ACLCNT
995                 tprintf(", st_aclcnt=%d", statbuf.st_aclcnt);
996 #endif
997 #if HAVE_STRUCT_STAT_ST_LEVEL
998                 tprintf(", st_level=%ld", statbuf.st_level);
999 #endif
1000 #if HAVE_STRUCT_STAT_ST_FSTYPE
1001                 tprintf(", st_fstype=%.*s",
1002                         (int) sizeof statbuf.st_fstype, statbuf.st_fstype);
1003 #endif
1004 #if HAVE_STRUCT_STAT_ST_GEN
1005                 tprintf(", st_gen=%u", statbuf.st_gen);
1006 #endif
1007                 tprintf("}");
1008         }
1009         else
1010                 tprintf("...}");
1011 }
1012 #endif /* HAVE_STAT64 */
1013
1014 #if defined(LINUX) && defined(HAVE_STRUCT___OLD_KERNEL_STAT)
1015 static void
1016 convertoldstat(oldbuf, newbuf)
1017 const struct __old_kernel_stat *oldbuf;
1018 struct stat *newbuf;
1019 {
1020     newbuf->st_dev=oldbuf->st_dev;
1021     newbuf->st_ino=oldbuf->st_ino;
1022     newbuf->st_mode=oldbuf->st_mode;
1023     newbuf->st_nlink=oldbuf->st_nlink;
1024     newbuf->st_uid=oldbuf->st_uid;
1025     newbuf->st_gid=oldbuf->st_gid;
1026     newbuf->st_rdev=oldbuf->st_rdev;
1027     newbuf->st_size=oldbuf->st_size;
1028     newbuf->st_atime=oldbuf->st_atime;
1029     newbuf->st_mtime=oldbuf->st_mtime;
1030     newbuf->st_ctime=oldbuf->st_ctime;
1031     newbuf->st_blksize=0;       /* not supported in old_stat */
1032     newbuf->st_blocks=0;                /* not supported in old_stat */
1033 }
1034
1035
1036 static void
1037 printoldstat(tcp, addr)
1038 struct tcb *tcp;
1039 long addr;
1040 {
1041         struct __old_kernel_stat statbuf;
1042         struct stat newstatbuf;
1043
1044 #ifdef LINUXSPARC
1045         if (current_personality == 1) {
1046                 printstatsol(tcp, addr);
1047                 return;
1048         }
1049 #endif /* LINUXSPARC */
1050
1051         if (!addr) {
1052                 tprintf("NULL");
1053                 return;
1054         }
1055         if (syserror(tcp) || !verbose(tcp)) {
1056                 tprintf("%#lx", addr);
1057                 return;
1058         }
1059         if (umove(tcp, addr, &statbuf) < 0) {
1060                 tprintf("{...}");
1061                 return;
1062         }
1063
1064         convertoldstat(&statbuf, &newstatbuf);
1065         realprintstat(tcp, &newstatbuf);
1066 }
1067 #endif /* LINUX && !IA64 && !HPPA && !X86_64 && !S390 && !S390X */
1068
1069 #ifndef HAVE_LONG_LONG_OFF_T
1070 int
1071 sys_stat(tcp)
1072 struct tcb *tcp;
1073 {
1074         if (entering(tcp)) {
1075                 printpath(tcp, tcp->u_arg[0]);
1076                 tprintf(", ");
1077         } else {
1078                 printstat(tcp, tcp->u_arg[1]);
1079         }
1080         return 0;
1081 }
1082 #endif
1083
1084 int
1085 sys_stat64(tcp)
1086 struct tcb *tcp;
1087 {
1088 #ifdef HAVE_STAT64
1089         if (entering(tcp)) {
1090                 printpath(tcp, tcp->u_arg[0]);
1091                 tprintf(", ");
1092         } else {
1093                 printstat64(tcp, tcp->u_arg[1]);
1094         }
1095         return 0;
1096 #else
1097         return printargs(tcp);
1098 #endif
1099 }
1100
1101 #if defined(LINUX) && defined(HAVE_STRUCT___OLD_KERNEL_STAT)
1102 int
1103 sys_oldstat(tcp)
1104 struct tcb *tcp;
1105 {
1106         if (entering(tcp)) {
1107                 printpath(tcp, tcp->u_arg[0]);
1108                 tprintf(", ");
1109         } else {
1110                 printoldstat(tcp, tcp->u_arg[1]);
1111         }
1112         return 0;
1113 }
1114 #endif /* LINUX && HAVE_STRUCT___OLD_KERNEL_STAT */
1115
1116 #ifndef HAVE_LONG_LONG_OFF_T
1117 int
1118 sys_fstat(tcp)
1119 struct tcb *tcp;
1120 {
1121         if (entering(tcp))
1122                 tprintf("%ld, ", tcp->u_arg[0]);
1123         else {
1124                 printstat(tcp, tcp->u_arg[1]);
1125         }
1126         return 0;
1127 }
1128 #endif
1129
1130 int
1131 sys_fstat64(tcp)
1132 struct tcb *tcp;
1133 {
1134 #ifdef HAVE_STAT64
1135         if (entering(tcp))
1136                 tprintf("%ld, ", tcp->u_arg[0]);
1137         else {
1138                 printstat64(tcp, tcp->u_arg[1]);
1139         }
1140         return 0;
1141 #else
1142         return printargs(tcp);
1143 #endif
1144 }
1145
1146 #if defined(LINUX) && defined(HAVE_STRUCT___OLD_KERNEL_STAT)
1147 int
1148 sys_oldfstat(tcp)
1149 struct tcb *tcp;
1150 {
1151         if (entering(tcp))
1152                 tprintf("%ld, ", tcp->u_arg[0]);
1153         else {
1154                 printoldstat(tcp, tcp->u_arg[1]);
1155         }
1156         return 0;
1157 }
1158 #endif /* LINUX && HAVE_STRUCT___OLD_KERNEL_STAT */
1159
1160 #ifndef HAVE_LONG_LONG_OFF_T
1161 int
1162 sys_lstat(tcp)
1163 struct tcb *tcp;
1164 {
1165         if (entering(tcp)) {
1166                 printpath(tcp, tcp->u_arg[0]);
1167                 tprintf(", ");
1168         } else {
1169                 printstat(tcp, tcp->u_arg[1]);
1170         }
1171         return 0;
1172 }
1173 #endif
1174
1175 int
1176 sys_lstat64(tcp)
1177 struct tcb *tcp;
1178 {
1179 #ifdef HAVE_STAT64
1180         if (entering(tcp)) {
1181                 printpath(tcp, tcp->u_arg[0]);
1182                 tprintf(", ");
1183         } else {
1184                 printstat64(tcp, tcp->u_arg[1]);
1185         }
1186         return 0;
1187 #else
1188         return printargs(tcp);
1189 #endif
1190 }
1191
1192 #if defined(LINUX) && defined(HAVE_STRUCT___OLD_KERNEL_STAT)
1193 int
1194 sys_oldlstat(tcp)
1195 struct tcb *tcp;
1196 {
1197         if (entering(tcp)) {
1198                 printpath(tcp, tcp->u_arg[0]);
1199                 tprintf(", ");
1200         } else {
1201                 printoldstat(tcp, tcp->u_arg[1]);
1202         }
1203         return 0;
1204 }
1205 #endif /* LINUX && HAVE_STRUCT___OLD_KERNEL_STAT */
1206
1207
1208 #if defined(SVR4) || defined(LINUXSPARC)
1209
1210 int
1211 sys_xstat(tcp)
1212 struct tcb *tcp;
1213 {
1214         if (entering(tcp)) {
1215                 tprintf("%ld, ", tcp->u_arg[0]);
1216                 printpath(tcp, tcp->u_arg[1]);
1217                 tprintf(", ");
1218         } else {
1219 #ifdef _STAT64_VER
1220                 if (tcp->u_arg[0] == _STAT64_VER)
1221                         printstat64 (tcp, tcp->u_arg[2]);
1222                 else
1223 #endif
1224                 printstat(tcp, tcp->u_arg[2]);
1225         }
1226         return 0;
1227 }
1228
1229 int
1230 sys_fxstat(tcp)
1231 struct tcb *tcp;
1232 {
1233         if (entering(tcp))
1234                 tprintf("%ld, %ld, ", tcp->u_arg[0], tcp->u_arg[1]);
1235         else {
1236 #ifdef _STAT64_VER
1237                 if (tcp->u_arg[0] == _STAT64_VER)
1238                         printstat64 (tcp, tcp->u_arg[2]);
1239                 else
1240 #endif
1241                 printstat(tcp, tcp->u_arg[2]);
1242         }
1243         return 0;
1244 }
1245
1246 int
1247 sys_lxstat(tcp)
1248 struct tcb *tcp;
1249 {
1250         if (entering(tcp)) {
1251                 tprintf("%ld, ", tcp->u_arg[0]);
1252                 printpath(tcp, tcp->u_arg[1]);
1253                 tprintf(", ");
1254         } else {
1255 #ifdef _STAT64_VER
1256                 if (tcp->u_arg[0] == _STAT64_VER)
1257                         printstat64 (tcp, tcp->u_arg[2]);
1258                 else
1259 #endif
1260                 printstat(tcp, tcp->u_arg[2]);
1261         }
1262         return 0;
1263 }
1264
1265 int
1266 sys_xmknod(tcp)
1267 struct tcb *tcp;
1268 {
1269         int mode = tcp->u_arg[2];
1270
1271         if (entering(tcp)) {
1272                 tprintf("%ld, ", tcp->u_arg[0]);
1273                 printpath(tcp, tcp->u_arg[1]);
1274                 tprintf(", %s", sprintmode(mode));
1275                 switch (mode & S_IFMT) {
1276                 case S_IFCHR: case S_IFBLK:
1277 #ifdef LINUXSPARC
1278                         tprintf(", makedev(%lu, %lu)",
1279                                 (unsigned long) ((tcp->u_arg[3] >> 18) & 0x3fff),
1280                                 (unsigned long) (tcp->u_arg[3] & 0x3ffff));
1281 #else
1282                         tprintf(", makedev(%lu, %lu)",
1283                                 (unsigned long) major(tcp->u_arg[3]),
1284                                 (unsigned long) minor(tcp->u_arg[3]));
1285 #endif
1286                         break;
1287                 default:
1288                         break;
1289                 }
1290         }
1291         return 0;
1292 }
1293
1294 #ifdef HAVE_SYS_ACL_H
1295
1296 #include <sys/acl.h>
1297
1298 const struct xlat aclcmds[] = {
1299 #ifdef SETACL
1300         { SETACL,       "SETACL"        },
1301 #endif
1302 #ifdef GETACL
1303         { GETACL,       "GETACL"        },
1304 #endif
1305 #ifdef GETACLCNT
1306         { GETACLCNT,    "GETACLCNT"     },
1307 #endif
1308 #ifdef ACL_GET
1309         { ACL_GET,      "ACL_GET"       },
1310 #endif
1311 #ifdef ACL_SET
1312         { ACL_SET,      "ACL_SET"       },
1313 #endif
1314 #ifdef ACL_CNT
1315         { ACL_CNT,      "ACL_CNT"       },
1316 #endif
1317         { 0,            NULL            },
1318 };
1319
1320 int
1321 sys_acl(tcp)
1322 struct tcb *tcp;
1323 {
1324         if (entering(tcp)) {
1325                 printpath(tcp, tcp->u_arg[0]);
1326                 tprintf(", ");
1327                 printxval(aclcmds, tcp->u_arg[1], "???ACL???");
1328                 tprintf(", %ld", tcp->u_arg[2]);
1329                 /*
1330                  * FIXME - dump out the list of aclent_t's pointed to
1331                  * by "tcp->u_arg[3]" if it's not NULL.
1332                  */
1333                 if (tcp->u_arg[3])
1334                         tprintf(", %#lx", tcp->u_arg[3]);
1335                 else
1336                         tprintf(", NULL");
1337         }
1338         return 0;
1339 }
1340
1341
1342 int
1343 sys_facl(tcp)
1344 struct tcb *tcp;
1345 {
1346         if (entering(tcp)) {
1347                 tprintf("%ld, ", tcp->u_arg[0]);
1348                 printxval(aclcmds, tcp->u_arg[1], "???ACL???");
1349                 tprintf(", %ld", tcp->u_arg[2]);
1350                 /*
1351                  * FIXME - dump out the list of aclent_t's pointed to
1352                  * by "tcp->u_arg[3]" if it's not NULL.
1353                  */
1354                 if (tcp->u_arg[3])
1355                         tprintf(", %#lx", tcp->u_arg[3]);
1356                 else
1357                         tprintf(", NULL");
1358         }
1359         return 0;
1360 }
1361
1362
1363 const struct xlat aclipc[] = {
1364 #ifdef IPC_SHM
1365         { IPC_SHM,      "IPC_SHM"       },
1366 #endif
1367 #ifdef IPC_SEM
1368         { IPC_SEM,      "IPC_SEM"       },
1369 #endif
1370 #ifdef IPC_MSG
1371         { IPC_MSG,      "IPC_MSG"       },
1372 #endif
1373         { 0,            NULL            },
1374 };
1375
1376
1377 int
1378 sys_aclipc(tcp)
1379 struct tcb *tcp;
1380 {
1381         if (entering(tcp)) {
1382                 printxval(aclipc, tcp->u_arg[0], "???IPC???");
1383                 tprintf(", %#lx, ", tcp->u_arg[1]);
1384                 printxval(aclcmds, tcp->u_arg[2], "???ACL???");
1385                 tprintf(", %ld", tcp->u_arg[3]);
1386                 /*
1387                  * FIXME - dump out the list of aclent_t's pointed to
1388                  * by "tcp->u_arg[4]" if it's not NULL.
1389                  */
1390                 if (tcp->u_arg[4])
1391                         tprintf(", %#lx", tcp->u_arg[4]);
1392                 else
1393                         tprintf(", NULL");
1394         }
1395         return 0;
1396 }
1397
1398
1399
1400 #endif /* HAVE_SYS_ACL_H */
1401
1402 #endif /* SVR4 || LINUXSPARC */
1403
1404 #ifdef LINUX
1405
1406 static const struct xlat fsmagic[] = {
1407         { 0x73757245,   "CODA_SUPER_MAGIC"      },
1408         { 0x012ff7b7,   "COH_SUPER_MAGIC"       },
1409         { 0x1373,       "DEVFS_SUPER_MAGIC"     },
1410         { 0x1cd1,       "DEVPTS_SUPER_MAGIC"    },
1411         { 0x414A53,     "EFS_SUPER_MAGIC"       },
1412         { 0xef51,       "EXT2_OLD_SUPER_MAGIC"  },
1413         { 0xef53,       "EXT2_SUPER_MAGIC"      },
1414         { 0x137d,       "EXT_SUPER_MAGIC"       },
1415         { 0xf995e849,   "HPFS_SUPER_MAGIC"      },
1416         { 0x9660,       "ISOFS_SUPER_MAGIC"     },
1417         { 0x137f,       "MINIX_SUPER_MAGIC"     },
1418         { 0x138f,       "MINIX_SUPER_MAGIC2"    },
1419         { 0x2468,       "MINIX2_SUPER_MAGIC"    },
1420         { 0x2478,       "MINIX2_SUPER_MAGIC2"   },
1421         { 0x4d44,       "MSDOS_SUPER_MAGIC"     },
1422         { 0x564c,       "NCP_SUPER_MAGIC"       },
1423         { 0x6969,       "NFS_SUPER_MAGIC"       },
1424         { 0x9fa0,       "PROC_SUPER_MAGIC"      },
1425         { 0x002f,       "QNX4_SUPER_MAGIC"      },
1426         { 0x52654973,   "REISERFS_SUPER_MAGIC"  },
1427         { 0x02011994,   "SHMFS_SUPER_MAGIC"     },
1428         { 0x517b,       "SMB_SUPER_MAGIC"       },
1429         { 0x012ff7b6,   "SYSV2_SUPER_MAGIC"     },
1430         { 0x012ff7b5,   "SYSV4_SUPER_MAGIC"     },
1431         { 0x00011954,   "UFS_MAGIC"             },
1432         { 0x54190100,   "UFS_CIGAM"             },
1433         { 0x012ff7b4,   "XENIX_SUPER_MAGIC"     },
1434         { 0x012fd16d,   "XIAFS_SUPER_MAGIC"     },
1435         { 0x62656572,   "SYSFS_MAGIC"           },
1436         { 0,            NULL                    },
1437 };
1438
1439 #endif /* LINUX */
1440
1441 #ifndef SVR4
1442
1443 static const char *
1444 sprintfstype(magic)
1445 int magic;
1446 {
1447         static char buf[32];
1448 #ifdef LINUX
1449         const char *s;
1450
1451         s = xlookup(fsmagic, magic);
1452         if (s) {
1453                 sprintf(buf, "\"%s\"", s);
1454                 return buf;
1455         }
1456 #endif /* LINUX */
1457         sprintf(buf, "%#x", magic);
1458         return buf;
1459 }
1460
1461 static void
1462 printstatfs(tcp, addr)
1463 struct tcb *tcp;
1464 long addr;
1465 {
1466         struct statfs statbuf;
1467
1468         if (syserror(tcp) || !verbose(tcp)) {
1469                 tprintf("%#lx", addr);
1470                 return;
1471         }
1472         if (umove(tcp, addr, &statbuf) < 0) {
1473                 tprintf("{...}");
1474                 return;
1475         }
1476 #ifdef ALPHA
1477
1478         tprintf("{f_type=%s, f_fbsize=%u, f_blocks=%u, f_bfree=%u, ",
1479                 sprintfstype(statbuf.f_type),
1480                 statbuf.f_bsize, statbuf.f_blocks, statbuf.f_bfree);
1481         tprintf("f_bavail=%u, f_files=%u, f_ffree=%u, f_fsid={%d, %d}, f_namelen=%u",
1482                 statbuf.f_bavail,statbuf.f_files, statbuf.f_ffree,
1483                 statbuf.f_fsid.__val[0], statbuf.f_fsid.__val[1],
1484                 statbuf.f_namelen);
1485 #else /* !ALPHA */
1486         tprintf("{f_type=%s, f_bsize=%lu, f_blocks=%lu, f_bfree=%lu, ",
1487                 sprintfstype(statbuf.f_type),
1488                 (unsigned long)statbuf.f_bsize,
1489                 (unsigned long)statbuf.f_blocks,
1490                 (unsigned long)statbuf.f_bfree);
1491         tprintf("f_bavail=%lu, f_files=%lu, f_ffree=%lu, f_fsid={%d, %d}",
1492                 (unsigned long)statbuf.f_bavail,
1493                 (unsigned long)statbuf.f_files,
1494                 (unsigned long)statbuf.f_ffree,
1495                 statbuf.f_fsid.__val[0], statbuf.f_fsid.__val[1]);
1496 #ifdef LINUX
1497         tprintf(", f_namelen=%lu", (unsigned long)statbuf.f_namelen);
1498 #endif /* LINUX */
1499 #endif /* !ALPHA */
1500 #ifdef _STATFS_F_FRSIZE
1501         tprintf(", f_frsize=%lu", (unsigned long)statbuf.f_frsize);
1502 #endif
1503         tprintf("}");
1504 }
1505
1506 int
1507 sys_statfs(tcp)
1508 struct tcb *tcp;
1509 {
1510         if (entering(tcp)) {
1511                 printpath(tcp, tcp->u_arg[0]);
1512                 tprintf(", ");
1513         } else {
1514                 printstatfs(tcp, tcp->u_arg[1]);
1515         }
1516         return 0;
1517 }
1518
1519 int
1520 sys_fstatfs(tcp)
1521 struct tcb *tcp;
1522 {
1523         if (entering(tcp)) {
1524                 tprintf("%lu, ", tcp->u_arg[0]);
1525         } else {
1526                 printstatfs(tcp, tcp->u_arg[1]);
1527         }
1528         return 0;
1529 }
1530
1531 #ifdef LINUX
1532 static void
1533 printstatfs64(tcp, addr)
1534 struct tcb *tcp;
1535 long addr;
1536 {
1537         struct statfs64 statbuf;
1538
1539         if (syserror(tcp) || !verbose(tcp)) {
1540                 tprintf("%#lx", addr);
1541                 return;
1542         }
1543         if (umove(tcp, addr, &statbuf) < 0) {
1544                 tprintf("{...}");
1545                 return;
1546         }
1547 #ifdef ALPHA
1548
1549         tprintf("{f_type=%s, f_fbsize=%u, f_blocks=%u, f_bfree=%u, ",
1550                 sprintfstype(statbuf.f_type),
1551                 statbuf.f_bsize, statbuf.f_blocks, statbuf.f_bfree);
1552         tprintf("f_bavail=%u, f_files=%u, f_ffree=%u, f_fsid={%d, %d}, f_namelen=%u",
1553                 statbuf.f_bavail,statbuf.f_files, statbuf.f_ffree,
1554                 statbuf.f_fsid.__val[0], statbuf.f_fsid.__val[1],
1555                 statbuf.f_namelen);
1556 #else /* !ALPHA */
1557         tprintf("{f_type=%s, f_bsize=%lu, f_blocks=%lu, f_bfree=%lu, ",
1558                 sprintfstype(statbuf.f_type),
1559                 (unsigned long)statbuf.f_bsize,
1560                 (unsigned long)statbuf.f_blocks,
1561                 (unsigned long)statbuf.f_bfree);
1562         tprintf("f_bavail=%lu, f_files=%lu, f_ffree=%lu, f_fsid={%d, %d}",
1563                 (unsigned long)statbuf.f_bavail,
1564                 (unsigned long)statbuf.f_files,
1565                 (unsigned long)statbuf.f_ffree,
1566                 statbuf.f_fsid.__val[0], statbuf.f_fsid.__val[1]);
1567         tprintf(", f_namelen=%lu", (unsigned long)statbuf.f_namelen);
1568 #endif /* !ALPHA */
1569 #ifdef _STATFS_F_FRSIZE
1570         tprintf(", f_frsize=%lu", (unsigned long)statbuf.f_frsize);
1571 #endif
1572         tprintf("}");
1573 }
1574
1575 int
1576 sys_statfs64(tcp)
1577 struct tcb *tcp;
1578 {
1579         if (entering(tcp)) {
1580                 printpath(tcp, tcp->u_arg[0]);
1581                 tprintf(", %lu, ", tcp->u_arg[1]);
1582         } else {
1583                 if (tcp->u_arg[1] == sizeof (struct statfs64))
1584                         printstatfs64(tcp, tcp->u_arg[2]);
1585                 else
1586                         tprintf("{???}");
1587         }
1588         return 0;
1589 }
1590
1591 int
1592 sys_fstatfs64(tcp)
1593 struct tcb *tcp;
1594 {
1595         if (entering(tcp)) {
1596                 tprintf("%lu, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
1597         } else {
1598                 if (tcp->u_arg[1] == sizeof (struct statfs64))
1599                         printstatfs64(tcp, tcp->u_arg[2]);
1600                 else
1601                         tprintf("{???}");
1602         }
1603         return 0;
1604 }
1605 #endif
1606
1607 #if defined(LINUX) && defined(__alpha)
1608
1609 int
1610 osf_statfs(tcp)
1611 struct tcb *tcp;
1612 {
1613         if (entering(tcp)) {
1614                 printpath(tcp, tcp->u_arg[0]);
1615                 tprintf(", ");
1616         } else {
1617                 printstatfs(tcp, tcp->u_arg[1]);
1618                 tprintf(", %lu", tcp->u_arg[2]);
1619         }
1620         return 0;
1621 }
1622
1623 int
1624 osf_fstatfs(tcp)
1625 struct tcb *tcp;
1626 {
1627         if (entering(tcp)) {
1628                 tprintf("%lu, ", tcp->u_arg[0]);
1629         } else {
1630                 printstatfs(tcp, tcp->u_arg[1]);
1631                 tprintf(", %lu", tcp->u_arg[2]);
1632         }
1633         return 0;
1634 }
1635 #endif /* LINUX && __alpha */
1636
1637 #endif /* !SVR4 */
1638
1639 #ifdef SUNOS4
1640
1641 int
1642 sys_ustat(tcp)
1643 struct tcb *tcp;
1644 {
1645         struct ustat statbuf;
1646
1647         if (entering(tcp)) {
1648                 tprintf("makedev(%lu, %lu), ",
1649                                 (long) major(tcp->u_arg[0]),
1650                                 (long) minor(tcp->u_arg[0]));
1651         }
1652         else {
1653                 if (syserror(tcp) || !verbose(tcp))
1654                         tprintf("%#lx", tcp->u_arg[1]);
1655                 else if (umove(tcp, tcp->u_arg[1], &statbuf) < 0)
1656                         tprintf("{...}");
1657                 else {
1658                         tprintf("{f_tfree=%lu, f_tinode=%lu, ",
1659                                 statbuf.f_tfree, statbuf.f_tinode);
1660                         tprintf("f_fname=\"%.*s\", ",
1661                                 (int) sizeof(statbuf.f_fname),
1662                                 statbuf.f_fname);
1663                         tprintf("f_fpack=\"%.*s\"}",
1664                                 (int) sizeof(statbuf.f_fpack),
1665                                 statbuf.f_fpack);
1666                 }
1667         }
1668         return 0;
1669 }
1670
1671 #endif /* SUNOS4 */
1672
1673 int
1674 sys_pivotroot(tcp)
1675 struct tcb *tcp;
1676 {
1677         if (entering(tcp)) {
1678                 printpath(tcp, tcp->u_arg[0]);
1679                 tprintf(", ");
1680                 printpath(tcp, tcp->u_arg[1]);
1681         }
1682         return 0;
1683 }
1684
1685
1686 /* directory */
1687 int
1688 sys_chdir(tcp)
1689 struct tcb *tcp;
1690 {
1691         if (entering(tcp)) {
1692                 printpath(tcp, tcp->u_arg[0]);
1693         }
1694         return 0;
1695 }
1696
1697 int
1698 sys_mkdir(tcp)
1699 struct tcb *tcp;
1700 {
1701         if (entering(tcp)) {
1702                 printpath(tcp, tcp->u_arg[0]);
1703                 tprintf(", %#lo", tcp->u_arg[1]);
1704         }
1705         return 0;
1706 }
1707
1708 int
1709 sys_rmdir(tcp)
1710 struct tcb *tcp;
1711 {
1712         if (entering(tcp)) {
1713                 printpath(tcp, tcp->u_arg[0]);
1714         }
1715         return 0;
1716 }
1717
1718 int
1719 sys_fchdir(tcp)
1720 struct tcb *tcp;
1721 {
1722         if (entering(tcp)) {
1723                 tprintf("%ld", tcp->u_arg[0]);
1724         }
1725         return 0;
1726 }
1727
1728 int
1729 sys_chroot(tcp)
1730 struct tcb *tcp;
1731 {
1732         if (entering(tcp)) {
1733                 printpath(tcp, tcp->u_arg[0]);
1734         }
1735         return 0;
1736 }
1737
1738 int
1739 sys_fchroot(tcp)
1740 struct tcb *tcp;
1741 {
1742         if (entering(tcp)) {
1743                 tprintf("%ld", tcp->u_arg[0]);
1744         }
1745         return 0;
1746 }
1747
1748 int
1749 sys_link(tcp)
1750 struct tcb *tcp;
1751 {
1752         if (entering(tcp)) {
1753                 printpath(tcp, tcp->u_arg[0]);
1754                 tprintf(", ");
1755                 printpath(tcp, tcp->u_arg[1]);
1756         }
1757         return 0;
1758 }
1759
1760 int
1761 sys_unlink(tcp)
1762 struct tcb *tcp;
1763 {
1764         if (entering(tcp)) {
1765                 printpath(tcp, tcp->u_arg[0]);
1766         }
1767         return 0;
1768 }
1769
1770 int
1771 sys_symlink(tcp)
1772 struct tcb *tcp;
1773 {
1774         if (entering(tcp)) {
1775                 printpath(tcp, tcp->u_arg[0]);
1776                 tprintf(", ");
1777                 printpath(tcp, tcp->u_arg[1]);
1778         }
1779         return 0;
1780 }
1781
1782 int
1783 sys_readlink(tcp)
1784 struct tcb *tcp;
1785 {
1786         if (entering(tcp)) {
1787                 printpath(tcp, tcp->u_arg[0]);
1788                 tprintf(", ");
1789         } else {
1790                 if (syserror(tcp))
1791                         tprintf("%#lx", tcp->u_arg[1]);
1792                 else
1793                         printpathn(tcp, tcp->u_arg[1], tcp->u_rval);
1794                 tprintf(", %lu", tcp->u_arg[2]);
1795         }
1796         return 0;
1797 }
1798
1799 int
1800 sys_rename(tcp)
1801 struct tcb *tcp;
1802 {
1803         if (entering(tcp)) {
1804                 printpath(tcp, tcp->u_arg[0]);
1805                 tprintf(", ");
1806                 printpath(tcp, tcp->u_arg[1]);
1807         }
1808         return 0;
1809 }
1810
1811 int
1812 sys_chown(tcp)
1813 struct tcb *tcp;
1814 {
1815         if (entering(tcp)) {
1816                 printpath(tcp, tcp->u_arg[0]);
1817                 printuid(", ", tcp->u_arg[1]);
1818                 printuid(", ", tcp->u_arg[2]);
1819         }
1820         return 0;
1821 }
1822
1823 int
1824 sys_fchown(tcp)
1825 struct tcb *tcp;
1826 {
1827         if (entering(tcp)) {
1828                 tprintf("%ld", tcp->u_arg[0]);
1829                 printuid(", ", tcp->u_arg[1]);
1830                 printuid(", ", tcp->u_arg[2]);
1831         }
1832         return 0;
1833 }
1834
1835 int
1836 sys_chmod(tcp)
1837 struct tcb *tcp;
1838 {
1839         if (entering(tcp)) {
1840                 printpath(tcp, tcp->u_arg[0]);
1841                 tprintf(", %#lo", tcp->u_arg[1]);
1842         }
1843         return 0;
1844 }
1845
1846 int
1847 sys_fchmod(tcp)
1848 struct tcb *tcp;
1849 {
1850         if (entering(tcp)) {
1851                 tprintf("%ld, %#lo", tcp->u_arg[0], tcp->u_arg[1]);
1852         }
1853         return 0;
1854 }
1855
1856 #ifdef ALPHA
1857 int
1858 sys_osf_utimes(tcp)
1859 struct tcb *tcp;
1860 {
1861     if (entering(tcp)) {
1862         printpath(tcp, tcp->u_arg[0]);
1863         tprintf(", ");
1864         printtv32(tcp, tcp->u_arg[1]);
1865     }
1866     return 0;
1867 }
1868 #endif
1869
1870 int
1871 sys_utimes(tcp)
1872 struct tcb *tcp;
1873 {
1874         if (entering(tcp)) {
1875                 printpath(tcp, tcp->u_arg[0]);
1876                 tprintf(", ");
1877                 printtv(tcp, tcp->u_arg[1]);
1878         }
1879         return 0;
1880 }
1881
1882 int
1883 sys_utime(tcp)
1884 struct tcb *tcp;
1885 {
1886         long ut[2];
1887
1888         if (entering(tcp)) {
1889                 printpath(tcp, tcp->u_arg[0]);
1890                 tprintf(", ");
1891                 if (!tcp->u_arg[1])
1892                         tprintf("NULL");
1893                 else if (!verbose(tcp))
1894                         tprintf("%#lx", tcp->u_arg[1]);
1895                 else if (umoven(tcp, tcp->u_arg[1], sizeof ut,
1896                     (char *) ut) < 0)
1897                         tprintf("[?, ?]");
1898                 else {
1899                         tprintf("[%s,", sprinttime(ut[0]));
1900                         tprintf(" %s]", sprinttime(ut[1]));
1901                 }
1902         }
1903         return 0;
1904 }
1905
1906 int
1907 sys_mknod(tcp)
1908 struct tcb *tcp;
1909 {
1910         int mode = tcp->u_arg[1];
1911
1912         if (entering(tcp)) {
1913                 printpath(tcp, tcp->u_arg[0]);
1914                 tprintf(", %s", sprintmode(mode));
1915                 switch (mode & S_IFMT) {
1916                 case S_IFCHR: case S_IFBLK:
1917 #ifdef LINUXSPARC
1918                         if (current_personality == 1)
1919                         tprintf(", makedev(%lu, %lu)",
1920                                 (unsigned long) ((tcp->u_arg[2] >> 18) & 0x3fff),
1921                                 (unsigned long) (tcp->u_arg[2] & 0x3ffff));
1922                         else
1923 #endif
1924                         tprintf(", makedev(%lu, %lu)",
1925                                 (unsigned long) major(tcp->u_arg[2]),
1926                                 (unsigned long) minor(tcp->u_arg[2]));
1927                         break;
1928                 default:
1929                         break;
1930                 }
1931         }
1932         return 0;
1933 }
1934
1935 int
1936 sys_mkfifo(tcp)
1937 struct tcb *tcp;
1938 {
1939         if (entering(tcp)) {
1940                 printpath(tcp, tcp->u_arg[0]);
1941                 tprintf(", %#lo", tcp->u_arg[1]);
1942         }
1943         return 0;
1944 }
1945
1946 int
1947 sys_fsync(tcp)
1948 struct tcb *tcp;
1949 {
1950         if (entering(tcp)) {
1951                 tprintf("%ld", tcp->u_arg[0]);
1952         }
1953         return 0;
1954 }
1955
1956 #ifdef LINUX
1957
1958 static void
1959 printdir(tcp, addr)
1960 struct tcb *tcp;
1961 long addr;
1962 {
1963         struct dirent d;
1964
1965         if (!verbose(tcp)) {
1966                 tprintf("%#lx", addr);
1967                 return;
1968         }
1969         if (umove(tcp, addr, &d) < 0) {
1970                 tprintf("{...}");
1971                 return;
1972         }
1973         tprintf("{d_ino=%ld, ", (unsigned long) d.d_ino);
1974         tprintf("d_name=");
1975         printpathn(tcp, (long) ((struct dirent *) addr)->d_name, d.d_reclen);
1976         tprintf("}");
1977 }
1978
1979 int
1980 sys_readdir(tcp)
1981 struct tcb *tcp;
1982 {
1983         if (entering(tcp)) {
1984                 tprintf("%lu, ", tcp->u_arg[0]);
1985         } else {
1986                 if (syserror(tcp) || tcp->u_rval == 0 || !verbose(tcp))
1987                         tprintf("%#lx", tcp->u_arg[1]);
1988                 else
1989                         printdir(tcp, tcp->u_arg[1]);
1990                 /* Not much point in printing this out, it is always 1. */
1991                 if (tcp->u_arg[2] != 1)
1992                         tprintf(", %lu", tcp->u_arg[2]);
1993         }
1994         return 0;
1995 }
1996
1997 #endif /* LINUX */
1998
1999 #if defined FREEBSD || defined LINUX
2000 const struct xlat direnttypes[] = {
2001         { DT_UNKNOWN,   "DT_UNKNOWN"    },
2002         { DT_FIFO,      "DT_FIFO"       },
2003         { DT_CHR,       "DT_CHR"        },
2004         { DT_DIR,       "DT_DIR"        },
2005         { DT_BLK,       "DT_BLK"        },
2006         { DT_REG,       "DT_REG"        },
2007         { DT_LNK,       "DT_LNK"        },
2008         { DT_SOCK,      "DT_SOCK"       },
2009         { DT_WHT,       "DT_WHT"        },
2010         { 0,            NULL            },
2011 };
2012
2013 #endif
2014
2015 int
2016 sys_getdents(tcp)
2017 struct tcb *tcp;
2018 {
2019         int i, len, dents = 0;
2020         char *buf;
2021
2022         if (entering(tcp)) {
2023                 tprintf("%lu, ", tcp->u_arg[0]);
2024                 return 0;
2025         }
2026         if (syserror(tcp) || !verbose(tcp)) {
2027                 tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
2028                 return 0;
2029         }
2030         len = tcp->u_rval;
2031         if ((buf = malloc(len)) == NULL) {
2032                 tprintf("out of memory\n");
2033                 return 0;
2034         }
2035         if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
2036                 tprintf("{...}, %lu", tcp->u_arg[2]);
2037                 free(buf);
2038                 return 0;
2039         }
2040         if (!abbrev(tcp))
2041                 tprintf("{");
2042         for (i = 0; i < len;) {
2043                 struct kernel_dirent *d = (struct kernel_dirent *) &buf[i];
2044 #ifdef LINUX
2045                 if (!abbrev(tcp)) {
2046                         tprintf("%s{d_ino=%lu, d_off=%lu, ",
2047                                 i ? " " : "", d->d_ino, d->d_off);
2048                         tprintf("d_reclen=%u, d_name=\"%s\"}",
2049                                 d->d_reclen, d->d_name);
2050                 }
2051 #endif /* LINUX */
2052 #ifdef SVR4
2053                 if (!abbrev(tcp)) {
2054                         tprintf("%s{d_ino=%lu, d_off=%lu, ",
2055                                 i ? " " : "",
2056                                 (unsigned long) d->d_ino,
2057                                 (unsigned long) d->d_off);
2058                         tprintf("d_reclen=%u, d_name=\"%s\"}",
2059                                 d->d_reclen, d->d_name);
2060                 }
2061 #endif /* SVR4 */
2062 #ifdef SUNOS4
2063                 if (!abbrev(tcp)) {
2064                         tprintf("%s{d_off=%lu, d_fileno=%lu, d_reclen=%u, ",
2065                                 i ? " " : "", d->d_off, d->d_fileno,
2066                                 d->d_reclen);
2067                         tprintf("d_namlen=%u, d_name=\"%.*s\"}",
2068                                 d->d_namlen, d->d_namlen, d->d_name);
2069                 }
2070 #endif /* SUNOS4 */
2071 #ifdef FREEBSD
2072                 if (!abbrev(tcp)) {
2073                         tprintf("%s{d_fileno=%u, d_reclen=%u, d_type=",
2074                                 i ? " " : "", d->d_fileno, d->d_reclen);
2075                         printxval(direnttypes, d->d_type, "DT_???");
2076                         tprintf(", d_namlen=%u, d_name=\"%.*s\"}",
2077                                 d->d_namlen, d->d_namlen, d->d_name);
2078                 }
2079 #endif /* FREEBSD */
2080                 if (!d->d_reclen) {
2081                         tprintf("/* d_reclen == 0, problem here */");
2082                         break;
2083                 }
2084                 i += d->d_reclen;
2085                 dents++;
2086         }
2087         if (!abbrev(tcp))
2088                 tprintf("}");
2089         else
2090                 tprintf("/* %u entries */", dents);
2091         tprintf(", %lu", tcp->u_arg[2]);
2092         free(buf);
2093         return 0;
2094 }
2095
2096
2097 #if _LFS64_LARGEFILE
2098 int
2099 sys_getdents64(tcp)
2100 struct tcb *tcp;
2101 {
2102         int i, len, dents = 0;
2103         char *buf;
2104
2105         if (entering(tcp)) {
2106                 tprintf("%lu, ", tcp->u_arg[0]);
2107                 return 0;
2108         }
2109         if (syserror(tcp) || !verbose(tcp)) {
2110                 tprintf("%#lx, %lu", tcp->u_arg[1], tcp->u_arg[2]);
2111                 return 0;
2112         }
2113         len = tcp->u_rval;
2114         if ((buf = malloc(len)) == NULL) {
2115                 tprintf("out of memory\n");
2116                 return 0;
2117         }
2118         if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
2119                 tprintf("{...}, %lu", tcp->u_arg[2]);
2120                 free(buf);
2121                 return 0;
2122         }
2123         if (!abbrev(tcp))
2124                 tprintf("{");
2125         for (i = 0; i < len;) {
2126                 struct dirent64 *d = (struct dirent64 *) &buf[i];
2127 #if defined(LINUX) || defined(SVR4)
2128                 if (!abbrev(tcp)) {
2129                         tprintf("%s{d_ino=%llu, d_off=%llu, ",
2130                                 i ? " " : "",
2131                                 d->d_ino,
2132                                 d->d_off);
2133 #ifdef LINUX
2134                         tprintf("d_type=");
2135                         printxval(direnttypes, d->d_type, "DT_???");
2136                         tprintf(", ");
2137 #endif
2138                         tprintf("d_reclen=%u, d_name=\"%s\"}",
2139                                 d->d_reclen, d->d_name);
2140                 }
2141 #endif /* LINUX || SVR4 */
2142 #ifdef SUNOS4
2143                 if (!abbrev(tcp)) {
2144                         tprintf("%s{d_off=%lu, d_fileno=%lu, d_reclen=%u, ",
2145                                 i ? " " : "", d->d_off, d->d_fileno,
2146                                 d->d_reclen);
2147                         tprintf("d_namlen=%u, d_name=\"%.*s\"}",
2148                                 d->d_namlen, d->d_namlen, d->d_name);
2149                 }
2150 #endif /* SUNOS4 */
2151                 i += d->d_reclen;
2152                 dents++;
2153         }
2154         if (!abbrev(tcp))
2155                 tprintf("}");
2156         else
2157                 tprintf("/* %u entries */", dents);
2158         tprintf(", %lu", tcp->u_arg[2]);
2159         free(buf);
2160         return 0;
2161 }
2162 #endif
2163
2164 #ifdef FREEBSD
2165 int
2166 sys_getdirentries(tcp)
2167 struct tcb * tcp;
2168 {
2169         int i, len, dents = 0;
2170         long basep;
2171         char *buf;
2172
2173         if (entering(tcp)) {
2174                 tprintf("%lu, ", tcp->u_arg[0]);
2175                 return 0;
2176         }
2177         if (syserror(tcp) || !verbose(tcp)) {
2178                 tprintf("%#lx, %lu, %#lx", tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3]);
2179                 return 0;
2180         }
2181         len = tcp->u_rval;
2182         if ((buf = malloc(len)) == NULL) {
2183                 tprintf("out of memory\n");
2184                 return 0;
2185         }
2186         if (umoven(tcp, tcp->u_arg[1], len, buf) < 0) {
2187                 tprintf("{...}, %lu, %#lx", tcp->u_arg[2], tcp->u_arg[3]);
2188                 free(buf);
2189                 return 0;
2190         }
2191         if (!abbrev(tcp))
2192                 tprintf("{");
2193         for (i = 0; i < len;) {
2194                 struct kernel_dirent *d = (struct kernel_dirent *) &buf[i];
2195                 if (!abbrev(tcp)) {
2196                         tprintf("%s{d_fileno=%u, d_reclen=%u, d_type=",
2197                                 i ? " " : "", d->d_fileno, d->d_reclen);
2198                         printxval(direnttypes, d->d_type, "DT_???");
2199                         tprintf(", d_namlen=%u, d_name=\"%.*s\"}",
2200                                 d->d_namlen, d->d_namlen, d->d_name);
2201                 }
2202                 i += d->d_reclen;
2203                 dents++;
2204         }
2205         if (!abbrev(tcp))
2206                 tprintf("}");
2207         else
2208                 tprintf("/* %u entries */", dents);
2209         free(buf);
2210         tprintf(", %lu", tcp->u_arg[2]);
2211         if (umove(tcp, tcp->u_arg[3], &basep) < 0)
2212                 tprintf(", %#lx", tcp->u_arg[3]);
2213         else
2214                 tprintf(", [%lu]", basep);
2215         return 0;
2216 }
2217 #endif
2218
2219 #ifdef LINUX
2220 int
2221 sys_getcwd(tcp)
2222 struct tcb *tcp;
2223 {
2224     if (exiting(tcp)) {
2225         if (syserror(tcp))
2226             tprintf("%#lx", tcp->u_arg[0]);
2227         else
2228             printpathn(tcp, tcp->u_arg[0], tcp->u_rval - 1);
2229         tprintf(", %lu", tcp->u_arg[1]);
2230     }
2231     return 0;
2232 }
2233 #endif /* LINUX */
2234
2235 #ifdef FREEBSD
2236 int
2237 sys___getcwd(tcp)
2238 struct tcb *tcp;
2239 {
2240     if (exiting(tcp)) {
2241         if (syserror(tcp))
2242             tprintf("%#lx", tcp->u_arg[0]);
2243         else
2244             printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
2245         tprintf(", %lu", tcp->u_arg[1]);
2246     }
2247     return 0;
2248 }
2249 #endif
2250
2251 #ifdef HAVE_SYS_ASYNCH_H
2252
2253 int
2254 sys_aioread(tcp)
2255 struct tcb *tcp;
2256 {
2257         struct aio_result_t res;
2258
2259         if (entering(tcp)) {
2260                 tprintf("%lu, ", tcp->u_arg[0]);
2261         } else {
2262                 if (syserror(tcp))
2263                         tprintf("%#lx", tcp->u_arg[1]);
2264                 else
2265                         printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
2266                 tprintf(", %lu, %lu, ", tcp->u_arg[2], tcp->u_arg[3]);
2267                 printxval(whence, tcp->u_arg[4], "L_???");
2268                 if (syserror(tcp) || tcp->u_arg[5] == 0
2269                     || umove(tcp, tcp->u_arg[5], &res) < 0)
2270                         tprintf(", %#lx", tcp->u_arg[5]);
2271                 else
2272                         tprintf(", {aio_return %d aio_errno %d}",
2273                                 res.aio_return, res.aio_errno);
2274         }
2275         return 0;
2276 }
2277
2278 int
2279 sys_aiowrite(tcp)
2280 struct tcb *tcp;
2281 {
2282         struct aio_result_t res;
2283
2284         if (entering(tcp)) {
2285                 tprintf("%lu, ", tcp->u_arg[0]);
2286                 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
2287                 tprintf(", %lu, %lu, ", tcp->u_arg[2], tcp->u_arg[3]);
2288                 printxval(whence, tcp->u_arg[4], "L_???");
2289         }
2290         else {
2291                 if (tcp->u_arg[5] == 0)
2292                         tprintf(", NULL");
2293                 else if (syserror(tcp)
2294                     || umove(tcp, tcp->u_arg[5], &res) < 0)
2295                         tprintf(", %#lx", tcp->u_arg[5]);
2296                 else
2297                         tprintf(", {aio_return %d aio_errno %d}",
2298                                 res.aio_return, res.aio_errno);
2299         }
2300         return 0;
2301 }
2302
2303 int
2304 sys_aiowait(tcp)
2305 struct tcb *tcp;
2306 {
2307         if (entering(tcp))
2308                 printtv(tcp, tcp->u_arg[0]);
2309         return 0;
2310 }
2311
2312 int
2313 sys_aiocancel(tcp)
2314 struct tcb *tcp;
2315 {
2316         struct aio_result_t res;
2317
2318         if (exiting(tcp)) {
2319                 if (tcp->u_arg[0] == 0)
2320                         tprintf("NULL");
2321                 else if (syserror(tcp)
2322                     || umove(tcp, tcp->u_arg[0], &res) < 0)
2323                         tprintf("%#lx", tcp->u_arg[0]);
2324                 else
2325                         tprintf("{aio_return %d aio_errno %d}",
2326                                 res.aio_return, res.aio_errno);
2327         }
2328         return 0;
2329 }
2330
2331 #endif /* HAVE_SYS_ASYNCH_H */
2332
2333 const struct xlat xattrflags[] = {
2334 #ifdef XATTR_CREATE
2335         { XATTR_CREATE,  "XATTR_CREATE" },
2336         { XATTR_REPLACE, "XATTR_REPLACE" },
2337 #endif
2338         { 0,             NULL }
2339 };
2340
2341 static void
2342 print_xattr_val(tcp, failed, arg, insize, size)
2343 struct tcb *tcp;
2344 int failed;
2345 unsigned long arg;
2346 size_t size;
2347 {
2348     unsigned char buf[4 * size + 1];
2349     if (!failed && umoven(tcp, arg, size, &buf[3 * size]) >= 0) {
2350         unsigned char *out = buf;
2351         unsigned char *in = &buf[3 * size];
2352         size_t i;
2353         for (i = 0; i < size; ++i)
2354             if (isprint(in[i]))
2355                 *out++ = in[i];
2356             else {
2357 #define tohex(n) "0123456789abcdef"[n]
2358                 *out++ = '\\';
2359                 *out++ = 'x';
2360                 *out++ = tohex(in[i] / 16);
2361                 *out++ = tohex(in[i] % 16);
2362             }
2363         /* Don't print terminating NUL if there is one.  */
2364         if (in[i - 1] == '\0')
2365             out -= 4;
2366         *out = '\0';
2367         tprintf(", \"%s\", %zd", buf, insize);
2368     } else
2369         tprintf(", 0x%lx, %zd", arg, insize);
2370 }
2371
2372 int
2373 sys_setxattr(tcp)
2374 struct tcb *tcp;
2375 {
2376     if (entering(tcp)) {
2377         printpath(tcp, tcp->u_arg[0]);
2378         tprintf(", ");
2379         printstr(tcp, tcp->u_arg[1], -1);
2380         print_xattr_val(tcp, 0, tcp->u_arg[2], tcp->u_arg[3], tcp->u_arg[3]);
2381         tprintf(", ");
2382         printflags(xattrflags, tcp->u_arg[4]);
2383     }
2384     return 0;
2385 }
2386
2387 int
2388 sys_fsetxattr(tcp)
2389 struct tcb *tcp;
2390 {
2391     if (entering(tcp)) {
2392         tprintf("%ld, ", tcp->u_arg[0]);
2393         printstr(tcp, tcp->u_arg[1], -1);
2394         print_xattr_val(tcp, 0, tcp->u_arg[2], tcp->u_arg[3], tcp->u_arg[3]);
2395         tprintf(", ");
2396         printflags(xattrflags, tcp->u_arg[4]);
2397     }
2398     return 0;
2399 }
2400
2401 int
2402 sys_getxattr(tcp)
2403 struct tcb *tcp;
2404 {
2405     if (entering(tcp)) {
2406         printpath(tcp, tcp->u_arg[0]);
2407         tprintf(", ");
2408         printstr(tcp, tcp->u_arg[1], -1);
2409     } else {
2410         print_xattr_val(tcp, syserror(tcp), tcp->u_arg[2], tcp->u_arg[3],
2411                         tcp->u_rval);
2412     }
2413     return 0;
2414 }
2415
2416 int
2417 sys_fgetxattr(tcp)
2418 struct tcb *tcp;
2419 {
2420     if (entering(tcp)) {
2421         tprintf("%ld, ", tcp->u_arg[0]);
2422         printstr(tcp, tcp->u_arg[1], -1);
2423     } else {
2424         print_xattr_val(tcp, syserror(tcp), tcp->u_arg[2], tcp->u_arg[3],
2425                         tcp->u_rval);
2426     }
2427     return 0;
2428 }
2429
2430 int
2431 sys_listxattr(tcp)
2432 struct tcb *tcp;
2433 {
2434     if (entering(tcp)) {
2435         printpath(tcp, tcp->u_arg[0]);
2436     } else {
2437         /* XXX Print value in format */
2438         tprintf(", %p, %lu", (void *) tcp->u_arg[1], tcp->u_arg[2]);
2439     }
2440     return 0;
2441 }
2442
2443 int
2444 sys_flistxattr(tcp)
2445 struct tcb *tcp;
2446 {
2447     if (entering(tcp)) {
2448         tprintf("%ld", tcp->u_arg[0]);
2449     } else {
2450         /* XXX Print value in format */
2451         tprintf(", %p, %lu", (void *) tcp->u_arg[1], tcp->u_arg[2]);
2452     }
2453     return 0;
2454 }
2455
2456 int
2457 sys_removexattr(tcp)
2458 struct tcb *tcp;
2459 {
2460     if (entering(tcp)) {
2461         printpath(tcp, tcp->u_arg[0]);
2462         tprintf(", ");
2463         printstr(tcp, tcp->u_arg[1], -1);
2464     }
2465     return 0;
2466 }
2467
2468 int
2469 sys_fremovexattr(tcp)
2470 struct tcb *tcp;
2471 {
2472     if (entering(tcp)) {
2473         tprintf("%ld, ", tcp->u_arg[0]);
2474         printstr(tcp, tcp->u_arg[1], -1);
2475     }
2476     return 0;
2477 }
2478
2479
2480 static const struct xlat advise[] = {
2481   { POSIX_FADV_NORMAL,          "POSIX_FADV_NORMAL"     },
2482   { POSIX_FADV_RANDOM,          "POSIX_FADV_RANDOM"     },
2483   { POSIX_FADV_SEQUENTIAL,      "POSIX_FADV_SEQUENTIAL" },
2484   { POSIX_FADV_WILLNEED,        "POSIX_FADV_WILLNEED"   },
2485   { POSIX_FADV_DONTNEED,        "POSIX_FADV_DONTNEED"   },
2486   { POSIX_FADV_NOREUSE,         "POSIX_FADV_NOREUSE"    },
2487   { 0,                          NULL                    }
2488 };
2489
2490
2491 #ifdef LINUX
2492 int
2493 sys_fadvise64(tcp)
2494 struct tcb *tcp;
2495 {
2496     if (entering(tcp)) {
2497         tprintf("%ld, %lld, %ld, ",
2498                 tcp->u_arg[0],
2499 # if defined IA64 || defined X86_64 || defined ALPHA
2500                 (long long int) tcp->u_arg[1], tcp->u_arg[2]);
2501         printxval(advise, tcp->u_arg[3], "POSIX_FADV_???");
2502 #else
2503                 LONG_LONG(tcp->u_arg[1], tcp->u_arg[2]), tcp->u_arg[3]);
2504         printxval(advise, tcp->u_arg[4], "POSIX_FADV_???");
2505 #endif
2506     }
2507     return 0;
2508 }
2509 #endif
2510
2511
2512 int
2513 sys_fadvise64_64(tcp)
2514 struct tcb *tcp;
2515 {
2516     if (entering(tcp)) {
2517         tprintf("%ld, %lld, %lld, ",
2518                 tcp->u_arg[0],
2519 # if defined IA64 || defined X86_64 || defined ALPHA
2520                 (long long int) tcp->u_arg[1], (long long int) tcp->u_arg[2]);
2521         printxval(advise, tcp->u_arg[3], "POSIX_FADV_???");
2522 #else
2523                 LONG_LONG(tcp->u_arg[1], tcp->u_arg[2]),
2524                 LONG_LONG(tcp->u_arg[3], tcp->u_arg[4]));
2525         printxval(advise, tcp->u_arg[5], "POSIX_FADV_???");
2526 #endif
2527     }
2528     return 0;
2529 }