xref: /freebsd-src/contrib/pjdfstest/pjdfstest.c (revision 531c2d7af3cd2e64eec94aa1b19c4b2f16fce515)
140a8ac8fSEnji Cooper /*-
240a8ac8fSEnji Cooper  * Copyright (c) 2006-2010 Pawel Jakub Dawidek <pjd@FreeBSD.org>
340a8ac8fSEnji Cooper  * All rights reserved.
440a8ac8fSEnji Cooper  *
540a8ac8fSEnji Cooper  * Redistribution and use in source and binary forms, with or without
640a8ac8fSEnji Cooper  * modification, are permitted provided that the following conditions
740a8ac8fSEnji Cooper  * are met:
840a8ac8fSEnji Cooper  * 1. Redistributions of source code must retain the above copyright
940a8ac8fSEnji Cooper  *    notice, this list of conditions and the following disclaimer.
1040a8ac8fSEnji Cooper  * 2. Redistributions in binary form must reproduce the above copyright
1140a8ac8fSEnji Cooper  *    notice, this list of conditions and the following disclaimer in the
1240a8ac8fSEnji Cooper  *    documentation and/or other materials provided with the distribution.
1340a8ac8fSEnji Cooper  *
1440a8ac8fSEnji Cooper  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
1540a8ac8fSEnji Cooper  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1640a8ac8fSEnji Cooper  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1740a8ac8fSEnji Cooper  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
1840a8ac8fSEnji Cooper  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1940a8ac8fSEnji Cooper  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2040a8ac8fSEnji Cooper  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2140a8ac8fSEnji Cooper  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2240a8ac8fSEnji Cooper  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2340a8ac8fSEnji Cooper  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2440a8ac8fSEnji Cooper  * SUCH DAMAGE.
2540a8ac8fSEnji Cooper  *
2640a8ac8fSEnji Cooper  * $FreeBSD$
2740a8ac8fSEnji Cooper  */
2840a8ac8fSEnji Cooper 
29*3416500aSEnji Cooper /* Needs to be first to twiddle appropriate system configuration/HAVE_* flags */
30*3416500aSEnji Cooper #include "config.h"
31*3416500aSEnji Cooper 
3240a8ac8fSEnji Cooper #include <sys/param.h>
33*3416500aSEnji Cooper #ifdef	HAVE_SYS_ACL_H
34*3416500aSEnji Cooper #include <sys/acl.h>
35*3416500aSEnji Cooper #endif
36*3416500aSEnji Cooper #ifdef	HAVE_SYS_MKDEV_H
37*3416500aSEnji Cooper #include <sys/mkdev.h>
38*3416500aSEnji Cooper #endif
3940a8ac8fSEnji Cooper #include <sys/stat.h>
4040a8ac8fSEnji Cooper #include <sys/socket.h>
4140a8ac8fSEnji Cooper #include <sys/un.h>
4240a8ac8fSEnji Cooper 
4340a8ac8fSEnji Cooper #include <assert.h>
4440a8ac8fSEnji Cooper #include <ctype.h>
4540a8ac8fSEnji Cooper #include <errno.h>
4640a8ac8fSEnji Cooper #include <fcntl.h>
4740a8ac8fSEnji Cooper #include <grp.h>
4840a8ac8fSEnji Cooper #include <stdio.h>
4940a8ac8fSEnji Cooper #include <stdlib.h>
5040a8ac8fSEnji Cooper #include <string.h>
5140a8ac8fSEnji Cooper #include <unistd.h>
5240a8ac8fSEnji Cooper 
53*3416500aSEnji Cooper #ifdef	__sun__
54*3416500aSEnji Cooper #define	_USE_STAT64
5540a8ac8fSEnji Cooper #endif
56*3416500aSEnji Cooper 
57*3416500aSEnji Cooper #ifdef	_USE_STAT64
58*3416500aSEnji Cooper typedef	struct stat64	stat_t;
59*3416500aSEnji Cooper #else
60*3416500aSEnji Cooper typedef	struct stat	stat_t;
6140a8ac8fSEnji Cooper #endif
6240a8ac8fSEnji Cooper 
6340a8ac8fSEnji Cooper #ifndef ALLPERMS
6440a8ac8fSEnji Cooper #define	ALLPERMS	(S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)
6540a8ac8fSEnji Cooper #endif
6640a8ac8fSEnji Cooper 
6740a8ac8fSEnji Cooper enum action {
6840a8ac8fSEnji Cooper 	ACTION_OPEN,
69*3416500aSEnji Cooper #ifdef	HAVE_OPENAT
7040a8ac8fSEnji Cooper 	ACTION_OPENAT,
71*3416500aSEnji Cooper #endif
7240a8ac8fSEnji Cooper 	ACTION_CREATE,
7340a8ac8fSEnji Cooper 	ACTION_UNLINK,
74*3416500aSEnji Cooper #ifdef	HAVE_UNLINKAT
7540a8ac8fSEnji Cooper 	ACTION_UNLINKAT,
76*3416500aSEnji Cooper #endif
7740a8ac8fSEnji Cooper 	ACTION_MKDIR,
78*3416500aSEnji Cooper #ifdef	HAVE_MKDIRAT
7940a8ac8fSEnji Cooper 	ACTION_MKDIRAT,
80*3416500aSEnji Cooper #endif
8140a8ac8fSEnji Cooper 	ACTION_RMDIR,
8240a8ac8fSEnji Cooper 	ACTION_LINK,
83*3416500aSEnji Cooper #ifdef	HAVE_LINKAT
8440a8ac8fSEnji Cooper 	ACTION_LINKAT,
85*3416500aSEnji Cooper #endif
8640a8ac8fSEnji Cooper 	ACTION_SYMLINK,
87*3416500aSEnji Cooper #ifdef	HAVE_SYMLINKAT
8840a8ac8fSEnji Cooper 	ACTION_SYMLINKAT,
89*3416500aSEnji Cooper #endif
9040a8ac8fSEnji Cooper 	ACTION_RENAME,
91*3416500aSEnji Cooper #ifdef	HAVE_RENAMEAT
9240a8ac8fSEnji Cooper 	ACTION_RENAMEAT,
93*3416500aSEnji Cooper #endif
9440a8ac8fSEnji Cooper 	ACTION_MKFIFO,
95*3416500aSEnji Cooper #ifdef	HAVE_MKFIFOAT
9640a8ac8fSEnji Cooper 	ACTION_MKFIFOAT,
97*3416500aSEnji Cooper #endif
9840a8ac8fSEnji Cooper 	ACTION_MKNOD,
9940a8ac8fSEnji Cooper 	ACTION_MKNODAT,
10040a8ac8fSEnji Cooper 	ACTION_BIND,
101*3416500aSEnji Cooper #ifdef	HAVE_BINDAT
10240a8ac8fSEnji Cooper 	ACTION_BINDAT,
10340a8ac8fSEnji Cooper #endif
10440a8ac8fSEnji Cooper 	ACTION_CONNECT,
105*3416500aSEnji Cooper #ifdef	HAVE_CONNECTAT
10640a8ac8fSEnji Cooper 	ACTION_CONNECTAT,
10740a8ac8fSEnji Cooper #endif
10840a8ac8fSEnji Cooper 	ACTION_CHMOD,
10940a8ac8fSEnji Cooper 	ACTION_FCHMOD,
110*3416500aSEnji Cooper #ifdef	HAVE_LCHMOD
11140a8ac8fSEnji Cooper 	ACTION_LCHMOD,
11240a8ac8fSEnji Cooper #endif
11340a8ac8fSEnji Cooper 	ACTION_FCHMODAT,
11440a8ac8fSEnji Cooper 	ACTION_CHOWN,
11540a8ac8fSEnji Cooper 	ACTION_FCHOWN,
11640a8ac8fSEnji Cooper 	ACTION_LCHOWN,
117*3416500aSEnji Cooper #ifdef	HAVE_FCHOWNAT
11840a8ac8fSEnji Cooper 	ACTION_FCHOWNAT,
119*3416500aSEnji Cooper #endif
120*3416500aSEnji Cooper #ifdef	HAVE_CHFLAGS
12140a8ac8fSEnji Cooper 	ACTION_CHFLAGS,
12240a8ac8fSEnji Cooper #endif
123*3416500aSEnji Cooper #ifdef	HAVE_FCHFLAGS
12440a8ac8fSEnji Cooper 	ACTION_FCHFLAGS,
12540a8ac8fSEnji Cooper #endif
126*3416500aSEnji Cooper #ifdef	HAVE_CHFLAGSAT
12740a8ac8fSEnji Cooper 	ACTION_CHFLAGSAT,
12840a8ac8fSEnji Cooper #endif
129*3416500aSEnji Cooper #ifdef	HAVE_LCHFLAGS
13040a8ac8fSEnji Cooper 	ACTION_LCHFLAGS,
13140a8ac8fSEnji Cooper #endif
13240a8ac8fSEnji Cooper 	ACTION_TRUNCATE,
13340a8ac8fSEnji Cooper 	ACTION_FTRUNCATE,
134*3416500aSEnji Cooper #ifdef	HAVE_POSIX_FALLOCATE
135*3416500aSEnji Cooper 	ACTION_POSIX_FALLOCATE,
136*3416500aSEnji Cooper #endif
13740a8ac8fSEnji Cooper 	ACTION_STAT,
13840a8ac8fSEnji Cooper 	ACTION_FSTAT,
13940a8ac8fSEnji Cooper 	ACTION_LSTAT,
14040a8ac8fSEnji Cooper 	ACTION_FSTATAT,
14140a8ac8fSEnji Cooper 	ACTION_PATHCONF,
14240a8ac8fSEnji Cooper 	ACTION_FPATHCONF,
143*3416500aSEnji Cooper #ifdef	HAVE_LPATHCONF
14440a8ac8fSEnji Cooper 	ACTION_LPATHCONF,
14540a8ac8fSEnji Cooper #endif
146*3416500aSEnji Cooper #ifdef	HAS_NFSV4_ACL_SUPPORT
14740a8ac8fSEnji Cooper 	ACTION_PREPENDACL,
14840a8ac8fSEnji Cooper 	ACTION_READACL,
14940a8ac8fSEnji Cooper #endif
15040a8ac8fSEnji Cooper 	ACTION_WRITE,
151*3416500aSEnji Cooper #ifdef	HAVE_UTIMENSAT
152*3416500aSEnji Cooper 	ACTION_UTIMENSAT,
153*3416500aSEnji Cooper #endif
15440a8ac8fSEnji Cooper };
15540a8ac8fSEnji Cooper 
15640a8ac8fSEnji Cooper #define	TYPE_NONE	0x0000
15740a8ac8fSEnji Cooper #define	TYPE_STRING	0x0001
15840a8ac8fSEnji Cooper #define	TYPE_NUMBER	0x0002
15940a8ac8fSEnji Cooper #define	TYPE_DESCRIPTOR	0x0003
16040a8ac8fSEnji Cooper #define	TYPE_MASK	0x000f
16140a8ac8fSEnji Cooper 
16240a8ac8fSEnji Cooper #define	TYPE_OPTIONAL	0x0100
16340a8ac8fSEnji Cooper 
16440a8ac8fSEnji Cooper #define	MAX_ARGS	8
16540a8ac8fSEnji Cooper 
16640a8ac8fSEnji Cooper struct syscall_desc {
16740a8ac8fSEnji Cooper 	const char	*sd_name;
16840a8ac8fSEnji Cooper 	enum action	 sd_action;
16940a8ac8fSEnji Cooper 	int		 sd_args[MAX_ARGS];
17040a8ac8fSEnji Cooper };
17140a8ac8fSEnji Cooper 
17240a8ac8fSEnji Cooper static struct syscall_desc syscalls[] = {
17340a8ac8fSEnji Cooper 	{ "open", ACTION_OPEN, { TYPE_STRING, TYPE_STRING, TYPE_NUMBER | TYPE_OPTIONAL, TYPE_NONE } },
174*3416500aSEnji Cooper #ifdef	HAVE_OPENAT
17540a8ac8fSEnji Cooper 	{ "openat", ACTION_OPENAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_STRING, TYPE_NUMBER | TYPE_OPTIONAL, TYPE_NONE } },
176*3416500aSEnji Cooper #endif
17740a8ac8fSEnji Cooper 	{ "create", ACTION_CREATE, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
17840a8ac8fSEnji Cooper 	{ "unlink", ACTION_UNLINK, { TYPE_STRING, TYPE_NONE } },
179*3416500aSEnji Cooper #ifdef	HAVE_UNLINKAT
18040a8ac8fSEnji Cooper 	{ "unlinkat", ACTION_UNLINKAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_STRING, TYPE_NONE } },
181*3416500aSEnji Cooper #endif
18240a8ac8fSEnji Cooper 	{ "mkdir", ACTION_MKDIR, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
183*3416500aSEnji Cooper #ifdef	HAVE_MKDIRAT
18440a8ac8fSEnji Cooper 	{ "mkdirat", ACTION_MKDIRAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
185*3416500aSEnji Cooper #endif
18640a8ac8fSEnji Cooper 	{ "rmdir", ACTION_RMDIR, { TYPE_STRING, TYPE_NONE } },
18740a8ac8fSEnji Cooper 	{ "link", ACTION_LINK, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
188*3416500aSEnji Cooper #ifdef	HAVE_LINKAT
18940a8ac8fSEnji Cooper 	{ "linkat", ACTION_LINKAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_DESCRIPTOR, TYPE_STRING, TYPE_STRING, TYPE_NONE } },
190*3416500aSEnji Cooper #endif
19140a8ac8fSEnji Cooper 	{ "symlink", ACTION_SYMLINK, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
192*3416500aSEnji Cooper #ifdef	HAVE_SYMLINKAT
19340a8ac8fSEnji Cooper 	{ "symlinkat", ACTION_SYMLINKAT, { TYPE_STRING, TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } },
194*3416500aSEnji Cooper #endif
19540a8ac8fSEnji Cooper 	{ "rename", ACTION_RENAME, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
196*3416500aSEnji Cooper #ifdef	HAVE_RENAMEAT
19740a8ac8fSEnji Cooper 	{ "renameat", ACTION_RENAMEAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } },
198*3416500aSEnji Cooper #endif
19940a8ac8fSEnji Cooper 	{ "mkfifo", ACTION_MKFIFO, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
200*3416500aSEnji Cooper #ifdef	HAVE_MKFIFOAT
20140a8ac8fSEnji Cooper 	{ "mkfifoat", ACTION_MKFIFOAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
202*3416500aSEnji Cooper #endif
20340a8ac8fSEnji Cooper 	{ "mknod", ACTION_MKNOD, { TYPE_STRING, TYPE_STRING, TYPE_NUMBER, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE} },
204*3416500aSEnji Cooper #ifdef	HAVE_MKNODAT
20540a8ac8fSEnji Cooper 	{ "mknodat", ACTION_MKNODAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_STRING, TYPE_NUMBER, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE} },
206*3416500aSEnji Cooper #endif
20740a8ac8fSEnji Cooper 	{ "bind", ACTION_BIND, { TYPE_STRING, TYPE_NONE } },
208*3416500aSEnji Cooper #ifdef	HAVE_BINDAT
20940a8ac8fSEnji Cooper 	{ "bindat", ACTION_BINDAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } },
21040a8ac8fSEnji Cooper #endif
21140a8ac8fSEnji Cooper 	{ "connect", ACTION_CONNECT, { TYPE_STRING, TYPE_NONE } },
212*3416500aSEnji Cooper #ifdef	HAVE_CONNECTAT
21340a8ac8fSEnji Cooper 	{ "connectat", ACTION_CONNECTAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } },
21440a8ac8fSEnji Cooper #endif
21540a8ac8fSEnji Cooper 	{ "chmod", ACTION_CHMOD, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
21640a8ac8fSEnji Cooper 	{ "fchmod", ACTION_FCHMOD, { TYPE_DESCRIPTOR, TYPE_NUMBER, TYPE_NONE } },
217*3416500aSEnji Cooper #ifdef	HAVE_LCHMOD
21840a8ac8fSEnji Cooper 	{ "lchmod", ACTION_LCHMOD, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
21940a8ac8fSEnji Cooper #endif
220*3416500aSEnji Cooper #ifdef	HAVE_FCHMODAT
22140a8ac8fSEnji Cooper 	{ "fchmodat", ACTION_FCHMODAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NUMBER, TYPE_STRING, TYPE_NONE } },
222*3416500aSEnji Cooper #endif
22340a8ac8fSEnji Cooper 	{ "chown", ACTION_CHOWN, { TYPE_STRING, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE } },
22440a8ac8fSEnji Cooper 	{ "fchown", ACTION_FCHOWN, { TYPE_DESCRIPTOR, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE } },
22540a8ac8fSEnji Cooper 	{ "lchown", ACTION_LCHOWN, { TYPE_STRING, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE } },
226*3416500aSEnji Cooper #ifdef	HAVE_FCHOWNAT
22740a8ac8fSEnji Cooper 	{ "fchownat", ACTION_FCHOWNAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NUMBER, TYPE_NUMBER, TYPE_STRING, TYPE_NONE } },
228*3416500aSEnji Cooper #endif
229*3416500aSEnji Cooper #ifdef	HAVE_CHFLAGS
23040a8ac8fSEnji Cooper 	{ "chflags", ACTION_CHFLAGS, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
23140a8ac8fSEnji Cooper #endif
232*3416500aSEnji Cooper #ifdef	HAVE_FCHFLAGS
23340a8ac8fSEnji Cooper 	{ "fchflags", ACTION_FCHFLAGS, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } },
23440a8ac8fSEnji Cooper #endif
235*3416500aSEnji Cooper #ifdef	HAVE_CHFLAGSAT
23640a8ac8fSEnji Cooper 	{ "chflagsat", ACTION_CHFLAGSAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_NONE } },
23740a8ac8fSEnji Cooper #endif
238*3416500aSEnji Cooper #ifdef	HAVE_LCHFLAGS
23940a8ac8fSEnji Cooper 	{ "lchflags", ACTION_LCHFLAGS, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
24040a8ac8fSEnji Cooper #endif
24140a8ac8fSEnji Cooper 	{ "truncate", ACTION_TRUNCATE, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
24240a8ac8fSEnji Cooper 	{ "ftruncate", ACTION_FTRUNCATE, { TYPE_DESCRIPTOR, TYPE_NUMBER, TYPE_NONE } },
243*3416500aSEnji Cooper #ifdef	HAVE_POSIX_FALLOCATE
244*3416500aSEnji Cooper 	{ "posix_fallocate", ACTION_POSIX_FALLOCATE, { TYPE_DESCRIPTOR, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE } },
245*3416500aSEnji Cooper #endif
24640a8ac8fSEnji Cooper 	{ "stat", ACTION_STAT, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
24740a8ac8fSEnji Cooper 	{ "fstat", ACTION_FSTAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } },
24840a8ac8fSEnji Cooper 	{ "lstat", ACTION_LSTAT, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
249*3416500aSEnji Cooper #ifdef	HAVE_FSTATAT
25040a8ac8fSEnji Cooper 	{ "fstatat", ACTION_FSTATAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_NONE } },
251*3416500aSEnji Cooper #endif
25240a8ac8fSEnji Cooper 	{ "pathconf", ACTION_PATHCONF, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
25340a8ac8fSEnji Cooper 	{ "fpathconf", ACTION_FPATHCONF, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } },
254*3416500aSEnji Cooper #ifdef	HAVE_LPATHCONF
25540a8ac8fSEnji Cooper 	{ "lpathconf", ACTION_LPATHCONF, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
25640a8ac8fSEnji Cooper #endif
257*3416500aSEnji Cooper #ifdef	HAS_NFSV4_ACL_SUPPORT
25840a8ac8fSEnji Cooper 	{ "prependacl", ACTION_PREPENDACL, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
25940a8ac8fSEnji Cooper 	{ "readacl", ACTION_READACL, { TYPE_STRING, TYPE_NONE } },
26040a8ac8fSEnji Cooper #endif
26140a8ac8fSEnji Cooper 	{ "write", ACTION_WRITE, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } },
262*3416500aSEnji Cooper #ifdef	HAVE_UTIMENSAT
263*3416500aSEnji Cooper 	{ "utimensat", ACTION_UTIMENSAT, {
264*3416500aSEnji Cooper 						 TYPE_DESCRIPTOR, /* Directory */
265*3416500aSEnji Cooper 						 TYPE_STRING, /* Relative path */
266*3416500aSEnji Cooper 						 TYPE_NUMBER, /* atime seconds */
267*3416500aSEnji Cooper 						 TYPE_STRING, /* atime nanoseconds */
268*3416500aSEnji Cooper 						 TYPE_NUMBER, /* mtime seconds */
269*3416500aSEnji Cooper 						 TYPE_STRING, /* mtime nanoseconds */
270*3416500aSEnji Cooper 						 TYPE_STRING, /* flags */}},
271*3416500aSEnji Cooper #endif
27240a8ac8fSEnji Cooper 	{ NULL, -1, { TYPE_NONE } }
27340a8ac8fSEnji Cooper };
27440a8ac8fSEnji Cooper 
27540a8ac8fSEnji Cooper struct flag {
27640a8ac8fSEnji Cooper 	long long	 f_flag;
27740a8ac8fSEnji Cooper 	const char	*f_str;
27840a8ac8fSEnji Cooper };
27940a8ac8fSEnji Cooper 
28040a8ac8fSEnji Cooper static struct flag open_flags[] = {
28140a8ac8fSEnji Cooper #ifdef	O_RDONLY
28240a8ac8fSEnji Cooper 	{ O_RDONLY, "O_RDONLY" },
28340a8ac8fSEnji Cooper #endif
28440a8ac8fSEnji Cooper #ifdef	O_WRONLY
28540a8ac8fSEnji Cooper 	{ O_WRONLY, "O_WRONLY" },
28640a8ac8fSEnji Cooper #endif
28740a8ac8fSEnji Cooper #ifdef	O_RDWR
28840a8ac8fSEnji Cooper 	{ O_RDWR, "O_RDWR" },
28940a8ac8fSEnji Cooper #endif
29040a8ac8fSEnji Cooper #ifdef	O_NONBLOCK
29140a8ac8fSEnji Cooper 	{ O_NONBLOCK, "O_NONBLOCK" },
29240a8ac8fSEnji Cooper #endif
29340a8ac8fSEnji Cooper #ifdef	O_APPEND
29440a8ac8fSEnji Cooper 	{ O_APPEND, "O_APPEND" },
29540a8ac8fSEnji Cooper #endif
29640a8ac8fSEnji Cooper #ifdef	O_CREAT
29740a8ac8fSEnji Cooper 	{ O_CREAT, "O_CREAT" },
29840a8ac8fSEnji Cooper #endif
29940a8ac8fSEnji Cooper #ifdef	O_TRUNC
30040a8ac8fSEnji Cooper 	{ O_TRUNC, "O_TRUNC" },
30140a8ac8fSEnji Cooper #endif
30240a8ac8fSEnji Cooper #ifdef	O_EXCL
30340a8ac8fSEnji Cooper 	{ O_EXCL, "O_EXCL" },
30440a8ac8fSEnji Cooper #endif
30540a8ac8fSEnji Cooper #ifdef	O_SHLOCK
30640a8ac8fSEnji Cooper 	{ O_SHLOCK, "O_SHLOCK" },
30740a8ac8fSEnji Cooper #endif
30840a8ac8fSEnji Cooper #ifdef	O_EXLOCK
30940a8ac8fSEnji Cooper 	{ O_EXLOCK, "O_EXLOCK" },
31040a8ac8fSEnji Cooper #endif
31140a8ac8fSEnji Cooper #ifdef	O_DIRECT
31240a8ac8fSEnji Cooper 	{ O_DIRECT, "O_DIRECT" },
31340a8ac8fSEnji Cooper #endif
31440a8ac8fSEnji Cooper #ifdef	O_FSYNC
31540a8ac8fSEnji Cooper 	{ O_FSYNC, "O_FSYNC" },
31640a8ac8fSEnji Cooper #endif
31740a8ac8fSEnji Cooper #ifdef	O_SYNC
31840a8ac8fSEnji Cooper 	{ O_SYNC, "O_SYNC" },
31940a8ac8fSEnji Cooper #endif
32040a8ac8fSEnji Cooper #ifdef	O_NOFOLLOW
32140a8ac8fSEnji Cooper 	{ O_NOFOLLOW, "O_NOFOLLOW" },
32240a8ac8fSEnji Cooper #endif
32340a8ac8fSEnji Cooper #ifdef	O_NOCTTY
32440a8ac8fSEnji Cooper 	{ O_NOCTTY, "O_NOCTTY" },
32540a8ac8fSEnji Cooper #endif
32640a8ac8fSEnji Cooper #ifdef	O_DIRECTORY
32740a8ac8fSEnji Cooper 	{ O_DIRECTORY, "O_DIRECTORY" },
32840a8ac8fSEnji Cooper #endif
32940a8ac8fSEnji Cooper 	{ 0, NULL }
33040a8ac8fSEnji Cooper };
33140a8ac8fSEnji Cooper 
332*3416500aSEnji Cooper #ifdef	HAVE_CHFLAGS
33340a8ac8fSEnji Cooper static struct flag chflags_flags[] = {
33440a8ac8fSEnji Cooper #ifdef	UF_NODUMP
33540a8ac8fSEnji Cooper 	{ UF_NODUMP, "UF_NODUMP" },
33640a8ac8fSEnji Cooper #endif
33740a8ac8fSEnji Cooper #ifdef	UF_IMMUTABLE
33840a8ac8fSEnji Cooper 	{ UF_IMMUTABLE, "UF_IMMUTABLE" },
33940a8ac8fSEnji Cooper #endif
34040a8ac8fSEnji Cooper #ifdef	UF_APPEND
34140a8ac8fSEnji Cooper 	{ UF_APPEND, "UF_APPEND" },
34240a8ac8fSEnji Cooper #endif
34340a8ac8fSEnji Cooper #ifdef	UF_NOUNLINK
34440a8ac8fSEnji Cooper 	{ UF_NOUNLINK, "UF_NOUNLINK" },
34540a8ac8fSEnji Cooper #endif
34640a8ac8fSEnji Cooper #ifdef	UF_OPAQUE
34740a8ac8fSEnji Cooper 	{ UF_OPAQUE, "UF_OPAQUE" },
34840a8ac8fSEnji Cooper #endif
34940a8ac8fSEnji Cooper #ifdef	SF_ARCHIVED
35040a8ac8fSEnji Cooper 	{ SF_ARCHIVED, "SF_ARCHIVED" },
35140a8ac8fSEnji Cooper #endif
35240a8ac8fSEnji Cooper #ifdef	SF_IMMUTABLE
35340a8ac8fSEnji Cooper 	{ SF_IMMUTABLE, "SF_IMMUTABLE" },
35440a8ac8fSEnji Cooper #endif
35540a8ac8fSEnji Cooper #ifdef	SF_APPEND
35640a8ac8fSEnji Cooper 	{ SF_APPEND, "SF_APPEND" },
35740a8ac8fSEnji Cooper #endif
35840a8ac8fSEnji Cooper #ifdef	SF_NOUNLINK
35940a8ac8fSEnji Cooper 	{ SF_NOUNLINK, "SF_NOUNLINK" },
36040a8ac8fSEnji Cooper #endif
36140a8ac8fSEnji Cooper #ifdef	SF_SNAPSHOT
36240a8ac8fSEnji Cooper 	{ SF_SNAPSHOT, "SF_SNAPSHOT" },
36340a8ac8fSEnji Cooper #endif
36440a8ac8fSEnji Cooper 	{ 0, NULL }
36540a8ac8fSEnji Cooper };
36640a8ac8fSEnji Cooper #endif
36740a8ac8fSEnji Cooper 
368*3416500aSEnji Cooper #ifdef	HAVE_UNLINKAT
36940a8ac8fSEnji Cooper static struct flag unlinkat_flags[] = {
37040a8ac8fSEnji Cooper 	{ AT_REMOVEDIR, "AT_REMOVEDIR" },
37140a8ac8fSEnji Cooper 	{ 0, NULL }
37240a8ac8fSEnji Cooper };
373*3416500aSEnji Cooper #endif
37440a8ac8fSEnji Cooper 
375*3416500aSEnji Cooper #ifdef	HAVE_LINKAT
37640a8ac8fSEnji Cooper static struct flag linkat_flags[] = {
377*3416500aSEnji Cooper #ifdef	AT_SYMLINK_FOLLOW
37840a8ac8fSEnji Cooper 	{ AT_SYMLINK_FOLLOW, "AT_SYMLINK_FOLLOW" },
379*3416500aSEnji Cooper #endif
38040a8ac8fSEnji Cooper 	{ 0, NULL }
38140a8ac8fSEnji Cooper };
382*3416500aSEnji Cooper #endif
38340a8ac8fSEnji Cooper 
384*3416500aSEnji Cooper #ifdef	HAVE_CHFLAGSAT
38540a8ac8fSEnji Cooper static struct flag chflagsat_flags[] = {
38640a8ac8fSEnji Cooper 	{ AT_SYMLINK_NOFOLLOW, "AT_SYMLINK_NOFOLLOW" },
38740a8ac8fSEnji Cooper 	{ 0, NULL }
38840a8ac8fSEnji Cooper };
389*3416500aSEnji Cooper #endif
39040a8ac8fSEnji Cooper 
391*3416500aSEnji Cooper #ifdef	HAVE_FCHMODAT
39240a8ac8fSEnji Cooper static struct flag fchmodat_flags[] = {
39340a8ac8fSEnji Cooper 	{ AT_SYMLINK_NOFOLLOW, "AT_SYMLINK_NOFOLLOW" },
39440a8ac8fSEnji Cooper 	{ 0, NULL }
39540a8ac8fSEnji Cooper };
396*3416500aSEnji Cooper #endif
39740a8ac8fSEnji Cooper 
398*3416500aSEnji Cooper #ifdef	HAVE_FCHOWNAT
39940a8ac8fSEnji Cooper static struct flag fchownat_flags[] = {
40040a8ac8fSEnji Cooper 	{ AT_SYMLINK_NOFOLLOW, "AT_SYMLINK_NOFOLLOW" },
40140a8ac8fSEnji Cooper 	{ 0, NULL }
40240a8ac8fSEnji Cooper };
403*3416500aSEnji Cooper #endif
40440a8ac8fSEnji Cooper 
405*3416500aSEnji Cooper #ifdef	HAVE_FSTATAT
40640a8ac8fSEnji Cooper static struct flag fstatat_flags[] = {
40740a8ac8fSEnji Cooper 	{ AT_SYMLINK_NOFOLLOW, "AT_SYMLINK_NOFOLLOW" },
40840a8ac8fSEnji Cooper 	{ 0, NULL }
40940a8ac8fSEnji Cooper };
410*3416500aSEnji Cooper #endif
41140a8ac8fSEnji Cooper 
41240a8ac8fSEnji Cooper struct name {
41340a8ac8fSEnji Cooper 	int		 n_name;
41440a8ac8fSEnji Cooper 	const char	*n_str;
41540a8ac8fSEnji Cooper };
41640a8ac8fSEnji Cooper 
41740a8ac8fSEnji Cooper static struct name pathconf_names[] = {
41840a8ac8fSEnji Cooper #ifdef	_PC_LINK_MAX
41940a8ac8fSEnji Cooper 	{ _PC_LINK_MAX, "_PC_LINK_MAX" },
42040a8ac8fSEnji Cooper #endif
42140a8ac8fSEnji Cooper #ifdef	_PC_NAME_MAX
42240a8ac8fSEnji Cooper 	{ _PC_NAME_MAX, "_PC_NAME_MAX" },
42340a8ac8fSEnji Cooper #endif
42440a8ac8fSEnji Cooper #ifdef	_PC_PATH_MAX
42540a8ac8fSEnji Cooper 	{ _PC_PATH_MAX, "_PC_PATH_MAX" },
42640a8ac8fSEnji Cooper #endif
42740a8ac8fSEnji Cooper #ifdef	_PC_SYMLINK_MAX
42840a8ac8fSEnji Cooper 	{ _PC_SYMLINK_MAX, "_PC_SYMLINK_MAX" },
42940a8ac8fSEnji Cooper #endif
43040a8ac8fSEnji Cooper 	{ 0, NULL }
43140a8ac8fSEnji Cooper };
43240a8ac8fSEnji Cooper 
43340a8ac8fSEnji Cooper static const char *err2str(int error);
43440a8ac8fSEnji Cooper 
43540a8ac8fSEnji Cooper static int *descriptors;
43640a8ac8fSEnji Cooper static int ndescriptors;
43740a8ac8fSEnji Cooper 
43840a8ac8fSEnji Cooper static void
usage(void)43940a8ac8fSEnji Cooper usage(void)
44040a8ac8fSEnji Cooper {
44140a8ac8fSEnji Cooper 
44240a8ac8fSEnji Cooper 	fprintf(stderr, "usage: pjdfstest [-U umask] [-u uid] [-g gid1[,gid2[...]]] syscall args ...\n");
44340a8ac8fSEnji Cooper 	exit(1);
44440a8ac8fSEnji Cooper }
44540a8ac8fSEnji Cooper 
44640a8ac8fSEnji Cooper static long long
str2flags(struct flag * tflags,char * sflags)44740a8ac8fSEnji Cooper str2flags(struct flag *tflags, char *sflags)
44840a8ac8fSEnji Cooper {
44940a8ac8fSEnji Cooper 	long long flags = 0;
45040a8ac8fSEnji Cooper 	unsigned int i;
45140a8ac8fSEnji Cooper 	char *f;
45240a8ac8fSEnji Cooper 
45340a8ac8fSEnji Cooper 	/* 'none' or '0' means no flags */
45440a8ac8fSEnji Cooper 	if (strcmp(sflags, "none") == 0 || strcmp(sflags, "0") == 0)
45540a8ac8fSEnji Cooper 		return (0);
45640a8ac8fSEnji Cooper 	for (f = strtok(sflags, ",|"); f != NULL; f = strtok(NULL, ",|")) {
45740a8ac8fSEnji Cooper 		for (i = 0; tflags[i].f_str != NULL; i++) {
45840a8ac8fSEnji Cooper 			if (strcmp(tflags[i].f_str, f) == 0)
45940a8ac8fSEnji Cooper 				break;
46040a8ac8fSEnji Cooper 		}
46140a8ac8fSEnji Cooper 		if (tflags[i].f_str == NULL) {
46240a8ac8fSEnji Cooper 			fprintf(stderr, "unknown flag '%s'\n", f);
46340a8ac8fSEnji Cooper 			exit(1);
46440a8ac8fSEnji Cooper 		}
46540a8ac8fSEnji Cooper 		flags |= tflags[i].f_flag;
46640a8ac8fSEnji Cooper 	}
46740a8ac8fSEnji Cooper 	return (flags);
46840a8ac8fSEnji Cooper }
46940a8ac8fSEnji Cooper 
470*3416500aSEnji Cooper #ifdef	HAVE_CHFLAGS
47140a8ac8fSEnji Cooper static char *
flags2str(struct flag * tflags,long long flags)47240a8ac8fSEnji Cooper flags2str(struct flag *tflags, long long flags)
47340a8ac8fSEnji Cooper {
47440a8ac8fSEnji Cooper 	static char sflags[1024];
47540a8ac8fSEnji Cooper 	unsigned int i;
47640a8ac8fSEnji Cooper 
47740a8ac8fSEnji Cooper 	sflags[0] = '\0';
47840a8ac8fSEnji Cooper 	for (i = 0; tflags[i].f_str != NULL; i++) {
47940a8ac8fSEnji Cooper 		if (flags & tflags[i].f_flag) {
48040a8ac8fSEnji Cooper 			if (sflags[0] != '\0')
48140a8ac8fSEnji Cooper 				strlcat(sflags, ",", sizeof(sflags));
48240a8ac8fSEnji Cooper 			strlcat(sflags, tflags[i].f_str, sizeof(sflags));
48340a8ac8fSEnji Cooper 		}
48440a8ac8fSEnji Cooper 	}
48540a8ac8fSEnji Cooper 	if (sflags[0] == '\0')
48640a8ac8fSEnji Cooper 		strlcpy(sflags, "none", sizeof(sflags));
48740a8ac8fSEnji Cooper 	return (sflags);
48840a8ac8fSEnji Cooper }
48940a8ac8fSEnji Cooper #endif
49040a8ac8fSEnji Cooper 
49140a8ac8fSEnji Cooper static int
str2name(struct name * names,char * name)49240a8ac8fSEnji Cooper str2name(struct name *names, char *name)
49340a8ac8fSEnji Cooper {
49440a8ac8fSEnji Cooper 	unsigned int i;
49540a8ac8fSEnji Cooper 
49640a8ac8fSEnji Cooper 	for (i = 0; names[i].n_str != NULL; i++) {
49740a8ac8fSEnji Cooper 		if (strcmp(names[i].n_str, name) == 0)
49840a8ac8fSEnji Cooper 			return (names[i].n_name);
49940a8ac8fSEnji Cooper 	}
50040a8ac8fSEnji Cooper 	return (-1);
50140a8ac8fSEnji Cooper }
50240a8ac8fSEnji Cooper 
50340a8ac8fSEnji Cooper static struct syscall_desc *
find_syscall(const char * name)50440a8ac8fSEnji Cooper find_syscall(const char *name)
50540a8ac8fSEnji Cooper {
50640a8ac8fSEnji Cooper 	int i;
50740a8ac8fSEnji Cooper 
50840a8ac8fSEnji Cooper 	for (i = 0; syscalls[i].sd_name != NULL; i++) {
50940a8ac8fSEnji Cooper 		if (strcmp(syscalls[i].sd_name, name) == 0)
51040a8ac8fSEnji Cooper 			return (&syscalls[i]);
51140a8ac8fSEnji Cooper 	}
51240a8ac8fSEnji Cooper 	return (NULL);
51340a8ac8fSEnji Cooper }
51440a8ac8fSEnji Cooper 
51540a8ac8fSEnji Cooper static void
show_stat(stat_t * sp,const char * what)516*3416500aSEnji Cooper show_stat(stat_t *sp, const char *what)
51740a8ac8fSEnji Cooper {
51840a8ac8fSEnji Cooper 
51940a8ac8fSEnji Cooper 	if (strcmp(what, "mode") == 0)
52040a8ac8fSEnji Cooper 		printf("0%o", (unsigned int)(sp->st_mode & ALLPERMS));
52140a8ac8fSEnji Cooper 	else if (strcmp(what, "inode") == 0)
52240a8ac8fSEnji Cooper 		printf("%lld", (long long)sp->st_ino);
52340a8ac8fSEnji Cooper 	else if (strcmp(what, "nlink") == 0)
52440a8ac8fSEnji Cooper 		printf("%lld", (long long)sp->st_nlink);
52540a8ac8fSEnji Cooper 	else if (strcmp(what, "uid") == 0)
52640a8ac8fSEnji Cooper 		printf("%d", (int)sp->st_uid);
52740a8ac8fSEnji Cooper 	else if (strcmp(what, "gid") == 0)
52840a8ac8fSEnji Cooper 		printf("%d", (int)sp->st_gid);
52940a8ac8fSEnji Cooper 	else if (strcmp(what, "size") == 0)
53040a8ac8fSEnji Cooper 		printf("%lld", (long long)sp->st_size);
53140a8ac8fSEnji Cooper 	else if (strcmp(what, "blocks") == 0)
53240a8ac8fSEnji Cooper 		printf("%lld", (long long)sp->st_blocks);
53340a8ac8fSEnji Cooper 	else if (strcmp(what, "atime") == 0)
53440a8ac8fSEnji Cooper 		printf("%lld", (long long)sp->st_atime);
535*3416500aSEnji Cooper #if	defined(HAVE_STRUCT_STAT_ST_ATIM) || \
536*3416500aSEnji Cooper 	defined(HAVE_STRUCT_STAT_ST_ATIMESPEC)
537*3416500aSEnji Cooper 	else if (strcmp(what, "atime_ns") == 0)
538*3416500aSEnji Cooper #ifdef	HAVE_STRUCT_STAT_ST_ATIMESPEC
539*3416500aSEnji Cooper 		printf("%lld", (long long)sp->st_atimespec.tv_nsec);
540*3416500aSEnji Cooper #else
541*3416500aSEnji Cooper 		printf("%lld", (long long)sp->st_atim.tv_nsec);
542*3416500aSEnji Cooper #endif
543*3416500aSEnji Cooper #endif	/* st_atim* */
54440a8ac8fSEnji Cooper 	else if (strcmp(what, "ctime") == 0)
54540a8ac8fSEnji Cooper 		printf("%lld", (long long)sp->st_ctime);
546*3416500aSEnji Cooper #if	defined(HAVE_STRUCT_STAT_ST_CTIM) || \
547*3416500aSEnji Cooper 	defined(HAVE_STRUCT_STAT_ST_CTIMESPEC)
548*3416500aSEnji Cooper 	else if (strcmp(what, "ctime_ns") == 0)
549*3416500aSEnji Cooper #ifdef	HAVE_STRUCT_STAT_ST_CTIMESPEC
550*3416500aSEnji Cooper 		printf("%lld", (long long)sp->st_ctimespec.tv_nsec);
551*3416500aSEnji Cooper #else
552*3416500aSEnji Cooper 		printf("%lld", (long long)sp->st_ctim.tv_nsec);
553*3416500aSEnji Cooper #endif
554*3416500aSEnji Cooper #endif	/* st_ctim* */
555*3416500aSEnji Cooper 	else if (strcmp(what, "mtime") == 0)
556*3416500aSEnji Cooper 		printf("%lld", (long long)sp->st_mtime);
557*3416500aSEnji Cooper 	else if (strcmp(what, "mtime_ns") == 0)
558*3416500aSEnji Cooper #if	defined(HAVE_STRUCT_STAT_ST_MTIM) || \
559*3416500aSEnji Cooper 	defined(HAVE_STRUCT_STAT_ST_MTIMESPEC)
560*3416500aSEnji Cooper #ifdef	HAVE_STRUCT_STAT_ST_MTIMESPEC
561*3416500aSEnji Cooper 		printf("%lld", (long long)sp->st_mtimespec.tv_nsec);
562*3416500aSEnji Cooper #else
563*3416500aSEnji Cooper 		printf("%lld", (long long)sp->st_mtim.tv_nsec);
564*3416500aSEnji Cooper #endif
565*3416500aSEnji Cooper #endif	/* st_mtim* */
566*3416500aSEnji Cooper #ifdef	HAVE_STRUCT_STAT_ST_BIRTHTIME
567*3416500aSEnji Cooper 	else if (strcmp(what, "birthtime") == 0)
568*3416500aSEnji Cooper 		printf("%lld", (long long)sp->st_birthtime);
569*3416500aSEnji Cooper #endif	/* st_birthtime */
570*3416500aSEnji Cooper #if	defined(HAVE_STRUCT_STAT_ST_BIRTHTIM) || \
571*3416500aSEnji Cooper 	defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC)
572*3416500aSEnji Cooper 	else if (strcmp(what, "birthtime_ns") == 0)
573*3416500aSEnji Cooper #ifdef	HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC
574*3416500aSEnji Cooper 		printf("%lld", (long long)sp->st_birthtimespec.tv_nsec);
575*3416500aSEnji Cooper #else
576*3416500aSEnji Cooper 		printf("%lld", (long long)sp->st_birthtim.tv_nsec);
577*3416500aSEnji Cooper #endif
578*3416500aSEnji Cooper #endif	/* st_birthtim{,espec} */
579*3416500aSEnji Cooper #ifdef	HAVE_CHFLAGS
58040a8ac8fSEnji Cooper 	else if (strcmp(what, "flags") == 0)
58140a8ac8fSEnji Cooper 		printf("%s", flags2str(chflags_flags, (long long)sp->st_flags));
58240a8ac8fSEnji Cooper #endif
58340a8ac8fSEnji Cooper 	else if (strcmp(what, "major") == 0)
58440a8ac8fSEnji Cooper 		printf("%u", (unsigned int)major(sp->st_rdev));
58540a8ac8fSEnji Cooper 	else if (strcmp(what, "minor") == 0)
58640a8ac8fSEnji Cooper 		printf("%u", (unsigned int)minor(sp->st_rdev));
58740a8ac8fSEnji Cooper 	else if (strcmp(what, "type") == 0) {
58840a8ac8fSEnji Cooper 		switch (sp->st_mode & S_IFMT) {
58940a8ac8fSEnji Cooper 		case S_IFIFO:
59040a8ac8fSEnji Cooper 			printf("fifo");
59140a8ac8fSEnji Cooper 			break;
59240a8ac8fSEnji Cooper 		case S_IFCHR:
59340a8ac8fSEnji Cooper 			printf("char");
59440a8ac8fSEnji Cooper 			break;
59540a8ac8fSEnji Cooper 		case S_IFDIR:
59640a8ac8fSEnji Cooper 			printf("dir");
59740a8ac8fSEnji Cooper 			break;
59840a8ac8fSEnji Cooper 		case S_IFBLK:
59940a8ac8fSEnji Cooper 			printf("block");
60040a8ac8fSEnji Cooper 			break;
60140a8ac8fSEnji Cooper 		case S_IFREG:
60240a8ac8fSEnji Cooper 			printf("regular");
60340a8ac8fSEnji Cooper 			break;
60440a8ac8fSEnji Cooper 		case S_IFLNK:
60540a8ac8fSEnji Cooper 			printf("symlink");
60640a8ac8fSEnji Cooper 			break;
60740a8ac8fSEnji Cooper 		case S_IFSOCK:
60840a8ac8fSEnji Cooper 			printf("socket");
60940a8ac8fSEnji Cooper 			break;
61040a8ac8fSEnji Cooper 		default:
61140a8ac8fSEnji Cooper 			printf("unknown");
61240a8ac8fSEnji Cooper 			break;
61340a8ac8fSEnji Cooper 		}
61440a8ac8fSEnji Cooper 	} else {
61540a8ac8fSEnji Cooper 		printf("unknown");
61640a8ac8fSEnji Cooper 	}
61740a8ac8fSEnji Cooper }
61840a8ac8fSEnji Cooper 
61940a8ac8fSEnji Cooper static void
show_stats(stat_t * sp,char * what)620*3416500aSEnji Cooper show_stats(stat_t *sp, char *what)
62140a8ac8fSEnji Cooper {
62240a8ac8fSEnji Cooper 	const char *s = "";
62340a8ac8fSEnji Cooper 	char *w;
62440a8ac8fSEnji Cooper 
62540a8ac8fSEnji Cooper 	for (w = strtok(what, ","); w != NULL; w = strtok(NULL, ",")) {
62640a8ac8fSEnji Cooper 		printf("%s", s);
62740a8ac8fSEnji Cooper 		show_stat(sp, w);
62840a8ac8fSEnji Cooper 		s = ",";
62940a8ac8fSEnji Cooper 	}
63040a8ac8fSEnji Cooper 	printf("\n");
63140a8ac8fSEnji Cooper }
63240a8ac8fSEnji Cooper 
63340a8ac8fSEnji Cooper static void
descriptor_add(int fd)63440a8ac8fSEnji Cooper descriptor_add(int fd)
63540a8ac8fSEnji Cooper {
63640a8ac8fSEnji Cooper 
63740a8ac8fSEnji Cooper 	ndescriptors++;
63840a8ac8fSEnji Cooper 	if (descriptors == NULL) {
63940a8ac8fSEnji Cooper 		descriptors = malloc(sizeof(descriptors[0]) * ndescriptors);
64040a8ac8fSEnji Cooper 	} else {
64140a8ac8fSEnji Cooper 		descriptors = realloc(descriptors,
64240a8ac8fSEnji Cooper 		    sizeof(descriptors[0]) * ndescriptors);
64340a8ac8fSEnji Cooper 	}
64440a8ac8fSEnji Cooper 	assert(descriptors != NULL);
64540a8ac8fSEnji Cooper 	descriptors[ndescriptors - 1] = fd;
64640a8ac8fSEnji Cooper }
64740a8ac8fSEnji Cooper 
64840a8ac8fSEnji Cooper static int
descriptor_get(int pos)64940a8ac8fSEnji Cooper descriptor_get(int pos)
65040a8ac8fSEnji Cooper {
65140a8ac8fSEnji Cooper 
65240a8ac8fSEnji Cooper 	if (pos < 0 || pos >= ndescriptors) {
65340a8ac8fSEnji Cooper 		fprintf(stderr, "invalid descriptor %d\n", pos);
65440a8ac8fSEnji Cooper 		exit(1);
65540a8ac8fSEnji Cooper 	}
65640a8ac8fSEnji Cooper 
65740a8ac8fSEnji Cooper 	return (descriptors[pos]);
65840a8ac8fSEnji Cooper }
65940a8ac8fSEnji Cooper 
66040a8ac8fSEnji Cooper static unsigned int
call_syscall(struct syscall_desc * scall,char * argv[])66140a8ac8fSEnji Cooper call_syscall(struct syscall_desc *scall, char *argv[])
66240a8ac8fSEnji Cooper {
663*3416500aSEnji Cooper 	stat_t sb;
664*3416500aSEnji Cooper #ifdef	HAVE_UTIMENSAT
665*3416500aSEnji Cooper 	struct timespec times[2];
666*3416500aSEnji Cooper 	int flag;
667*3416500aSEnji Cooper #endif
66840a8ac8fSEnji Cooper 	long long flags;
66940a8ac8fSEnji Cooper 	unsigned int i;
67040a8ac8fSEnji Cooper 	char *endp;
67140a8ac8fSEnji Cooper 	int name, rval;
67240a8ac8fSEnji Cooper 	union {
67340a8ac8fSEnji Cooper 		char *str;
67440a8ac8fSEnji Cooper 		long long num;
67540a8ac8fSEnji Cooper 	} args[MAX_ARGS];
676*3416500aSEnji Cooper #ifdef	HAS_NFSV4_ACL_SUPPORT
67740a8ac8fSEnji Cooper 	int entry_id = ACL_FIRST_ENTRY;
67840a8ac8fSEnji Cooper 	acl_t acl, newacl;
67940a8ac8fSEnji Cooper 	acl_entry_t entry, newentry;
68040a8ac8fSEnji Cooper #endif
68140a8ac8fSEnji Cooper 
68240a8ac8fSEnji Cooper 	/*
68340a8ac8fSEnji Cooper 	 * Verify correctness of the arguments.
68440a8ac8fSEnji Cooper 	 */
68540a8ac8fSEnji Cooper 	for (i = 0; i < sizeof(args)/sizeof(args[0]); i++) {
68640a8ac8fSEnji Cooper 		if (scall->sd_args[i] == TYPE_NONE) {
68740a8ac8fSEnji Cooper 			if (argv[i] == NULL || strcmp(argv[i], ":") == 0)
68840a8ac8fSEnji Cooper 				break;
68940a8ac8fSEnji Cooper 			fprintf(stderr, "too many arguments [%s]\n", argv[i]);
69040a8ac8fSEnji Cooper 			exit(1);
69140a8ac8fSEnji Cooper 		} else {
69240a8ac8fSEnji Cooper 			if (argv[i] == NULL || strcmp(argv[i], ":") == 0) {
69340a8ac8fSEnji Cooper 				if (scall->sd_args[i] & TYPE_OPTIONAL)
69440a8ac8fSEnji Cooper 					break;
69540a8ac8fSEnji Cooper 				fprintf(stderr, "too few arguments\n");
69640a8ac8fSEnji Cooper 				exit(1);
69740a8ac8fSEnji Cooper 			}
69840a8ac8fSEnji Cooper 			if ((scall->sd_args[i] & TYPE_MASK) == TYPE_STRING) {
69940a8ac8fSEnji Cooper 				if (strcmp(argv[i], "NULL") == 0)
70040a8ac8fSEnji Cooper 					args[i].str = NULL;
70140a8ac8fSEnji Cooper 				else if (strcmp(argv[i], "DEADCODE") == 0)
70240a8ac8fSEnji Cooper 					args[i].str = (void *)0xdeadc0de;
70340a8ac8fSEnji Cooper 				else
70440a8ac8fSEnji Cooper 					args[i].str = argv[i];
70540a8ac8fSEnji Cooper 			} else if ((scall->sd_args[i] & TYPE_MASK) ==
70640a8ac8fSEnji Cooper 			    TYPE_NUMBER) {
70740a8ac8fSEnji Cooper 				args[i].num = strtoll(argv[i], &endp, 0);
70840a8ac8fSEnji Cooper 				if (*endp != '\0' &&
70940a8ac8fSEnji Cooper 				    !isspace((unsigned char)*endp)) {
71040a8ac8fSEnji Cooper 					fprintf(stderr,
71140a8ac8fSEnji Cooper 					    "invalid argument %u, number expected [%s]\n",
71240a8ac8fSEnji Cooper 					    i, endp);
71340a8ac8fSEnji Cooper 					exit(1);
71440a8ac8fSEnji Cooper 				}
71540a8ac8fSEnji Cooper 			} else if ((scall->sd_args[i] & TYPE_MASK) ==
71640a8ac8fSEnji Cooper 			    TYPE_DESCRIPTOR) {
71740a8ac8fSEnji Cooper 				if (strcmp(argv[i], "AT_FDCWD") == 0) {
71840a8ac8fSEnji Cooper 					args[i].num = AT_FDCWD;
71940a8ac8fSEnji Cooper 				} else if (strcmp(argv[i], "BADFD") == 0) {
72040a8ac8fSEnji Cooper 					/* In case AT_FDCWD is -1 on some systems... */
72140a8ac8fSEnji Cooper 					if (AT_FDCWD == -1)
72240a8ac8fSEnji Cooper 						args[i].num = -2;
72340a8ac8fSEnji Cooper 					else
72440a8ac8fSEnji Cooper 						args[i].num = -1;
72540a8ac8fSEnji Cooper 				} else {
72640a8ac8fSEnji Cooper 					int pos;
72740a8ac8fSEnji Cooper 
72840a8ac8fSEnji Cooper 					pos = strtoll(argv[i], &endp, 0);
72940a8ac8fSEnji Cooper 					if (*endp != '\0' &&
73040a8ac8fSEnji Cooper 					    !isspace((unsigned char)*endp)) {
73140a8ac8fSEnji Cooper 						fprintf(stderr,
73240a8ac8fSEnji Cooper 						    "invalid argument %u, number expected [%s]\n",
73340a8ac8fSEnji Cooper 						    i, endp);
73440a8ac8fSEnji Cooper 						exit(1);
73540a8ac8fSEnji Cooper 					}
73640a8ac8fSEnji Cooper 					args[i].num = descriptor_get(pos);
73740a8ac8fSEnji Cooper 				}
73840a8ac8fSEnji Cooper 			}
73940a8ac8fSEnji Cooper 		}
74040a8ac8fSEnji Cooper 	}
74140a8ac8fSEnji Cooper 	/*
74240a8ac8fSEnji Cooper 	 * Call the given syscall.
74340a8ac8fSEnji Cooper 	 */
74440a8ac8fSEnji Cooper #define	NUM(n)	(args[(n)].num)
74540a8ac8fSEnji Cooper #define	STR(n)	(args[(n)].str)
74640a8ac8fSEnji Cooper 	switch (scall->sd_action) {
74740a8ac8fSEnji Cooper 	case ACTION_OPEN:
74840a8ac8fSEnji Cooper 		flags = str2flags(open_flags, STR(1));
74940a8ac8fSEnji Cooper 		if (flags & O_CREAT) {
75040a8ac8fSEnji Cooper 			if (i == 2) {
75140a8ac8fSEnji Cooper 				fprintf(stderr, "too few arguments\n");
75240a8ac8fSEnji Cooper 				exit(1);
75340a8ac8fSEnji Cooper 			}
75440a8ac8fSEnji Cooper 			rval = open(STR(0), (int)flags, (mode_t)NUM(2));
75540a8ac8fSEnji Cooper 		} else {
75640a8ac8fSEnji Cooper 			if (i == 3) {
75740a8ac8fSEnji Cooper 				fprintf(stderr, "too many arguments\n");
75840a8ac8fSEnji Cooper 				exit(1);
75940a8ac8fSEnji Cooper 			}
76040a8ac8fSEnji Cooper 			rval = open(STR(0), (int)flags);
76140a8ac8fSEnji Cooper 		}
76240a8ac8fSEnji Cooper 		if (rval >= 0)
76340a8ac8fSEnji Cooper 			descriptor_add(rval);
76440a8ac8fSEnji Cooper 		break;
765*3416500aSEnji Cooper #ifdef	HAVE_OPENAT
76640a8ac8fSEnji Cooper 	case ACTION_OPENAT:
76740a8ac8fSEnji Cooper 		flags = str2flags(open_flags, STR(2));
76840a8ac8fSEnji Cooper 		if (flags & O_CREAT) {
76940a8ac8fSEnji Cooper 			if (i == 3) {
77040a8ac8fSEnji Cooper 				fprintf(stderr, "too few arguments\n");
77140a8ac8fSEnji Cooper 				exit(1);
77240a8ac8fSEnji Cooper 			}
77340a8ac8fSEnji Cooper 			rval = openat(NUM(0), STR(1), (int)flags,
77440a8ac8fSEnji Cooper 			    (mode_t)NUM(3));
77540a8ac8fSEnji Cooper 		} else {
77640a8ac8fSEnji Cooper 			if (i == 4) {
77740a8ac8fSEnji Cooper 				fprintf(stderr, "too many arguments\n");
77840a8ac8fSEnji Cooper 				exit(1);
77940a8ac8fSEnji Cooper 			}
78040a8ac8fSEnji Cooper 			rval = openat(NUM(0), STR(1), (int)flags);
78140a8ac8fSEnji Cooper 		}
78240a8ac8fSEnji Cooper 		if (rval >= 0)
78340a8ac8fSEnji Cooper 			descriptor_add(rval);
78440a8ac8fSEnji Cooper 		break;
785*3416500aSEnji Cooper #endif
78640a8ac8fSEnji Cooper 	case ACTION_CREATE:
78740a8ac8fSEnji Cooper 		rval = open(STR(0), O_CREAT | O_EXCL, (mode_t)NUM(1));
78840a8ac8fSEnji Cooper 		if (rval >= 0)
78940a8ac8fSEnji Cooper 			close(rval);
79040a8ac8fSEnji Cooper 		break;
79140a8ac8fSEnji Cooper 	case ACTION_UNLINK:
79240a8ac8fSEnji Cooper 		rval = unlink(STR(0));
79340a8ac8fSEnji Cooper 		break;
794*3416500aSEnji Cooper #ifdef	HAVE_UNLINKAT
79540a8ac8fSEnji Cooper 	case ACTION_UNLINKAT:
79640a8ac8fSEnji Cooper 		rval = unlinkat(NUM(0), STR(1),
79740a8ac8fSEnji Cooper 		    (int)str2flags(unlinkat_flags, STR(2)));
79840a8ac8fSEnji Cooper 		break;
799*3416500aSEnji Cooper #endif
80040a8ac8fSEnji Cooper 	case ACTION_MKDIR:
80140a8ac8fSEnji Cooper 		rval = mkdir(STR(0), (mode_t)NUM(1));
80240a8ac8fSEnji Cooper 		break;
803*3416500aSEnji Cooper #ifdef	HAVE_MKDIRAT
80440a8ac8fSEnji Cooper 	case ACTION_MKDIRAT:
80540a8ac8fSEnji Cooper 		rval = mkdirat(NUM(0), STR(1), (mode_t)NUM(2));
80640a8ac8fSEnji Cooper 		break;
807*3416500aSEnji Cooper #endif
80840a8ac8fSEnji Cooper 	case ACTION_RMDIR:
80940a8ac8fSEnji Cooper 		rval = rmdir(STR(0));
81040a8ac8fSEnji Cooper 		break;
81140a8ac8fSEnji Cooper 	case ACTION_LINK:
81240a8ac8fSEnji Cooper 		rval = link(STR(0), STR(1));
81340a8ac8fSEnji Cooper 		break;
814*3416500aSEnji Cooper #ifdef	HAVE_LINKAT
81540a8ac8fSEnji Cooper 	case ACTION_LINKAT:
81640a8ac8fSEnji Cooper 		rval = linkat(NUM(0), STR(1), NUM(2), STR(3),
81740a8ac8fSEnji Cooper 		    (int)str2flags(linkat_flags, STR(4)));
81840a8ac8fSEnji Cooper 		break;
819*3416500aSEnji Cooper #endif
82040a8ac8fSEnji Cooper 	case ACTION_SYMLINK:
82140a8ac8fSEnji Cooper 		rval = symlink(STR(0), STR(1));
82240a8ac8fSEnji Cooper 		break;
823*3416500aSEnji Cooper #ifdef	HAVE_SYMLINKAT
82440a8ac8fSEnji Cooper 	case ACTION_SYMLINKAT:
82540a8ac8fSEnji Cooper 		rval = symlinkat(STR(0), NUM(1), STR(2));
82640a8ac8fSEnji Cooper 		break;
827*3416500aSEnji Cooper #endif
82840a8ac8fSEnji Cooper 	case ACTION_RENAME:
82940a8ac8fSEnji Cooper 		rval = rename(STR(0), STR(1));
83040a8ac8fSEnji Cooper 		break;
831*3416500aSEnji Cooper #ifdef	HAVE_RENAMEAT
83240a8ac8fSEnji Cooper 	case ACTION_RENAMEAT:
83340a8ac8fSEnji Cooper 		rval = renameat(NUM(0), STR(1), NUM(2), STR(3));
83440a8ac8fSEnji Cooper 		break;
835*3416500aSEnji Cooper #endif
83640a8ac8fSEnji Cooper 	case ACTION_MKFIFO:
83740a8ac8fSEnji Cooper 		rval = mkfifo(STR(0), (mode_t)NUM(1));
83840a8ac8fSEnji Cooper 		break;
839*3416500aSEnji Cooper #ifdef	HAVE_MKFIFOAT
84040a8ac8fSEnji Cooper 	case ACTION_MKFIFOAT:
84140a8ac8fSEnji Cooper 		rval = mkfifoat(NUM(0), STR(1), (mode_t)NUM(2));
84240a8ac8fSEnji Cooper 		break;
843*3416500aSEnji Cooper #endif
84440a8ac8fSEnji Cooper 	case ACTION_MKNOD:
845*3416500aSEnji Cooper #ifdef	HAVE_MKNODAT
84640a8ac8fSEnji Cooper 	case ACTION_MKNODAT:
847*3416500aSEnji Cooper #endif
84840a8ac8fSEnji Cooper 	    {
84940a8ac8fSEnji Cooper 		mode_t ntype;
85040a8ac8fSEnji Cooper 		dev_t dev;
85140a8ac8fSEnji Cooper 		int fa;
85240a8ac8fSEnji Cooper 
85340a8ac8fSEnji Cooper 		switch (scall->sd_action) {
85440a8ac8fSEnji Cooper 		case ACTION_MKNOD:
85540a8ac8fSEnji Cooper 			fa = 0;
85640a8ac8fSEnji Cooper 			break;
857*3416500aSEnji Cooper #ifdef	HAVE_MKNODAT
85840a8ac8fSEnji Cooper 		case ACTION_MKNODAT:
85940a8ac8fSEnji Cooper 			fa = 1;
86040a8ac8fSEnji Cooper 			break;
861*3416500aSEnji Cooper #endif
86240a8ac8fSEnji Cooper 		default:
86340a8ac8fSEnji Cooper 			abort();
86440a8ac8fSEnji Cooper 		}
86540a8ac8fSEnji Cooper 
86640a8ac8fSEnji Cooper 		dev = makedev(NUM(fa + 3), NUM(fa + 4));
86740a8ac8fSEnji Cooper 		if (strcmp(STR(fa + 1), "c") == 0)	/* character device */
86840a8ac8fSEnji Cooper 			ntype = S_IFCHR;
86940a8ac8fSEnji Cooper 		else if (strcmp(STR(fa + 1), "b") == 0)	/* block device */
87040a8ac8fSEnji Cooper 			ntype = S_IFBLK;
87140a8ac8fSEnji Cooper 		else if (strcmp(STR(fa + 1), "f") == 0)	/* fifo special */
87240a8ac8fSEnji Cooper 			ntype = S_IFIFO;
87340a8ac8fSEnji Cooper 		else if (strcmp(STR(fa + 1), "d") == 0)	/* directory */
87440a8ac8fSEnji Cooper 			ntype = S_IFDIR;
87540a8ac8fSEnji Cooper 		else if (strcmp(STR(fa + 1), "o") == 0)	/* regular file */
87640a8ac8fSEnji Cooper 			ntype = S_IFREG;
87740a8ac8fSEnji Cooper 		else {
87840a8ac8fSEnji Cooper 			fprintf(stderr, "wrong argument 1\n");
87940a8ac8fSEnji Cooper 			exit(1);
88040a8ac8fSEnji Cooper 		}
88140a8ac8fSEnji Cooper 		switch (scall->sd_action) {
88240a8ac8fSEnji Cooper 		case ACTION_MKNOD:
88340a8ac8fSEnji Cooper 			rval = mknod(STR(0), ntype | NUM(2), dev);
88440a8ac8fSEnji Cooper 			break;
885*3416500aSEnji Cooper #ifdef	HAVE_MKNODAT
88640a8ac8fSEnji Cooper 		case ACTION_MKNODAT:
88740a8ac8fSEnji Cooper 			rval = mknodat(NUM(0), STR(1), ntype | NUM(3), dev);
88840a8ac8fSEnji Cooper 			break;
889*3416500aSEnji Cooper #endif
89040a8ac8fSEnji Cooper 		default:
89140a8ac8fSEnji Cooper 			abort();
89240a8ac8fSEnji Cooper 		}
89340a8ac8fSEnji Cooper 		break;
89440a8ac8fSEnji Cooper 	    }
89540a8ac8fSEnji Cooper 	case ACTION_BIND:
89640a8ac8fSEnji Cooper 	    {
89740a8ac8fSEnji Cooper 		struct sockaddr_un sunx;
89840a8ac8fSEnji Cooper 
89940a8ac8fSEnji Cooper 		sunx.sun_family = AF_UNIX;
90040a8ac8fSEnji Cooper 		strncpy(sunx.sun_path, STR(0), sizeof(sunx.sun_path) - 1);
90140a8ac8fSEnji Cooper 		sunx.sun_path[sizeof(sunx.sun_path) - 1] = '\0';
90240a8ac8fSEnji Cooper 		rval = socket(AF_UNIX, SOCK_STREAM, 0);
90340a8ac8fSEnji Cooper 		if (rval < 0)
90440a8ac8fSEnji Cooper 			break;
90540a8ac8fSEnji Cooper 		rval = bind(rval, (struct sockaddr *)&sunx, sizeof(sunx));
90640a8ac8fSEnji Cooper 		break;
90740a8ac8fSEnji Cooper 	    }
908*3416500aSEnji Cooper #ifdef	HAVE_BINDAT
90940a8ac8fSEnji Cooper 	case ACTION_BINDAT:
91040a8ac8fSEnji Cooper 	    {
91140a8ac8fSEnji Cooper 		struct sockaddr_un sunx;
91240a8ac8fSEnji Cooper 
91340a8ac8fSEnji Cooper 		sunx.sun_family = AF_UNIX;
91440a8ac8fSEnji Cooper 		strncpy(sunx.sun_path, STR(1), sizeof(sunx.sun_path) - 1);
91540a8ac8fSEnji Cooper 		sunx.sun_path[sizeof(sunx.sun_path) - 1] = '\0';
91640a8ac8fSEnji Cooper 		rval = socket(AF_UNIX, SOCK_STREAM, 0);
91740a8ac8fSEnji Cooper 		if (rval < 0)
91840a8ac8fSEnji Cooper 			break;
91940a8ac8fSEnji Cooper 		rval = bindat(NUM(0), rval, (struct sockaddr *)&sunx,
92040a8ac8fSEnji Cooper 		    sizeof(sunx));
92140a8ac8fSEnji Cooper 		break;
92240a8ac8fSEnji Cooper 	    }
92340a8ac8fSEnji Cooper #endif
92440a8ac8fSEnji Cooper 	case ACTION_CONNECT:
92540a8ac8fSEnji Cooper 	    {
92640a8ac8fSEnji Cooper 		struct sockaddr_un sunx;
92740a8ac8fSEnji Cooper 
92840a8ac8fSEnji Cooper 		sunx.sun_family = AF_UNIX;
92940a8ac8fSEnji Cooper 		strncpy(sunx.sun_path, STR(0), sizeof(sunx.sun_path) - 1);
93040a8ac8fSEnji Cooper 		sunx.sun_path[sizeof(sunx.sun_path) - 1] = '\0';
93140a8ac8fSEnji Cooper 		rval = socket(AF_UNIX, SOCK_STREAM, 0);
93240a8ac8fSEnji Cooper 		if (rval < 0)
93340a8ac8fSEnji Cooper 			break;
93440a8ac8fSEnji Cooper 		rval = connect(rval, (struct sockaddr *)&sunx, sizeof(sunx));
93540a8ac8fSEnji Cooper 		break;
93640a8ac8fSEnji Cooper 	    }
937*3416500aSEnji Cooper #ifdef	HAVE_CONNECTAT
93840a8ac8fSEnji Cooper 	case ACTION_CONNECTAT:
93940a8ac8fSEnji Cooper 	    {
94040a8ac8fSEnji Cooper 		struct sockaddr_un sunx;
94140a8ac8fSEnji Cooper 
94240a8ac8fSEnji Cooper 		sunx.sun_family = AF_UNIX;
94340a8ac8fSEnji Cooper 		strncpy(sunx.sun_path, STR(1), sizeof(sunx.sun_path) - 1);
94440a8ac8fSEnji Cooper 		sunx.sun_path[sizeof(sunx.sun_path) - 1] = '\0';
94540a8ac8fSEnji Cooper 		rval = socket(AF_UNIX, SOCK_STREAM, 0);
94640a8ac8fSEnji Cooper 		if (rval < 0)
94740a8ac8fSEnji Cooper 			break;
94840a8ac8fSEnji Cooper 		rval = connectat(NUM(0), rval, (struct sockaddr *)&sunx,
94940a8ac8fSEnji Cooper 		    sizeof(sunx));
95040a8ac8fSEnji Cooper 		break;
95140a8ac8fSEnji Cooper 	    }
95240a8ac8fSEnji Cooper #endif
95340a8ac8fSEnji Cooper 	case ACTION_CHMOD:
95440a8ac8fSEnji Cooper 		rval = chmod(STR(0), (mode_t)NUM(1));
95540a8ac8fSEnji Cooper 		break;
95640a8ac8fSEnji Cooper 	case ACTION_FCHMOD:
95740a8ac8fSEnji Cooper 		rval = fchmod(NUM(0), (mode_t)NUM(1));
95840a8ac8fSEnji Cooper 		break;
959*3416500aSEnji Cooper #ifdef	HAVE_LCHMOD
96040a8ac8fSEnji Cooper 	case ACTION_LCHMOD:
96140a8ac8fSEnji Cooper 		rval = lchmod(STR(0), (mode_t)NUM(1));
96240a8ac8fSEnji Cooper 		break;
96340a8ac8fSEnji Cooper #endif
964*3416500aSEnji Cooper #ifdef	HAVE_FCHMODAT
96540a8ac8fSEnji Cooper 	case ACTION_FCHMODAT:
96640a8ac8fSEnji Cooper 		rval = fchmodat(NUM(0), STR(1), (mode_t)NUM(2),
96740a8ac8fSEnji Cooper 		    str2flags(fchmodat_flags, STR(3)));
96840a8ac8fSEnji Cooper 		break;
969*3416500aSEnji Cooper #endif
97040a8ac8fSEnji Cooper 	case ACTION_CHOWN:
97140a8ac8fSEnji Cooper 		rval = chown(STR(0), (uid_t)NUM(1), (gid_t)NUM(2));
97240a8ac8fSEnji Cooper 		break;
97340a8ac8fSEnji Cooper 	case ACTION_FCHOWN:
97440a8ac8fSEnji Cooper 		rval = fchown(NUM(0), (uid_t)NUM(1), (gid_t)NUM(2));
97540a8ac8fSEnji Cooper 		break;
97640a8ac8fSEnji Cooper 	case ACTION_LCHOWN:
97740a8ac8fSEnji Cooper 		rval = lchown(STR(0), (uid_t)NUM(1), (gid_t)NUM(2));
97840a8ac8fSEnji Cooper 		break;
979*3416500aSEnji Cooper #ifdef	HAVE_FCHOWNAT
98040a8ac8fSEnji Cooper 	case ACTION_FCHOWNAT:
98140a8ac8fSEnji Cooper 		rval = fchownat(NUM(0), STR(1), (uid_t)NUM(2), (gid_t)NUM(3),
98240a8ac8fSEnji Cooper 		    (int)str2flags(fchownat_flags, STR(4)));
98340a8ac8fSEnji Cooper 		break;
984*3416500aSEnji Cooper #endif
985*3416500aSEnji Cooper #ifdef	HAVE_CHFLAGS
98640a8ac8fSEnji Cooper 	case ACTION_CHFLAGS:
98740a8ac8fSEnji Cooper 		rval = chflags(STR(0),
98840a8ac8fSEnji Cooper 		    (unsigned long)str2flags(chflags_flags, STR(1)));
98940a8ac8fSEnji Cooper 		break;
99040a8ac8fSEnji Cooper #endif
991*3416500aSEnji Cooper #ifdef	HAVE_FCHFLAGS
99240a8ac8fSEnji Cooper 	case ACTION_FCHFLAGS:
99340a8ac8fSEnji Cooper 		rval = fchflags(NUM(0),
99440a8ac8fSEnji Cooper 		    (unsigned long)str2flags(chflags_flags, STR(1)));
99540a8ac8fSEnji Cooper 		break;
99640a8ac8fSEnji Cooper #endif
997*3416500aSEnji Cooper #ifdef	HAVE_CHFLAGSAT
99840a8ac8fSEnji Cooper 	case ACTION_CHFLAGSAT:
99940a8ac8fSEnji Cooper 		rval = chflagsat(NUM(0), STR(1),
100040a8ac8fSEnji Cooper 		    (unsigned long)str2flags(chflags_flags, STR(2)),
100140a8ac8fSEnji Cooper 		    (int)str2flags(chflagsat_flags, STR(3)));
100240a8ac8fSEnji Cooper 		break;
100340a8ac8fSEnji Cooper #endif
1004*3416500aSEnji Cooper #ifdef	HAVE_LCHFLAGS
100540a8ac8fSEnji Cooper 	case ACTION_LCHFLAGS:
100640a8ac8fSEnji Cooper 		rval = lchflags(STR(0),
100740a8ac8fSEnji Cooper 		    (unsigned long)str2flags(chflags_flags, STR(1)));
100840a8ac8fSEnji Cooper 		break;
100940a8ac8fSEnji Cooper #endif
101040a8ac8fSEnji Cooper 	case ACTION_TRUNCATE:
1011*3416500aSEnji Cooper #ifdef	_USE_STAT64
101240a8ac8fSEnji Cooper 		rval = truncate64(STR(0), NUM(1));
1013*3416500aSEnji Cooper #else
1014*3416500aSEnji Cooper 		rval = truncate(STR(0), NUM(1));
1015*3416500aSEnji Cooper #endif
101640a8ac8fSEnji Cooper 		break;
101740a8ac8fSEnji Cooper 	case ACTION_FTRUNCATE:
1018*3416500aSEnji Cooper #ifdef	_USE_STAT64
101940a8ac8fSEnji Cooper 		rval = ftruncate64(NUM(0), NUM(1));
1020*3416500aSEnji Cooper #else
1021*3416500aSEnji Cooper 		rval = ftruncate(NUM(0), NUM(1));
1022*3416500aSEnji Cooper #endif
102340a8ac8fSEnji Cooper 		break;
1024*3416500aSEnji Cooper #ifdef	HAVE_POSIX_FALLOCATE
1025*3416500aSEnji Cooper 	case ACTION_POSIX_FALLOCATE:
1026*3416500aSEnji Cooper 		rval = posix_fallocate(NUM(0), NUM(1), NUM(2));
1027*3416500aSEnji Cooper 		if (rval != 0) {
1028*3416500aSEnji Cooper 			errno = rval;
1029*3416500aSEnji Cooper 			rval = -1;
1030*3416500aSEnji Cooper 		}
1031*3416500aSEnji Cooper 		break;
1032*3416500aSEnji Cooper #endif
103340a8ac8fSEnji Cooper 	case ACTION_STAT:
1034*3416500aSEnji Cooper #ifdef	_USE_STAT64
103540a8ac8fSEnji Cooper 		rval = stat64(STR(0), &sb);
1036*3416500aSEnji Cooper #else
1037*3416500aSEnji Cooper 		rval = stat(STR(0), &sb);
1038*3416500aSEnji Cooper #endif
103940a8ac8fSEnji Cooper 		if (rval == 0) {
104040a8ac8fSEnji Cooper 			show_stats(&sb, STR(1));
104140a8ac8fSEnji Cooper 			return (i);
104240a8ac8fSEnji Cooper 		}
104340a8ac8fSEnji Cooper 		break;
104440a8ac8fSEnji Cooper 	case ACTION_FSTAT:
1045*3416500aSEnji Cooper #ifdef	_USE_STAT64
104640a8ac8fSEnji Cooper 		rval = fstat64(NUM(0), &sb);
1047*3416500aSEnji Cooper #else
1048*3416500aSEnji Cooper 		rval = fstat(NUM(0), &sb);
1049*3416500aSEnji Cooper #endif
105040a8ac8fSEnji Cooper 		if (rval == 0) {
105140a8ac8fSEnji Cooper 			show_stats(&sb, STR(1));
105240a8ac8fSEnji Cooper 			return (i);
105340a8ac8fSEnji Cooper 		}
105440a8ac8fSEnji Cooper 		break;
105540a8ac8fSEnji Cooper 	case ACTION_LSTAT:
1056*3416500aSEnji Cooper #ifdef	_USE_STAT64
105740a8ac8fSEnji Cooper 		rval = lstat64(STR(0), &sb);
1058*3416500aSEnji Cooper #else
1059*3416500aSEnji Cooper 		rval = lstat(STR(0), &sb);
1060*3416500aSEnji Cooper #endif
106140a8ac8fSEnji Cooper 		if (rval == 0) {
106240a8ac8fSEnji Cooper 			show_stats(&sb, STR(1));
106340a8ac8fSEnji Cooper 			return (i);
106440a8ac8fSEnji Cooper 		}
106540a8ac8fSEnji Cooper 		break;
1066*3416500aSEnji Cooper #ifdef	HAVE_FSTATAT
106740a8ac8fSEnji Cooper 	case ACTION_FSTATAT:
106840a8ac8fSEnji Cooper 		rval = fstatat(NUM(0), STR(1), &sb,
106940a8ac8fSEnji Cooper 		    (int)str2flags(fstatat_flags, STR(2)));
107040a8ac8fSEnji Cooper 		if (rval == 0) {
107140a8ac8fSEnji Cooper 			show_stats(&sb, STR(3));
107240a8ac8fSEnji Cooper 			return (i);
107340a8ac8fSEnji Cooper 		}
107440a8ac8fSEnji Cooper 		break;
1075*3416500aSEnji Cooper #endif
107640a8ac8fSEnji Cooper 	case ACTION_PATHCONF:
107740a8ac8fSEnji Cooper 	case ACTION_FPATHCONF:
1078*3416500aSEnji Cooper #ifdef	HAVE_LPATHCONF
107940a8ac8fSEnji Cooper 	case ACTION_LPATHCONF:
108040a8ac8fSEnji Cooper #endif
108140a8ac8fSEnji Cooper 	    {
108240a8ac8fSEnji Cooper 		long lrval;
108340a8ac8fSEnji Cooper 
108440a8ac8fSEnji Cooper 		name = str2name(pathconf_names, STR(1));
108540a8ac8fSEnji Cooper 		if (name == -1) {
108640a8ac8fSEnji Cooper 			fprintf(stderr, "unknown name %s", STR(1));
108740a8ac8fSEnji Cooper 			exit(1);
108840a8ac8fSEnji Cooper 		}
108940a8ac8fSEnji Cooper 		errno = 0;
109040a8ac8fSEnji Cooper 		switch (scall->sd_action) {
109140a8ac8fSEnji Cooper 		case ACTION_PATHCONF:
109240a8ac8fSEnji Cooper 			lrval = pathconf(STR(0), name);
109340a8ac8fSEnji Cooper 			break;
109440a8ac8fSEnji Cooper 		case ACTION_FPATHCONF:
109540a8ac8fSEnji Cooper 			lrval = fpathconf(NUM(0), name);
109640a8ac8fSEnji Cooper 			break;
1097*3416500aSEnji Cooper #ifdef	HAVE_LPATHCONF
109840a8ac8fSEnji Cooper 		case ACTION_LPATHCONF:
109940a8ac8fSEnji Cooper 			lrval = lpathconf(STR(0), name);
110040a8ac8fSEnji Cooper 			break;
110140a8ac8fSEnji Cooper #endif
110240a8ac8fSEnji Cooper 		default:
110340a8ac8fSEnji Cooper 			abort();
110440a8ac8fSEnji Cooper 		}
110540a8ac8fSEnji Cooper 		if (lrval == -1 && errno == 0) {
110640a8ac8fSEnji Cooper 			printf("unlimited\n");
110740a8ac8fSEnji Cooper 			return (i);
110840a8ac8fSEnji Cooper 		} else if (lrval >= 0) {
110940a8ac8fSEnji Cooper 			printf("%ld\n", lrval);
111040a8ac8fSEnji Cooper 			return (i);
111140a8ac8fSEnji Cooper 		}
111240a8ac8fSEnji Cooper 		rval = -1;
111340a8ac8fSEnji Cooper 		break;
111440a8ac8fSEnji Cooper 	    }
1115*3416500aSEnji Cooper #ifdef	HAS_NFSV4_ACL_SUPPORT
111640a8ac8fSEnji Cooper 	case ACTION_PREPENDACL:
111740a8ac8fSEnji Cooper 		rval = -1;
111840a8ac8fSEnji Cooper 
111940a8ac8fSEnji Cooper 		acl = acl_get_file(STR(0), ACL_TYPE_NFS4);
112040a8ac8fSEnji Cooper 		if (acl == NULL)
112140a8ac8fSEnji Cooper 			break;
112240a8ac8fSEnji Cooper 
112340a8ac8fSEnji Cooper 		newacl = acl_from_text(STR(1));
112440a8ac8fSEnji Cooper 		if (acl == NULL)
112540a8ac8fSEnji Cooper 			break;
112640a8ac8fSEnji Cooper 
112740a8ac8fSEnji Cooper 		while (acl_get_entry(newacl, entry_id, &newentry) == 1) {
112840a8ac8fSEnji Cooper 			entry_id = ACL_NEXT_ENTRY;
112940a8ac8fSEnji Cooper 
113040a8ac8fSEnji Cooper 			if (acl_create_entry_np(&acl, &entry, 0))
113140a8ac8fSEnji Cooper 				break;
113240a8ac8fSEnji Cooper 
113340a8ac8fSEnji Cooper 			if (acl_copy_entry(entry, newentry))
113440a8ac8fSEnji Cooper 				break;
113540a8ac8fSEnji Cooper 		}
113640a8ac8fSEnji Cooper 
113740a8ac8fSEnji Cooper 		rval = acl_set_file(STR(0), ACL_TYPE_NFS4, acl);
113840a8ac8fSEnji Cooper 		break;
113940a8ac8fSEnji Cooper 	case ACTION_READACL:
114040a8ac8fSEnji Cooper 		acl = acl_get_file(STR(0), ACL_TYPE_NFS4);
114140a8ac8fSEnji Cooper 		if (acl == NULL)
114240a8ac8fSEnji Cooper 			rval = -1;
114340a8ac8fSEnji Cooper 		else
114440a8ac8fSEnji Cooper 			rval = 0;
114540a8ac8fSEnji Cooper 		break;
114640a8ac8fSEnji Cooper #endif
114740a8ac8fSEnji Cooper 	case ACTION_WRITE:
114840a8ac8fSEnji Cooper 		rval = write(NUM(0), STR(1), strlen(STR(1)));
114940a8ac8fSEnji Cooper 		break;
1150*3416500aSEnji Cooper #ifdef	HAVE_UTIMENSAT
1151*3416500aSEnji Cooper 	case ACTION_UTIMENSAT:
1152*3416500aSEnji Cooper 		times[0].tv_sec = NUM(2);
1153*3416500aSEnji Cooper 		if (strcmp(STR(3), "UTIME_NOW") == 0)
1154*3416500aSEnji Cooper 			times[0].tv_nsec = UTIME_NOW;
1155*3416500aSEnji Cooper 		else if (strcmp(STR(3), "UTIME_OMIT") == 0)
1156*3416500aSEnji Cooper 			times[0].tv_nsec = UTIME_OMIT;
1157*3416500aSEnji Cooper 		else
1158*3416500aSEnji Cooper 			times[0].tv_nsec = strtol(STR(3), NULL, 10);
1159*3416500aSEnji Cooper 		times[1].tv_sec = NUM(4);
1160*3416500aSEnji Cooper 		if (strcmp(STR(5), "UTIME_NOW") == 0)
1161*3416500aSEnji Cooper 			times[1].tv_nsec = UTIME_NOW;
1162*3416500aSEnji Cooper 		else if (strcmp(STR(5), "UTIME_OMIT") == 0)
1163*3416500aSEnji Cooper 			times[1].tv_nsec = UTIME_OMIT;
1164*3416500aSEnji Cooper 		else
1165*3416500aSEnji Cooper 			times[1].tv_nsec = strtol(STR(5), NULL, 10);
1166*3416500aSEnji Cooper 		if (strcmp(STR(6), "AT_SYMLINK_NOFOLLOW") == 0)
1167*3416500aSEnji Cooper 			flag = AT_SYMLINK_NOFOLLOW;
1168*3416500aSEnji Cooper 		else
1169*3416500aSEnji Cooper 			flag = strtol(STR(6), NULL, 10);
1170*3416500aSEnji Cooper 		rval = utimensat(NUM(0), STR(1), times, flag);
1171*3416500aSEnji Cooper 		break;
1172*3416500aSEnji Cooper #endif
117340a8ac8fSEnji Cooper 	default:
117440a8ac8fSEnji Cooper 		fprintf(stderr, "unsupported syscall\n");
117540a8ac8fSEnji Cooper 		exit(1);
117640a8ac8fSEnji Cooper 	}
117740a8ac8fSEnji Cooper #undef STR
117840a8ac8fSEnji Cooper #undef NUM
117940a8ac8fSEnji Cooper 	if (rval < 0) {
118040a8ac8fSEnji Cooper 		const char *serrno;
118140a8ac8fSEnji Cooper 
118240a8ac8fSEnji Cooper 		serrno = err2str(errno);
118340a8ac8fSEnji Cooper 		fprintf(stderr, "%s returned %d\n", scall->sd_name, rval);
118440a8ac8fSEnji Cooper 		printf("%s\n", serrno);
118540a8ac8fSEnji Cooper 		exit(1);
118640a8ac8fSEnji Cooper 	}
118740a8ac8fSEnji Cooper 	printf("0\n");
118840a8ac8fSEnji Cooper 	return (i);
118940a8ac8fSEnji Cooper }
119040a8ac8fSEnji Cooper 
119140a8ac8fSEnji Cooper static void
set_gids(char * gids)119240a8ac8fSEnji Cooper set_gids(char *gids)
119340a8ac8fSEnji Cooper {
119440a8ac8fSEnji Cooper 	gid_t *gidset;
119540a8ac8fSEnji Cooper 	long ngroups;
119640a8ac8fSEnji Cooper 	char *g, *endp;
119740a8ac8fSEnji Cooper 	unsigned i;
119840a8ac8fSEnji Cooper 
119940a8ac8fSEnji Cooper 	ngroups = sysconf(_SC_NGROUPS_MAX);
120040a8ac8fSEnji Cooper 	assert(ngroups > 0);
120140a8ac8fSEnji Cooper 	gidset = malloc(sizeof(*gidset) * ngroups);
120240a8ac8fSEnji Cooper 	assert(gidset != NULL);
120340a8ac8fSEnji Cooper 	for (i = 0, g = strtok(gids, ","); g != NULL;
120440a8ac8fSEnji Cooper 	    g = strtok(NULL, ","), i++) {
1205*3416500aSEnji Cooper 		if ((long)i >= ngroups) {
120640a8ac8fSEnji Cooper 			fprintf(stderr, "too many gids\n");
120740a8ac8fSEnji Cooper 			exit(1);
120840a8ac8fSEnji Cooper 		}
120940a8ac8fSEnji Cooper 		gidset[i] = strtol(g, &endp, 0);
121040a8ac8fSEnji Cooper 		if (*endp != '\0' && !isspace((unsigned char)*endp)) {
121140a8ac8fSEnji Cooper 			fprintf(stderr, "invalid gid '%s' - number expected\n",
121240a8ac8fSEnji Cooper 			    g);
121340a8ac8fSEnji Cooper 			exit(1);
121440a8ac8fSEnji Cooper 		}
121540a8ac8fSEnji Cooper 	}
121640a8ac8fSEnji Cooper 	if (setgroups(i, gidset) < 0) {
121740a8ac8fSEnji Cooper 		fprintf(stderr, "cannot change groups: %s\n", strerror(errno));
121840a8ac8fSEnji Cooper 		exit(1);
121940a8ac8fSEnji Cooper 	}
122040a8ac8fSEnji Cooper 	if (setegid(gidset[0]) < 0) {
122140a8ac8fSEnji Cooper 		fprintf(stderr, "cannot change effective gid: %s\n",
122240a8ac8fSEnji Cooper 		    strerror(errno));
122340a8ac8fSEnji Cooper 		exit(1);
122440a8ac8fSEnji Cooper 	}
122540a8ac8fSEnji Cooper 	free(gidset);
122640a8ac8fSEnji Cooper }
122740a8ac8fSEnji Cooper 
122840a8ac8fSEnji Cooper int
main(int argc,char * argv[])122940a8ac8fSEnji Cooper main(int argc, char *argv[])
123040a8ac8fSEnji Cooper {
123140a8ac8fSEnji Cooper 	struct syscall_desc *scall;
123240a8ac8fSEnji Cooper 	unsigned int n;
123340a8ac8fSEnji Cooper 	char *gids, *endp;
123440a8ac8fSEnji Cooper 	int uid, umsk, ch;
123540a8ac8fSEnji Cooper 
123640a8ac8fSEnji Cooper 	uid = -1;
123740a8ac8fSEnji Cooper 	gids = NULL;
123840a8ac8fSEnji Cooper 	umsk = 0;
123940a8ac8fSEnji Cooper 
124040a8ac8fSEnji Cooper 	while ((ch = getopt(argc, argv, "g:u:U:")) != -1) {
124140a8ac8fSEnji Cooper 		switch(ch) {
124240a8ac8fSEnji Cooper 		case 'g':
124340a8ac8fSEnji Cooper 			gids = optarg;
124440a8ac8fSEnji Cooper 			break;
124540a8ac8fSEnji Cooper 		case 'u':
124640a8ac8fSEnji Cooper 			uid = (int)strtol(optarg, &endp, 0);
124740a8ac8fSEnji Cooper 			if (*endp != '\0' && !isspace((unsigned char)*endp)) {
124840a8ac8fSEnji Cooper 				fprintf(stderr, "invalid uid '%s' - number "
124940a8ac8fSEnji Cooper 				    "expected\n", optarg);
125040a8ac8fSEnji Cooper 				exit(1);
125140a8ac8fSEnji Cooper 			}
125240a8ac8fSEnji Cooper 			break;
125340a8ac8fSEnji Cooper 		case 'U':
125440a8ac8fSEnji Cooper 			umsk = (int)strtol(optarg, &endp, 0);
125540a8ac8fSEnji Cooper 			if (*endp != '\0' && !isspace((unsigned char)*endp)) {
125640a8ac8fSEnji Cooper 				fprintf(stderr, "invalid umask '%s' - number "
125740a8ac8fSEnji Cooper 				    "expected\n", optarg);
125840a8ac8fSEnji Cooper 				exit(1);
125940a8ac8fSEnji Cooper 			}
126040a8ac8fSEnji Cooper 			break;
126140a8ac8fSEnji Cooper 		default:
126240a8ac8fSEnji Cooper 			usage();
126340a8ac8fSEnji Cooper 		}
126440a8ac8fSEnji Cooper 	}
126540a8ac8fSEnji Cooper 	argc -= optind;
126640a8ac8fSEnji Cooper 	argv += optind;
126740a8ac8fSEnji Cooper 
126840a8ac8fSEnji Cooper 	if (argc < 1) {
126940a8ac8fSEnji Cooper 		fprintf(stderr, "too few arguments\n");
127040a8ac8fSEnji Cooper 		usage();
127140a8ac8fSEnji Cooper 	}
127240a8ac8fSEnji Cooper 
127340a8ac8fSEnji Cooper 	if (gids != NULL) {
127440a8ac8fSEnji Cooper 		fprintf(stderr, "changing groups to %s\n", gids);
127540a8ac8fSEnji Cooper 		set_gids(gids);
127640a8ac8fSEnji Cooper 	}
127740a8ac8fSEnji Cooper 	if (uid != -1) {
127840a8ac8fSEnji Cooper 		fprintf(stderr, "changing uid to %d\n", uid);
127940a8ac8fSEnji Cooper 		if (setuid(uid) < 0) {
128040a8ac8fSEnji Cooper 			fprintf(stderr, "cannot change uid: %s\n",
128140a8ac8fSEnji Cooper 			    strerror(errno));
128240a8ac8fSEnji Cooper 			exit(1);
128340a8ac8fSEnji Cooper 		}
128440a8ac8fSEnji Cooper 	}
128540a8ac8fSEnji Cooper 
128640a8ac8fSEnji Cooper 	/* Change umask to requested value or to 0, if not requested. */
128740a8ac8fSEnji Cooper 	umask(umsk);
128840a8ac8fSEnji Cooper 
128940a8ac8fSEnji Cooper 	for (;;) {
129040a8ac8fSEnji Cooper 		scall = find_syscall(argv[0]);
129140a8ac8fSEnji Cooper 		if (scall == NULL) {
129240a8ac8fSEnji Cooper 			fprintf(stderr, "syscall '%s' not supported\n",
129340a8ac8fSEnji Cooper 			    argv[0]);
129440a8ac8fSEnji Cooper 			exit(1);
129540a8ac8fSEnji Cooper 		}
129640a8ac8fSEnji Cooper 		argc++;
129740a8ac8fSEnji Cooper 		argv++;
129840a8ac8fSEnji Cooper 		n = call_syscall(scall, argv);
129940a8ac8fSEnji Cooper 		argc += n;
130040a8ac8fSEnji Cooper 		argv += n;
130140a8ac8fSEnji Cooper 		if (argv[0] == NULL)
130240a8ac8fSEnji Cooper 			break;
130340a8ac8fSEnji Cooper 		argc++;
130440a8ac8fSEnji Cooper 		argv++;
130540a8ac8fSEnji Cooper 	}
130640a8ac8fSEnji Cooper 
130740a8ac8fSEnji Cooper 	exit(0);
130840a8ac8fSEnji Cooper }
130940a8ac8fSEnji Cooper 
131040a8ac8fSEnji Cooper static const char *
err2str(int error)131140a8ac8fSEnji Cooper err2str(int error)
131240a8ac8fSEnji Cooper {
131340a8ac8fSEnji Cooper 	static char errnum[8];
131440a8ac8fSEnji Cooper 
131540a8ac8fSEnji Cooper 	switch (error) {
131640a8ac8fSEnji Cooper #ifdef	EPERM
131740a8ac8fSEnji Cooper 	case EPERM:
131840a8ac8fSEnji Cooper 		return ("EPERM");
131940a8ac8fSEnji Cooper #endif
132040a8ac8fSEnji Cooper #ifdef	ENOENT
132140a8ac8fSEnji Cooper 	case ENOENT:
132240a8ac8fSEnji Cooper 		return ("ENOENT");
132340a8ac8fSEnji Cooper #endif
132440a8ac8fSEnji Cooper #ifdef	ESRCH
132540a8ac8fSEnji Cooper 	case ESRCH:
132640a8ac8fSEnji Cooper 		return ("ESRCH");
132740a8ac8fSEnji Cooper #endif
132840a8ac8fSEnji Cooper #ifdef	EINTR
132940a8ac8fSEnji Cooper 	case EINTR:
133040a8ac8fSEnji Cooper 		return ("EINTR");
133140a8ac8fSEnji Cooper #endif
133240a8ac8fSEnji Cooper #ifdef	EIO
133340a8ac8fSEnji Cooper 	case EIO:
133440a8ac8fSEnji Cooper 		return ("EIO");
133540a8ac8fSEnji Cooper #endif
133640a8ac8fSEnji Cooper #ifdef	ENXIO
133740a8ac8fSEnji Cooper 	case ENXIO:
133840a8ac8fSEnji Cooper 		return ("ENXIO");
133940a8ac8fSEnji Cooper #endif
134040a8ac8fSEnji Cooper #ifdef	E2BIG
134140a8ac8fSEnji Cooper 	case E2BIG:
134240a8ac8fSEnji Cooper 		return ("E2BIG");
134340a8ac8fSEnji Cooper #endif
134440a8ac8fSEnji Cooper #ifdef	ENOEXEC
134540a8ac8fSEnji Cooper 	case ENOEXEC:
134640a8ac8fSEnji Cooper 		return ("ENOEXEC");
134740a8ac8fSEnji Cooper #endif
134840a8ac8fSEnji Cooper #ifdef	EBADF
134940a8ac8fSEnji Cooper 	case EBADF:
135040a8ac8fSEnji Cooper 		return ("EBADF");
135140a8ac8fSEnji Cooper #endif
135240a8ac8fSEnji Cooper #ifdef	ECHILD
135340a8ac8fSEnji Cooper 	case ECHILD:
135440a8ac8fSEnji Cooper 		return ("ECHILD");
135540a8ac8fSEnji Cooper #endif
135640a8ac8fSEnji Cooper #ifdef	EDEADLK
135740a8ac8fSEnji Cooper 	case EDEADLK:
135840a8ac8fSEnji Cooper 		return ("EDEADLK");
135940a8ac8fSEnji Cooper #endif
136040a8ac8fSEnji Cooper #ifdef	ENOMEM
136140a8ac8fSEnji Cooper 	case ENOMEM:
136240a8ac8fSEnji Cooper 		return ("ENOMEM");
136340a8ac8fSEnji Cooper #endif
136440a8ac8fSEnji Cooper #ifdef	EACCES
136540a8ac8fSEnji Cooper 	case EACCES:
136640a8ac8fSEnji Cooper 		return ("EACCES");
136740a8ac8fSEnji Cooper #endif
136840a8ac8fSEnji Cooper #ifdef	EFAULT
136940a8ac8fSEnji Cooper 	case EFAULT:
137040a8ac8fSEnji Cooper 		return ("EFAULT");
137140a8ac8fSEnji Cooper #endif
137240a8ac8fSEnji Cooper #ifdef	ENOTBLK
137340a8ac8fSEnji Cooper 	case ENOTBLK:
137440a8ac8fSEnji Cooper 		return ("ENOTBLK");
137540a8ac8fSEnji Cooper #endif
137640a8ac8fSEnji Cooper #ifdef	EBUSY
137740a8ac8fSEnji Cooper 	case EBUSY:
137840a8ac8fSEnji Cooper 		return ("EBUSY");
137940a8ac8fSEnji Cooper #endif
138040a8ac8fSEnji Cooper #ifdef	EEXIST
138140a8ac8fSEnji Cooper 	case EEXIST:
138240a8ac8fSEnji Cooper 		return ("EEXIST");
138340a8ac8fSEnji Cooper #endif
138440a8ac8fSEnji Cooper #ifdef	EXDEV
138540a8ac8fSEnji Cooper 	case EXDEV:
138640a8ac8fSEnji Cooper 		return ("EXDEV");
138740a8ac8fSEnji Cooper #endif
138840a8ac8fSEnji Cooper #ifdef	ENODEV
138940a8ac8fSEnji Cooper 	case ENODEV:
139040a8ac8fSEnji Cooper 		return ("ENODEV");
139140a8ac8fSEnji Cooper #endif
139240a8ac8fSEnji Cooper #ifdef	ENOTDIR
139340a8ac8fSEnji Cooper 	case ENOTDIR:
139440a8ac8fSEnji Cooper 		return ("ENOTDIR");
139540a8ac8fSEnji Cooper #endif
139640a8ac8fSEnji Cooper #ifdef	EISDIR
139740a8ac8fSEnji Cooper 	case EISDIR:
139840a8ac8fSEnji Cooper 		return ("EISDIR");
139940a8ac8fSEnji Cooper #endif
140040a8ac8fSEnji Cooper #ifdef	EINVAL
140140a8ac8fSEnji Cooper 	case EINVAL:
140240a8ac8fSEnji Cooper 		return ("EINVAL");
140340a8ac8fSEnji Cooper #endif
140440a8ac8fSEnji Cooper #ifdef	ENFILE
140540a8ac8fSEnji Cooper 	case ENFILE:
140640a8ac8fSEnji Cooper 		return ("ENFILE");
140740a8ac8fSEnji Cooper #endif
140840a8ac8fSEnji Cooper #ifdef	EMFILE
140940a8ac8fSEnji Cooper 	case EMFILE:
141040a8ac8fSEnji Cooper 		return ("EMFILE");
141140a8ac8fSEnji Cooper #endif
141240a8ac8fSEnji Cooper #ifdef	ENOTTY
141340a8ac8fSEnji Cooper 	case ENOTTY:
141440a8ac8fSEnji Cooper 		return ("ENOTTY");
141540a8ac8fSEnji Cooper #endif
141640a8ac8fSEnji Cooper #ifdef	ETXTBSY
141740a8ac8fSEnji Cooper 	case ETXTBSY:
141840a8ac8fSEnji Cooper 		return ("ETXTBSY");
141940a8ac8fSEnji Cooper #endif
142040a8ac8fSEnji Cooper #ifdef	EFBIG
142140a8ac8fSEnji Cooper 	case EFBIG:
142240a8ac8fSEnji Cooper 		return ("EFBIG");
142340a8ac8fSEnji Cooper #endif
142440a8ac8fSEnji Cooper #ifdef	ENOSPC
142540a8ac8fSEnji Cooper 	case ENOSPC:
142640a8ac8fSEnji Cooper 		return ("ENOSPC");
142740a8ac8fSEnji Cooper #endif
142840a8ac8fSEnji Cooper #ifdef	ESPIPE
142940a8ac8fSEnji Cooper 	case ESPIPE:
143040a8ac8fSEnji Cooper 		return ("ESPIPE");
143140a8ac8fSEnji Cooper #endif
143240a8ac8fSEnji Cooper #ifdef	EROFS
143340a8ac8fSEnji Cooper 	case EROFS:
143440a8ac8fSEnji Cooper 		return ("EROFS");
143540a8ac8fSEnji Cooper #endif
143640a8ac8fSEnji Cooper #ifdef	EMLINK
143740a8ac8fSEnji Cooper 	case EMLINK:
143840a8ac8fSEnji Cooper 		return ("EMLINK");
143940a8ac8fSEnji Cooper #endif
144040a8ac8fSEnji Cooper #ifdef	EPIPE
144140a8ac8fSEnji Cooper 	case EPIPE:
144240a8ac8fSEnji Cooper 		return ("EPIPE");
144340a8ac8fSEnji Cooper #endif
144440a8ac8fSEnji Cooper #ifdef	EDOM
144540a8ac8fSEnji Cooper 	case EDOM:
144640a8ac8fSEnji Cooper 		return ("EDOM");
144740a8ac8fSEnji Cooper #endif
144840a8ac8fSEnji Cooper #ifdef	ERANGE
144940a8ac8fSEnji Cooper 	case ERANGE:
145040a8ac8fSEnji Cooper 		return ("ERANGE");
145140a8ac8fSEnji Cooper #endif
145240a8ac8fSEnji Cooper #ifdef	EAGAIN
145340a8ac8fSEnji Cooper 	case EAGAIN:
145440a8ac8fSEnji Cooper 		return ("EAGAIN");
145540a8ac8fSEnji Cooper #endif
145640a8ac8fSEnji Cooper #ifdef	EINPROGRESS
145740a8ac8fSEnji Cooper 	case EINPROGRESS:
145840a8ac8fSEnji Cooper 		return ("EINPROGRESS");
145940a8ac8fSEnji Cooper #endif
146040a8ac8fSEnji Cooper #ifdef	EALREADY
146140a8ac8fSEnji Cooper 	case EALREADY:
146240a8ac8fSEnji Cooper 		return ("EALREADY");
146340a8ac8fSEnji Cooper #endif
146440a8ac8fSEnji Cooper #ifdef	ENOTSOCK
146540a8ac8fSEnji Cooper 	case ENOTSOCK:
146640a8ac8fSEnji Cooper 		return ("ENOTSOCK");
146740a8ac8fSEnji Cooper #endif
146840a8ac8fSEnji Cooper #ifdef	EDESTADDRREQ
146940a8ac8fSEnji Cooper 	case EDESTADDRREQ:
147040a8ac8fSEnji Cooper 		return ("EDESTADDRREQ");
147140a8ac8fSEnji Cooper #endif
147240a8ac8fSEnji Cooper #ifdef	EMSGSIZE
147340a8ac8fSEnji Cooper 	case EMSGSIZE:
147440a8ac8fSEnji Cooper 		return ("EMSGSIZE");
147540a8ac8fSEnji Cooper #endif
147640a8ac8fSEnji Cooper #ifdef	EPROTOTYPE
147740a8ac8fSEnji Cooper 	case EPROTOTYPE:
147840a8ac8fSEnji Cooper 		return ("EPROTOTYPE");
147940a8ac8fSEnji Cooper #endif
148040a8ac8fSEnji Cooper #ifdef	ENOPROTOOPT
148140a8ac8fSEnji Cooper 	case ENOPROTOOPT:
148240a8ac8fSEnji Cooper 		return ("ENOPROTOOPT");
148340a8ac8fSEnji Cooper #endif
148440a8ac8fSEnji Cooper #ifdef	EPROTONOSUPPORT
148540a8ac8fSEnji Cooper 	case EPROTONOSUPPORT:
148640a8ac8fSEnji Cooper 		return ("EPROTONOSUPPORT");
148740a8ac8fSEnji Cooper #endif
148840a8ac8fSEnji Cooper #ifdef	ESOCKTNOSUPPORT
148940a8ac8fSEnji Cooper 	case ESOCKTNOSUPPORT:
149040a8ac8fSEnji Cooper 		return ("ESOCKTNOSUPPORT");
149140a8ac8fSEnji Cooper #endif
149240a8ac8fSEnji Cooper #ifdef	EOPNOTSUPP
149340a8ac8fSEnji Cooper 	case EOPNOTSUPP:
149440a8ac8fSEnji Cooper 		return ("EOPNOTSUPP");
149540a8ac8fSEnji Cooper #endif
149640a8ac8fSEnji Cooper #ifdef	EPFNOSUPPORT
149740a8ac8fSEnji Cooper 	case EPFNOSUPPORT:
149840a8ac8fSEnji Cooper 		return ("EPFNOSUPPORT");
149940a8ac8fSEnji Cooper #endif
150040a8ac8fSEnji Cooper #ifdef	EAFNOSUPPORT
150140a8ac8fSEnji Cooper 	case EAFNOSUPPORT:
150240a8ac8fSEnji Cooper 		return ("EAFNOSUPPORT");
150340a8ac8fSEnji Cooper #endif
150440a8ac8fSEnji Cooper #ifdef	EADDRINUSE
150540a8ac8fSEnji Cooper 	case EADDRINUSE:
150640a8ac8fSEnji Cooper 		return ("EADDRINUSE");
150740a8ac8fSEnji Cooper #endif
150840a8ac8fSEnji Cooper #ifdef	EADDRNOTAVAIL
150940a8ac8fSEnji Cooper 	case EADDRNOTAVAIL:
151040a8ac8fSEnji Cooper 		return ("EADDRNOTAVAIL");
151140a8ac8fSEnji Cooper #endif
151240a8ac8fSEnji Cooper #ifdef	ENETDOWN
151340a8ac8fSEnji Cooper 	case ENETDOWN:
151440a8ac8fSEnji Cooper 		return ("ENETDOWN");
151540a8ac8fSEnji Cooper #endif
151640a8ac8fSEnji Cooper #ifdef	ENETUNREACH
151740a8ac8fSEnji Cooper 	case ENETUNREACH:
151840a8ac8fSEnji Cooper 		return ("ENETUNREACH");
151940a8ac8fSEnji Cooper #endif
152040a8ac8fSEnji Cooper #ifdef	ENETRESET
152140a8ac8fSEnji Cooper 	case ENETRESET:
152240a8ac8fSEnji Cooper 		return ("ENETRESET");
152340a8ac8fSEnji Cooper #endif
152440a8ac8fSEnji Cooper #ifdef	ECONNABORTED
152540a8ac8fSEnji Cooper 	case ECONNABORTED:
152640a8ac8fSEnji Cooper 		return ("ECONNABORTED");
152740a8ac8fSEnji Cooper #endif
152840a8ac8fSEnji Cooper #ifdef	ECONNRESET
152940a8ac8fSEnji Cooper 	case ECONNRESET:
153040a8ac8fSEnji Cooper 		return ("ECONNRESET");
153140a8ac8fSEnji Cooper #endif
153240a8ac8fSEnji Cooper #ifdef	ENOBUFS
153340a8ac8fSEnji Cooper 	case ENOBUFS:
153440a8ac8fSEnji Cooper 		return ("ENOBUFS");
153540a8ac8fSEnji Cooper #endif
153640a8ac8fSEnji Cooper #ifdef	EISCONN
153740a8ac8fSEnji Cooper 	case EISCONN:
153840a8ac8fSEnji Cooper 		return ("EISCONN");
153940a8ac8fSEnji Cooper #endif
154040a8ac8fSEnji Cooper #ifdef	ENOTCONN
154140a8ac8fSEnji Cooper 	case ENOTCONN:
154240a8ac8fSEnji Cooper 		return ("ENOTCONN");
154340a8ac8fSEnji Cooper #endif
154440a8ac8fSEnji Cooper #ifdef	ESHUTDOWN
154540a8ac8fSEnji Cooper 	case ESHUTDOWN:
154640a8ac8fSEnji Cooper 		return ("ESHUTDOWN");
154740a8ac8fSEnji Cooper #endif
154840a8ac8fSEnji Cooper #ifdef	ETOOMANYREFS
154940a8ac8fSEnji Cooper 	case ETOOMANYREFS:
155040a8ac8fSEnji Cooper 		return ("ETOOMANYREFS");
155140a8ac8fSEnji Cooper #endif
155240a8ac8fSEnji Cooper #ifdef	ETIMEDOUT
155340a8ac8fSEnji Cooper 	case ETIMEDOUT:
155440a8ac8fSEnji Cooper 		return ("ETIMEDOUT");
155540a8ac8fSEnji Cooper #endif
155640a8ac8fSEnji Cooper #ifdef	ECONNREFUSED
155740a8ac8fSEnji Cooper 	case ECONNREFUSED:
155840a8ac8fSEnji Cooper 		return ("ECONNREFUSED");
155940a8ac8fSEnji Cooper #endif
156040a8ac8fSEnji Cooper #ifdef	ELOOP
156140a8ac8fSEnji Cooper 	case ELOOP:
156240a8ac8fSEnji Cooper 		return ("ELOOP");
156340a8ac8fSEnji Cooper #endif
156440a8ac8fSEnji Cooper #ifdef	ENAMETOOLONG
156540a8ac8fSEnji Cooper 	case ENAMETOOLONG:
156640a8ac8fSEnji Cooper 		return ("ENAMETOOLONG");
156740a8ac8fSEnji Cooper #endif
156840a8ac8fSEnji Cooper #ifdef	EHOSTDOWN
156940a8ac8fSEnji Cooper 	case EHOSTDOWN:
157040a8ac8fSEnji Cooper 		return ("EHOSTDOWN");
157140a8ac8fSEnji Cooper #endif
157240a8ac8fSEnji Cooper #ifdef	EHOSTUNREACH
157340a8ac8fSEnji Cooper 	case EHOSTUNREACH:
157440a8ac8fSEnji Cooper 		return ("EHOSTUNREACH");
157540a8ac8fSEnji Cooper #endif
157640a8ac8fSEnji Cooper #ifdef	ENOTEMPTY
157740a8ac8fSEnji Cooper 	case ENOTEMPTY:
157840a8ac8fSEnji Cooper 		return ("ENOTEMPTY");
157940a8ac8fSEnji Cooper #endif
158040a8ac8fSEnji Cooper #ifdef	EPROCLIM
158140a8ac8fSEnji Cooper 	case EPROCLIM:
158240a8ac8fSEnji Cooper 		return ("EPROCLIM");
158340a8ac8fSEnji Cooper #endif
158440a8ac8fSEnji Cooper #ifdef	EUSERS
158540a8ac8fSEnji Cooper 	case EUSERS:
158640a8ac8fSEnji Cooper 		return ("EUSERS");
158740a8ac8fSEnji Cooper #endif
158840a8ac8fSEnji Cooper #ifdef	EDQUOT
158940a8ac8fSEnji Cooper 	case EDQUOT:
159040a8ac8fSEnji Cooper 		return ("EDQUOT");
159140a8ac8fSEnji Cooper #endif
159240a8ac8fSEnji Cooper #ifdef	ESTALE
159340a8ac8fSEnji Cooper 	case ESTALE:
159440a8ac8fSEnji Cooper 		return ("ESTALE");
159540a8ac8fSEnji Cooper #endif
159640a8ac8fSEnji Cooper #ifdef	EREMOTE
159740a8ac8fSEnji Cooper 	case EREMOTE:
159840a8ac8fSEnji Cooper 		return ("EREMOTE");
159940a8ac8fSEnji Cooper #endif
160040a8ac8fSEnji Cooper #ifdef	EBADRPC
160140a8ac8fSEnji Cooper 	case EBADRPC:
160240a8ac8fSEnji Cooper 		return ("EBADRPC");
160340a8ac8fSEnji Cooper #endif
160440a8ac8fSEnji Cooper #ifdef	ERPCMISMATCH
160540a8ac8fSEnji Cooper 	case ERPCMISMATCH:
160640a8ac8fSEnji Cooper 		return ("ERPCMISMATCH");
160740a8ac8fSEnji Cooper #endif
160840a8ac8fSEnji Cooper #ifdef	EPROGUNAVAIL
160940a8ac8fSEnji Cooper 	case EPROGUNAVAIL:
161040a8ac8fSEnji Cooper 		return ("EPROGUNAVAIL");
161140a8ac8fSEnji Cooper #endif
161240a8ac8fSEnji Cooper #ifdef	EPROGMISMATCH
161340a8ac8fSEnji Cooper 	case EPROGMISMATCH:
161440a8ac8fSEnji Cooper 		return ("EPROGMISMATCH");
161540a8ac8fSEnji Cooper #endif
161640a8ac8fSEnji Cooper #ifdef	EPROCUNAVAIL
161740a8ac8fSEnji Cooper 	case EPROCUNAVAIL:
161840a8ac8fSEnji Cooper 		return ("EPROCUNAVAIL");
161940a8ac8fSEnji Cooper #endif
162040a8ac8fSEnji Cooper #ifdef	ENOLCK
162140a8ac8fSEnji Cooper 	case ENOLCK:
162240a8ac8fSEnji Cooper 		return ("ENOLCK");
162340a8ac8fSEnji Cooper #endif
162440a8ac8fSEnji Cooper #ifdef	ENOSYS
162540a8ac8fSEnji Cooper 	case ENOSYS:
162640a8ac8fSEnji Cooper 		return ("ENOSYS");
162740a8ac8fSEnji Cooper #endif
162840a8ac8fSEnji Cooper #ifdef	EFTYPE
162940a8ac8fSEnji Cooper 	case EFTYPE:
163040a8ac8fSEnji Cooper 		return ("EFTYPE");
163140a8ac8fSEnji Cooper #endif
163240a8ac8fSEnji Cooper #ifdef	EAUTH
163340a8ac8fSEnji Cooper 	case EAUTH:
163440a8ac8fSEnji Cooper 		return ("EAUTH");
163540a8ac8fSEnji Cooper #endif
163640a8ac8fSEnji Cooper #ifdef	ENEEDAUTH
163740a8ac8fSEnji Cooper 	case ENEEDAUTH:
163840a8ac8fSEnji Cooper 		return ("ENEEDAUTH");
163940a8ac8fSEnji Cooper #endif
164040a8ac8fSEnji Cooper #ifdef	EIDRM
164140a8ac8fSEnji Cooper 	case EIDRM:
164240a8ac8fSEnji Cooper 		return ("EIDRM");
164340a8ac8fSEnji Cooper #endif
164440a8ac8fSEnji Cooper #ifdef	ENOMSG
164540a8ac8fSEnji Cooper 	case ENOMSG:
164640a8ac8fSEnji Cooper 		return ("ENOMSG");
164740a8ac8fSEnji Cooper #endif
164840a8ac8fSEnji Cooper #ifdef	EOVERFLOW
164940a8ac8fSEnji Cooper 	case EOVERFLOW:
165040a8ac8fSEnji Cooper 		return ("EOVERFLOW");
165140a8ac8fSEnji Cooper #endif
165240a8ac8fSEnji Cooper #ifdef	ECANCELED
165340a8ac8fSEnji Cooper 	case ECANCELED:
165440a8ac8fSEnji Cooper 		return ("ECANCELED");
165540a8ac8fSEnji Cooper #endif
165640a8ac8fSEnji Cooper #ifdef	EILSEQ
165740a8ac8fSEnji Cooper 	case EILSEQ:
165840a8ac8fSEnji Cooper 		return ("EILSEQ");
165940a8ac8fSEnji Cooper #endif
166040a8ac8fSEnji Cooper #ifdef	ENOATTR
166140a8ac8fSEnji Cooper 	case ENOATTR:
166240a8ac8fSEnji Cooper 		return ("ENOATTR");
166340a8ac8fSEnji Cooper #endif
166440a8ac8fSEnji Cooper #ifdef	EDOOFUS
166540a8ac8fSEnji Cooper 	case EDOOFUS:
166640a8ac8fSEnji Cooper 		return ("EDOOFUS");
166740a8ac8fSEnji Cooper #endif
166840a8ac8fSEnji Cooper #ifdef	EBADMSG
166940a8ac8fSEnji Cooper 	case EBADMSG:
167040a8ac8fSEnji Cooper 		return ("EBADMSG");
167140a8ac8fSEnji Cooper #endif
167240a8ac8fSEnji Cooper #ifdef	EMULTIHOP
167340a8ac8fSEnji Cooper 	case EMULTIHOP:
167440a8ac8fSEnji Cooper 		return ("EMULTIHOP");
167540a8ac8fSEnji Cooper #endif
167640a8ac8fSEnji Cooper #ifdef	ENOLINK
167740a8ac8fSEnji Cooper 	case ENOLINK:
167840a8ac8fSEnji Cooper 		return ("ENOLINK");
167940a8ac8fSEnji Cooper #endif
168040a8ac8fSEnji Cooper #ifdef	EPROTO
168140a8ac8fSEnji Cooper 	case EPROTO:
168240a8ac8fSEnji Cooper 		return ("EPROTO");
168340a8ac8fSEnji Cooper #endif
168440a8ac8fSEnji Cooper 	default:
168540a8ac8fSEnji Cooper 		snprintf(errnum, sizeof(errnum), "%d", error);
168640a8ac8fSEnji Cooper 		return (errnum);
168740a8ac8fSEnji Cooper 	}
168840a8ac8fSEnji Cooper }
1689