Add a renameat(2) system call.
authorSascha Wildner <saw@online.de>
Sat, 31 Jul 2010 20:46:31 +0000 (22:46 +0200)
committerSascha Wildner <saw@online.de>
Sat, 31 Jul 2010 20:47:10 +0000 (22:47 +0200)
Based-on: FreeBSD

13 files changed:
bin/ln/symlink.7
include/stdio.h
lib/libc/sys/Makefile.inc
lib/libc/sys/rename.2
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 e2c8aeb..c4f345a 100644 (file)
@@ -31,9 +31,8 @@
 .\"
 .\"    @(#)symlink.7   8.3 (Berkeley) 3/31/94
 .\" $FreeBSD: src/bin/ln/symlink.7,v 1.13.2.7 2003/03/03 19:04:46 trhodes Exp $
-.\" $DragonFly: src/bin/ln/symlink.7,v 1.2 2003/06/17 04:22:50 dillon Exp $
 .\"
-.Dd March 31, 1994
+.Dd July 31, 2010
 .Dt SYMLINK 7
 .Os
 .Sh NAME
@@ -446,6 +445,7 @@ whether specified on the command line or encountered in the tree walk.
 .Xr lstat 2 ,
 .Xr readlink 2 ,
 .Xr rename 2 ,
+.Xr renameat 2 ,
 .Xr symlink 2 ,
 .Xr unlink 2 ,
 .Xr fts 3 ,
