Skip to content

Commit

Permalink
Add support for renameat2()
Browse files Browse the repository at this point in the history
  • Loading branch information
Ratler committed May 28, 2019
1 parent b50e64e commit 77680a9
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 3 deletions.
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ AC_CHECK_HEADERS([sys/param.h \
utime.h \
dirent.h \
linux/version.h])
AC_CHECK_FUNCS(utimensat)
AC_CHECK_FUNCS_ONCE([utimensat renameat renameat2])

local_cflags="$CFLAGS"

Expand Down
61 changes: 60 additions & 1 deletion installwatch.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,6 @@ static int (*true_scandir64)( const char *,struct dirent64 ***,
static int (*true_xstat64)(int,const char *, struct stat64 *);
static int (*true_lxstat64)(int,const char *, struct stat64 *);
static int (*true_truncate64)(const char *, __off64_t);

#endif

#if (GLIBC_MINOR >= 4)
Expand All @@ -173,6 +172,10 @@ static int (*true_symlinkat)(const char *, int, const char *);
static int (*true_unlinkat)(int, const char *, int);
#endif

#ifdef HAVE_RENAMEAT2
static int (*true_renameat2)(int, const char *, int, const char *, unsigned int);
#endif

#ifdef HAVE_UTIMENSAT
static int (*true_utimensat)(int, const char *, const struct timespec[2], int);
#endif
Expand Down Expand Up @@ -428,6 +431,9 @@ static void initialize(void) {
true_access = dlsym(handle, "access");
#endif

#ifdef HAVE_RENAMEAT2
true_renameat2 = dlsym(handle, "renameat2");
#endif

#if(GLIBC_MINOR >= 1)
true_creat64 = dlsym(handle, "creat64");
Expand Down Expand Up @@ -4627,3 +4633,56 @@ int unlinkat (int dirfd, const char *path, int flags) {


#endif /* GLIBC_MINOR >= 4 */

#ifdef HAVE_RENAMEAT2
int renameat2 (int olddirfd, const char *oldpath,
int newdirfd, const char *newpath, unsigned int flags) {

int result;
instw_t instwold;
instw_t instwnew;

/* If all we are doing is normal open, forgo refcounting, etc. */
if( (olddirfd == AT_FDCWD || *oldpath == '/') &&
(newdirfd == AT_FDCWD || *newpath == '/') ) {
#if DEBUG
debug(2, "renameat2(%d, %s, %d, %s, %d)\n", olddirfd, oldpath, newdirfd, newpath, flags);
#endif

return rename(oldpath, newpath);
}

REFCOUNT;

if (!libc_handle)
initialize();

#if DEBUG
debug(2, "renameat2(%d, %s, %d, %s, %d)\n", olddirfd, oldpath, newdirfd, newpath, flags);
#endif

/* We were asked to work in "real" mode */
if(!(__instw.gstatus & INSTW_INITIALIZED) ||
!(__instw.gstatus & INSTW_OKWRAP))
return true_renameat2(olddirfd, oldpath, newdirfd, newpath, flags);

instw_new(&instwold);
instw_new(&instwnew);
instw_setpathrel(&instwold, olddirfd, oldpath);
instw_setpathrel(&instwnew, newdirfd, newpath);

#if DEBUG
instw_print(&instwold);
instw_print(&instwnew);
#endif

result=rename(instwold.path, instwnew.path);

instw_delete(&instwold);
instw_delete(&instwnew);

return result;
}


#endif
19 changes: 18 additions & 1 deletion test-installwatch.c
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,20 @@ void test_utimensat(void) {
}
#endif

#ifdef HAVE_RENAMEAT2
void test_renameat2(void) {
int fd;
FILE *fd_read;
fd = creat(TESTFILE, 0700);
close(fd);
renameat2(AT_FDCWD, TESTFILE, AT_FDCWD, TESTFILE2, 0);
fd_read = fopen(TESTFILE2, "r");
close(fd_read);
if (fd_read != NULL)
unlinkat(AT_FDCWD, TESTFILE2, 0);
}
#endif

int do_test(const char *name, void (*function)(void), int increment) {
int old_refcount;

Expand Down Expand Up @@ -395,7 +409,10 @@ int main(int argc, char **argv) {
do_test("unlinkat", test_unlinkat, 2);
#endif
#ifdef HAVE_UTIMENSAT
do_test("utimensat", test_utimensat, 2);
do_test("utimensat", test_utimensat, 2);
#endif
#ifdef HAVE_RENAMEAT2
do_test("renameat2", test_renameat2, 4);
#endif

putchar('\n');
Expand Down

0 comments on commit 77680a9

Please sign in to comment.