Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 9 Mar 2011 22:39:10 +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: r219437 - in head/tools/regression/pjdfstest: . tests/chmod
Message-ID:  <201103092239.p29MdAmN022833@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: pjd
Date: Wed Mar  9 22:39:10 2011
New Revision: 219437
URL: http://svn.freebsd.org/changeset/base/219437

Log:
  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);

Modified:
  head/tools/regression/pjdfstest/Makefile
  head/tools/regression/pjdfstest/pjdfstest.c
  head/tools/regression/pjdfstest/tests/chmod/12.t

Modified: head/tools/regression/pjdfstest/Makefile
==============================================================================
--- head/tools/regression/pjdfstest/Makefile	Wed Mar  9 21:07:09 2011	(r219436)
+++ head/tools/regression/pjdfstest/Makefile	Wed Mar  9 22:39:10 2011	(r219437)
@@ -6,7 +6,7 @@ ${PROG}:	${PROG}.c
 	@OSTYPE=`uname`; \
 	CFLAGS=-D__OS_$${OSTYPE}__; \
 	if [ $$OSTYPE = "FreeBSD" ]; then \
-		CFLAGS="$$CFLAGS -DHAS_LCHMOD -DHAS_CHFLAGS -DHAS_LCHFLAGS -DHAS_FREEBSD_ACL"; \
+		CFLAGS="$$CFLAGS -DHAS_LCHMOD -DHAS_CHFLAGS -DHAS_FCHFLAGS -DHAS_LCHFLAGS -DHAS_FREEBSD_ACL"; \
 	elif [ $$OSTYPE = "SunOS" ]; then \
 		CFLAGS="$$CFLAGS -DHAS_TRUNCATE64 -DHAS_STAT64"; \
 		CFLAGS="$$CFLAGS -lsocket"; \

Modified: head/tools/regression/pjdfstest/pjdfstest.c
==============================================================================
--- head/tools/regression/pjdfstest/pjdfstest.c	Wed Mar  9 21:07:09 2011	(r219436)
+++ head/tools/regression/pjdfstest/pjdfstest.c	Wed Mar  9 22:39:10 2011	(r219437)
@@ -47,9 +47,11 @@
 
 #ifndef HAS_TRUNCATE64
 #define	truncate64	truncate
+#define	ftruncate64	ftruncate
 #endif
 #ifndef HAS_STAT64
 #define	stat64	stat
+#define	fstat64	fstat
 #define	lstat64	lstat
 #endif
 #ifdef HAS_FREEBSD_ACL
@@ -74,21 +76,30 @@ enum action {
 	ACTION_BIND,
 	ACTION_CONNECT,
 	ACTION_CHMOD,
+	ACTION_FCHMOD,
 #ifdef HAS_LCHMOD
 	ACTION_LCHMOD,
 #endif
 	ACTION_CHOWN,
+	ACTION_FCHOWN,
 	ACTION_LCHOWN,
 #ifdef HAS_CHFLAGS
 	ACTION_CHFLAGS,
 #endif
+#ifdef HAS_FCHFLAGS
+	ACTION_FCHFLAGS,
+#endif
 #ifdef HAS_LCHFLAGS
 	ACTION_LCHFLAGS,
 #endif
 	ACTION_TRUNCATE,
+	ACTION_FTRUNCATE,
 	ACTION_STAT,
+	ACTION_FSTAT,
 	ACTION_LSTAT,
 	ACTION_PATHCONF,
+	ACTION_FPATHCONF,
+	ACTION_LPATHCONF,
 #ifdef HAS_FREEBSD_ACL
 	ACTION_PREPENDACL,
 	ACTION_READACL,
@@ -124,26 +135,35 @@ static struct syscall_desc syscalls[] = 
 	{ "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 } },
 #ifdef HAS_LCHMOD
 	{ "lchmod", ACTION_LCHMOD, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
 #endif
 	{ "chown", ACTION_CHOWN, { TYPE_STRING, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE } },
+	{ "fchown", ACTION_FCHOWN, { TYPE_NUMBER, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE } },
 	{ "lchown", ACTION_LCHOWN, { TYPE_STRING, TYPE_NUMBER, TYPE_NUMBER, 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 } },
+#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 } },
 	{ "stat", ACTION_STAT, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
+	{ "fstat", ACTION_FSTAT, { TYPE_NUMBER, TYPE_STRING, TYPE_NONE } },
 	{ "lstat", ACTION_LSTAT, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
 	{ "pathconf", ACTION_PATHCONF, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
+	{ "fpathconf", ACTION_FPATHCONF, { TYPE_NUMBER, 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_STRING, TYPE_NONE } },
+	{ "write", ACTION_WRITE, { TYPE_NUMBER, TYPE_NONE } },
 	{ NULL, -1, { TYPE_NONE } }
 };
 
@@ -260,6 +280,9 @@ static struct name pathconf_names[] = {
 
 static const char *err2str(int error);
 
+static int *descriptors;
+static int ndescriptors;
+
 static void
 usage(void)
 {
@@ -415,6 +438,33 @@ show_stats(struct stat64 *sp, char *what
 	printf("\n");
 }
 
+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]);
+}
+
 static unsigned int
 call_syscall(struct syscall_desc *scall, char *argv[])
 {
@@ -470,6 +520,7 @@ 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));
@@ -486,6 +537,8 @@ call_syscall(struct syscall_desc *scall,
 			}
 			rval = open(STR(0), (int)flags);
 		}
+		if (rval >= 0)
+			descriptor_add(rval);
 		break;
 	case ACTION_CREATE:
 		rval = open(STR(0), O_CREAT | O_EXCL, (mode_t)NUM(1));
@@ -565,6 +618,9 @@ call_syscall(struct syscall_desc *scall,
 	case ACTION_CHMOD:
 		rval = chmod(STR(0), (mode_t)NUM(1));
 		break;
+	case ACTION_FCHMOD:
+		rval = fchmod(DESC(0), (mode_t)NUM(1));
+		break;
 #ifdef HAS_LCHMOD
 	case ACTION_LCHMOD:
 		rval = lchmod(STR(0), (mode_t)NUM(1));
@@ -573,6 +629,9 @@ call_syscall(struct syscall_desc *scall,
 	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));
+		break;
 	case ACTION_LCHOWN:
 		rval = lchown(STR(0), (uid_t)NUM(1), (gid_t)NUM(2));
 		break;
@@ -581,6 +640,11 @@ call_syscall(struct syscall_desc *scall,
 		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)));
