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