From cf9308cb74fee4f4401cf06a8701318f885a6bd3 Mon Sep 17 00:00:00 2001 From: Maxime Devos Date: Thu, 11 Mar 2021 22:47:16 +0100 Subject: [PATCH 08/17] =?UTF-8?q?Define=20a=20Scheme=20binding=20to=20?= =?UTF-8?q?=E2=80=98renameat=E2=80=99=20when=20it=20exists.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * configure.ac: Detect if ‘renameat’ is defined. * libguile/filesys.c (scm_renameat): Define a Scheme binding to the ‘renameat’ system call. * doc/ref/posix.texi (File System): Document it. * libguile/filesys.h (scm_renameat): Make it part of the C API. --- configure.ac | 2 +- doc/ref/posix.texi | 8 ++++++++ libguile/filesys.c | 27 +++++++++++++++++++++++++++ libguile/filesys.h | 1 + 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 15b0ff4a9..a2ad3364f 100644 --- a/configure.ac +++ b/configure.ac @@ -482,7 +482,7 @@ AC_CHECK_HEADERS([assert.h crt_externs.h]) # AC_CHECK_FUNCS([DINFINITY DQNAN cexp chsize clog clog10 ctermid \ fesetround ftime ftruncate fchown fchmod fchdir readlinkat \ - symlinkat mkdirat getcwd geteuid getsid \ + symlinkat mkdirat renameat getcwd geteuid getsid \ gettimeofday getuid getgid gmtime_r ioctl lstat mkdir mkdtemp mknod \ nice readlink rename rmdir setegid seteuid \ setlocale setuid setgid setpgid setsid sigaction siginterrupt stat64 \ diff --git a/doc/ref/posix.texi b/doc/ref/posix.texi index 72e0c3032..a5dabf5e1 100644 --- a/doc/ref/posix.texi +++ b/doc/ref/posix.texi @@ -905,6 +905,14 @@ Renames the file specified by @var{oldname} to @var{newname}. The return value is unspecified. @end deffn +@findex renameat +@deffn {Scheme Procedure} rename-file-at olddir oldname newdir newname +@deffnx {C Function} scm_renameat (olddir, oldname, newdir, newname) +Like @code{rename-file}, but resolve @var{oldname} and @var{newname} +relative to the directories referred to by the file ports @var{olddir} +and @var{newdir} respectively. +@end deffn + @deffn {Scheme Procedure} link oldpath newpath @deffnx {C Function} scm_link (oldpath, newpath) Creates a new name @var{newpath} in the file system for the diff --git a/libguile/filesys.c b/libguile/filesys.c index 2d0c619af..61a16f981 100644 --- a/libguile/filesys.c +++ b/libguile/filesys.c @@ -1454,6 +1454,33 @@ SCM_DEFINE (scm_rename, "rename-file", 2, 0, 0, } #undef FUNC_NAME +#ifdef HAVE_RENAMEAT +SCM_DEFINE (scm_renameat, "rename-file-at", 4, 0, 0, + (SCM olddir, SCM oldname, SCM newdir, SCM newname), + "Like @code{rename-file}, but resolve @var{oldname} and @var{newname}\n" + "relative to the directories referred to by the file ports @var{olddir}\n" + "and @var{newdir} respectively.") +#define FUNC_NAME s_scm_renameat +{ + int rv; + int old_fdes, new_fdes; + + SCM_VALIDATE_OPFPORT (SCM_ARG1, olddir); + SCM_VALIDATE_OPFPORT (SCM_ARG3, newdir); + + old_fdes = SCM_FPORT_FDES (olddir); + new_fdes = SCM_FPORT_FDES (newdir); + + STRING2_SYSCALL (oldname, c_oldname, + newname, c_newname, + rv = renameat (old_fdes, c_oldname, new_fdes, c_newname)); + scm_remember_upto_here_2 (olddir, newdir); + if (rv != 0) + SCM_SYSERROR; + return SCM_UNSPECIFIED; +} +#undef FUNC_NAME +#endif SCM_DEFINE (scm_delete_file, "delete-file", 1, 0, 0, (SCM str), diff --git a/libguile/filesys.h b/libguile/filesys.h index f0dd35ede..7e17cc585 100644 --- a/libguile/filesys.h +++ b/libguile/filesys.h @@ -48,6 +48,7 @@ SCM_API SCM scm_close_fdes (SCM fd); SCM_API SCM scm_stat (SCM object, SCM exception_on_error); SCM_API SCM scm_link (SCM oldpath, SCM newpath); SCM_API SCM scm_rename (SCM oldname, SCM newname); +SCM_API SCM scm_renameat (SCM olddir, SCM oldname, SCM newdir, SCM newname); SCM_API SCM scm_delete_file (SCM str); SCM_API SCM scm_mkdir (SCM path, SCM mode); SCM_API SCM scm_mkdirat (SCM dir, SCM path, SCM mode); -- 2.30.2