+		break;
+#endif
 #ifdef HAS_LCHFLAGS
 	case ACTION_LCHFLAGS:
 		rval = lchflags(STR(0), (int)str2flags(chflags_flags, STR(1)));
@@ -589,6 +653,9 @@ call_syscall(struct syscall_desc *scall,
 	case ACTION_TRUNCATE:
 		rval = truncate64(STR(0), NUM(1));
 		break;
+	case ACTION_FTRUNCATE:
+		rval = ftruncate64(DESC(0), NUM(1));
+		break;
 	case ACTION_STAT:
 		rval = stat64(STR(0), &sb);
 		if (rval == 0) {
@@ -596,6 +663,13 @@ call_syscall(struct syscall_desc *scall,
 			return (i);
 		}
 		break;
+	case ACTION_FSTAT:
+		rval = fstat64(DESC(0), &sb);
+		if (rval == 0) {
+			show_stats(&sb, STR(1));
+			return (i);
+		}
+		break;
 	case ACTION_LSTAT:
 		rval = lstat64(STR(0), &sb);
 		if (rval == 0) {
@@ -604,6 +678,8 @@ call_syscall(struct syscall_desc *scall,
 		}
 		break;
 	case ACTION_PATHCONF:
+	case ACTION_FPATHCONF:
+	case ACTION_LPATHCONF:
 	    {
 		long lrval;
 
@@ -613,7 +689,19 @@ call_syscall(struct syscall_desc *scall,
 			exit(1);
 		}
 		errno = 0;
-		lrval = pathconf(STR(0), name);
+		switch (scall->sd_action) {
+		case ACTION_PATHCONF:
+			lrval = pathconf(STR(0), name);
+			break;
+		case ACTION_FPATHCONF:
+			lrval = fpathconf(DESC(0), name);
+			break;
+		case ACTION_LPATHCONF:
+			lrval = lpathconf(STR(0), name);
+			break;
+		default:
+			abort();
+		}
 		if (lrval == -1 && errno == 0) {
 			printf("unlimited\n");
 			return (i);
@@ -648,7 +736,6 @@ call_syscall(struct syscall_desc *scall,
 
 		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)
@@ -657,15 +744,9 @@ call_syscall(struct syscall_desc *scall,
 			rval = 0;
 		break;
 #endif
-
 	case ACTION_WRITE:
-		rval = open(STR(0), O_WRONLY);
-		if (rval < 0)
-			break;
-
-		rval = write(rval, "x", 1);
+		rval = write(DESC(0), "x", 1);
 		break;
-
 	default:
 		fprintf(stderr, "unsupported syscall\n");
 		exit(1);

Modified: head/tools/regression/pjdfstest/tests/chmod/12.t
==============================================================================
--- head/tools/regression/pjdfstest/tests/chmod/12.t	Wed Mar  9 21:07:09 2011	(r219436)
+++ head/tools/regression/pjdfstest/tests/chmod/12.t	Wed Mar  9 22:39:10 2011	(r219437)
@@ -18,13 +18,13 @@ cd ${n2}
 
 # Check whether writing to the file by non-owner clears the SUID.
 expect 0 create ${n0} 04777
-expect 0 -u 65534 -g 65534 write ${n0}
+expect 0 -u 65534 -g 65534 write ${n0} x
 expect 0777 stat ${n0} mode
 expect 0 unlink ${n0}
 
 # Check whether writing to the file by non-owner clears the SGID.
 expect 0 create ${n0} 02777
-expect 0 -u 65534 -g 65534 write ${n0}
+expect 0 -u 65534 -g 65534 write ${n0} x
 expect 0777 stat ${n0} mode
 expect 0 unlink ${n0}
 



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