add fchownat(2) system call
authorNicolas Thery <nthery@gmail.com>
Sun, 9 Aug 2009 17:33:23 +0000 (19:33 +0200)
committerNicolas Thery <nthery@gmail.com>
Sun, 9 Aug 2009 17:33:26 +0000 (19:33 +0200)
Add also libc_r wrapper and man page.

14 files changed:
include/unistd.h
lib/libc/sys/Makefile.inc
lib/libc/sys/chown.2
lib/libc_r/uthread/Makefile.inc
lib/libc_r/uthread/uthread_fchownat.c [new file with mode: 0644]
sys/kern/init_sysent.c
sys/kern/syscalls.c
sys/kern/syscalls.master
sys/kern/vfs_syscalls.c
sys/sys/syscall-hide.h
sys/sys/syscall.h
sys/sys/syscall.mk
sys/sys/sysproto.h
sys/sys/sysunion.h

index 83139db..1735b98 100644 (file)
@@ -318,6 +318,7 @@ int  access(const char *, int);
 unsigned int    alarm(unsigned int);
 int     chdir(const char *);
 int     chown(const char *, uid_t, gid_t);
+int     fchownat(int, const char *, uid_t, gid_t, int);
 int     close(int);
 int     dup(int);
 int     dup2(int, int);
index dd847f8..01f7699 100644 (file)
@@ -103,7 +103,7 @@ MLINKS+=caps_sys_get.2 caps_sys_wait.2
 MLINKS+=chdir.2 fchdir.2
 MLINKS+=chflags.2 fchflags.2 chflags.2 lchflags.2
 MLINKS+=chmod.2 fchmod.2 chmod.2 lchmod.2 chmod.2 fchmodat.2
-MLINKS+=chown.2 fchown.2 chown.2 lchown.2
+MLINKS+=chown.2 fchown.2 chown.2 lchown.2 chown.2 fchownat.2
 MLINKS+=clock_gettime.2 clock_getres.2 clock_gettime.2 clock_settime.2
 MLINKS+=dup.2 dup2.2
 MLINKS+=fhopen.2 fhstat.2 fhopen.2 fhstatfs.2 fhopen.2 fhstatvfs.2
index 96b1b35..7326161 100644 (file)
 .\" $FreeBSD: src/lib/libc/sys/chown.2,v 1.12.2.6 2001/12/14 18:34:00 ru Exp $
 .\" $DragonFly: src/lib/libc/sys/chown.2,v 1.2 2003/06/17 04:26:47 dillon Exp $
 .\"
-.Dd April 19, 1994
+.Dd August 9, 2009
 .Dt CHOWN 2
 .Os
 .Sh NAME
 .Nm chown ,
 .Nm fchown ,
-.Nm lchown
+.Nm lchown ,
+.Nm fchownat
 .Nd change owner and group of a file
 .Sh LIBRARY
 .Lb libc
@@ -51,6 +52,8 @@
 .Fn fchown "int fd" "uid_t owner" "gid_t group"
 .Ft int
 .Fn lchown "const char *path" "uid_t owner" "gid_t group"
+.Ft int
+.Fn fchownat "int dirfd" "const char *path" "uid_t owner" "gid_t group" "int flags"
 .Sh DESCRIPTION
 The owner ID and group ID of the file
 named by
@@ -91,16 +94,56 @@ but does not follow symbolic links.
 .Pp
 One of the owner or group id's
 may be left unchanged by specifying it as -1.
+.Pp
+The
+.Fn fchownat
+function is equivalent to the
+.Fn chown
+or
+.Fn lchown
+functions except in the case where the
+.Fa path
+specifies a relative path.
+In this case the file to be opened is determined relative to the directory
+associated with the file descriptor
+.Fa dirfd
+instead of the current working directory.
+If
+.Fn fchownat
+is passed the special value
+.Dv AT_FDCWD
+in the
+.Fa dirfd
+parameter, the current working directory is used
+and the behavior is identical to a call to
+.Fn chown
+or
+.Fn lchown .
+.Pp
+The values for the
+.Fa flags
+are constructed by a bitwise-inclusive OR of flags from the following list,
+defined in
+.In fcntl.h :
+.Bl -tag -width indent
+.It Dv AT_SYMLINK_NOFOLLOW
+If
+.Fa path
+names a symbolic link, the mode of the symbolic link is changed.
+.El
 .Sh RETURN VALUES
 .Rv -std
 .Sh ERRORS
-.Fn Chown
-and
+.Fn Chown ,
 .Fn lchown
+and
+.Fn fchownat
 will fail and the file will be unchanged if:
 .Bl -tag -width Er
 .It Bq Er ENOTDIR
-A component of the path prefix is not a directory.
+A component of the path prefix or
+.Fa dirfd
+is not a directory.
 .It Bq Er ENAMETOOLONG
 A component of a pathname exceeded 255 characters,
 or an entire path name exceeded 1023 characters.
@@ -167,3 +210,8 @@ The
 function was added in
 .Fx 3.0
 to compensate for the loss of functionality.
+.Pp
+The
+.Fn fchownat
+system call appeared in
+.Dx 2.3 .
index 67298fa..eebb177 100644 (file)
@@ -50,6 +50,7 @@ SRCS+= \
        uthread_fchmod.c \
        uthread_fchmodat.c \
        uthread_fchown.c \
+       uthread_fchownat.c \
        uthread_fcntl.c \
        uthread_fd.c \
        uthread_find_thread.c \
