[openssh-commits] [openssh] branch master updated: Add fallback for mkdir_path() without openat().
git+noreply at mindrot.org
git+noreply at mindrot.org
Thu Sep 17 07:53:34 AEST 2026
This is an automated email from the git hooks/post-receive script.
dtucker pushed a commit to branch master
in repository openssh.
The following commit(s) were added to refs/heads/master by this push:
new fb6d39e61 Add fallback for mkdir_path() without openat().
fb6d39e61 is described below
commit fb6d39e619f721ff588719c3ac8d417c0ebcffce
Author: Darren Tucker <dtucker at dtucker.net>
AuthorDate: Thu Sep 17 07:51:31 2026 +1000
Add fallback for mkdir_path() without openat().
Fixes builds on pre POSIX.1-2008 systems.
---
configure.ac | 1 +
misc.c | 36 ++++++++++++++++++++++++++++++++++++
regress/unittests/misc/test_misc.c | 2 ++
3 files changed, 39 insertions(+)
diff --git a/configure.ac b/configure.ac
index 224f29a5a..d4ccbe1ca 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2170,6 +2170,7 @@ AC_CHECK_FUNCS([ \
nlist \
nsleep \
ogetaddrinfo \
+ openat \
openlog_r \
pledge \
poll \
diff --git a/misc.c b/misc.c
index dee84336e..866f7b8e2 100644
--- a/misc.c
+++ b/misc.c
@@ -3268,6 +3268,7 @@ get_homedir(void)
int
mkdir_path(const char *target, mode_t mode)
{
+#if defined(HAVE_OPENAT) && defined(O_DIRECTORY)
char *dir, *odir = NULL, *next;
int fd = AT_FDCWD, fd2, subpath_len, ret = -1;
@@ -3311,4 +3312,39 @@ mkdir_path(const char *target, mode_t mode)
if (fd != AT_FDCWD)
close(fd);
return ret;
+#else
+ /*
+ * If we don't have openat (which was added in POSIX.1-2008), fall back
+ * to the possibly racy way.
+ */
+ char *dir, *odir, *p, path[PATH_MAX] = "";
+ int ret = -1;
+ size_t plen = sizeof(path);
+
+ dir = odir = xstrdup(target);
+
+ /* If the dir is relative, start with cwd. */
+ if (*dir != '/' && getcwd(path, plen) == NULL) {
+ error_f("getcwd: %s", strerror(errno));
+ goto out;
+ }
+
+ /* Work through the path, component-wise */
+ while ((p = strsep(&dir, "/")) && p != '\0') {
+ if (strlcat(path, "/", plen) >= plen ||
+ strlcat(path, p, plen) >= plen)
+ goto out;
+ if (mkdir(path, mode) == 0)
+ debug_f("created directory %s", path);
+ else if (errno != EEXIST && errno != EISDIR) {
+ error_f("mkdir(\"%s\"): %s", path, strerror(errno));
+ goto out;
+ }
+ }
+ /* success */
+ ret = 0;
+ out:
+ free(odir);
+ return ret;
+#endif
}
diff --git a/regress/unittests/misc/test_misc.c b/regress/unittests/misc/test_misc.c
index db0b5bb66..317de9f14 100644
--- a/regress/unittests/misc/test_misc.c
+++ b/regress/unittests/misc/test_misc.c
@@ -462,6 +462,8 @@ test_skip_space(void)
void
test_misc(void)
{
+ mkdir_path("/tmp/foo/bar", 0700);
+ exit(0);
test_chop();
test_rtrim();
test_strprefix();
--
To stop receiving notification emails like this one, please contact
djm at mindrot.org.
More information about the openssh-commits
mailing list