From owner-svn-src-head@FreeBSD.ORG Thu Mar 10 21:00:30 2011 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 6E361106564A; Thu, 10 Mar 2011 21:00:30 +0000 (UTC) (envelope-from pjd@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 5CDBB8FC0C; Thu, 10 Mar 2011 21:00:30 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id p2AL0UTN055900; Thu, 10 Mar 2011 21:00:30 GMT (envelope-from pjd@svn.freebsd.org) Received: (from pjd@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id p2AL0Ukh055898; Thu, 10 Mar 2011 21:00:30 GMT (envelope-from pjd@svn.freebsd.org) Message-Id: <201103102100.p2AL0Ukh055898@svn.freebsd.org> From: Pawel Jakub Dawidek Date: Thu, 10 Mar 2011 21:00:30 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r219464 - head/tools/regression/pjdfstest X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 10 Mar 2011 21:00:30 -0000 Author: pjd Date: Thu Mar 10 21:00:30 2011 New Revision: 219464 URL: http://svn.freebsd.org/changeset/base/219464 Log: Add support for *at syscalls: - openat(2) - unlinkat(2) - mkdirat(2) - linkat(2) - symlinkat(2) - renameat(2) - mkfifoat(2) - mknodat(2) - fchmodat(2) - fchownat(2) - fstatat(2) Modified: head/tools/regression/pjdfstest/pjdfstest.c Modified: head/tools/regression/pjdfstest/pjdfstest.c ============================================================================== --- head/tools/regression/pjdfstest/pjdfstest.c Thu Mar 10 20:59:02 2011 (r219463) +++ head/tools/regression/pjdfstest/pjdfstest.c Thu Mar 10 21:00:30 2011 (r219464) @@ -64,15 +64,23 @@ enum action { ACTION_OPEN, + ACTION_OPENAT, ACTION_CREATE, ACTION_UNLINK, + ACTION_UNLINKAT, ACTION_MKDIR, + ACTION_MKDIRAT, ACTION_RMDIR, ACTION_LINK, + ACTION_LINKAT, ACTION_SYMLINK, + ACTION_SYMLINKAT, ACTION_RENAME, + ACTION_RENAMEAT, ACTION_MKFIFO, + ACTION_MKFIFOAT, ACTION_MKNOD, + ACTION_MKNODAT, ACTION_BIND, ACTION_CONNECT, ACTION_CHMOD, @@ -80,9 +88,11 @@ enum action { #ifdef HAS_LCHMOD ACTION_LCHMOD, #endif + ACTION_FCHMODAT, ACTION_CHOWN, ACTION_FCHOWN, ACTION_LCHOWN, + ACTION_FCHOWNAT, #ifdef HAS_CHFLAGS ACTION_CHFLAGS, #endif @@ -97,6 +107,7 @@ enum action { ACTION_STAT, ACTION_FSTAT, ACTION_LSTAT, + ACTION_FSTATAT, ACTION_PATHCONF, ACTION_FPATHCONF, ACTION_LPATHCONF, @@ -110,6 +121,8 @@ enum action { #define TYPE_NONE 0x0000 #define TYPE_STRING 0x0001 #define TYPE_NUMBER 0x0002 +#define TYPE_DESCRIPTOR 0x0003 +#define TYPE_MASK 0x000f #define TYPE_OPTIONAL 0x0100 @@ -123,47 +136,58 @@ struct syscall_desc { static struct syscall_desc syscalls[] = { { "open", ACTION_OPEN, { TYPE_STRING, TYPE_STRING, TYPE_NUMBER | TYPE_OPTIONAL, TYPE_NONE } }, + { "openat", ACTION_OPENAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_STRING, TYPE_NUMBER | TYPE_OPTIONAL, TYPE_NONE } }, { "create", ACTION_CREATE, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } }, { "unlink", ACTION_UNLINK, { TYPE_STRING, TYPE_NONE } }, + { "unlinkat", ACTION_UNLINKAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_STRING, TYPE_NONE } }, { "mkdir", ACTION_MKDIR, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } }, + { "mkdirat", ACTION_MKDIRAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NUMBER, TYPE_NONE } }, { "rmdir", ACTION_RMDIR, { TYPE_STRING, TYPE_NONE } }, { "link", ACTION_LINK, { TYPE_STRING, TYPE_STRING, TYPE_NONE } }, + { "linkat", ACTION_LINKAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_DESCRIPTOR, TYPE_STRING, TYPE_STRING, TYPE_NONE } }, { "symlink", ACTION_SYMLINK, { TYPE_STRING, TYPE_STRING, TYPE_NONE } }, + { "symlinkat", ACTION_SYMLINKAT, { TYPE_STRING, TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } }, { "rename", ACTION_RENAME, { TYPE_STRING, TYPE_STRING, TYPE_NONE } }, + { "renameat", ACTION_RENAMEAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } }, { "mkfifo", ACTION_MKFIFO, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } }, + { "mkfifoat", ACTION_MKFIFOAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NUMBER, TYPE_NONE } }, { "mknod", ACTION_MKNOD, { TYPE_STRING, TYPE_STRING, TYPE_NUMBER, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE} }, + { "mknodat", ACTION_MKNODAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_STRING, TYPE_NUMBER, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE} }, { "bind", ACTION_BIND, { TYPE_STRING, TYPE_NONE } }, { "connect", ACTION_CONNECT, { TYPE_STRING, TYPE_NONE } }, { "chmod", ACTION_CHMOD, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } }, - { "fchmod", ACTION_FCHMOD, { TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE } }, + { "fchmod", ACTION_FCHMOD, { TYPE_DESCRIPTOR, TYPE_NUMBER, TYPE_NONE } }, #ifdef HAS_LCHMOD { "lchmod", ACTION_LCHMOD, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } }, #endif + { "fchmodat", ACTION_FCHMODAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NUMBER, TYPE_STRING, TYPE_NONE } }, { "chown", ACTION_CHOWN, { TYPE_STRING, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE } }, - { "fchown", ACTION_FCHOWN, { TYPE_NUMBER, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE } }, + { "fchown", ACTION_FCHOWN, { TYPE_DESCRIPTOR, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE } }, { "lchown", ACTION_LCHOWN, { TYPE_STRING, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE } }, + { "fchownat", ACTION_FCHOWNAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NUMBER, TYPE_NUMBER, TYPE_STRING, TYPE_NONE } }, #ifdef HAS_CHFLAGS { "chflags", ACTION_CHFLAGS, { TYPE_STRING, TYPE_STRING, TYPE_NONE } }, #endif #ifdef HAS_FCHFLAGS - { "fchflags", ACTION_FCHFLAGS, { TYPE_NUMBER, TYPE_STRING, TYPE_NONE } }, + { "fchflags", ACTION_FCHFLAGS, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } }, #endif #ifdef HAS_LCHFLAGS { "lchflags", ACTION_LCHFLAGS, { TYPE_STRING, TYPE_STRING, TYPE_NONE } }, #endif { "truncate", ACTION_TRUNCATE, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } }, - { "ftruncate", ACTION_FTRUNCATE, { TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE } }, + { "ftruncate", ACTION_FTRUNCATE, { TYPE_DESCRIPTOR, TYPE_NUMBER, TYPE_NONE } }, { "stat", ACTION_STAT, { TYPE_STRING, TYPE_STRING, TYPE_NONE } }, - { "fstat", ACTION_FSTAT, { TYPE_NUMBER, TYPE_STRING, TYPE_NONE } }, + { "fstat", ACTION_FSTAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } }, { "lstat", ACTION_LSTAT, { TYPE_STRING, TYPE_STRING, TYPE_NONE } }, + { "fstatat", ACTION_FSTATAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_NONE } }, { "pathconf", ACTION_PATHCONF, { TYPE_STRING, TYPE_STRING, TYPE_NONE } }, - { "fpathconf", ACTION_FPATHCONF, { TYPE_NUMBER, TYPE_STRING, TYPE_NONE } }, + { "fpathconf", ACTION_FPATHCONF, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } }, { "lpathconf", ACTION_LPATHCONF, { TYPE_STRING, TYPE_STRING, TYPE_NONE } }, #ifdef HAS_FREEBSD_ACL { "prependacl", ACTION_PREPENDACL, { TYPE_STRING, TYPE_STRING, TYPE_NONE } }, { "readacl", ACTION_READACL, { TYPE_STRING, TYPE_NONE } }, #endif - { "write", ACTION_WRITE, { TYPE_NUMBER, TYPE_STRING, TYPE_NONE } }, + { "write", ACTION_WRITE, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } }, { NULL, -1, { TYPE_NONE } } }; @@ -218,6 +242,9 @@ static struct flag open_flags[] = { #ifdef O_NOCTTY { O_NOCTTY, "O_NOCTTY" }, #endif +#ifdef O_DIRECTORY + { O_DIRECTORY, "O_DIRECTORY" }, +#endif { 0, NULL } }; @@ -257,6 +284,31 @@ static struct flag chflags_flags[] = { }; #endif +static struct flag unlinkat_flags[] = { + { AT_REMOVEDIR, "AT_REMOVEDIR" }, + { 0, NULL } +}; + +static struct flag linkat_flags[] = { + { AT_SYMLINK_FOLLOW, "AT_SYMLINK_FOLLOW" }, + { 0, NULL } +}; + +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 } +}; + struct name { int n_name; char *n_str; @@ -499,19 +551,38 @@ call_syscall(struct syscall_desc *scall, fprintf(stderr, "too few arguments\n"); exit(1); } - if (scall->sd_args[i] & TYPE_STRING) { + if ((scall->sd_args[i] & TYPE_MASK) == TYPE_STRING) { 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]; - } else if (scall->sd_args[i] & TYPE_NUMBER) { + } else if ((scall->sd_args[i] & TYPE_MASK) == TYPE_NUMBER) { args[i].num = strtoll(argv[i], &endp, 0); if (*endp != '\0' && !isspace((unsigned char)*endp)) { fprintf(stderr, "invalid argument %u, number expected [%s]\n", i, endp); exit(1); } + } else if ((scall->sd_args[i] & TYPE_MASK) == TYPE_DESCRIPTOR) { + 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); + if (*endp != '\0' && !isspace((unsigned char)*endp)) { + fprintf(stderr, "invalid argument %u, number expected [%s]\n", i, endp); + exit(1); + } + args[i].num = descriptor_get(pos); + } } } } @@ -520,7 +591,6 @@ call_syscall(struct syscall_desc *scall, */ #define NUM(n) (args[(n)].num) #define STR(n) (args[(n)].str) -#define DESC(n) (descriptor_get((int)NUM(n))) switch (scall->sd_action) { case ACTION_OPEN: flags = str2flags(open_flags, STR(1)); @@ -540,6 +610,24 @@ call_syscall(struct syscall_desc *scall, if (rval >= 0) descriptor_add(rval); break; + case ACTION_OPENAT: + flags = str2flags(open_flags, STR(2)); + if (flags & O_CREAT) { + if (i == 3) { + fprintf(stderr, "too few arguments\n"); + exit(1); + } + rval = openat(NUM(0), STR(1), (int)flags, (mode_t)NUM(3)); + } 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; case ACTION_CREATE: rval = open(STR(0), O_CREAT | O_EXCL, (mode_t)NUM(1)); if (rval >= 0) @@ -548,45 +636,87 @@ call_syscall(struct syscall_desc *scall, case ACTION_UNLINK: rval = unlink(STR(0)); break; + case ACTION_UNLINKAT: + rval = unlinkat(NUM(0), STR(1), + (int)str2flags(unlinkat_flags, STR(2))); + break; case ACTION_MKDIR: rval = mkdir(STR(0), (mode_t)NUM(1)); break; + case ACTION_MKDIRAT: + rval = mkdirat(NUM(0), STR(1), (mode_t)NUM(2)); + break; case ACTION_RMDIR: rval = rmdir(STR(0)); break; case ACTION_LINK: rval = link(STR(0), STR(1)); break; + case ACTION_LINKAT: + rval = linkat(NUM(0), STR(1), NUM(2), STR(3), + (int)str2flags(linkat_flags, STR(4))); + break; case ACTION_SYMLINK: rval = symlink(STR(0), STR(1)); break; + case ACTION_SYMLINKAT: + rval = symlinkat(STR(0), NUM(1), STR(2)); + break; case ACTION_RENAME: rval = rename(STR(0), STR(1)); break; + case ACTION_RENAMEAT: + rval = renameat(NUM(0), STR(1), NUM(2), STR(3)); + break; case ACTION_MKFIFO: rval = mkfifo(STR(0), (mode_t)NUM(1)); break; + case ACTION_MKFIFOAT: + rval = mkfifoat(NUM(0), STR(1), (mode_t)NUM(2)); + break; case ACTION_MKNOD: + case ACTION_MKNODAT: { mode_t ntype; dev_t dev; + int fa; - dev = makedev(NUM(3), NUM(4)); - if (strcmp(STR(1), "c") == 0) /* character device */ + 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)); + if (strcmp(STR(fa + 1), "c") == 0) /* character device */ ntype = S_IFCHR; - else if (strcmp(STR(1), "b") == 0) /* block device */ + else if (strcmp(STR(fa + 1), "b") == 0) /* block device */ ntype = S_IFBLK; - else if (strcmp(STR(1), "f") == 0) /* fifo special */ + else if (strcmp(STR(fa + 1), "f") == 0) /* fifo special */ ntype = S_IFIFO; - else if (strcmp(STR(1), "d") == 0) /* directory */ + else if (strcmp(STR(fa + 1), "d") == 0) /* directory */ ntype = S_IFDIR; - else if (strcmp(STR(1), "o") == 0) /* regular file */ + else if (strcmp(STR(fa + 1), "o") == 0) /* regular file */ ntype = S_IFREG; else { fprintf(stderr, "wrong argument 1\n"); exit(1); } - rval = mknod(STR(0), ntype | NUM(2), dev); + 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(); + } break; } case ACTION_BIND: @@ -619,30 +749,40 @@ call_syscall(struct syscall_desc *scall, rval = chmod(STR(0), (mode_t)NUM(1)); break; case ACTION_FCHMOD: - rval = fchmod(DESC(0), (mode_t)NUM(1)); + rval = fchmod(NUM(0), (mode_t)NUM(1)); break; #ifdef HAS_LCHMOD case ACTION_LCHMOD: rval = lchmod(STR(0), (mode_t)NUM(1)); break; #endif + case ACTION_FCHMODAT: + rval = fchmodat(NUM(0), STR(1), (mode_t)NUM(2), + str2flags(fchmodat_flags, STR(3))); + break; case ACTION_CHOWN: rval = chown(STR(0), (uid_t)NUM(1), (gid_t)NUM(2)); break; case ACTION_FCHOWN: - rval = fchown(DESC(0), (uid_t)NUM(1), (gid_t)NUM(2)); + rval = fchown(NUM(0), (uid_t)NUM(1), (gid_t)NUM(2)); break; case ACTION_LCHOWN: rval = lchown(STR(0), (uid_t)NUM(1), (gid_t)NUM(2)); break; + case ACTION_FCHOWNAT: + rval = fchownat(NUM(0), STR(1), (uid_t)NUM(2), (gid_t)NUM(3), + (int)str2flags(fchownat_flags, STR(4))); + break; #ifdef HAS_CHFLAGS case ACTION_CHFLAGS: - rval = chflags(STR(0), (unsigned long)str2flags(chflags_flags, STR(1))); + rval = chflags(STR(0), + (unsigned long)str2flags(chflags_flags, STR(1))); break; #endif #ifdef HAS_FCHFLAGS case ACTION_FCHFLAGS: - rval = fchflags(DESC(0), (unsigned long)str2flags(chflags_flags, STR(1))); + rval = fchflags(NUM(0), + (unsigned long)str2flags(chflags_flags, STR(1))); break; #endif #ifdef HAS_LCHFLAGS @@ -654,7 +794,7 @@ call_syscall(struct syscall_desc *scall, rval = truncate64(STR(0), NUM(1)); break; case ACTION_FTRUNCATE: - rval = ftruncate64(DESC(0), NUM(1)); + rval = ftruncate64(NUM(0), NUM(1)); break; case ACTION_STAT: rval = stat64(STR(0), &sb); @@ -664,7 +804,7 @@ call_syscall(struct syscall_desc *scall, } break; case ACTION_FSTAT: - rval = fstat64(DESC(0), &sb); + rval = fstat64(NUM(0), &sb); if (rval == 0) { show_stats(&sb, STR(1)); return (i); @@ -677,6 +817,14 @@ call_syscall(struct syscall_desc *scall, return (i); } break; + 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; case ACTION_PATHCONF: case ACTION_FPATHCONF: case ACTION_LPATHCONF: @@ -694,7 +842,7 @@ call_syscall(struct syscall_desc *scall, lrval = pathconf(STR(0), name); break; case ACTION_FPATHCONF: - lrval = fpathconf(DESC(0), name); + lrval = fpathconf(NUM(0), name); break; case ACTION_LPATHCONF: lrval = lpathconf(STR(0), name); @@ -745,7 +893,7 @@ call_syscall(struct syscall_desc *scall, break; #endif case ACTION_WRITE: - rval = write(DESC(0), STR(1), strlen(STR(1))); + rval = write(NUM(0), STR(1), strlen(STR(1))); break; default: fprintf(stderr, "unsupported syscall\n");