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