mirror of
https://codeberg.org/guix/guix.git
synced 2026-01-25 12:05:19 -06:00
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 <ludo@gnu.org>
This commit is contained in:
parent
228d687fbe
commit
4ce3a53ae5
1 changed files with 16 additions and 6 deletions
|
|
@ -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];
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue