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