guix_mirror_bot pushed a commit to branch master
in repository guix.
commit 4ce3a53ae5ee832aa92e0345f15780bc7da060d7
Author: Romain GARBAGE <[email protected]>
AuthorDate: Fri Sep 12 16:57:59 2025 +0200
pack: Address DT_UNKNOWN case for exotic filesystems.
In some filesystems, the d_type field in the dirent struct returned by
readdir(3) is not properly filled. According to readdir(3), "All
applications
must properly handle a return of DT_UNKNOWN". This patch addresses the
issue.
* gnu/packages/aux-files/run-in-namespace.c: Handle DT_UNKNOWN case.
Change-Id: I128b0b88add1e9990e4fbf316ee03c3d19d4e0fc
Signed-off-by: Ludovic Courtès <[email protected]>
---
gnu/packages/aux-files/run-in-namespace.c | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/gnu/packages/aux-files/run-in-namespace.c
b/gnu/packages/aux-files/run-in-namespace.c
index 074befde46..0ba017cec3 100644
--- a/gnu/packages/aux-files/run-in-namespace.c
+++ b/gnu/packages/aux-files/run-in-namespace.c
@@ -160,24 +160,34 @@ mirror_directory (const char *source, const char *target,
int (* firmlink) (const char *, const struct dirent *,
const char *))
{
- DIR *stream = opendir (source);
+ int dir_fd = open (source, O_DIRECTORY | O_RDONLY | O_CLOEXEC);
+ DIR *stream = fdopendir (dir_fd);
for (struct dirent *entry = readdir (stream);
entry != NULL;
entry = readdir (stream))
{
- /* XXX: Some file systems may not report a useful 'd_type'. Ignore them
- for now. */
- assert (entry->d_type != DT_UNKNOWN);
-
if (strcmp (entry->d_name, ".") == 0
|| strcmp (entry->d_name, "..") == 0)
continue;
+ int is_link = 0;
+ if (entry->d_type == DT_UNKNOWN)
+ {
+ struct stat statbuf;
+ if (fstatat (dir_fd, entry->d_name, &statbuf,
+ AT_SYMLINK_NOFOLLOW) < 0)
+ assert_perror (errno);
+ if ((statbuf.st_mode & S_IFMT) == S_IFLNK)
+ is_link = 1;
+ }
+ else if (entry->d_type == DT_LNK)
+ is_link = 1;
+
char *abs_source = concat (source, entry->d_name);
char *new_entry = concat (target, entry->d_name);
- if (entry->d_type == DT_LNK)
+ if (is_link)
{
char target[PATH_MAX];