[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 1/2] renameat2: port to Solaris 10
From: |
Paul Eggert |
Subject: |
[PATCH 1/2] renameat2: port to Solaris 10 |
Date: |
Thu, 27 Jul 2017 18:03:36 -0700 |
* lib/renameat2.c (rename_noreplace): Use lstat, not faccessat
with AT_SYMLINK_NOFOLLOW (which is not portable).
(renameat): Undef before using, to avoid endless recursion when
the replacement renameat calls renameat2 which calls the
replacement renameat.
(renameat2): Use lstatat, not faccessat with AT_SYMLINK_NOFOLLOW.
* modules/renameat2 (Depends-on): Remove faccessat.
* modules/renameat-tests (test_renameat_LDADD):
* modules/renameat2-tests (test_renameat2_LDADD):
Remove $(LIB_EACCESS).
---
ChangeLog | 12 ++++++++++++
lib/renameat2.c | 37 +++++++++++++++++++++++--------------
modules/renameat-tests | 2 +-
modules/renameat2 | 1 -
modules/renameat2-tests | 2 +-
5 files changed, 37 insertions(+), 17 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index d922e31..ec39037 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
2017-07-27 Paul Eggert <address@hidden>
+ renameat2: port to Solaris 10
+ * lib/renameat2.c (rename_noreplace): Use lstat, not faccessat
+ with AT_SYMLINK_NOFOLLOW (which is not portable).
+ (renameat): Undef before using, to avoid endless recursion when
+ the replacement renameat calls renameat2 which calls the
+ replacement renameat.
+ (renameat2): Use lstatat, not faccessat with AT_SYMLINK_NOFOLLOW.
+ * modules/renameat2 (Depends-on): Remove faccessat.
+ * modules/renameat-tests (test_renameat_LDADD):
+ * modules/renameat2-tests (test_renameat2_LDADD):
+ Remove $(LIB_EACCESS).
+
renameat2: new module
Although the Linux syscall renameat2 is not in glibc (yet?), it is
useful to have access to its RENAME_NOREPLACE flag.
diff --git a/lib/renameat2.c b/lib/renameat2.c
index 19df58c..e223653 100644
--- a/lib/renameat2.c
+++ b/lib/renameat2.c
@@ -51,14 +51,15 @@ errno_fail (int e)
static int
rename_noreplace (char const *src, char const *dst)
{
- /* This has a race between the call to faccessat and the call to rename. */
- int r = faccessat (AT_FDCWD, dst, F_OK, AT_EACCESS | AT_SYMLINK_NOFOLLOW);
- reurn (r == 0 ? errno_fail (EEXIST)
- : errno == ENOENT ? rename (src, dst)
- : r);
+ /* This has a race between the call to lstat and the call to rename. */
+ struct stat st;
+ return (lstat (dst, &st) == 0 ? errno_fail (EEXIST)
+ : errno == ENOENT ? rename (src, dst)
+ : -1);
}
#endif
+#undef renameat
/* Rename FILE1, in the directory open on descriptor FD1, to FILE2, in
the directory open on descriptor FD2. If possible, do it without
@@ -91,20 +92,23 @@ renameat2 (int fd1, char const *src, int fd2, char const
*dst,
int rename_errno = ENOTDIR;
struct stat src_st;
struct stat dst_st;
+ bool dst_found_nonexistent = false;
if (flags != 0)
{
- int r;
/* RENAME_NOREPLACE is the only flag currently supported. */
if (flags & ~RENAME_NOREPLACE)
return errno_fail (ENOTSUP);
- /* This has a race between the call to faccessat and the
- call to renameat. */
- r = faccessat (fd2, dst, F_OK, AT_EACCESS | AT_SYMLINK_NOFOLLOW);
- if (r == 0)
- return errno_fail (EEXIST);
- if (errno != ENOENT)
- return r;
+ else
+ {
+ /* This has a race between the call to lstatat and the calls to
+ renameat below. */
+ if (lstatat (fd2, dst, &dst_st) == 0)
+ return errno_fail (EEXIST);
+ if (errno != ENOENT)
+ return -1;
+ dst_found_nonexistent = true;
+ }
}
/* Let strace see any ENOENT failure. */
@@ -124,7 +128,12 @@ renameat2 (int fd1, char const *src, int fd2, char const
*dst,
before calling rename. */
if (lstatat (fd1, src, &src_st))
return -1;
- if (lstatat (fd2, dst, &dst_st))
+ if (dst_found_nonexistent)
+ {
+ if (!S_ISDIR (src_st.st_mode))
+ return errno_fail (ENOENT);
+ }
+ else if (lstatat (fd2, dst, &dst_st))
{
if (errno != ENOENT || !S_ISDIR (src_st.st_mode))
return -1;
diff --git a/modules/renameat-tests b/modules/renameat-tests
index 4e9bf2f..970ebd7 100644
--- a/modules/renameat-tests
+++ b/modules/renameat-tests
@@ -17,4 +17,4 @@ configure.ac:
Makefile.am:
TESTS += test-renameat
check_PROGRAMS += test-renameat
-test_renameat_LDADD = $(LDADD) $(LIB_EACCESS) @LIBINTL@
+test_renameat_LDADD = $(LDADD) @LIBINTL@
diff --git a/modules/renameat2 b/modules/renameat2
index f0ce195..54f72e1 100644
--- a/modules/renameat2
+++ b/modules/renameat2
@@ -10,7 +10,6 @@ m4/renameat.m4
Depends-on:
stdio
extensions
-faccessat
fcntl-h
filenamecat-lgpl [test $HAVE_RENAMEAT = 0 || test $REPLACE_RENAMEAT = 1]
openat-h [test $HAVE_RENAMEAT = 0 || test $REPLACE_RENAMEAT = 1]
diff --git a/modules/renameat2-tests b/modules/renameat2-tests
index efcc33d..accf3c4 100644
--- a/modules/renameat2-tests
+++ b/modules/renameat2-tests
@@ -17,4 +17,4 @@ configure.ac:
Makefile.am:
TESTS += test-renameat2
check_PROGRAMS += test-renameat2
-test_renameat2_LDADD = $(LDADD) $(LIB_EACCESS) @LIBINTL@
+test_renameat2_LDADD = $(LDADD) @LIBINTL@
--
2.7.4
- [PATCH 1/2] renameat2: port to Solaris 10,
Paul Eggert <=