index 473e91a..2f241ad 100644 (file)
@@ -35,7 +35,6 @@
  *
  *     @(#)stdio.h     8.5 (Berkeley) 4/29/95
  * $FreeBSD: src/include/stdio.h,v 1.78 2009/03/25 08:07:52 das Exp $
- * $DragonFly: src/include/stdio.h,v 1.14 2008/06/05 17:53:10 swildner Exp $
  */
 
 #ifndef        _STDIO_H_
@@ -298,7 +297,7 @@ char        *tempnam(const char *, const char *);
 #if __BSD_VISIBLE || __POSIX_VISIBLE >= 200809
 ssize_t         getdelim(char ** __restrict, size_t * __restrict, int,
                  FILE * __restrict);
-/* int  renameat(int, const char *, int, const char *); */
+int     renameat(int, const char *, int, const char *);
 int     vdprintf(int, const char * __restrict, __va_list);
 
 /*
index b50849f..7bd1592 100644 (file)
@@ -1,6 +1,5 @@
 #      @(#)Makefile.inc        8.3 (Berkeley) 10/24/94
 # $FreeBSD: src/lib/libc/sys/Makefile.inc,v 1.75.2.7 2003/04/22 17:31:18 trhodes Exp $
-# $DragonFly: src/lib/libc/sys/Makefile.inc,v 1.39 2008/11/11 00:55:49 pavalos Exp $
 
 # sys sources
 .PATH: ${.CURDIR}/../libc/${MACHINE_ARCH}/sys ${.CURDIR}/../libc/sys
@@ -141,6 +140,7 @@ MLINKS+=open.2 openat.2
 MLINKS+=pathconf.2 fpathconf.2
 MLINKS+=read.2 pread.2 read.2 preadv.2 read.2 readv.2
 MLINKS+=recv.2 recvfrom.2 recv.2 recvmsg.2
+MLINKS+=rename.2 renameat.2
 MLINKS+=rtprio.2 lwp_rtprio.2
 .if !defined(NO_P1003_1B)
 MLINKS+=sched_get_priority_max.2 sched_get_priority_min.2 \
index f06d358..a133a62 100644 (file)
@@ -31,9 +31,8 @@
 .\"
 .\"     @(#)rename.2   8.1 (Berkeley) 6/4/93
 .\" $FreeBSD: src/lib/libc/sys/rename.2,v 1.8.2.7 2001/12/14 18:34:01 ru Exp $
-.\" $DragonFly: src/lib/libc/sys/rename.2,v 1.2 2003/06/17 04:26:47 dillon Exp $
 .\"
-.Dd June 4, 1993
+.Dd July 31, 2010
 .Dt RENAME 2
 .Os
 .Sh NAME
@@ -45,6 +44,8 @@
 .In stdio.h
 .Ft int
 .Fn rename "const char *from" "const char *to"
+.Ft int
+.Fn renameat "int fromfd" "const char *from" "int tofd" "const char *to"
 .Sh DESCRIPTION
 .Fn Rename
 causes the link named
@@ -74,6 +75,37 @@ If the final component of
 is a symbolic link,
 the symbolic link is renamed,
 not the file or directory to which it points.
+.Pp
+The
+.Fn renameat
+system call is equivalent to
+.Fn rename
+except in the case where either
+.Fa from
+or
+.Fa to
+specifies a relative path.
+If
+.Fa from
+is a relative path, the file to be renamed is located
+relative to the directory associated with the file descriptor
+.Fa fromfd
+instead of the current working directory.
+If the
+.Fa to
+is a relative path, the same happens only relative to the directory associated
+with
+.Fa tofd .
+If the
+.Fn renameat
+is passed the special value
+.Dv AT_FDCWD
+in the
+.Fa fromfd
+or
+.Fa tofd
+parameter, the current working directory is used in the determination
+of the file for the respective path parameter.
 .\".Sh CAVEAT
 .\"The system can deadlock if a loop in the file system graph is present.
 .\"This loop takes the form of an entry in directory
@@ -190,11 +222,55 @@ or
 .Fa To
 is a directory and is not empty.
 .El
+.Pp
+In addition to the errors returned by the
+.Fn rename ,
+the
+.Fn renameat
+may fail if:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The
+.Fa from
+argument does not specify an absolute path and the
+.Fa fromfd
+argument is neither
+.Dv AT_FDCWD
+nor a valid file descriptor open for searching, or the
+.Fa to
+argument does not specify an absolute path and the
+.Fa tofd
+argument is neither
+.Dv AT_FDCWD
+nor a valid file descriptor open for searching.
+.It Bq Er ENOTDIR
+The
+.Fa from
+argument is not an absolute path and
+.Fa fromfd
+is neither
+.Dv AT_FDCWD
+nor a file descriptor associated with a directory, or the
+.Fa to
+argument is not an absolute path and
+.Fa tofd
+is neither
+.Dv AT_FDCWD
+nor a file descriptor associated with a directory.
+.El
 .Sh SEE ALSO
 .Xr open 2 ,
 .Xr symlink 7
 .Sh STANDARDS
 The
 .Fn rename
-function call is expected to conform to
+system call is expected to conform to
 .St -p1003.1-96 .
+The
+.Fn renameat
+system call follows The Open Group Extended API Set 2 specification.
+.Sh HISTORY
+The
+.Fn renameat
+system call appeared in
+.Dx 2.7 .
index f186de1..71b3d7b 100644 (file)
@@ -556,4 +556,5 @@ struct sysent sysent[] = {
        { AS(ioprio_set_args), (sy_call_t *)sys_ioprio_set },   /* 520 = ioprio_set */
        { AS(ioprio_get_args), (sy_call_t *)sys_ioprio_get },   /* 521 = ioprio_get */
        { AS(chroot_kernel_args), (sy_call_t *)sys_chroot_kernel },     /* 522 = chroot_kernel */
+       { AS(renameat_args), (sy_call_t *)sys_renameat },       /* 523 = renameat */
 };
index 42d6c83..22eddad 100644 (file)
@@ -530,4 +530,5 @@ const char *syscallnames[] = {
        "ioprio_set",                   /* 520 = ioprio_set */
        "ioprio_get",                   /* 521 = ioprio_get */
        "chroot_kernel",                        /* 522 = chroot_kernel */
+       "renameat",                     /* 523 = renameat */
 };
index 591bcef..1c2fca5 100644 (file)
 520    STD     BSD     { int ioprio_set(int which, int who, int prio); }
 521    STD     BSD     { int ioprio_get(int which, int who); }
 522    STD     BSD     { int chroot_kernel(char *path); }