diff --git a/lib/libc_r/uthread/uthread_fchownat.c b/lib/libc_r/uthread/uthread_fchownat.c
new file mode 100644 (file)
index 0000000..6a5ff7d
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2009 The DragonFly Project.  All rights reserved.
+ * 
+ * This code is derived from software contributed to The DragonFly Project
+ * by Nicolas Thery <nthery@gmail.com>
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name of The DragonFly Project nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific, prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <pthread.h>
+#include <unistd.h>
+#include "pthread_private.h"
+
+int
+_fchownat(int fd, const char *path, uid_t owner, gid_t group, int flags)
+{
+       int             ret;
+
+       if ((ret = _FD_LOCK(fd, FD_READ, NULL)) == 0) {
+               ret = __sys_fchownat(fd, path, owner, group, flags);
+               _FD_UNLOCK(fd, FD_READ);
+       }
+       return (ret);
+}
+
+__strong_reference(_fchownat, fchownat);
index 6d69ef6..65bfd12 100644 (file)
@@ -540,4 +540,5 @@ struct sysent sysent[] = {
        { AS(openat_args), (sy_call_t *)sys_openat },   /* 504 = openat */
        { AS(fstatat_args), (sy_call_t *)sys_fstatat }, /* 505 = fstatat */
        { AS(fchmodat_args), (sy_call_t *)sys_fchmodat },       /* 506 = fchmodat */
+       { AS(fchownat_args), (sy_call_t *)sys_fchownat },       /* 507 = fchownat */
 };
index 007e6a9..e1fa422 100644 (file)
@@ -514,4 +514,5 @@ const char *syscallnames[] = {
        "openat",                       /* 504 = openat */
        "fstatat",                      /* 505 = fstatat */
        "fchmodat",                     /* 506 = fchmodat */
+       "fchownat",                     /* 507 = fchownat */
 };
index 83fe3f1..628a138 100644 (file)
                                        struct stat *sb, int flags); }
 506    STD     POSIX   { int fchmodat(int fd, char *path, int mode, \
                                        int flags); }
+507    STD     POSIX   { int fchownat(int fd, char *path, int uid, int gid, \
+                                       int flags); }
index 83bf5cf..0c723e4 100644 (file)
@@ -2906,6 +2906,32 @@ sys_fchown(struct fchown_args *uap)
        return (error);
 }
 
+/*
+ * fchownat(int fd, char *path, int uid, int gid, int flags)
+ *
+ * Set ownership of file pointed to by fd/path.
+ */
+int
+sys_fchownat(struct fchownat_args *uap)
+{
+       struct nlookupdata nd;
+       struct file *fp;
+       int error;
+       int flags;
+
+       if (uap->flags & ~_AT_SYMLINK_MASK)
+               return (EINVAL);
+       flags = (uap->flags & AT_SYMLINK_NOFOLLOW) ? 0 : NLC_FOLLOW;
+
+       error = nlookup_init_at(&nd, &fp, uap->fd, uap->path, 
+                               UIO_USERSPACE, flags);
+       if (error == 0)
+               error = kern_chown(&nd, uap->uid, uap->gid);
+       nlookup_done_at(&nd, fp);
+       return (error);
+}
+
+
 static int
 getutimes(const struct timeval *tvp, struct timespec *tsp)
 {
index cb22bbd..6e83a94 100644 (file)
@@ -337,3 +337,4 @@ HIDE_BSD(getvfsstat)
 HIDE_POSIX(openat)
 HIDE_POSIX(fstatat)
 HIDE_POSIX(fchmodat)
+HIDE_POSIX(fchownat)
index ff73c93..e641151 100644 (file)
 #define        SYS_openat      504
 #define        SYS_fstatat     505
 #define        SYS_fchmodat    506
-#define        SYS_MAXSYSCALL  507
+#define        SYS_fchownat    507
+#define        SYS_MAXSYSCALL  508
index e027afd..aee75a1 100644 (file)
@@ -288,4 +288,5 @@ MIASM =  \
        getvfsstat.o \
        openat.o \
        fstatat.o \
-       fchmodat.o
+       fchmodat.o \
+       fchownat.o
index 05db2a2..6f80bc7 100644 (file)
@@ -2186,6 +2186,16 @@ struct   fchmodat_args {
        int     mode;   char mode_[PAD_(int)];
        int     flags;  char flags_[PAD_(int)];
 };
+struct fchownat_args {
+#ifdef _KERNEL
+       struct sysmsg sysmsg;
+#endif
+       int     fd;     char fd_[PAD_(int)];
+       char *  path;   char path_[PAD_(char *)];
+       int     uid;    char uid_[PAD_(int)];
+       int     gid;    char gid_[PAD_(int)];
+       int     flags;  char flags_[PAD_(int)];
+};
 
 #ifdef COMPAT_43
 
@@ -2775,6 +2785,7 @@ int       sys_getvfsstat (struct getvfsstat_args *);
 int    sys_openat (struct openat_args *);
 int    sys_fstatat (struct fstatat_args *);
 int    sys_fchmodat (struct fchmodat_args *);
+int    sys_fchownat (struct fchownat_args *);
 
 #endif /* !_SYS_SYSPROTO_H_ */
 #undef PAD_
index f2bc2fe..4d70eec 100644 (file)
@@ -393,4 +393,5 @@ union sysunion {
        struct  openat_args openat;
        struct  fstatat_args fstatat;
        struct  fchmodat_args fchmodat;
+       struct  fchownat_args fchownat;
 };