Welcome to little lamb

Code » limb » commit d9d6bf2

djbunix.h: Add sarealpathat()

author Olivier Brunel
2023-05-30 17:24:43 UTC
committer Olivier Brunel
2023-07-05 07:39:26 UTC
parent 6f1346f3be33a18eeb4bee74a6b9ed475a5077d5

djbunix.h: Add sarealpathat()

src/doc/djbunix.h.0.md +8 -0
src/doc/djbunix.h/sarealpath.3.md +59 -0
src/liblimb/djbunix.h/sarealpathat.c +31 -0
src/liblimb/include/limb/djbunix.h +1 -0

diff --git a/src/doc/djbunix.h.0.md b/src/doc/djbunix.h.0.md
index d6eab10..e255dfa 100644
--- a/src/doc/djbunix.h.0.md
+++ b/src/doc/djbunix.h.0.md
@@ -105,3 +105,11 @@ The following functions/macros are defined :
 
 : [sareadlinkat0](3)
 :: Similar to [sareadlinkat](3) but ensures the content is NUL-terminated
+
+
+: [sarealpath](3)
+:: Place the canonicalized absolute pathname into the given *stralloc*.
+
+: [sarealpathat](3)
+:: Similar to [sarealpath](3) except for relative path, relative to given file
+:: descriptor.
diff --git a/src/doc/djbunix.h/sarealpath.3.md b/src/doc/djbunix.h/sarealpath.3.md
new file mode 100644
index 0000000..9d7b8dd
--- /dev/null
+++ b/src/doc/djbunix.h/sarealpath.3.md
@@ -0,0 +1,59 @@
+% limb manual
+% sarealpath(3)
+
+# NAME
+
+sarealpath, sarealpathat - place canonicalized absolute pathname into a stralloc
+
+# SYNOPSIS
+
+    #include <fcntl.h> /* AT_FDCWD */
+    #include <limb/djbunix.h>
+
+```pre hl
+int sarealpath(stralloc *<em>sa</em>, const char *<em>path</em>)
+int sarealpathat(stralloc *<em>sa</em>, int <em>fd</em>, const char *<em>path</em>)
+```
+
+# DESCRIPTION
+
+The `sarealpath`() function expands all symbolic links and resolves references
+to `.` and `..` in the NUL-terminated string pointed by `path` to produce the
+corresponding canonicalized absolute pathname, added into the stralloc pointed
+by `sa`.
+
+For more details, refer to [realpath](3).
+
+The `sarealpathat`() function is similar except when `path` specifies a relative
+path, in which case it is then determined relative to the directory associated
+with the file descriptor `fd`.
+If passed the special value *AT_FDCWD* in the `fd` parameter, the current
+working directory is used.
+
+# RETURN VALUE
+
+Upon successful completion these functions return 0. Otherwise they return -1
+and set `errno` to indicate the error.
+
+# ERRORS
+
+The `sarealpath`() and `sarealpathat`() functions may fail and set `errno` for
+any of the errors specified for the function [realpath](3).
+
+They may also fail and set `errno` if:
+
+: *ENOMEM*
+:: Insufficient memory available to grow `sa`
+
+The `sarealpathat`() function may also fail and set `errno` if :
+
+: *EACCESS*
+:: Search permission is denied for the current working directory or the
+:: directory referenced by `fd`.
+
+: *EMFILE*
+:: All dile descriptors available to the process are currently open, or the
+:: maximum allowable number of files is currently open in the system.
+
+: *EIO*
+:: An I/O error occured while reading from the file system.
diff --git a/src/liblimb/djbunix.h/sarealpathat.c b/src/liblimb/djbunix.h/sarealpathat.c
new file mode 100644
index 0000000..c72ff59
--- /dev/null
+++ b/src/liblimb/djbunix.h/sarealpathat.c
@@ -0,0 +1,31 @@
+/* This file is part of limb                           https://lila.oss/limb
+ * Copyright (C) 2023 Olivier Brunel                          jjk@jjacky.com */
+/* SPDX-License-Identifier: GPL-2.0-only */
+#include <limb/djbunix.h>
+
+int
+sarealpathat(stralloc *sa, int bfd, const char *file)
+{
+    int ret = -1;
+    int cwd = -1;
+
+    if (bfd != AT_FDCWD) {
+        cwd = open_read(".");
+        if (cwd < 0) return -1;
+
+        if (fd_chdir(bfd) < 0) {
+            fd_close(cwd);
+            return -1;
+        }
+    }
+
+    if (!sarealpath(sa, file))
+        ret = 0;
+
+    if (cwd >= 0) {
+        fd_chdir(cwd);
+        fd_close(cwd);
+    }
+
+    return ret;
+}
diff --git a/src/liblimb/include/limb/djbunix.h b/src/liblimb/include/limb/djbunix.h
index c44d43a..385546c 100644
--- a/src/liblimb/include/limb/djbunix.h
+++ b/src/liblimb/include/limb/djbunix.h
@@ -35,6 +35,7 @@ extern int salsat(int fd, const char *name, stralloc *sa, size_t *maxlen);
 extern int sareadlink0(stralloc *sa, const char * restrict file);
 extern int sareadlinkat(stralloc *sa, int fd, const char * restrict file);
 extern int sareadlinkat0(stralloc *sa, int fd, const char * restrict file);
+extern int sarealpathat(stralloc *sa, int fd, const char * restrict file);
 
 #define salst(sa,name,maxlen)       sals(name, sa,maxlen)
 #define salstat(sa,fd,name,maxlen)  salsat(fd, name, sa, maxlen)