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