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");
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to