Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 10 Mar 2011 21:00:30 +0000 (UTC)
From:      Pawel Jakub Dawidek <pjd@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r219464 - head/tools/regression/pjdfstest
Message-ID:  <201103102100.p2AL0Ukh055898@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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");



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201103102100.p2AL0Ukh055898>