svn commit: r285323 - in head/sys: compat/cloudabi kern sys

Ed Schouten ed at FreeBSD.org
Thu Jul 9 16:07:04 UTC 2015


Author: ed
Date: Thu Jul  9 16:07:01 2015
New Revision: 285323
URL: https://svnweb.freebsd.org/changeset/base/285323

Log:
  Add implementations for some of the CloudABI file descriptor system calls.
  
  All of the CloudABI system calls that operate on file descriptors of an
  arbitrary type are prefixed with fd_. This change adds wrappers for
  most of these system calls around their FreeBSD equivalents.
  
  The dup2() system call present on CloudABI deviates from POSIX, in the
  sense that it can only be used to replace existing file descriptor. It
  cannot be used to create new ones. The reason for this is that this is
  inherently thread-unsafe. Furthermore, there is no need on CloudABI to
  use fixed file descriptor numbers. File descriptors 0, 1 and 2 have no
  special meaning.
  
  This change exposes the kern_dup() through <sys/syscallsubr.h> and puts
  the FDDUP_* flags in <sys/filedesc.h>. It then adds a new flag,
  FDDUP_MUSTREPLACE to force that file descriptors are replaced -- not
  allocated.
  
  Differential Revision:	https://reviews.freebsd.org/D3035
  Reviewed by:	mjg

Modified:
  head/sys/compat/cloudabi/cloudabi_fd.c
  head/sys/kern/kern_descrip.c
  head/sys/sys/filedesc.h
  head/sys/sys/syscallsubr.h

Modified: head/sys/compat/cloudabi/cloudabi_fd.c
==============================================================================
--- head/sys/compat/cloudabi/cloudabi_fd.c	Thu Jul  9 15:56:51 2015	(r285322)
+++ head/sys/compat/cloudabi/cloudabi_fd.c	Thu Jul  9 16:07:01 2015	(r285323)
@@ -26,14 +26,20 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include <sys/param.h>
+#include <sys/filedesc.h>
+#include <sys/proc.h>
+#include <sys/syscallsubr.h>
+#include <sys/sysproto.h>
+#include <sys/unistd.h>
+
 #include <compat/cloudabi/cloudabi_proto.h>
 
 int
 cloudabi_sys_fd_close(struct thread *td, struct cloudabi_sys_fd_close_args *uap)
 {
 
-	/* Not implemented. */
-	return (ENOSYS);
+	return (kern_close(td, uap->fd));
 }
 
 int
@@ -58,34 +64,67 @@ int
 cloudabi_sys_fd_datasync(struct thread *td,
     struct cloudabi_sys_fd_datasync_args *uap)
 {
+	struct fsync_args fsync_args = {
+		.fd = uap->fd
+	};
 
-	/* Not implemented. */
-	return (ENOSYS);
+	/* Call into fsync(), as FreeBSD lacks fdatasync(). */
+	return (sys_fsync(td, &fsync_args));
 }
 
 int
 cloudabi_sys_fd_dup(struct thread *td, struct cloudabi_sys_fd_dup_args *uap)
 {
 
-	/* Not implemented. */
-	return (ENOSYS);
+	return (kern_dup(td, 0, uap->from, 0));
 }
 
 int
 cloudabi_sys_fd_replace(struct thread *td,
     struct cloudabi_sys_fd_replace_args *uap)
 {
+	int error;
 
-	/* Not implemented. */
-	return (ENOSYS);
+	/*
+	 * CloudABI's equivalent to dup2(). CloudABI processes should
+	 * not depend on hardcoded file descriptor layouts, but simply
+	 * use the file descriptor numbers that are allocated by the
+	 * kernel. Duplicating file descriptors to arbitrary numbers
+	 * should not be done.
+	 *
+	 * Invoke kern_dup() with FDDUP_MUSTREPLACE, so that we return
+	 * EBADF when duplicating to a nonexistent file descriptor. Also
+	 * clear the return value, as this system call yields no return
+	 * value.
+	 */
+	error = kern_dup(td, FDDUP_MUSTREPLACE, uap->from, uap->to);
+	td->td_retval[0] = 0;
+	return (error);
 }
 
 int
 cloudabi_sys_fd_seek(struct thread *td, struct cloudabi_sys_fd_seek_args *uap)
 {
+	struct lseek_args lseek_args = {
+		.fd	= uap->fd,
+		.offset	= uap->offset
+	};
+
+	switch (uap->whence) {
+	case CLOUDABI_WHENCE_CUR:
+		lseek_args.whence = SEEK_CUR;
+		break;
+	case CLOUDABI_WHENCE_END:
+		lseek_args.whence = SEEK_END;
+		break;
+	case CLOUDABI_WHENCE_SET:
+		lseek_args.whence = SEEK_SET;
+		break;
+	default:
+		return (EINVAL);
+	}
 
-	/* Not implemented. */
-	return (ENOSYS);
+	return (sys_lseek(td, &lseek_args));
 }
 
 int