+523    STD     POSIX   { int renameat(int oldfd, char *old, int newfd, \
+                                 char *new); }
index 3ab94e2..eed3543 100644 (file)
@@ -37,7 +37,6 @@
  *
  *     @(#)vfs_syscalls.c      8.13 (Berkeley) 4/15/94
  * $FreeBSD: src/sys/kern/vfs_syscalls.c,v 1.151.2.18 2003/04/04 20:35:58 tegge Exp $
- * $DragonFly: src/sys/kern/vfs_syscalls.c,v 1.135 2008/11/11 00:55:49 pavalos Exp $
  */
 
 #include <sys/param.h>
@@ -3800,6 +3799,37 @@ sys_rename(struct rename_args *uap)
        return (error);
 }
 
+/*
+ * renameat_args(int oldfd, char *old, int newfd, char *new)
+ *
+ * Rename files using paths relative to the directories associated with
+ * oldfd and newfd.  Source and destination must either both be directories,
+ * or both not be directories.  If target is a directory, it must be empty.
+ *
+ * MPALMOSTSAFE
+ */
+int
+sys_renameat(struct renameat_args *uap)
+{
+       struct nlookupdata oldnd, newnd;
+       struct file *oldfp, *newfp;
+       int error;
+
+       get_mplock();
+       error = nlookup_init_at(&oldnd, &oldfp, uap->oldfd, uap->old,
+           UIO_USERSPACE, 0);
+       if (error == 0) {
+               error = nlookup_init_at(&newnd, &newfp, uap->newfd, uap->new,
+                   UIO_USERSPACE, 0);
+               if (error == 0)
+                       error = kern_rename(&oldnd, &newnd);
+               nlookup_done(&newnd);
+       }
+       nlookup_done(&oldnd);
+       rel_mplock();
+       return (error);
+}
+
 int
 kern_mkdir(struct nlookupdata *nd, int mode)
 {
index 0607195..0d7d32d 100644 (file)
@@ -353,3 +353,4 @@ HIDE_POSIX(mq_timedreceive)
 HIDE_BSD(ioprio_set)
 HIDE_BSD(ioprio_get)
 HIDE_BSD(chroot_kernel)
+HIDE_POSIX(renameat)
index b121f6e..3553127 100644 (file)
 #define        SYS_ioprio_set  520
 #define        SYS_ioprio_get  521
 #define        SYS_chroot_kernel       522
-#define        SYS_MAXSYSCALL  523
+#define        SYS_renameat    523
+#define        SYS_MAXSYSCALL  524
index 4103f66..892e5e8 100644 (file)
@@ -301,4 +301,5 @@ MIASM =  \
        mq_timedreceive.o \
        ioprio_set.o \
        ioprio_get.o \
-       chroot_kernel.o
+       chroot_kernel.o \
+       renameat.o
index 6b365af..de8594e 100644 (file)
@@ -2301,6 +2301,15 @@ struct   chroot_kernel_args {
 #endif
        char *  path;   char path_[PAD_(char *)];
 };
+struct renameat_args {
+#ifdef _KERNEL
+       struct sysmsg sysmsg;
+#endif
+       int     oldfd;  char oldfd_[PAD_(int)];
+       char *  old;    char old_[PAD_(char *)];
+       int     newfd;  char newfd_[PAD_(int)];
+       char *  new;    char new_[PAD_(char *)];
+};
 
 #ifdef COMPAT_43
 
@@ -2910,6 +2919,7 @@ int       sys_mq_timedreceive (struct mq_timedreceive_args *);
 int    sys_ioprio_set (struct ioprio_set_args *);
 int    sys_ioprio_get (struct ioprio_get_args *);
 int    sys_chroot_kernel (struct chroot_kernel_args *);
+int    sys_renameat (struct renameat_args *);
 
 #endif /* !_SYS_SYSPROTO_H_ */
 #undef PAD_
index 374ee3c..62aef5d 100644 (file)
@@ -409,4 +409,5 @@ union sysunion {
        struct  ioprio_set_args ioprio_set;
        struct  ioprio_get_args ioprio_get;
        struct  chroot_kernel_args chroot_kernel;
+       struct  renameat_args renameat;
 };