2007-01-17 01:42:12 +00:00
|
|
|
/*-
|
2010-08-15 21:20:40 +00:00
|
|
|
* Copyright (c) 2006-2010 Pawel Jakub Dawidek <pjd@FreeBSD.org>
|
2007-01-17 01:42:12 +00:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*
|
|
|
|
* $FreeBSD$
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <sys/param.h>
|
2010-08-06 20:48:10 +00:00
|
|
|
#include <sys/types.h>
|
2007-01-17 01:42:12 +00:00
|
|
|
#include <sys/stat.h>
|
2010-08-06 19:16:20 +00:00
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <sys/un.h>
|
2010-08-06 20:48:10 +00:00
|
|
|
#ifndef makedev
|
|
|
|
#include <sys/mkdev.h>
|
|
|
|
#endif
|
2010-08-06 20:46:26 +00:00
|
|
|
|
|
|
|
#include <assert.h>
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <errno.h>
|
2007-01-17 01:42:12 +00:00
|
|
|
#include <fcntl.h>
|
|
|
|
#include <grp.h>
|
2010-08-06 20:46:26 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2007-01-17 01:42:12 +00:00
|
|
|
#include <string.h>
|
2010-08-06 20:46:26 +00:00
|
|
|
#include <unistd.h>
|
2007-01-17 01:42:12 +00:00
|
|
|
|
|
|
|
#ifndef HAS_TRUNCATE64
|
|
|
|
#define truncate64 truncate
|
Add support for the following syscalls:
- fchmod(2),
- fchown(2),
- fchflags(2),
- fstat(2),
- ftruncate(2),
- fpathconf(2),
- lpathconf(2).
Make write(2) syscall to take descriptor instead of file name.
We implement descriptors by keeping track of open files and allowing to
reference them by the following syscalls. Because pjdfstest already supports
executing multiple syscalls from one command it works pretty well.
For example, the following command:
pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444
is equivalent of (error checking omitted):
int fd[2];
fd[0] = open("foo", O_CREAT | O_RDWR, 0);
fd[1] = open("bar", O_CREAT | O_RDONLY, 0640);
fchmod(fd[0], 0666);
fchown(fd[0], -1, 20);
fchmod(fd[1], 0444);
2011-03-09 22:39:10 +00:00
|
|
|
#define ftruncate64 ftruncate
|
2007-01-17 01:42:12 +00:00
|
|
|
#endif
|
|
|
|
#ifndef HAS_STAT64
|
|
|
|
#define stat64 stat
|
Add support for the following syscalls:
- fchmod(2),
- fchown(2),
- fchflags(2),
- fstat(2),
- ftruncate(2),
- fpathconf(2),
- lpathconf(2).
Make write(2) syscall to take descriptor instead of file name.
We implement descriptors by keeping track of open files and allowing to
reference them by the following syscalls. Because pjdfstest already supports
executing multiple syscalls from one command it works pretty well.
For example, the following command:
pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444
is equivalent of (error checking omitted):
int fd[2];
fd[0] = open("foo", O_CREAT | O_RDWR, 0);
fd[1] = open("bar", O_CREAT | O_RDONLY, 0640);
fchmod(fd[0], 0666);
fchown(fd[0], -1, 20);
fchmod(fd[1], 0444);
2011-03-09 22:39:10 +00:00
|
|
|
#define fstat64 fstat
|
2007-01-17 01:42:12 +00:00
|
|
|
#define lstat64 lstat
|
|
|
|
#endif
|
2009-09-07 19:40:22 +00:00
|
|
|
#ifdef HAS_FREEBSD_ACL
|
|
|
|
#include <sys/acl.h>
|
|
|
|
#endif
|
2007-01-17 01:42:12 +00:00
|
|
|
|
|
|
|
#ifndef ALLPERMS
|
|
|
|
#define ALLPERMS (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
enum action {
|
|
|
|
ACTION_OPEN,
|
2011-03-10 21:00:30 +00:00
|
|
|
ACTION_OPENAT,
|
2007-01-17 01:42:12 +00:00
|
|
|
ACTION_CREATE,
|
|
|
|
ACTION_UNLINK,
|
2011-03-10 21:00:30 +00:00
|
|
|
ACTION_UNLINKAT,
|
2007-01-17 01:42:12 +00:00
|
|
|
ACTION_MKDIR,
|
2011-03-10 21:00:30 +00:00
|
|
|
ACTION_MKDIRAT,
|
2007-01-17 01:42:12 +00:00
|
|
|
ACTION_RMDIR,
|
|
|
|
ACTION_LINK,
|
2011-03-10 21:00:30 +00:00
|
|
|
ACTION_LINKAT,
|
2007-01-17 01:42:12 +00:00
|
|
|
ACTION_SYMLINK,
|
2011-03-10 21:00:30 +00:00
|
|
|
ACTION_SYMLINKAT,
|
2007-01-17 01:42:12 +00:00
|
|
|
ACTION_RENAME,
|
2011-03-10 21:00:30 +00:00
|
|
|
ACTION_RENAMEAT,
|
2007-01-17 01:42:12 +00:00
|
|
|
ACTION_MKFIFO,
|
2011-03-10 21:00:30 +00:00
|
|
|
ACTION_MKFIFOAT,
|
2010-08-06 20:48:10 +00:00
|
|
|
ACTION_MKNOD,
|
2011-03-10 21:00:30 +00:00
|
|
|
ACTION_MKNODAT,
|
2010-08-06 19:16:20 +00:00
|
|
|
ACTION_BIND,
|
2013-03-02 21:16:40 +00:00
|
|
|
#ifdef HAS_BINDAT
|
|
|
|
ACTION_BINDAT,
|
|
|
|
#endif
|
2010-08-06 19:16:20 +00:00
|
|
|
ACTION_CONNECT,
|
2013-03-02 21:16:40 +00:00
|
|
|
#ifdef HAS_CONNECTAT
|
|
|
|
ACTION_CONNECTAT,
|
|
|
|
#endif
|
2007-01-17 01:42:12 +00:00
|
|
|
ACTION_CHMOD,
|
Add support for the following syscalls:
- fchmod(2),
- fchown(2),
- fchflags(2),
- fstat(2),
- ftruncate(2),
- fpathconf(2),
- lpathconf(2).
Make write(2) syscall to take descriptor instead of file name.
We implement descriptors by keeping track of open files and allowing to
reference them by the following syscalls. Because pjdfstest already supports
executing multiple syscalls from one command it works pretty well.
For example, the following command:
pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444
is equivalent of (error checking omitted):
int fd[2];
fd[0] = open("foo", O_CREAT | O_RDWR, 0);
fd[1] = open("bar", O_CREAT | O_RDONLY, 0640);
fchmod(fd[0], 0666);
fchown(fd[0], -1, 20);
fchmod(fd[1], 0444);
2011-03-09 22:39:10 +00:00
|
|
|
ACTION_FCHMOD,
|
2007-01-17 01:42:12 +00:00
|
|
|
#ifdef HAS_LCHMOD
|
|
|
|
ACTION_LCHMOD,
|
|
|
|
#endif
|
2011-03-10 21:00:30 +00:00
|
|
|
ACTION_FCHMODAT,
|
2007-01-17 01:42:12 +00:00
|
|
|
ACTION_CHOWN,
|
Add support for the following syscalls:
- fchmod(2),
- fchown(2),
- fchflags(2),
- fstat(2),
- ftruncate(2),
- fpathconf(2),
- lpathconf(2).
Make write(2) syscall to take descriptor instead of file name.
We implement descriptors by keeping track of open files and allowing to
reference them by the following syscalls. Because pjdfstest already supports
executing multiple syscalls from one command it works pretty well.
For example, the following command:
pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444
is equivalent of (error checking omitted):
int fd[2];
fd[0] = open("foo", O_CREAT | O_RDWR, 0);
fd[1] = open("bar", O_CREAT | O_RDONLY, 0640);
fchmod(fd[0], 0666);
fchown(fd[0], -1, 20);
fchmod(fd[1], 0444);
2011-03-09 22:39:10 +00:00
|
|
|
ACTION_FCHOWN,
|
2007-01-17 01:42:12 +00:00
|
|
|
ACTION_LCHOWN,
|
2011-03-10 21:00:30 +00:00
|
|
|
ACTION_FCHOWNAT,
|
2007-01-17 01:42:12 +00:00
|
|
|
#ifdef HAS_CHFLAGS
|
|
|
|
ACTION_CHFLAGS,
|
|
|
|
#endif
|
Add support for the following syscalls:
- fchmod(2),
- fchown(2),
- fchflags(2),
- fstat(2),
- ftruncate(2),
- fpathconf(2),
- lpathconf(2).
Make write(2) syscall to take descriptor instead of file name.
We implement descriptors by keeping track of open files and allowing to
reference them by the following syscalls. Because pjdfstest already supports
executing multiple syscalls from one command it works pretty well.
For example, the following command:
pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444
is equivalent of (error checking omitted):
int fd[2];
fd[0] = open("foo", O_CREAT | O_RDWR, 0);
fd[1] = open("bar", O_CREAT | O_RDONLY, 0640);
fchmod(fd[0], 0666);
fchown(fd[0], -1, 20);
fchmod(fd[1], 0444);
2011-03-09 22:39:10 +00:00
|
|
|
#ifdef HAS_FCHFLAGS
|
|
|
|
ACTION_FCHFLAGS,
|
|
|
|
#endif
|
2013-03-21 23:07:04 +00:00
|
|
|
#ifdef HAS_CHFLAGSAT
|
|
|
|
ACTION_CHFLAGSAT,
|
|
|
|
#endif
|
2007-01-17 01:42:12 +00:00
|
|
|
#ifdef HAS_LCHFLAGS
|
|
|
|
ACTION_LCHFLAGS,
|
|
|
|
#endif
|
|
|
|
ACTION_TRUNCATE,
|
Add support for the following syscalls:
- fchmod(2),
- fchown(2),
- fchflags(2),
- fstat(2),
- ftruncate(2),
- fpathconf(2),
- lpathconf(2).
Make write(2) syscall to take descriptor instead of file name.
We implement descriptors by keeping track of open files and allowing to
reference them by the following syscalls. Because pjdfstest already supports
executing multiple syscalls from one command it works pretty well.
For example, the following command:
pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444
is equivalent of (error checking omitted):
int fd[2];
fd[0] = open("foo", O_CREAT | O_RDWR, 0);
fd[1] = open("bar", O_CREAT | O_RDONLY, 0640);
fchmod(fd[0], 0666);
fchown(fd[0], -1, 20);
fchmod(fd[1], 0444);
2011-03-09 22:39:10 +00:00
|
|
|
ACTION_FTRUNCATE,
|
2007-01-17 01:42:12 +00:00
|
|
|
ACTION_STAT,
|
Add support for the following syscalls:
- fchmod(2),
- fchown(2),
- fchflags(2),
- fstat(2),
- ftruncate(2),
- fpathconf(2),
- lpathconf(2).
Make write(2) syscall to take descriptor instead of file name.
We implement descriptors by keeping track of open files and allowing to
reference them by the following syscalls. Because pjdfstest already supports
executing multiple syscalls from one command it works pretty well.
For example, the following command:
pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444
is equivalent of (error checking omitted):
int fd[2];
fd[0] = open("foo", O_CREAT | O_RDWR, 0);
fd[1] = open("bar", O_CREAT | O_RDONLY, 0640);
fchmod(fd[0], 0666);
fchown(fd[0], -1, 20);
fchmod(fd[1], 0444);
2011-03-09 22:39:10 +00:00
|
|
|
ACTION_FSTAT,
|
2007-01-17 01:42:12 +00:00
|
|
|
ACTION_LSTAT,
|
2011-03-10 21:00:30 +00:00
|
|
|
ACTION_FSTATAT,
|
2009-09-07 19:40:22 +00:00
|
|
|
ACTION_PATHCONF,
|
Add support for the following syscalls:
- fchmod(2),
- fchown(2),
- fchflags(2),
- fstat(2),
- ftruncate(2),
- fpathconf(2),
- lpathconf(2).
Make write(2) syscall to take descriptor instead of file name.
We implement descriptors by keeping track of open files and allowing to
reference them by the following syscalls. Because pjdfstest already supports
executing multiple syscalls from one command it works pretty well.
For example, the following command:
pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444
is equivalent of (error checking omitted):
int fd[2];
fd[0] = open("foo", O_CREAT | O_RDWR, 0);
fd[1] = open("bar", O_CREAT | O_RDONLY, 0640);
fchmod(fd[0], 0666);
fchown(fd[0], -1, 20);
fchmod(fd[1], 0444);
2011-03-09 22:39:10 +00:00
|
|
|
ACTION_FPATHCONF,
|
2013-10-31 11:38:25 +00:00
|
|
|
#ifdef HAS_LPATHCONF
|
Add support for the following syscalls:
- fchmod(2),
- fchown(2),
- fchflags(2),
- fstat(2),
- ftruncate(2),
- fpathconf(2),
- lpathconf(2).
Make write(2) syscall to take descriptor instead of file name.
We implement descriptors by keeping track of open files and allowing to
reference them by the following syscalls. Because pjdfstest already supports
executing multiple syscalls from one command it works pretty well.
For example, the following command:
pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444
is equivalent of (error checking omitted):
int fd[2];
fd[0] = open("foo", O_CREAT | O_RDWR, 0);
fd[1] = open("bar", O_CREAT | O_RDONLY, 0640);
fchmod(fd[0], 0666);
fchown(fd[0], -1, 20);
fchmod(fd[1], 0444);
2011-03-09 22:39:10 +00:00
|
|
|
ACTION_LPATHCONF,
|
2013-10-31 11:38:25 +00:00
|
|
|
#endif
|
2009-09-07 19:40:22 +00:00
|
|
|
#ifdef HAS_FREEBSD_ACL
|
|
|
|
ACTION_PREPENDACL,
|
|
|
|
ACTION_READACL,
|
|
|
|
#endif
|
|
|
|
ACTION_WRITE,
|
2007-01-17 01:42:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#define TYPE_NONE 0x0000
|
|
|
|
#define TYPE_STRING 0x0001
|
|
|
|
#define TYPE_NUMBER 0x0002
|
2011-03-10 21:00:30 +00:00
|
|
|
#define TYPE_DESCRIPTOR 0x0003
|
|
|
|
#define TYPE_MASK 0x000f
|
2007-01-17 01:42:12 +00:00
|
|
|
|
|
|
|
#define TYPE_OPTIONAL 0x0100
|
|
|
|
|
|
|
|
#define MAX_ARGS 8
|
|
|
|
|
|
|
|
struct syscall_desc {
|
2011-03-12 14:09:43 +00:00
|
|
|
const char *sd_name;
|
2007-01-17 01:42:12 +00:00
|
|
|
enum action sd_action;
|
|
|
|
int sd_args[MAX_ARGS];
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct syscall_desc syscalls[] = {
|
|
|
|
{ "open", ACTION_OPEN, { TYPE_STRING, TYPE_STRING, TYPE_NUMBER | TYPE_OPTIONAL, TYPE_NONE } },
|
2011-03-10 21:00:30 +00:00
|
|
|
{ "openat", ACTION_OPENAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_STRING, TYPE_NUMBER | TYPE_OPTIONAL, TYPE_NONE } },
|
2007-01-17 01:42:12 +00:00
|
|
|
{ "create", ACTION_CREATE, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
|
|
|
|
{ "unlink", ACTION_UNLINK, { TYPE_STRING, TYPE_NONE } },
|
2011-03-10 21:00:30 +00:00
|
|
|
{ "unlinkat", ACTION_UNLINKAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_STRING, TYPE_NONE } },
|
2007-01-17 01:42:12 +00:00
|
|
|
{ "mkdir", ACTION_MKDIR, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
|
2011-03-10 21:00:30 +00:00
|
|
|
{ "mkdirat", ACTION_MKDIRAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
|
2007-01-17 01:42:12 +00:00
|
|
|
{ "rmdir", ACTION_RMDIR, { TYPE_STRING, TYPE_NONE } },
|
|
|
|
{ "link", ACTION_LINK, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
|
2011-03-10 21:00:30 +00:00
|
|
|
{ "linkat", ACTION_LINKAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_DESCRIPTOR, TYPE_STRING, TYPE_STRING, TYPE_NONE } },
|
2007-01-17 01:42:12 +00:00
|
|
|
{ "symlink", ACTION_SYMLINK, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
|
2011-03-10 21:00:30 +00:00
|
|
|
{ "symlinkat", ACTION_SYMLINKAT, { TYPE_STRING, TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } },
|
2007-01-17 01:42:12 +00:00
|
|
|
{ "rename", ACTION_RENAME, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
|
2011-03-10 21:00:30 +00:00
|
|
|
{ "renameat", ACTION_RENAMEAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } },
|
2007-01-17 01:42:12 +00:00
|
|
|
{ "mkfifo", ACTION_MKFIFO, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
|
2011-03-10 21:00:30 +00:00
|
|
|
{ "mkfifoat", ACTION_MKFIFOAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
|
2010-08-06 20:48:10 +00:00
|
|
|
{ "mknod", ACTION_MKNOD, { TYPE_STRING, TYPE_STRING, TYPE_NUMBER, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE} },
|
2011-03-10 21:00:30 +00:00
|
|
|
{ "mknodat", ACTION_MKNODAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_STRING, TYPE_NUMBER, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE} },
|
2010-08-06 19:16:20 +00:00
|
|
|
{ "bind", ACTION_BIND, { TYPE_STRING, TYPE_NONE } },
|
2013-03-02 21:16:40 +00:00
|
|
|
#ifdef HAS_BINDAT
|
|
|
|
{ "bindat", ACTION_BINDAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } },
|
|
|
|
#endif
|
2010-08-06 19:16:20 +00:00
|
|
|
{ "connect", ACTION_CONNECT, { TYPE_STRING, TYPE_NONE } },
|
2013-03-02 21:16:40 +00:00
|
|
|
#ifdef HAS_CONNECTAT
|
|
|
|
{ "connectat", ACTION_CONNECTAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } },
|
|
|
|
#endif
|
2007-01-17 01:42:12 +00:00
|
|
|
{ "chmod", ACTION_CHMOD, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
|
2011-03-10 21:00:30 +00:00
|
|
|
{ "fchmod", ACTION_FCHMOD, { TYPE_DESCRIPTOR, TYPE_NUMBER, TYPE_NONE } },
|
2007-01-17 01:42:12 +00:00
|
|
|
#ifdef HAS_LCHMOD
|
|
|
|
{ "lchmod", ACTION_LCHMOD, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
|
|
|
|
#endif
|
2011-03-10 21:00:30 +00:00
|
|
|
{ "fchmodat", ACTION_FCHMODAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NUMBER, TYPE_STRING, TYPE_NONE } },
|
2007-01-17 01:42:12 +00:00
|
|
|
{ "chown", ACTION_CHOWN, { TYPE_STRING, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE } },
|
2011-03-10 21:00:30 +00:00
|
|
|
{ "fchown", ACTION_FCHOWN, { TYPE_DESCRIPTOR, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE } },
|
2007-01-17 01:42:12 +00:00
|
|
|
{ "lchown", ACTION_LCHOWN, { TYPE_STRING, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE } },
|
2011-03-10 21:00:30 +00:00
|
|
|
{ "fchownat", ACTION_FCHOWNAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NUMBER, TYPE_NUMBER, TYPE_STRING, TYPE_NONE } },
|
2007-01-17 01:42:12 +00:00
|
|
|
#ifdef HAS_CHFLAGS
|
|
|
|
{ "chflags", ACTION_CHFLAGS, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
|
|
|
|
#endif
|
Add support for the following syscalls:
- fchmod(2),
- fchown(2),
- fchflags(2),
- fstat(2),
- ftruncate(2),
- fpathconf(2),
- lpathconf(2).
Make write(2) syscall to take descriptor instead of file name.
We implement descriptors by keeping track of open files and allowing to
reference them by the following syscalls. Because pjdfstest already supports
executing multiple syscalls from one command it works pretty well.
For example, the following command:
pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444
is equivalent of (error checking omitted):
int fd[2];
fd[0] = open("foo", O_CREAT | O_RDWR, 0);
fd[1] = open("bar", O_CREAT | O_RDONLY, 0640);
fchmod(fd[0], 0666);
fchown(fd[0], -1, 20);
fchmod(fd[1], 0444);
2011-03-09 22:39:10 +00:00
|
|
|
#ifdef HAS_FCHFLAGS
|
2011-03-10 21:00:30 +00:00
|
|
|
{ "fchflags", ACTION_FCHFLAGS, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } },
|
Add support for the following syscalls:
- fchmod(2),
- fchown(2),
- fchflags(2),
- fstat(2),
- ftruncate(2),
- fpathconf(2),
- lpathconf(2).
Make write(2) syscall to take descriptor instead of file name.
We implement descriptors by keeping track of open files and allowing to
reference them by the following syscalls. Because pjdfstest already supports
executing multiple syscalls from one command it works pretty well.
For example, the following command:
pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444
is equivalent of (error checking omitted):
int fd[2];
fd[0] = open("foo", O_CREAT | O_RDWR, 0);
fd[1] = open("bar", O_CREAT | O_RDONLY, 0640);
fchmod(fd[0], 0666);
fchown(fd[0], -1, 20);
fchmod(fd[1], 0444);
2011-03-09 22:39:10 +00:00
|
|
|
#endif
|
2013-03-21 23:07:04 +00:00
|
|
|
#ifdef HAS_CHFLAGSAT
|
|
|
|
{ "chflagsat", ACTION_CHFLAGSAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_NONE } },
|
|
|
|
#endif
|
2007-01-17 01:42:12 +00:00
|
|
|
#ifdef HAS_LCHFLAGS
|
|
|
|
{ "lchflags", ACTION_LCHFLAGS, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
|
|
|
|
#endif
|
|
|
|
{ "truncate", ACTION_TRUNCATE, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
|
2011-03-10 21:00:30 +00:00
|
|
|
{ "ftruncate", ACTION_FTRUNCATE, { TYPE_DESCRIPTOR, TYPE_NUMBER, TYPE_NONE } },
|
2007-01-17 01:42:12 +00:00
|
|
|
{ "stat", ACTION_STAT, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
|
2011-03-10 21:00:30 +00:00
|
|
|
{ "fstat", ACTION_FSTAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } },
|
2007-01-17 01:42:12 +00:00
|
|
|
{ "lstat", ACTION_LSTAT, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
|
2011-03-10 21:00:30 +00:00
|
|
|
{ "fstatat", ACTION_FSTATAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_NONE } },
|
2008-11-23 19:56:40 +00:00
|
|
|
{ "pathconf", ACTION_PATHCONF, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
|
2011-03-10 21:00:30 +00:00
|
|
|
{ "fpathconf", ACTION_FPATHCONF, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } },
|
2013-10-31 11:38:25 +00:00
|
|
|
#ifdef HAS_LPATHCONF
|
Add support for the following syscalls:
- fchmod(2),
- fchown(2),
- fchflags(2),
- fstat(2),
- ftruncate(2),
- fpathconf(2),
- lpathconf(2).
Make write(2) syscall to take descriptor instead of file name.
We implement descriptors by keeping track of open files and allowing to
reference them by the following syscalls. Because pjdfstest already supports
executing multiple syscalls from one command it works pretty well.
For example, the following command:
pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444
is equivalent of (error checking omitted):
int fd[2];
fd[0] = open("foo", O_CREAT | O_RDWR, 0);
fd[1] = open("bar", O_CREAT | O_RDONLY, 0640);
fchmod(fd[0], 0666);
fchown(fd[0], -1, 20);
fchmod(fd[1], 0444);
2011-03-09 22:39:10 +00:00
|
|
|
{ "lpathconf", ACTION_LPATHCONF, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
|
2013-10-31 11:38:25 +00:00
|
|
|
#endif
|
2009-09-07 19:40:22 +00:00
|
|
|
#ifdef HAS_FREEBSD_ACL
|
|
|
|
{ "prependacl", ACTION_PREPENDACL, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
|
|
|
|
{ "readacl", ACTION_READACL, { TYPE_STRING, TYPE_NONE } },
|
|
|
|
#endif
|
2011-03-10 21:00:30 +00:00
|
|
|
{ "write", ACTION_WRITE, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } },
|
2007-01-17 01:42:12 +00:00
|
|
|
{ NULL, -1, { TYPE_NONE } }
|
|
|
|
};
|
|
|
|
|
|
|
|
struct flag {
|
|
|
|
long long f_flag;
|
2011-03-12 14:09:43 +00:00
|
|
|
const char *f_str;
|
2007-01-17 01:42:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static struct flag open_flags[] = {
|
|
|
|
#ifdef O_RDONLY
|
|
|
|
{ O_RDONLY, "O_RDONLY" },
|
|
|
|
#endif
|
|
|
|
#ifdef O_WRONLY
|
|
|
|
{ O_WRONLY, "O_WRONLY" },
|
|
|
|
#endif
|
|
|
|
#ifdef O_RDWR
|
|
|
|
{ O_RDWR, "O_RDWR" },
|
|
|
|
#endif
|
|
|
|
#ifdef O_NONBLOCK
|
|
|
|
{ O_NONBLOCK, "O_NONBLOCK" },
|
|
|
|
#endif
|
|
|
|
#ifdef O_APPEND
|
|
|
|
{ O_APPEND, "O_APPEND" },
|
|
|
|
#endif
|
|
|
|
#ifdef O_CREAT
|
|
|
|
{ O_CREAT, "O_CREAT" },
|
|
|
|
#endif
|
|
|
|
#ifdef O_TRUNC
|
|
|
|
{ O_TRUNC, "O_TRUNC" },
|
|
|
|
#endif
|
|
|
|
#ifdef O_EXCL
|
|
|
|
{ O_EXCL, "O_EXCL" },
|
|
|
|
#endif
|
|
|
|
#ifdef O_SHLOCK
|
|
|
|
{ O_SHLOCK, "O_SHLOCK" },
|
|
|
|
#endif
|
|
|
|
#ifdef O_EXLOCK
|
|
|
|
{ O_EXLOCK, "O_EXLOCK" },
|
|
|
|
#endif
|
|
|
|
#ifdef O_DIRECT
|
|
|
|
{ O_DIRECT, "O_DIRECT" },
|
|
|
|
#endif
|
|
|
|
#ifdef O_FSYNC
|
|
|
|
{ O_FSYNC, "O_FSYNC" },
|
|
|
|
#endif
|
|
|
|
#ifdef O_SYNC
|
|
|
|
{ O_SYNC, "O_SYNC" },
|
|
|
|
#endif
|
|
|
|
#ifdef O_NOFOLLOW
|
|
|
|
{ O_NOFOLLOW, "O_NOFOLLOW" },
|
|
|
|
#endif
|
|
|
|
#ifdef O_NOCTTY
|
|
|
|
{ O_NOCTTY, "O_NOCTTY" },
|
2011-03-10 21:00:30 +00:00
|
|
|
#endif
|
|
|
|
#ifdef O_DIRECTORY
|
|
|
|
{ O_DIRECTORY, "O_DIRECTORY" },
|
2007-01-17 01:42:12 +00:00
|
|
|
#endif
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
#ifdef HAS_CHFLAGS
|
|
|
|
static struct flag chflags_flags[] = {
|
|
|
|
#ifdef UF_NODUMP
|
|
|
|
{ UF_NODUMP, "UF_NODUMP" },
|
|
|
|
#endif
|
|
|
|
#ifdef UF_IMMUTABLE
|
|
|
|
{ UF_IMMUTABLE, "UF_IMMUTABLE" },
|
|
|
|
#endif
|
|
|
|
#ifdef UF_APPEND
|
|
|
|
{ UF_APPEND, "UF_APPEND" },
|
|
|
|
#endif
|
|
|
|
#ifdef UF_NOUNLINK
|
|
|
|
{ UF_NOUNLINK, "UF_NOUNLINK" },
|
|
|
|
#endif
|
|
|
|
#ifdef UF_OPAQUE
|
|
|
|
{ UF_OPAQUE, "UF_OPAQUE" },
|
|
|
|
#endif
|
|
|
|
#ifdef SF_ARCHIVED
|
|
|
|
{ SF_ARCHIVED, "SF_ARCHIVED" },
|
|
|
|
#endif
|
|
|
|
#ifdef SF_IMMUTABLE
|
|
|
|
{ SF_IMMUTABLE, "SF_IMMUTABLE" },
|
|
|
|
#endif
|
|
|
|
#ifdef SF_APPEND
|
|
|
|
{ SF_APPEND, "SF_APPEND" },
|
|
|
|
#endif
|
|
|
|
#ifdef SF_NOUNLINK
|
|
|
|
{ SF_NOUNLINK, "SF_NOUNLINK" },
|
|
|
|
#endif
|
|
|
|
#ifdef SF_SNAPSHOT
|
|
|
|
{ SF_SNAPSHOT, "SF_SNAPSHOT" },
|
|
|
|
#endif
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2011-03-10 21:00:30 +00:00
|
|
|
static struct flag unlinkat_flags[] = {
|
|
|
|
{ AT_REMOVEDIR, "AT_REMOVEDIR" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct flag linkat_flags[] = {
|
|
|
|
{ AT_SYMLINK_FOLLOW, "AT_SYMLINK_FOLLOW" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
2013-03-21 23:07:04 +00:00
|
|
|
static struct flag chflagsat_flags[] = {
|
|
|
|
{ AT_SYMLINK_NOFOLLOW, "AT_SYMLINK_NOFOLLOW" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
2011-03-10 21:00:30 +00:00
|
|
|
static struct flag fchmodat_flags[] = {
|
|
|
|
{ AT_SYMLINK_NOFOLLOW, "AT_SYMLINK_NOFOLLOW" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct flag fchownat_flags[] = {
|
|
|
|
{ AT_SYMLINK_NOFOLLOW, "AT_SYMLINK_NOFOLLOW" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct flag fstatat_flags[] = {
|
|
|
|
{ AT_SYMLINK_NOFOLLOW, "AT_SYMLINK_NOFOLLOW" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
2008-11-23 19:56:40 +00:00
|
|
|
struct name {
|
2011-03-12 14:09:43 +00:00
|
|
|
int n_name;
|
|
|
|
const char *n_str;
|
2008-11-23 19:56:40 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static struct name pathconf_names[] = {
|
|
|
|
#ifdef _PC_LINK_MAX
|
|
|
|
{ _PC_LINK_MAX, "_PC_LINK_MAX" },
|
|
|
|
#endif
|
|
|
|
#ifdef _PC_NAME_MAX
|
|
|
|
{ _PC_NAME_MAX, "_PC_NAME_MAX" },
|
|
|
|
#endif
|
|
|
|
#ifdef _PC_PATH_MAX
|
|
|
|
{ _PC_PATH_MAX, "_PC_PATH_MAX" },
|
|
|
|
#endif
|
|
|
|
#ifdef _PC_SYMLINK_MAX
|
|
|
|
{ _PC_SYMLINK_MAX, "_PC_SYMLINK_MAX" },
|
|
|
|
#endif
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
2007-01-17 01:42:12 +00:00
|
|
|
static const char *err2str(int error);
|
|
|
|
|
Add support for the following syscalls:
- fchmod(2),
- fchown(2),
- fchflags(2),
- fstat(2),
- ftruncate(2),
- fpathconf(2),
- lpathconf(2).
Make write(2) syscall to take descriptor instead of file name.
We implement descriptors by keeping track of open files and allowing to
reference them by the following syscalls. Because pjdfstest already supports
executing multiple syscalls from one command it works pretty well.
For example, the following command:
pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444
is equivalent of (error checking omitted):
int fd[2];
fd[0] = open("foo", O_CREAT | O_RDWR, 0);
fd[1] = open("bar", O_CREAT | O_RDONLY, 0640);
fchmod(fd[0], 0666);
fchown(fd[0], -1, 20);
fchmod(fd[1], 0444);
2011-03-09 22:39:10 +00:00
|
|
|
static int *descriptors;
|
|
|
|
static int ndescriptors;
|
|
|
|
|
2007-01-17 01:42:12 +00:00
|
|
|
static void
|
|
|
|
usage(void)
|
|
|
|
{
|
|
|
|
|
2010-08-15 21:29:03 +00:00
|
|
|
fprintf(stderr, "usage: pjdfstest [-U umask] [-u uid] [-g gid1[,gid2[...]]] syscall args ...\n");
|
2007-01-17 01:42:12 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static long long
|
|
|
|
str2flags(struct flag *tflags, char *sflags)
|
|
|
|
{
|
|
|
|
long long flags = 0;
|
|
|
|
unsigned int i;
|
|
|
|
char *f;
|
|
|
|
|
2012-07-04 17:31:53 +00:00
|
|
|
/* 'none' or '0' means no flags */
|
|
|
|
if (strcmp(sflags, "none") == 0 || strcmp(sflags, "0") == 0)
|
|
|
|
return (0);
|
|
|
|
for (f = strtok(sflags, ",|"); f != NULL; f = strtok(NULL, ",|")) {
|
2007-01-17 01:42:12 +00:00
|
|
|
for (i = 0; tflags[i].f_str != NULL; i++) {
|
|
|
|
if (strcmp(tflags[i].f_str, f) == 0)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (tflags[i].f_str == NULL) {
|
|
|
|
fprintf(stderr, "unknown flag '%s'\n", f);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
flags |= tflags[i].f_flag;
|
|
|
|
}
|
|
|
|
return (flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef HAS_CHFLAGS
|
|
|
|
static char *
|
|
|
|
flags2str(struct flag *tflags, long long flags)
|
|
|
|
{
|
|
|
|
static char sflags[1024];
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
sflags[0] = '\0';
|
|
|
|
for (i = 0; tflags[i].f_str != NULL; i++) {
|
|
|
|
if (flags & tflags[i].f_flag) {
|
|
|
|
if (sflags[0] != '\0')
|
|
|
|
strlcat(sflags, ",", sizeof(sflags));
|
|
|
|
strlcat(sflags, tflags[i].f_str, sizeof(sflags));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (sflags[0] == '\0')
|
|
|
|
strlcpy(sflags, "none", sizeof(sflags));
|
|
|
|
return (sflags);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2008-11-23 19:56:40 +00:00
|
|
|
static int
|
|
|
|
str2name(struct name *names, char *name)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
for (i = 0; names[i].n_str != NULL; i++) {
|
|
|
|
if (strcmp(names[i].n_str, name) == 0)
|
|
|
|
return (names[i].n_name);
|
|
|
|
}
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
|
2007-01-17 01:42:12 +00:00
|
|
|
static struct syscall_desc *
|
|
|
|
find_syscall(const char *name)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; syscalls[i].sd_name != NULL; i++) {
|
|
|
|
if (strcmp(syscalls[i].sd_name, name) == 0)
|
|
|
|
return (&syscalls[i]);
|
|
|
|
}
|
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
show_stat(struct stat64 *sp, const char *what)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (strcmp(what, "mode") == 0)
|
|
|
|
printf("0%o", (unsigned int)(sp->st_mode & ALLPERMS));
|
|
|
|
else if (strcmp(what, "inode") == 0)
|
|
|
|
printf("%lld", (long long)sp->st_ino);
|
|
|
|
else if (strcmp(what, "nlink") == 0)
|
|
|
|
printf("%lld", (long long)sp->st_nlink);
|
|
|
|
else if (strcmp(what, "uid") == 0)
|
|
|
|
printf("%d", (int)sp->st_uid);
|
|
|
|
else if (strcmp(what, "gid") == 0)
|
|
|
|
printf("%d", (int)sp->st_gid);
|
|
|
|
else if (strcmp(what, "size") == 0)
|
|
|
|
printf("%lld", (long long)sp->st_size);
|
|
|
|
else if (strcmp(what, "blocks") == 0)
|
|
|
|
printf("%lld", (long long)sp->st_blocks);
|
|
|
|
else if (strcmp(what, "atime") == 0)
|
|
|
|
printf("%lld", (long long)sp->st_atime);
|
|
|
|
else if (strcmp(what, "mtime") == 0)
|
|
|
|
printf("%lld", (long long)sp->st_mtime);
|
|
|
|
else if (strcmp(what, "ctime") == 0)
|
|
|
|
printf("%lld", (long long)sp->st_ctime);
|
|
|
|
#ifdef HAS_CHFLAGS
|
|
|
|
else if (strcmp(what, "flags") == 0)
|
2009-02-23 07:33:29 +00:00
|
|
|
printf("%s", flags2str(chflags_flags, (long long)sp->st_flags));
|
2007-01-17 01:42:12 +00:00
|
|
|
#endif
|
2010-08-06 20:48:10 +00:00
|
|
|
else if (strcmp(what, "major") == 0)
|
|
|
|
printf("%u", (unsigned int)major(sp->st_rdev));
|
|
|
|
else if (strcmp(what, "minor") == 0)
|
|
|
|
printf("%u", (unsigned int)minor(sp->st_rdev));
|
2007-01-17 01:42:12 +00:00
|
|
|
else if (strcmp(what, "type") == 0) {
|
|
|
|
switch (sp->st_mode & S_IFMT) {
|
|
|
|
case S_IFIFO:
|
|
|
|
printf("fifo");
|
|
|
|
break;
|
|
|
|
case S_IFCHR:
|
|
|
|
printf("char");
|
|
|
|
break;
|
|
|
|
case S_IFDIR:
|
|
|
|
printf("dir");
|
|
|
|
break;
|
|
|
|
case S_IFBLK:
|
|
|
|
printf("block");
|
|
|
|
break;
|
|
|
|
case S_IFREG:
|
|
|
|
printf("regular");
|
|
|
|
break;
|
|
|
|
case S_IFLNK:
|
|
|
|
printf("symlink");
|
|
|
|
break;
|
|
|
|
case S_IFSOCK:
|
|
|
|
printf("socket");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
printf("unknown");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
printf("unknown");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
show_stats(struct stat64 *sp, char *what)
|
|
|
|
{
|
|
|
|
const char *s = "";
|
|
|
|
char *w;
|
|
|
|
|
|
|
|
for (w = strtok(what, ","); w != NULL; w = strtok(NULL, ",")) {
|
|
|
|
printf("%s", s);
|
|
|
|
show_stat(sp, w);
|
|
|
|
s = ",";
|
|
|
|
}
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
|
Add support for the following syscalls:
- fchmod(2),
- fchown(2),
- fchflags(2),
- fstat(2),
- ftruncate(2),
- fpathconf(2),
- lpathconf(2).
Make write(2) syscall to take descriptor instead of file name.
We implement descriptors by keeping track of open files and allowing to
reference them by the following syscalls. Because pjdfstest already supports
executing multiple syscalls from one command it works pretty well.
For example, the following command:
pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444
is equivalent of (error checking omitted):
int fd[2];
fd[0] = open("foo", O_CREAT | O_RDWR, 0);
fd[1] = open("bar", O_CREAT | O_RDONLY, 0640);
fchmod(fd[0], 0666);
fchown(fd[0], -1, 20);
fchmod(fd[1], 0444);
2011-03-09 22:39:10 +00:00
|
|
|
static void
|
|
|
|
descriptor_add(int fd)
|
|
|
|
{
|
|
|
|
|
|
|
|
ndescriptors++;
|
|
|
|
if (descriptors == NULL) {
|
|
|
|
descriptors = malloc(sizeof(descriptors[0]) * ndescriptors);
|
|
|
|
} else {
|
|
|
|
descriptors = realloc(descriptors,
|
|
|
|
sizeof(descriptors[0]) * ndescriptors);
|
|
|
|
}
|
|
|
|
assert(descriptors != NULL);
|
|
|
|
descriptors[ndescriptors - 1] = fd;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
descriptor_get(int pos)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (pos < 0 || pos >= ndescriptors) {
|
|
|
|
fprintf(stderr, "invalid descriptor %d\n", pos);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (descriptors[pos]);
|
|
|
|
}
|
|
|
|
|
2007-01-17 01:42:12 +00:00
|
|
|
static unsigned int
|
|
|
|
call_syscall(struct syscall_desc *scall, char *argv[])
|
|
|
|
{
|
|
|
|
struct stat64 sb;
|
|
|
|
long long flags;
|
|
|
|
unsigned int i;
|
|
|
|
char *endp;
|
2008-11-23 19:56:40 +00:00
|
|
|
int name, rval;
|
2007-01-17 01:42:12 +00:00
|
|
|
union {
|
|
|
|
char *str;
|
|
|
|
long long num;
|
|
|
|
} args[MAX_ARGS];
|
2009-09-07 19:40:22 +00:00
|
|
|
#ifdef HAS_FREEBSD_ACL
|
|
|
|
int entry_id = ACL_FIRST_ENTRY;
|
|
|
|
acl_t acl, newacl;
|
|
|
|
acl_entry_t entry, newentry;
|
|
|
|
#endif
|
2007-01-17 01:42:12 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Verify correctness of the arguments.
|
|
|
|
*/
|
|
|
|
for (i = 0; i < sizeof(args)/sizeof(args[0]); i++) {
|
|
|
|
if (scall->sd_args[i] == TYPE_NONE) {
|
|
|
|
if (argv[i] == NULL || strcmp(argv[i], ":") == 0)
|
|
|
|
break;
|
|
|
|
fprintf(stderr, "too many arguments [%s]\n", argv[i]);
|
|
|
|
exit(1);
|
|
|
|
} else {
|
|
|
|
if (argv[i] == NULL || strcmp(argv[i], ":") == 0) {
|
|
|
|
if (scall->sd_args[i] & TYPE_OPTIONAL)
|
|
|
|
break;
|
|
|
|
fprintf(stderr, "too few arguments\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2011-03-10 21:00:30 +00:00
|
|
|
if ((scall->sd_args[i] & TYPE_MASK) == TYPE_STRING) {
|
2007-01-17 01:42:12 +00:00
|
|
|
if (strcmp(argv[i], "NULL") == 0)
|
|
|
|
args[i].str = NULL;
|
|
|
|
else if (strcmp(argv[i], "DEADCODE") == 0)
|
|
|
|
args[i].str = (void *)0xdeadc0de;
|
|
|
|
else
|
|
|
|
args[i].str = argv[i];
|
2013-04-17 21:08:18 +00:00
|
|
|
} else if ((scall->sd_args[i] & TYPE_MASK) ==
|
|
|
|
TYPE_NUMBER) {
|
2007-01-17 01:42:12 +00:00
|
|
|
args[i].num = strtoll(argv[i], &endp, 0);
|
2013-04-17 21:08:18 +00:00
|
|
|
if (*endp != '\0' &&
|
|
|
|
!isspace((unsigned char)*endp)) {
|
|
|
|
fprintf(stderr,
|
|
|
|
"invalid argument %u, number expected [%s]\n",
|
|
|
|
i, endp);
|
2007-01-17 01:42:12 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
2013-04-17 21:08:18 +00:00
|
|
|
} else if ((scall->sd_args[i] & TYPE_MASK) ==
|
|
|
|
TYPE_DESCRIPTOR) {
|
2011-03-10 21:00:30 +00:00
|
|
|
if (strcmp(argv[i], "AT_FDCWD") == 0) {
|
|
|
|
args[i].num = AT_FDCWD;
|
|
|
|
} else if (strcmp(argv[i], "BADFD") == 0) {
|
|
|
|
/* In case AT_FDCWD is -1 on some systems... */
|
|
|
|
if (AT_FDCWD == -1)
|
|
|
|
args[i].num = -2;
|
|
|
|
else
|
|
|
|
args[i].num = -1;
|
|
|
|
} else {
|
|
|
|
int pos;
|
|
|
|
|
|
|
|
pos = strtoll(argv[i], &endp, 0);
|
2013-04-17 21:08:18 +00:00
|
|
|
if (*endp != '\0' &&
|
|
|
|
!isspace((unsigned char)*endp)) {
|
|
|
|
fprintf(stderr,
|
|
|
|
"invalid argument %u, number expected [%s]\n",
|
|
|
|
i, endp);
|
2011-03-10 21:00:30 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
args[i].num = descriptor_get(pos);
|
|
|
|
}
|
2007-01-17 01:42:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* Call the given syscall.
|
|
|
|
*/
|
|
|
|
#define NUM(n) (args[(n)].num)
|
|
|
|
#define STR(n) (args[(n)].str)
|
|
|
|
switch (scall->sd_action) {
|
|
|
|
case ACTION_OPEN:
|
|
|
|
flags = str2flags(open_flags, STR(1));
|
|
|
|
if (flags & O_CREAT) {
|
|
|
|
if (i == 2) {
|
|
|
|
fprintf(stderr, "too few arguments\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2009-02-23 07:33:29 +00:00
|
|
|
rval = open(STR(0), (int)flags, (mode_t)NUM(2));
|
2007-01-17 01:42:12 +00:00
|
|
|
} else {
|
|
|
|
if (i == 3) {
|
|
|
|
fprintf(stderr, "too many arguments\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2009-02-23 07:33:29 +00:00
|
|
|
rval = open(STR(0), (int)flags);
|
2007-01-17 01:42:12 +00:00
|
|
|
}
|
Add support for the following syscalls:
- fchmod(2),
- fchown(2),
- fchflags(2),
- fstat(2),
- ftruncate(2),
- fpathconf(2),
- lpathconf(2).
Make write(2) syscall to take descriptor instead of file name.
We implement descriptors by keeping track of open files and allowing to
reference them by the following syscalls. Because pjdfstest already supports
executing multiple syscalls from one command it works pretty well.
For example, the following command:
pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444
is equivalent of (error checking omitted):
int fd[2];
fd[0] = open("foo", O_CREAT | O_RDWR, 0);
fd[1] = open("bar", O_CREAT | O_RDONLY, 0640);
fchmod(fd[0], 0666);
fchown(fd[0], -1, 20);
fchmod(fd[1], 0444);
2011-03-09 22:39:10 +00:00
|
|
|
if (rval >= 0)
|
|
|
|
descriptor_add(rval);
|
2007-01-17 01:42:12 +00:00
|
|
|
break;
|
2011-03-10 21:00:30 +00:00
|
|
|
case ACTION_OPENAT:
|
|
|
|
flags = str2flags(open_flags, STR(2));
|
|
|
|
if (flags & O_CREAT) {
|
|
|
|
if (i == 3) {
|
|
|
|
fprintf(stderr, "too few arguments\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2013-04-17 21:08:18 +00:00
|
|
|
rval = openat(NUM(0), STR(1), (int)flags,
|
|
|
|
(mode_t)NUM(3));
|
2011-03-10 21:00:30 +00:00
|
|
|
} else {
|
|
|
|
if (i == 4) {
|
|
|
|
fprintf(stderr, "too many arguments\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
rval = openat(NUM(0), STR(1), (int)flags);
|
|
|
|
}
|
|
|
|
if (rval >= 0)
|
|
|
|
descriptor_add(rval);
|
|
|
|
break;
|
2007-01-17 01:42:12 +00:00
|
|
|
case ACTION_CREATE:
|
2009-02-23 07:33:29 +00:00
|
|
|
rval = open(STR(0), O_CREAT | O_EXCL, (mode_t)NUM(1));
|
2007-01-17 01:42:12 +00:00
|
|
|
if (rval >= 0)
|
|
|
|
close(rval);
|
|
|
|
break;
|
|
|
|
case ACTION_UNLINK:
|
|
|
|
rval = unlink(STR(0));
|
|
|
|
break;
|
2011-03-10 21:00:30 +00:00
|
|
|
case ACTION_UNLINKAT:
|
|
|
|
rval = unlinkat(NUM(0), STR(1),
|
|
|
|
(int)str2flags(unlinkat_flags, STR(2)));
|
|
|
|
break;
|
2007-01-17 01:42:12 +00:00
|
|
|
case ACTION_MKDIR:
|
2009-02-23 07:33:29 +00:00
|
|
|
rval = mkdir(STR(0), (mode_t)NUM(1));
|
2007-01-17 01:42:12 +00:00
|
|
|
break;
|
2011-03-10 21:00:30 +00:00
|
|
|
case ACTION_MKDIRAT:
|
|
|
|
rval = mkdirat(NUM(0), STR(1), (mode_t)NUM(2));
|
|
|
|
break;
|
2007-01-17 01:42:12 +00:00
|
|
|
case ACTION_RMDIR:
|
|
|
|
rval = rmdir(STR(0));
|
|
|
|
break;
|
|
|
|
case ACTION_LINK:
|
|
|
|
rval = link(STR(0), STR(1));
|
|
|
|
break;
|
2011-03-10 21:00:30 +00:00
|
|
|
case ACTION_LINKAT:
|
|
|
|
rval = linkat(NUM(0), STR(1), NUM(2), STR(3),
|
|
|
|
(int)str2flags(linkat_flags, STR(4)));
|
|
|
|
break;
|
2007-01-17 01:42:12 +00:00
|
|
|
case ACTION_SYMLINK:
|
|
|
|
rval = symlink(STR(0), STR(1));
|
|
|
|
break;
|
2011-03-10 21:00:30 +00:00
|
|
|
case ACTION_SYMLINKAT:
|
|
|
|
rval = symlinkat(STR(0), NUM(1), STR(2));
|
|
|
|
break;
|
2007-01-17 01:42:12 +00:00
|
|
|
case ACTION_RENAME:
|
|
|
|
rval = rename(STR(0), STR(1));
|
|
|
|
break;
|
2011-03-10 21:00:30 +00:00
|
|
|
case ACTION_RENAMEAT:
|
|
|
|
rval = renameat(NUM(0), STR(1), NUM(2), STR(3));
|
|
|
|
break;
|
2007-01-17 01:42:12 +00:00
|
|
|
case ACTION_MKFIFO:
|
2009-02-23 07:33:29 +00:00
|
|
|
rval = mkfifo(STR(0), (mode_t)NUM(1));
|
2007-01-17 01:42:12 +00:00
|
|
|
break;
|
2011-03-10 21:00:30 +00:00
|
|
|
case ACTION_MKFIFOAT:
|
|
|
|
rval = mkfifoat(NUM(0), STR(1), (mode_t)NUM(2));
|
|
|
|
break;
|
2010-08-06 20:48:10 +00:00
|
|
|
case ACTION_MKNOD:
|
2011-03-10 21:00:30 +00:00
|
|
|
case ACTION_MKNODAT:
|
2010-08-06 20:48:10 +00:00
|
|
|
{
|
|
|
|
mode_t ntype;
|
|
|
|
dev_t dev;
|
2011-03-10 21:00:30 +00:00
|
|
|
int fa;
|
2010-08-06 20:48:10 +00:00
|
|
|
|
2011-03-10 21:00:30 +00:00
|
|
|
switch (scall->sd_action) {
|
|
|
|
case ACTION_MKNOD:
|
|
|
|
fa = 0;
|
|
|
|
break;
|
|
|
|
case ACTION_MKNODAT:
|
|
|
|
fa = 1;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
|
|
|
dev = makedev(NUM(fa + 3), NUM(fa + 4));
|
2013-04-17 21:08:18 +00:00
|
|
|
if (strcmp(STR(fa + 1), "c") == 0) /* character device */
|
2010-08-06 20:48:10 +00:00
|
|
|
ntype = S_IFCHR;
|
2011-03-10 21:00:30 +00:00
|
|
|
else if (strcmp(STR(fa + 1), "b") == 0) /* block device */
|
2010-08-06 20:48:10 +00:00
|
|
|
ntype = S_IFBLK;
|
2011-03-10 21:00:30 +00:00
|
|
|
else if (strcmp(STR(fa + 1), "f") == 0) /* fifo special */
|
2010-08-06 20:48:10 +00:00
|
|
|
ntype = S_IFIFO;
|
2011-03-10 21:00:30 +00:00
|
|
|
else if (strcmp(STR(fa + 1), "d") == 0) /* directory */
|
2010-08-06 20:48:10 +00:00
|
|
|
ntype = S_IFDIR;
|
2011-03-10 21:00:30 +00:00
|
|
|
else if (strcmp(STR(fa + 1), "o") == 0) /* regular file */
|
2010-08-06 20:48:10 +00:00
|
|
|
ntype = S_IFREG;
|
|
|
|
else {
|
|
|
|
fprintf(stderr, "wrong argument 1\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2011-03-10 21:00:30 +00:00
|
|
|
switch (scall->sd_action) {
|
|
|
|
case ACTION_MKNOD:
|
|
|
|
rval = mknod(STR(0), ntype | NUM(2), dev);
|
|
|
|
break;
|
|
|
|
case ACTION_MKNODAT:
|
|
|
|
rval = mknodat(NUM(0), STR(1), ntype | NUM(3), dev);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
abort();
|
|
|
|
}
|
2010-08-06 20:48:10 +00:00
|
|
|
break;
|
|
|
|
}
|
2010-08-06 19:16:20 +00:00
|
|
|
case ACTION_BIND:
|
|
|
|
{
|
2010-08-09 17:42:04 +00:00
|
|
|
struct sockaddr_un sunx;
|
2010-08-06 19:16:20 +00:00
|
|
|
|
2010-08-09 17:42:04 +00:00
|
|
|
sunx.sun_family = AF_UNIX;
|
2010-08-09 20:16:52 +00:00
|
|
|
strncpy(sunx.sun_path, STR(0), sizeof(sunx.sun_path) - 1);
|
|
|
|
sunx.sun_path[sizeof(sunx.sun_path) - 1] = '\0';
|
2010-08-06 19:16:20 +00:00
|
|
|
rval = socket(AF_UNIX, SOCK_STREAM, 0);
|
|
|
|
if (rval < 0)
|
|
|
|
break;
|
2010-08-09 17:42:04 +00:00
|
|
|
rval = bind(rval, (struct sockaddr *)&sunx, sizeof(sunx));
|
2010-08-06 19:16:20 +00:00
|
|
|
break;
|
|
|
|
}
|
2013-03-02 21:16:40 +00:00
|
|
|
#ifdef HAS_BINDAT
|
|
|
|
case ACTION_BINDAT:
|
|
|
|
{
|
|
|
|
struct sockaddr_un sunx;
|
|
|
|
|
|
|
|
sunx.sun_family = AF_UNIX;
|
|
|
|
strncpy(sunx.sun_path, STR(1), sizeof(sunx.sun_path) - 1);
|
|
|
|
sunx.sun_path[sizeof(sunx.sun_path) - 1] = '\0';
|
|
|
|
rval = socket(AF_UNIX, SOCK_STREAM, 0);
|
|
|
|
if (rval < 0)
|
|
|
|
break;
|
|
|
|
rval = bindat(NUM(0), rval, (struct sockaddr *)&sunx,
|
|
|
|
sizeof(sunx));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
#endif
|
2010-08-06 19:16:20 +00:00
|
|
|
case ACTION_CONNECT:
|
|
|
|
{
|
2010-08-09 17:42:04 +00:00
|
|
|
struct sockaddr_un sunx;
|
2010-08-06 19:16:20 +00:00
|
|
|
|
2010-08-09 17:42:04 +00:00
|
|
|
sunx.sun_family = AF_UNIX;
|
2010-08-09 20:16:52 +00:00
|
|
|
strncpy(sunx.sun_path, STR(0), sizeof(sunx.sun_path) - 1);
|
|
|
|
sunx.sun_path[sizeof(sunx.sun_path) - 1] = '\0';
|
2010-08-06 19:16:20 +00:00
|
|
|
rval = socket(AF_UNIX, SOCK_STREAM, 0);
|
|
|
|
if (rval < 0)
|
|
|
|
break;
|
2010-08-09 17:42:04 +00:00
|
|
|
rval = connect(rval, (struct sockaddr *)&sunx, sizeof(sunx));
|
2010-08-06 19:16:20 +00:00
|
|
|
break;
|
|
|
|
}
|
2013-03-02 21:16:40 +00:00
|
|
|
#ifdef HAS_CONNECTAT
|
|
|
|
case ACTION_CONNECTAT:
|
|
|
|
{
|
|
|
|
struct sockaddr_un sunx;
|
|
|
|
|
|
|
|
sunx.sun_family = AF_UNIX;
|
|
|
|
strncpy(sunx.sun_path, STR(1), sizeof(sunx.sun_path) - 1);
|
|
|
|
sunx.sun_path[sizeof(sunx.sun_path) - 1] = '\0';
|
|
|
|
rval = socket(AF_UNIX, SOCK_STREAM, 0);
|
|
|
|
if (rval < 0)
|
|
|
|
break;
|
|
|
|
rval = connectat(NUM(0), rval, (struct sockaddr *)&sunx,
|
|
|
|
sizeof(sunx));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
#endif
|
2007-01-17 01:42:12 +00:00
|
|
|
case ACTION_CHMOD:
|
2009-02-23 07:33:29 +00:00
|
|
|
rval = chmod(STR(0), (mode_t)NUM(1));
|
2007-01-17 01:42:12 +00:00
|
|
|
break;
|
Add support for the following syscalls:
- fchmod(2),
- fchown(2),
- fchflags(2),
- fstat(2),
- ftruncate(2),
- fpathconf(2),
- lpathconf(2).
Make write(2) syscall to take descriptor instead of file name.
We implement descriptors by keeping track of open files and allowing to
reference them by the following syscalls. Because pjdfstest already supports
executing multiple syscalls from one command it works pretty well.
For example, the following command:
pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444
is equivalent of (error checking omitted):
int fd[2];
fd[0] = open("foo", O_CREAT | O_RDWR, 0);
fd[1] = open("bar", O_CREAT | O_RDONLY, 0640);
fchmod(fd[0], 0666);
fchown(fd[0], -1, 20);
fchmod(fd[1], 0444);
2011-03-09 22:39:10 +00:00
|
|
|
case ACTION_FCHMOD:
|
2011-03-10 21:00:30 +00:00
|
|
|
rval = fchmod(NUM(0), (mode_t)NUM(1));
|
Add support for the following syscalls:
- fchmod(2),
- fchown(2),
- fchflags(2),
- fstat(2),
- ftruncate(2),
- fpathconf(2),
- lpathconf(2).
Make write(2) syscall to take descriptor instead of file name.
We implement descriptors by keeping track of open files and allowing to
reference them by the following syscalls. Because pjdfstest already supports
executing multiple syscalls from one command it works pretty well.
For example, the following command:
pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444
is equivalent of (error checking omitted):
int fd[2];
fd[0] = open("foo", O_CREAT | O_RDWR, 0);
fd[1] = open("bar", O_CREAT | O_RDONLY, 0640);
fchmod(fd[0], 0666);
fchown(fd[0], -1, 20);
fchmod(fd[1], 0444);
2011-03-09 22:39:10 +00:00
|
|
|
break;
|
2007-01-17 01:42:12 +00:00
|
|
|
#ifdef HAS_LCHMOD
|
|
|
|
case ACTION_LCHMOD:
|
2009-02-23 07:33:29 +00:00
|
|
|
rval = lchmod(STR(0), (mode_t)NUM(1));
|
2007-01-17 01:42:12 +00:00
|
|
|
break;
|
|
|
|
#endif
|
2011-03-10 21:00:30 +00:00
|
|
|
case ACTION_FCHMODAT:
|
|
|
|
rval = fchmodat(NUM(0), STR(1), (mode_t)NUM(2),
|
|
|
|
str2flags(fchmodat_flags, STR(3)));
|
|
|
|
break;
|
2007-01-17 01:42:12 +00:00
|
|
|
case ACTION_CHOWN:
|
2009-02-23 07:33:29 +00:00
|
|
|
rval = chown(STR(0), (uid_t)NUM(1), (gid_t)NUM(2));
|
2007-01-17 01:42:12 +00:00
|
|
|
break;
|
Add support for the following syscalls:
- fchmod(2),
- fchown(2),
- fchflags(2),
- fstat(2),
- ftruncate(2),
- fpathconf(2),
- lpathconf(2).
Make write(2) syscall to take descriptor instead of file name.
We implement descriptors by keeping track of open files and allowing to
reference them by the following syscalls. Because pjdfstest already supports
executing multiple syscalls from one command it works pretty well.
For example, the following command:
pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444
is equivalent of (error checking omitted):
int fd[2];
fd[0] = open("foo", O_CREAT | O_RDWR, 0);
fd[1] = open("bar", O_CREAT | O_RDONLY, 0640);
fchmod(fd[0], 0666);
fchown(fd[0], -1, 20);
fchmod(fd[1], 0444);
2011-03-09 22:39:10 +00:00
|
|
|
case ACTION_FCHOWN:
|
2011-03-10 21:00:30 +00:00
|
|
|
rval = fchown(NUM(0), (uid_t)NUM(1), (gid_t)NUM(2));
|
Add support for the following syscalls:
- fchmod(2),
- fchown(2),
- fchflags(2),
- fstat(2),
- ftruncate(2),
- fpathconf(2),
- lpathconf(2).
Make write(2) syscall to take descriptor instead of file name.
We implement descriptors by keeping track of open files and allowing to
reference them by the following syscalls. Because pjdfstest already supports
executing multiple syscalls from one command it works pretty well.
For example, the following command:
pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444
is equivalent of (error checking omitted):
int fd[2];
fd[0] = open("foo", O_CREAT | O_RDWR, 0);
fd[1] = open("bar", O_CREAT | O_RDONLY, 0640);
fchmod(fd[0], 0666);
fchown(fd[0], -1, 20);
fchmod(fd[1], 0444);
2011-03-09 22:39:10 +00:00
|
|
|
break;
|
2007-01-17 01:42:12 +00:00
|
|
|
case ACTION_LCHOWN:
|
2009-02-23 07:33:29 +00:00
|
|
|
rval = lchown(STR(0), (uid_t)NUM(1), (gid_t)NUM(2));
|
2007-01-17 01:42:12 +00:00
|
|
|
break;
|
2011-03-10 21:00:30 +00:00
|
|
|
case ACTION_FCHOWNAT:
|
|
|
|
rval = fchownat(NUM(0), STR(1), (uid_t)NUM(2), (gid_t)NUM(3),
|
|
|
|
(int)str2flags(fchownat_flags, STR(4)));
|
|
|
|
break;
|
2007-01-17 01:42:12 +00:00
|
|
|
#ifdef HAS_CHFLAGS
|
|
|
|
case ACTION_CHFLAGS:
|
2011-03-10 21:00:30 +00:00
|
|
|
rval = chflags(STR(0),
|
|
|
|
(unsigned long)str2flags(chflags_flags, STR(1)));
|
2007-01-17 01:42:12 +00:00
|
|
|
break;
|
|
|
|
#endif
|
Add support for the following syscalls:
- fchmod(2),
- fchown(2),
- fchflags(2),
- fstat(2),
- ftruncate(2),
- fpathconf(2),
- lpathconf(2).
Make write(2) syscall to take descriptor instead of file name.
We implement descriptors by keeping track of open files and allowing to
reference them by the following syscalls. Because pjdfstest already supports
executing multiple syscalls from one command it works pretty well.
For example, the following command:
pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444
is equivalent of (error checking omitted):
int fd[2];
fd[0] = open("foo", O_CREAT | O_RDWR, 0);
fd[1] = open("bar", O_CREAT | O_RDONLY, 0640);
fchmod(fd[0], 0666);
fchown(fd[0], -1, 20);
fchmod(fd[1], 0444);
2011-03-09 22:39:10 +00:00
|
|
|
#ifdef HAS_FCHFLAGS
|
|
|
|
case ACTION_FCHFLAGS:
|
2011-03-10 21:00:30 +00:00
|
|
|
rval = fchflags(NUM(0),
|
|
|
|
(unsigned long)str2flags(chflags_flags, STR(1)));
|
Add support for the following syscalls:
- fchmod(2),
- fchown(2),
- fchflags(2),
- fstat(2),
- ftruncate(2),
- fpathconf(2),
- lpathconf(2).
Make write(2) syscall to take descriptor instead of file name.
We implement descriptors by keeping track of open files and allowing to
reference them by the following syscalls. Because pjdfstest already supports
executing multiple syscalls from one command it works pretty well.
For example, the following command:
pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444
is equivalent of (error checking omitted):
int fd[2];
fd[0] = open("foo", O_CREAT | O_RDWR, 0);
fd[1] = open("bar", O_CREAT | O_RDONLY, 0640);
fchmod(fd[0], 0666);
fchown(fd[0], -1, 20);
fchmod(fd[1], 0444);
2011-03-09 22:39:10 +00:00
|
|
|
break;
|
|
|
|
#endif
|
2013-03-21 23:07:04 +00:00
|
|
|
#ifdef HAS_CHFLAGSAT
|
|
|
|
case ACTION_CHFLAGSAT:
|
|
|
|
rval = chflagsat(NUM(0), STR(1),
|
|
|
|
(unsigned long)str2flags(chflags_flags, STR(2)),
|
|
|
|
(int)str2flags(chflagsat_flags, STR(3)));
|
|
|
|
break;
|
|
|
|
#endif
|
2007-01-17 01:42:12 +00:00
|
|
|
#ifdef HAS_LCHFLAGS
|
|
|
|
case ACTION_LCHFLAGS:
|
2013-03-21 22:44:33 +00:00
|
|
|
rval = lchflags(STR(0),
|
|
|
|
(unsigned long)str2flags(chflags_flags, STR(1)));
|
2007-01-17 01:42:12 +00:00
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
case ACTION_TRUNCATE:
|
|
|
|
rval = truncate64(STR(0), NUM(1));
|
|
|
|
break;
|
Add support for the following syscalls:
- fchmod(2),
- fchown(2),
- fchflags(2),
- fstat(2),
- ftruncate(2),
- fpathconf(2),
- lpathconf(2).
Make write(2) syscall to take descriptor instead of file name.
We implement descriptors by keeping track of open files and allowing to
reference them by the following syscalls. Because pjdfstest already supports
executing multiple syscalls from one command it works pretty well.
For example, the following command:
pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444
is equivalent of (error checking omitted):
int fd[2];
fd[0] = open("foo", O_CREAT | O_RDWR, 0);
fd[1] = open("bar", O_CREAT | O_RDONLY, 0640);
fchmod(fd[0], 0666);
fchown(fd[0], -1, 20);
fchmod(fd[1], 0444);
2011-03-09 22:39:10 +00:00
|
|
|
case ACTION_FTRUNCATE:
|
2011-03-10 21:00:30 +00:00
|
|
|
rval = ftruncate64(NUM(0), NUM(1));
|
Add support for the following syscalls:
- fchmod(2),
- fchown(2),
- fchflags(2),
- fstat(2),
- ftruncate(2),
- fpathconf(2),
- lpathconf(2).
Make write(2) syscall to take descriptor instead of file name.
We implement descriptors by keeping track of open files and allowing to
reference them by the following syscalls. Because pjdfstest already supports
executing multiple syscalls from one command it works pretty well.
For example, the following command:
pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444
is equivalent of (error checking omitted):
int fd[2];
fd[0] = open("foo", O_CREAT | O_RDWR, 0);
fd[1] = open("bar", O_CREAT | O_RDONLY, 0640);
fchmod(fd[0], 0666);
fchown(fd[0], -1, 20);
fchmod(fd[1], 0444);
2011-03-09 22:39:10 +00:00
|
|
|
break;
|
2007-01-17 01:42:12 +00:00
|
|
|
case ACTION_STAT:
|
|
|
|
rval = stat64(STR(0), &sb);
|
|
|
|
if (rval == 0) {
|
|
|
|
show_stats(&sb, STR(1));
|
|
|
|
return (i);
|
|
|
|
}
|
|
|
|
break;
|
Add support for the following syscalls:
- fchmod(2),
- fchown(2),
- fchflags(2),
- fstat(2),
- ftruncate(2),
- fpathconf(2),
- lpathconf(2).
Make write(2) syscall to take descriptor instead of file name.
We implement descriptors by keeping track of open files and allowing to
reference them by the following syscalls. Because pjdfstest already supports
executing multiple syscalls from one command it works pretty well.
For example, the following command:
pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444
is equivalent of (error checking omitted):
int fd[2];
fd[0] = open("foo", O_CREAT | O_RDWR, 0);
fd[1] = open("bar", O_CREAT | O_RDONLY, 0640);
fchmod(fd[0], 0666);
fchown(fd[0], -1, 20);
fchmod(fd[1], 0444);
2011-03-09 22:39:10 +00:00
|
|
|
case ACTION_FSTAT:
|
2011-03-10 21:00:30 +00:00
|
|
|
rval = fstat64(NUM(0), &sb);
|
Add support for the following syscalls:
- fchmod(2),
- fchown(2),
- fchflags(2),
- fstat(2),
- ftruncate(2),
- fpathconf(2),
- lpathconf(2).
Make write(2) syscall to take descriptor instead of file name.
We implement descriptors by keeping track of open files and allowing to
reference them by the following syscalls. Because pjdfstest already supports
executing multiple syscalls from one command it works pretty well.
For example, the following command:
pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444
is equivalent of (error checking omitted):
int fd[2];
fd[0] = open("foo", O_CREAT | O_RDWR, 0);
fd[1] = open("bar", O_CREAT | O_RDONLY, 0640);
fchmod(fd[0], 0666);
fchown(fd[0], -1, 20);
fchmod(fd[1], 0444);
2011-03-09 22:39:10 +00:00
|
|
|
if (rval == 0) {
|
|
|
|
show_stats(&sb, STR(1));
|
|
|
|
return (i);
|
|
|
|
}
|
|
|
|
break;
|
2007-01-17 01:42:12 +00:00
|
|
|
case ACTION_LSTAT:
|
|
|
|
rval = lstat64(STR(0), &sb);
|
|
|
|
if (rval == 0) {
|
|
|
|
show_stats(&sb, STR(1));
|
|
|
|
return (i);
|
|
|
|
}
|
|
|
|
break;
|
2011-03-10 21:00:30 +00:00
|
|
|
case ACTION_FSTATAT:
|
|
|
|
rval = fstatat(NUM(0), STR(1), &sb,
|
|
|
|
(int)str2flags(fstatat_flags, STR(2)));
|
|
|
|
if (rval == 0) {
|
|
|
|
show_stats(&sb, STR(3));
|
|
|
|
return (i);
|
|
|
|
}
|
|
|
|
break;
|
2008-11-23 19:56:40 +00:00
|
|
|
case ACTION_PATHCONF:
|
Add support for the following syscalls:
- fchmod(2),
- fchown(2),
- fchflags(2),
- fstat(2),
- ftruncate(2),
- fpathconf(2),
- lpathconf(2).
Make write(2) syscall to take descriptor instead of file name.
We implement descriptors by keeping track of open files and allowing to
reference them by the following syscalls. Because pjdfstest already supports
executing multiple syscalls from one command it works pretty well.
For example, the following command:
pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444
is equivalent of (error checking omitted):
int fd[2];
fd[0] = open("foo", O_CREAT | O_RDWR, 0);
fd[1] = open("bar", O_CREAT | O_RDONLY, 0640);
fchmod(fd[0], 0666);
fchown(fd[0], -1, 20);
fchmod(fd[1], 0444);
2011-03-09 22:39:10 +00:00
|
|
|
case ACTION_FPATHCONF:
|
2013-10-31 11:38:25 +00:00
|
|
|
#ifdef HAS_LPATHCONF
|
Add support for the following syscalls:
- fchmod(2),
- fchown(2),
- fchflags(2),
- fstat(2),
- ftruncate(2),
- fpathconf(2),
- lpathconf(2).
Make write(2) syscall to take descriptor instead of file name.
We implement descriptors by keeping track of open files and allowing to
reference them by the following syscalls. Because pjdfstest already supports
executing multiple syscalls from one command it works pretty well.
For example, the following command:
pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444
is equivalent of (error checking omitted):
int fd[2];
fd[0] = open("foo", O_CREAT | O_RDWR, 0);
fd[1] = open("bar", O_CREAT | O_RDONLY, 0640);
fchmod(fd[0], 0666);
fchown(fd[0], -1, 20);
fchmod(fd[1], 0444);
2011-03-09 22:39:10 +00:00
|
|
|
case ACTION_LPATHCONF:
|
2013-10-31 11:38:25 +00:00
|
|
|
#endif
|
2008-11-23 19:56:40 +00:00
|
|
|
{
|
|
|
|
long lrval;
|
|
|
|
|
|
|
|
name = str2name(pathconf_names, STR(1));
|
|
|
|
if (name == -1) {
|
|
|
|
fprintf(stderr, "unknown name %s", STR(1));
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
errno = 0;
|
Add support for the following syscalls:
- fchmod(2),
- fchown(2),
- fchflags(2),
- fstat(2),
- ftruncate(2),
- fpathconf(2),
- lpathconf(2).
Make write(2) syscall to take descriptor instead of file name.
We implement descriptors by keeping track of open files and allowing to
reference them by the following syscalls. Because pjdfstest already supports
executing multiple syscalls from one command it works pretty well.
For example, the following command:
pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444
is equivalent of (error checking omitted):
int fd[2];
fd[0] = open("foo", O_CREAT | O_RDWR, 0);
fd[1] = open("bar", O_CREAT | O_RDONLY, 0640);
fchmod(fd[0], 0666);
fchown(fd[0], -1, 20);
fchmod(fd[1], 0444);
2011-03-09 22:39:10 +00:00
|
|
|
switch (scall->sd_action) {
|
|
|
|
case ACTION_PATHCONF:
|
|
|
|
lrval = pathconf(STR(0), name);
|
|
|
|
break;
|
|
|
|
case ACTION_FPATHCONF:
|
2011-03-10 21:00:30 +00:00
|
|
|
lrval = fpathconf(NUM(0), name);
|
Add support for the following syscalls:
- fchmod(2),
- fchown(2),
- fchflags(2),
- fstat(2),
- ftruncate(2),
- fpathconf(2),
- lpathconf(2).
Make write(2) syscall to take descriptor instead of file name.
We implement descriptors by keeping track of open files and allowing to
reference them by the following syscalls. Because pjdfstest already supports
executing multiple syscalls from one command it works pretty well.
For example, the following command:
pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444
is equivalent of (error checking omitted):
int fd[2];
fd[0] = open("foo", O_CREAT | O_RDWR, 0);
fd[1] = open("bar", O_CREAT | O_RDONLY, 0640);
fchmod(fd[0], 0666);
fchown(fd[0], -1, 20);
fchmod(fd[1], 0444);
2011-03-09 22:39:10 +00:00
|
|
|
break;
|
2013-10-31 11:38:25 +00:00
|
|
|
#ifdef HAS_LPATHCONF
|
Add support for the following syscalls:
- fchmod(2),
- fchown(2),
- fchflags(2),
- fstat(2),
- ftruncate(2),
- fpathconf(2),
- lpathconf(2).
Make write(2) syscall to take descriptor instead of file name.
We implement descriptors by keeping track of open files and allowing to
reference them by the following syscalls. Because pjdfstest already supports
executing multiple syscalls from one command it works pretty well.
For example, the following command:
pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444
is equivalent of (error checking omitted):
int fd[2];
fd[0] = open("foo", O_CREAT | O_RDWR, 0);
fd[1] = open("bar", O_CREAT | O_RDONLY, 0640);
fchmod(fd[0], 0666);
fchown(fd[0], -1, 20);
fchmod(fd[1], 0444);
2011-03-09 22:39:10 +00:00
|
|
|
case ACTION_LPATHCONF:
|
|
|
|
lrval = lpathconf(STR(0), name);
|
|
|
|
break;
|
2013-10-31 11:38:25 +00:00
|
|
|
#endif
|
Add support for the following syscalls:
- fchmod(2),
- fchown(2),
- fchflags(2),
- fstat(2),
- ftruncate(2),
- fpathconf(2),
- lpathconf(2).
Make write(2) syscall to take descriptor instead of file name.
We implement descriptors by keeping track of open files and allowing to
reference them by the following syscalls. Because pjdfstest already supports
executing multiple syscalls from one command it works pretty well.
For example, the following command:
pjdfstest open foo "O_CREAT,O_RDWR" 0 : open bar "O_CREAT,O_RDONLY" 640 : fchmod 0 0666 : fchown 0 -1 20 : fchmod 1 0444
is equivalent of (error checking omitted):
int fd[2];
fd[0] = open("foo", O_CREAT | O_RDWR, 0);
fd[1] = open("bar", O_CREAT | O_RDONLY, 0640);
fchmod(fd[0], 0666);
fchown(fd[0], -1, 20);
fchmod(fd[1], 0444);
2011-03-09 22:39:10 +00:00
|
|
|
default:
|
|
|
|
abort();
|
|
|
|
}
|
2008-11-23 19:56:40 +00:00
|
|
|
if (lrval == -1 && errno == 0) {
|
|
|
|
printf("unlimited\n");
|
|
|
|
return (i);
|
|
|
|
} else if (lrval >= 0) {
|
|
|
|
printf("%ld\n", lrval);
|
|
|
|
return (i);
|
|
|
|
}
|
|
|
|
rval = -1;
|
|
|
|
break;
|
|
|
|
}
|
2009-09-07 19:40:22 +00:00
|
|
|
#ifdef HAS_FREEBSD_ACL
|
|
|
|
case ACTION_PREPENDACL:
|
|
|
|
rval = -1;
|
|
|
|
|
|
|
|
acl = acl_get_file(STR(0), ACL_TYPE_NFS4);
|
|
|
|
if (acl == NULL)
|
|
|
|
break;
|
|
|
|
|
|
|
|
newacl = acl_from_text(STR(1));
|
|
|
|
if (acl == NULL)
|
|
|
|
break;
|
|
|
|
|
|
|
|
while (acl_get_entry(newacl, entry_id, &newentry) == 1) {
|
|
|
|
entry_id = ACL_NEXT_ENTRY;
|
|
|
|
|
|
|
|
if (acl_create_entry_np(&acl, &entry, 0))
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (acl_copy_entry(entry, newentry))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
rval = acl_set_file(STR(0), ACL_TYPE_NFS4, acl);
|
|
|
|
break;
|
|
|
|
case ACTION_READACL:
|
|
|
|
acl = acl_get_file(STR(0), ACL_TYPE_NFS4);
|
|
|
|
if (acl == NULL)
|
|
|
|
rval = -1;
|
|
|
|
else
|
|
|
|
rval = 0;
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
case ACTION_WRITE:
|
2011-03-10 21:00:30 +00:00
|
|
|
rval = write(NUM(0), STR(1), strlen(STR(1)));
|
2009-09-07 19:40:22 +00:00
|
|
|
break;
|
2007-01-17 01:42:12 +00:00
|
|
|
default:
|
|
|
|
fprintf(stderr, "unsupported syscall\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
#undef STR
|
|
|
|
#undef NUM
|
|
|
|
if (rval < 0) {
|
|
|
|
const char *serrno;
|
|
|
|
|
|
|
|
serrno = err2str(errno);
|
|
|
|
fprintf(stderr, "%s returned %d\n", scall->sd_name, rval);
|
|
|
|
printf("%s\n", serrno);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
printf("0\n");
|
|
|
|
return (i);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
set_gids(char *gids)
|
|
|
|
{
|
|
|
|
gid_t *gidset;
|
|
|
|
long ngroups;
|
|
|
|
char *g, *endp;
|
|
|
|
unsigned i;
|
|
|
|
|
|
|
|
ngroups = sysconf(_SC_NGROUPS_MAX);
|
|
|
|
assert(ngroups > 0);
|
|
|
|
gidset = malloc(sizeof(*gidset) * ngroups);
|
|
|
|
assert(gidset != NULL);
|
2013-04-17 21:08:18 +00:00
|
|
|
for (i = 0, g = strtok(gids, ","); g != NULL;
|
|
|
|
g = strtok(NULL, ","), i++) {
|
2007-01-17 01:42:12 +00:00
|
|
|
if (i >= ngroups) {
|
|
|
|
fprintf(stderr, "too many gids\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
gidset[i] = strtol(g, &endp, 0);
|
|
|
|
if (*endp != '\0' && !isspace((unsigned char)*endp)) {
|
|
|
|
fprintf(stderr, "invalid gid '%s' - number expected\n",
|
|
|
|
g);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (setgroups(i, gidset) < 0) {
|
|
|
|
fprintf(stderr, "cannot change groups: %s\n", strerror(errno));
|
|
|
|
exit(1);
|
|
|
|
}
|
2007-07-18 18:07:15 +00:00
|
|
|
if (setegid(gidset[0]) < 0) {
|
2013-04-17 21:08:18 +00:00
|
|
|
fprintf(stderr, "cannot change effective gid: %s\n",
|
|
|
|
strerror(errno));
|
2007-07-18 18:07:15 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
2007-01-17 01:42:12 +00:00
|
|
|
free(gidset);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
main(int argc, char *argv[])
|
|
|
|
{
|
|
|
|
struct syscall_desc *scall;
|
|
|
|
unsigned int n;
|
|
|
|
char *gids, *endp;
|
|
|
|
int uid, umsk, ch;
|
|
|
|
|
|
|
|
uid = -1;
|
|
|
|
gids = NULL;
|
|
|
|
umsk = 0;
|
|
|
|
|
|
|
|
while ((ch = getopt(argc, argv, "g:u:U:")) != -1) {
|
|
|
|
switch(ch) {
|
|
|
|
case 'g':
|
|
|
|
gids = optarg;
|
|
|
|
break;
|
|
|
|
case 'u':
|
|
|
|
uid = (int)strtol(optarg, &endp, 0);
|
|
|
|
if (*endp != '\0' && !isspace((unsigned char)*endp)) {
|
|
|
|
fprintf(stderr, "invalid uid '%s' - number "
|
|
|
|
"expected\n", optarg);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'U':
|
|
|
|
umsk = (int)strtol(optarg, &endp, 0);
|
|
|
|
if (*endp != '\0' && !isspace((unsigned char)*endp)) {
|
|
|
|
fprintf(stderr, "invalid umask '%s' - number "
|
|
|
|
"expected\n", optarg);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
usage();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
argc -= optind;
|
|
|
|
argv += optind;
|
|
|
|
|
|
|
|
if (argc < 1) {
|
|
|
|
fprintf(stderr, "too few arguments\n");
|
|
|
|
usage();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gids != NULL) {
|
|
|
|
fprintf(stderr, "changing groups to %s\n", gids);
|
|
|
|
set_gids(gids);
|
|
|
|
}
|
|
|
|
if (uid != -1) {
|
|
|
|
fprintf(stderr, "changing uid to %d\n", uid);
|
|
|
|
if (setuid(uid) < 0) {
|
|
|
|
fprintf(stderr, "cannot change uid: %s\n",
|
|
|
|
strerror(errno));
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Change umask to requested value or to 0, if not requested. */
|
|
|
|
umask(umsk);
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
scall = find_syscall(argv[0]);
|
|
|
|
if (scall == NULL) {
|
2013-04-17 21:08:18 +00:00
|
|
|
fprintf(stderr, "syscall '%s' not supported\n",
|
|
|
|
argv[0]);
|
2007-01-17 01:42:12 +00:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
argc++;
|
|
|
|
argv++;
|
|
|
|
n = call_syscall(scall, argv);
|
|
|
|
argc += n;
|
|
|
|
argv += n;
|
|
|
|
if (argv[0] == NULL)
|
|
|
|
break;
|
|
|
|
argc++;
|
|
|
|
argv++;
|
|
|
|
}
|
|
|
|
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *
|
|
|
|
err2str(int error)
|
|
|
|
{
|
|
|
|
static char errnum[8];
|
|
|
|
|
|
|
|
switch (error) {
|
|
|
|
#ifdef EPERM
|
|
|
|
case EPERM:
|
|
|
|
return ("EPERM");
|
|
|
|
#endif
|
|
|
|
#ifdef ENOENT
|
|
|
|
case ENOENT:
|
|
|
|
return ("ENOENT");
|
|
|
|
#endif
|
|
|
|
#ifdef ESRCH
|
|
|
|
case ESRCH:
|
|
|
|
return ("ESRCH");
|
|
|
|
#endif
|
|
|
|
#ifdef EINTR
|
|
|
|
case EINTR:
|
|
|
|
return ("EINTR");
|
|
|
|
#endif
|
|
|
|
#ifdef EIO
|
|
|
|
case EIO:
|
|
|
|
return ("EIO");
|
|
|
|
#endif
|
|
|
|
#ifdef ENXIO
|
|
|
|
case ENXIO:
|
|
|
|
return ("ENXIO");
|
|
|
|
#endif
|
|
|
|
#ifdef E2BIG
|
|
|
|
case E2BIG:
|
|
|
|
return ("E2BIG");
|
|
|
|
#endif
|
|
|
|
#ifdef ENOEXEC
|
|
|
|
case ENOEXEC:
|
|
|
|
return ("ENOEXEC");
|
|
|
|
#endif
|
|
|
|
#ifdef EBADF
|
|
|
|
case EBADF:
|
|
|
|
return ("EBADF");
|
|
|
|
#endif
|
|
|
|
#ifdef ECHILD
|
|
|
|
case ECHILD:
|
|
|
|
return ("ECHILD");
|
|
|
|
#endif
|
|
|
|
#ifdef EDEADLK
|
|
|
|
case EDEADLK:
|
|
|
|
return ("EDEADLK");
|
|
|
|
#endif
|
|
|
|
#ifdef ENOMEM
|
|
|
|
case ENOMEM:
|
|
|
|
return ("ENOMEM");
|
|
|
|
#endif
|
|
|
|
#ifdef EACCES
|
|
|
|
case EACCES:
|
|
|
|
return ("EACCES");
|
|
|
|
#endif
|
|
|
|
#ifdef EFAULT
|
|
|
|
case EFAULT:
|
|
|
|
return ("EFAULT");
|
|
|
|
#endif
|
|
|
|
#ifdef ENOTBLK
|
|
|
|
case ENOTBLK:
|
|
|
|
return ("ENOTBLK");
|
|
|
|
#endif
|
|
|
|
#ifdef EBUSY
|
|
|
|
case EBUSY:
|
|
|
|
return ("EBUSY");
|
|
|
|
#endif
|
|
|
|
#ifdef EEXIST
|
|
|
|
case EEXIST:
|
|
|
|
return ("EEXIST");
|
|
|
|
#endif
|
|
|
|
#ifdef EXDEV
|
|
|
|
case EXDEV:
|
|
|
|
return ("EXDEV");
|
|
|
|
#endif
|
|
|
|
#ifdef ENODEV
|
|
|
|
case ENODEV:
|
|
|
|
return ("ENODEV");
|
|
|
|
#endif
|
|
|
|
#ifdef ENOTDIR
|
|
|
|
case ENOTDIR:
|
|
|
|
return ("ENOTDIR");
|
|
|
|
#endif
|
|
|
|
#ifdef EISDIR
|
|
|
|
case EISDIR:
|
|
|
|
return ("EISDIR");
|
|
|
|
#endif
|
|
|
|
#ifdef EINVAL
|
|
|
|
case EINVAL:
|
|
|
|
return ("EINVAL");
|
|
|
|
#endif
|
|
|
|
#ifdef ENFILE
|
|
|
|
case ENFILE:
|
|
|
|
return ("ENFILE");
|
|
|
|
#endif
|
|
|
|
#ifdef EMFILE
|
|
|
|
case EMFILE:
|
|
|
|
return ("EMFILE");
|
|
|
|
#endif
|
|
|
|
#ifdef ENOTTY
|
|
|
|
case ENOTTY:
|
|
|
|
return ("ENOTTY");
|
|
|
|
#endif
|
|
|
|
#ifdef ETXTBSY
|
|
|
|
case ETXTBSY:
|
|
|
|
return ("ETXTBSY");
|
|
|
|
#endif
|
|
|
|
#ifdef EFBIG
|
|
|
|
case EFBIG:
|
|
|
|
return ("EFBIG");
|
|
|
|
#endif
|
|
|
|
#ifdef ENOSPC
|
|
|
|
case ENOSPC:
|
|
|
|
return ("ENOSPC");
|
|
|
|
#endif
|
|
|
|
#ifdef ESPIPE
|
|
|
|
case ESPIPE:
|
|
|
|
return ("ESPIPE");
|
|
|
|
#endif
|
|
|
|
#ifdef EROFS
|
|
|
|
case EROFS:
|
|
|
|
return ("EROFS");
|
|
|
|
#endif
|
|
|
|
#ifdef EMLINK
|
|
|
|
case EMLINK:
|
|
|
|
return ("EMLINK");
|
|
|
|
#endif
|
|
|
|
#ifdef EPIPE
|
|
|
|
case EPIPE:
|
|
|
|
return ("EPIPE");
|
|
|
|
#endif
|
|
|
|
#ifdef EDOM
|
|
|
|
case EDOM:
|
|
|
|
return ("EDOM");
|
|
|
|
#endif
|
|
|
|
#ifdef ERANGE
|
|
|
|
case ERANGE:
|
|
|
|
return ("ERANGE");
|
|
|
|
#endif
|
|
|
|
#ifdef EAGAIN
|
|
|
|
case EAGAIN:
|
|
|
|
return ("EAGAIN");
|
|
|
|
#endif
|
|
|
|
#ifdef EINPROGRESS
|
|
|
|
case EINPROGRESS:
|
|
|
|
return ("EINPROGRESS");
|
|
|
|
#endif
|
|
|
|
#ifdef EALREADY
|
|
|
|
case EALREADY:
|
|
|
|
return ("EALREADY");
|
|
|
|
#endif
|
|
|
|
#ifdef ENOTSOCK
|
|
|
|
case ENOTSOCK:
|
|
|
|
return ("ENOTSOCK");
|
|
|
|
#endif
|
|
|
|
#ifdef EDESTADDRREQ
|
|
|
|
case EDESTADDRREQ:
|
|
|
|
return ("EDESTADDRREQ");
|
|
|
|
#endif
|
|
|
|
#ifdef EMSGSIZE
|
|
|
|
case EMSGSIZE:
|
|
|
|
return ("EMSGSIZE");
|
|
|
|
#endif
|
|
|
|
#ifdef EPROTOTYPE
|
|
|
|
case EPROTOTYPE:
|
|
|
|
return ("EPROTOTYPE");
|
|
|
|
#endif
|
|
|
|
#ifdef ENOPROTOOPT
|
|
|
|
case ENOPROTOOPT:
|
|
|
|
return ("ENOPROTOOPT");
|
|
|
|
#endif
|
|
|
|
#ifdef EPROTONOSUPPORT
|
|
|
|
case EPROTONOSUPPORT:
|
|
|
|
return ("EPROTONOSUPPORT");
|
|
|
|
#endif
|
|
|
|
#ifdef ESOCKTNOSUPPORT
|
|
|
|
case ESOCKTNOSUPPORT:
|
|
|
|
return ("ESOCKTNOSUPPORT");
|
|
|
|
#endif
|
|
|
|
#ifdef EOPNOTSUPP
|
|
|
|
case EOPNOTSUPP:
|
|
|
|
return ("EOPNOTSUPP");
|
|
|
|
#endif
|
|
|
|
#ifdef EPFNOSUPPORT
|
|
|
|
case EPFNOSUPPORT:
|
|
|
|
return ("EPFNOSUPPORT");
|
|
|
|
#endif
|
|
|
|
#ifdef EAFNOSUPPORT
|
|
|
|
case EAFNOSUPPORT:
|
|
|
|
return ("EAFNOSUPPORT");
|
|
|
|
#endif
|
|
|
|
#ifdef EADDRINUSE
|
|
|
|
case EADDRINUSE:
|
|
|
|
return ("EADDRINUSE");
|
|
|
|
#endif
|
|
|
|
#ifdef EADDRNOTAVAIL
|
|
|
|
case EADDRNOTAVAIL:
|
|
|
|
return ("EADDRNOTAVAIL");
|
|
|
|
#endif
|
|
|
|
#ifdef ENETDOWN
|
|
|
|
case ENETDOWN:
|
|
|
|
return ("ENETDOWN");
|
|
|
|
#endif
|
|
|
|
#ifdef ENETUNREACH
|
|
|
|
case ENETUNREACH:
|
|
|
|
return ("ENETUNREACH");
|
|
|
|
#endif
|
|
|
|
#ifdef ENETRESET
|
|
|
|
case ENETRESET:
|
|
|
|
return ("ENETRESET");
|
|
|
|
#endif
|
|
|
|
#ifdef ECONNABORTED
|
|
|
|
case ECONNABORTED:
|
|
|
|
return ("ECONNABORTED");
|
|
|
|
#endif
|
|
|
|
#ifdef ECONNRESET
|
|
|
|
case ECONNRESET:
|
|
|
|
return ("ECONNRESET");
|
|
|
|
#endif
|
|
|
|
#ifdef ENOBUFS
|
|
|
|
case ENOBUFS:
|
|
|
|
return ("ENOBUFS");
|
|
|
|
#endif
|
|
|
|
#ifdef EISCONN
|
|
|
|
case EISCONN:
|
|
|
|
return ("EISCONN");
|
|
|
|
#endif
|
|
|
|
#ifdef ENOTCONN
|
|
|
|
case ENOTCONN:
|
|
|
|
return ("ENOTCONN");
|
|
|
|
#endif
|
|
|
|
#ifdef ESHUTDOWN
|
|
|
|
case ESHUTDOWN:
|
|
|
|
return ("ESHUTDOWN");
|
|
|
|
#endif
|
|
|
|
#ifdef ETOOMANYREFS
|
|
|
|
case ETOOMANYREFS:
|
|
|
|
return ("ETOOMANYREFS");
|
|
|
|
#endif
|
|
|
|
#ifdef ETIMEDOUT
|
|
|
|
case ETIMEDOUT:
|
|
|
|
return ("ETIMEDOUT");
|
|
|
|
#endif
|
|
|
|
#ifdef ECONNREFUSED
|
|
|
|
case ECONNREFUSED:
|
|
|
|
return ("ECONNREFUSED");
|
|
|
|
#endif
|
|
|
|
#ifdef ELOOP
|
|
|
|
case ELOOP:
|
|
|
|
return ("ELOOP");
|
|
|
|
#endif
|
|
|
|
#ifdef ENAMETOOLONG
|
|
|
|
case ENAMETOOLONG:
|
|
|
|
return ("ENAMETOOLONG");
|
|
|
|
#endif
|
|
|
|
#ifdef EHOSTDOWN
|
|
|
|
case EHOSTDOWN:
|
|
|
|
return ("EHOSTDOWN");
|
|
|
|
#endif
|
|
|
|
#ifdef EHOSTUNREACH
|
|
|
|
case EHOSTUNREACH:
|
|
|
|
return ("EHOSTUNREACH");
|
|
|
|
#endif
|
|
|
|
#ifdef ENOTEMPTY
|
|
|
|
case ENOTEMPTY:
|
|
|
|
return ("ENOTEMPTY");
|
|
|
|
#endif
|
|
|
|
#ifdef EPROCLIM
|
|
|
|
case EPROCLIM:
|
|
|
|
return ("EPROCLIM");
|
|
|
|
#endif
|
|
|
|
#ifdef EUSERS
|
|
|
|
case EUSERS:
|
|
|
|
return ("EUSERS");
|
|
|
|
#endif
|
|
|
|
#ifdef EDQUOT
|
|
|
|
case EDQUOT:
|
|
|
|
return ("EDQUOT");
|
|
|
|
#endif
|
|
|
|
#ifdef ESTALE
|
|
|
|
case ESTALE:
|
|
|
|
return ("ESTALE");
|
|
|
|
#endif
|
|
|
|
#ifdef EREMOTE
|
|
|
|
case EREMOTE:
|
|
|
|
return ("EREMOTE");
|
|
|
|
#endif
|
|
|
|
#ifdef EBADRPC
|
|
|
|
case EBADRPC:
|
|
|
|
return ("EBADRPC");
|
|
|
|
#endif
|
|
|
|
#ifdef ERPCMISMATCH
|
|
|
|
case ERPCMISMATCH:
|
|
|
|
return ("ERPCMISMATCH");
|
|
|
|
#endif
|
|
|
|
#ifdef EPROGUNAVAIL
|
|
|
|
case EPROGUNAVAIL:
|
|
|
|
return ("EPROGUNAVAIL");
|
|
|
|
#endif
|
|
|
|
#ifdef EPROGMISMATCH
|
|
|
|
case EPROGMISMATCH:
|
|
|
|
return ("EPROGMISMATCH");
|
|
|
|
#endif
|
|
|
|
#ifdef EPROCUNAVAIL
|
|
|
|
case EPROCUNAVAIL:
|
|
|
|
return ("EPROCUNAVAIL");
|
|
|
|
#endif
|
|
|
|
#ifdef ENOLCK
|
|
|
|
case ENOLCK:
|
|
|
|
return ("ENOLCK");
|
|
|
|
#endif
|
|
|
|
#ifdef ENOSYS
|
|
|
|
case ENOSYS:
|
|
|
|
return ("ENOSYS");
|
|
|
|
#endif
|
|
|
|
#ifdef EFTYPE
|
|
|
|
case EFTYPE:
|
|
|
|
return ("EFTYPE");
|
|
|
|
#endif
|
|
|
|
#ifdef EAUTH
|
|
|
|
case EAUTH:
|
|
|
|
return ("EAUTH");
|
|
|
|
#endif
|
|
|
|
#ifdef ENEEDAUTH
|
|
|
|
case ENEEDAUTH:
|
|
|
|
return ("ENEEDAUTH");
|
|
|
|
#endif
|
|
|
|
#ifdef EIDRM
|
|
|
|
case EIDRM:
|
|
|
|
return ("EIDRM");
|
|
|
|
#endif
|
|
|
|
#ifdef ENOMSG
|
|
|
|
case ENOMSG:
|
|
|
|
return ("ENOMSG");
|
|
|
|
#endif
|
|
|
|
#ifdef EOVERFLOW
|
|
|
|
case EOVERFLOW:
|
|
|
|
return ("EOVERFLOW");
|
|
|
|
#endif
|
|
|
|
#ifdef ECANCELED
|
|
|
|
case ECANCELED:
|
|
|
|
return ("ECANCELED");
|
|
|
|
#endif
|
|
|
|
#ifdef EILSEQ
|
|
|
|
case EILSEQ:
|
|
|
|
return ("EILSEQ");
|
|
|
|
#endif
|
|
|
|
#ifdef ENOATTR
|
|
|
|
case ENOATTR:
|
|
|
|
return ("ENOATTR");
|
|
|
|
#endif
|
|
|
|
#ifdef EDOOFUS
|
|
|
|
case EDOOFUS:
|
|
|
|
return ("EDOOFUS");
|
|
|
|
#endif
|
|
|
|
#ifdef EBADMSG
|
|
|
|
case EBADMSG:
|
|
|
|
return ("EBADMSG");
|
|
|
|
#endif
|
|
|
|
#ifdef EMULTIHOP
|
|
|
|
case EMULTIHOP:
|
|
|
|
return ("EMULTIHOP");
|
|
|
|
#endif
|
|
|
|
#ifdef ENOLINK
|
|
|
|
case ENOLINK:
|
|
|
|
return ("ENOLINK");
|
|
|
|
#endif
|
|
|
|
#ifdef EPROTO
|
|
|
|
case EPROTO:
|
|
|
|
return ("EPROTO");
|
|
|
|
#endif
|
|
|
|
default:
|
|
|
|
snprintf(errnum, sizeof(errnum), "%d", error);
|
|
|
|
return (errnum);
|
|
|
|
}
|
|
|
|
}
|