summaryrefslogtreecommitdiff
path: root/libguile
diff options
context:
space:
mode:
authorMaxime Devos <maximedevos@telenet.be>2021-11-16 11:06:33 +0000
committerLudovic Courtès <ludo@gnu.org>2022-10-21 17:40:37 +0200
commit3b45185d8f40b5c41abfe15571550ce1a7fd4011 (patch)
tree069837a18afb4a44b90e0dcb6da5f32df436e3b5 /libguile
parent19b48b1c4a0335851a51d1ac69a24b154d401fdd (diff)
downloadguile-3b45185d8f40b5c41abfe15571550ce1a7fd4011.tar.gz
Define a Scheme binding to ‘unlinkat’ when it exists.
‘unlinkat’ is used for both unlinking regular files and removing empty directories. * configure.ac: Detect if ‘unlinkat’ exists. * doc/ref/posix.texi (File System): Document why there is no ‘rmdirat’ procedure, and document the ‘delete-file-at’ procedure. * libguile/filesys.c (scm_rmdir): Adjust the docstring here as well. (scm_delete_file_at): Define a Scheme binding to ‘unlinkat’. * libguile/filesys.h (scm_delete_file_at): Make ‘scm_delete_file_at’ part of the C API. Signed-off-by: Ludovic Courtès <ludo@gnu.org>
Diffstat (limited to 'libguile')
-rw-r--r--libguile/filesys.c32
-rw-r--r--libguile/filesys.h1
2 files changed, 33 insertions, 0 deletions
diff --git a/libguile/filesys.c b/libguile/filesys.c
index 1ec85d940..ee7fc5bfa 100644
--- a/libguile/filesys.c
+++ b/libguile/filesys.c
@@ -1456,6 +1456,38 @@ SCM_DEFINE (scm_delete_file, "delete-file", 1, 0, 0,
}
#undef FUNC_NAME
+#ifdef HAVE_UNLINKAT
+SCM_DEFINE (scm_delete_file_at, "delete-file-at", 2, 1, 0,
+ (SCM dir, SCM str, SCM flags),
+ "Like @code{unlink}, but resolve @var{str} relative to the\n"
+ "directory referred to by the file port @var{dir} instead.\n\n"
+ "The optional @var{flags} argument can be @code{AT_REMOVEDIR},\n"
+ "in which case @code{delete-file-at} will act like @code{rmdir} instead\n"
+ "of @code{delete-file}. Why doesn't POSIX have a @code{rmdirat} function\n"
+ "for this instead? No idea!")
+#define FUNC_NAME s_scm_delete_file_at
+{
+ int ans;
+ int dir_fdes;
+ int c_flags;
+
+ if (SCM_UNBNDP (flags))
+ c_flags = 0;
+ else
+ c_flags = scm_to_int (flags);
+
+ SCM_VALIDATE_OPFPORT (SCM_ARG1, dir);
+ dir_fdes = SCM_FPORT_FDES (dir);
+
+ STRING_SYSCALL (str, c_str, ans = unlinkat (dir_fdes, c_str, c_flags));
+ scm_remember_upto_here_1 (dir);
+ if (ans != 0)
+ SCM_SYSERROR;
+ return SCM_UNSPECIFIED;
+}
+#undef FUNC_NAME
+#endif
+
SCM_DEFINE (scm_access, "access?", 2, 0, 0,
(SCM path, SCM how),
"Test accessibility of a file under the real UID and GID of the\n"
diff --git a/libguile/filesys.h b/libguile/filesys.h
index 377a3795e..37d084cd5 100644
--- a/libguile/filesys.h
+++ b/libguile/filesys.h
@@ -51,6 +51,7 @@ 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_delete_file_at (SCM dir, SCM str, SCM flags);
SCM_API SCM scm_mkdir (SCM path, SCM mode);
SCM_API SCM scm_mkdirat (SCM dir, SCM path, SCM mode);
SCM_API SCM scm_rmdir (SCM path);