@@ -109,7 +148,9 @@ cloudabi_sys_fd_stat_put(struct thread *
 int
 cloudabi_sys_fd_sync(struct thread *td, struct cloudabi_sys_fd_sync_args *uap)
 {
+	struct fsync_args fsync_args = {
+		.fd = uap->fd
+	};
 
-	/* Not implemented. */
-	return (ENOSYS);
+	return (sys_fsync(td, &fsync_args));
 }

Modified: head/sys/kern/kern_descrip.c
==============================================================================
--- head/sys/kern/kern_descrip.c	Thu Jul  9 15:56:51 2015	(r285322)
+++ head/sys/kern/kern_descrip.c	Thu Jul  9 16:07:01 2015	(r285323)
@@ -102,7 +102,6 @@ static uma_zone_t filedesc0_zone;
 
 static int	closefp(struct filedesc *fdp, int fd, struct file *fp,
 		    struct thread *td, int holdleaders);
-static int	kern_dup(struct thread *td, int flags, int old, int new);
 static int	fd_first_free(struct filedesc *fdp, int low, int size);
 static int	fd_last_used(struct filedesc *fdp, int size);
 static void	fdgrowtable(struct filedesc *fdp, int nfd);
@@ -111,11 +110,6 @@ static void	fdunused(struct filedesc *fd
 static void	fdused(struct filedesc *fdp, int fd);
 static int	getmaxfd(struct thread *td);
 
-/* Flags for kern_dup() */
-#define	FDDUP_FIXED	0x1	/* Force fixed allocation. */
-#define	FDDUP_FCNTL	0x2	/* fcntl()-style errors. */
-#define	FDDUP_CLOEXEC	0x4	/* Atomically set FD_CLOEXEC. */
-
 /*
  * Each process has:
  *
@@ -794,7 +788,7 @@ getmaxfd(struct thread *td)
 /*
  * Common code for dup, dup2, fcntl(F_DUPFD) and fcntl(F_DUP2FD).
  */
-static int
+int
 kern_dup(struct thread *td, int flags, int old, int new)
 {
 	struct filedesc *fdp;
@@ -807,7 +801,10 @@ kern_dup(struct thread *td, int flags, i
 	p = td->td_proc;
 	fdp = p->p_fd;
 
-	MPASS((flags & ~(FDDUP_FIXED | FDDUP_FCNTL | FDDUP_CLOEXEC)) == 0);
+	MPASS((flags & ~(FDDUP_FIXED | FDDUP_FCNTL | FDDUP_CLOEXEC |
+	    FDDUP_MUSTREPLACE)) == 0);
+	MPASS((flags & (FDDUP_FIXED | FDDUP_MUSTREPLACE)) !=
+	    (FDDUP_FIXED | FDDUP_MUSTREPLACE));
 
 	/*
 	 * Verify we have a valid descriptor to dup from and possibly to
@@ -828,7 +825,7 @@ kern_dup(struct thread *td, int flags, i
 		return (EBADF);
 	}
 	oldfde = &fdp->fd_ofiles[old];
-	if (flags & FDDUP_FIXED && old == new) {
+	if (flags & (FDDUP_FIXED | FDDUP_MUSTREPLACE) && old == new) {
 		td->td_retval[0] = new;
 		if (flags & FDDUP_CLOEXEC)
 			fdp->fd_ofiles[new].fde_flags |= UF_EXCLOSE;
@@ -843,7 +840,16 @@ kern_dup(struct thread *td, int flags, i
 	 * table is large enough to hold it, and grab it.  Otherwise, just
 	 * allocate a new descriptor the usual way.
 	 */
-	if (flags & FDDUP_FIXED) {
+	if (flags & FDDUP_MUSTREPLACE) {
+		/* Target file descriptor must exist. */
+		if (new >= fdp->fd_nfiles ||
+		    fdp->fd_ofiles[new].fde_file == NULL) {
+			FILEDESC_XUNLOCK(fdp);
+			fdrop(fp, td);
+			return (EBADF);
+		}
+		newfde = &fdp->fd_ofiles[new];
+	} else if (flags & FDDUP_FIXED) {
 		if (new >= fdp->fd_nfiles) {
 			/*
 			 * The resource limits are here instead of e.g.

Modified: head/sys/sys/filedesc.h
==============================================================================
--- head/sys/sys/filedesc.h	Thu Jul  9 15:56:51 2015	(r285322)
+++ head/sys/sys/filedesc.h	Thu Jul  9 16:07:01 2015	(r285323)
@@ -134,6 +134,12 @@ struct filedesc_to_leader {
 					    SX_NOTRECURSED)
 #define	FILEDESC_UNLOCK_ASSERT(fdp)	sx_assert(&(fdp)->fd_sx, SX_UNLOCKED)
 
+/* Flags for kern_dup(). */
+#define	FDDUP_FIXED		0x1	/* Force fixed allocation. */
+#define	FDDUP_FCNTL		0x2	/* fcntl()-style errors. */
+#define	FDDUP_CLOEXEC		0x4	/* Atomically set FD_CLOEXEC. */
+#define	FDDUP_MUSTREPLACE	0x8	/* Target must exist. */
+
 struct thread;
 
 void	filecaps_init(struct filecaps *fcaps);

Modified: head/sys/sys/syscallsubr.h
==============================================================================
--- head/sys/sys/syscallsubr.h	Thu Jul  9 15:56:51 2015	(r285322)
+++ head/sys/sys/syscallsubr.h	Thu Jul  9 16:07:01 2015	(r285323)
@@ -85,6 +85,7 @@ int	kern_clock_settime(struct thread *td
 int	kern_close(struct thread *td, int fd);
 int	kern_connectat(struct thread *td, int dirfd, int fd,
 	    struct sockaddr *sa);
+int	kern_dup(struct thread *td, int flags, int old, int new);
 int	kern_execve(struct thread *td, struct image_args *args,
 	    struct mac *mac_p);
 int	kern_fchmodat(struct thread *td, int fd, char *path,


More information about the svn-src-head mailing list