Date: Thu, 9 Jul 2015 16:07:02 +0000 (UTC) From: Ed Schouten <ed@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r285323 - in head/sys: compat/cloudabi kern sys Message-ID: <201507091607.t69G72nt031613@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201507091607.t69G72nt031613>