mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-23 17:34:00 +03:00
Merge pull request #20962 from poettering/dttoif
Some tweaks to dirent-util.c
This commit is contained in:
commit
c17e8ce9ec
@ -5,22 +5,12 @@
|
||||
|
||||
#include "dirent-util.h"
|
||||
#include "path-util.h"
|
||||
#include "stat-util.h"
|
||||
#include "string-util.h"
|
||||
|
||||
int stat_mode_to_dirent_type(mode_t mode) {
|
||||
return
|
||||
S_ISREG(mode) ? DT_REG :
|
||||
S_ISDIR(mode) ? DT_DIR :
|
||||
S_ISLNK(mode) ? DT_LNK :
|
||||
S_ISFIFO(mode) ? DT_FIFO :
|
||||
S_ISSOCK(mode) ? DT_SOCK :
|
||||
S_ISCHR(mode) ? DT_CHR :
|
||||
S_ISBLK(mode) ? DT_BLK :
|
||||
DT_UNKNOWN;
|
||||
}
|
||||
|
||||
static int dirent_ensure_type(DIR *d, struct dirent *de) {
|
||||
struct stat st;
|
||||
STRUCT_STATX_DEFINE(sx);
|
||||
int r;
|
||||
|
||||
assert(d);
|
||||
assert(de);
|
||||
@ -33,10 +23,17 @@ static int dirent_ensure_type(DIR *d, struct dirent *de) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
|
||||
return -errno;
|
||||
/* Let's ask only for the type, nothing else. */
|
||||
r = statx_fallback(dirfd(d), de->d_name, AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, STATX_TYPE, &sx);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
de->d_type = stat_mode_to_dirent_type(st.st_mode);
|
||||
assert(FLAGS_SET(sx.stx_mask, STATX_TYPE));
|
||||
de->d_type = IFTODT(sx.stx_mode);
|
||||
|
||||
/* If the inode is passed too, update the field, i.e. report most recent data */
|
||||
if (FLAGS_SET(sx.stx_mask, STATX_INO))
|
||||
de->d_ino = sx.stx_ino;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -69,24 +66,40 @@ bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
|
||||
}
|
||||
|
||||
struct dirent *readdir_ensure_type(DIR *d) {
|
||||
struct dirent *de;
|
||||
int r;
|
||||
|
||||
assert(d);
|
||||
|
||||
errno = 0;
|
||||
de = readdir(d);
|
||||
if (de)
|
||||
(void) dirent_ensure_type(d, de);
|
||||
return de;
|
||||
}
|
||||
|
||||
struct dirent *readdir_no_dot(DIR *dirp) {
|
||||
struct dirent *d;
|
||||
/* Like readdir(), but fills in .d_type if it is DT_UNKNOWN */
|
||||
|
||||
for (;;) {
|
||||
d = readdir_ensure_type(dirp);
|
||||
if (d && dot_or_dot_dot(d->d_name))
|
||||
continue;
|
||||
return d;
|
||||
struct dirent *de;
|
||||
|
||||
errno = 0;
|
||||
de = readdir(d);
|
||||
if (!de)
|
||||
return NULL;
|
||||
|
||||
r = dirent_ensure_type(d, de);
|
||||
if (r >= 0)
|
||||
return de;
|
||||
if (r != -ENOENT) {
|
||||
errno = -r; /* We want to be compatible with readdir(), hence propagate error via errno here */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Vanished by now? Then skip immedately to next */
|
||||
}
|
||||
}
|
||||
|
||||
struct dirent *readdir_no_dot(DIR *d) {
|
||||
assert(d);
|
||||
|
||||
for (;;) {
|
||||
struct dirent *de;
|
||||
|
||||
de = readdir_ensure_type(d);
|
||||
if (!de || !dot_or_dot_dot(de->d_name))
|
||||
return de;
|
||||
}
|
||||
}
|
||||
|
@ -8,8 +8,6 @@
|
||||
#include "macro.h"
|
||||
#include "path-util.h"
|
||||
|
||||
int stat_mode_to_dirent_type(mode_t mode);
|
||||
|
||||
bool dirent_is_file(const struct dirent *de) _pure_;
|
||||
bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) _pure_;
|
||||
|
||||
|
@ -290,7 +290,7 @@ int recurse_dir(
|
||||
/* Copy over the data we acquired through statx() if we acquired any */
|
||||
if (sx.stx_mask & STATX_TYPE) {
|
||||
assert(!!subdir == !!S_ISDIR(sx.stx_mode));
|
||||
de[i]->d_type = stat_mode_to_dirent_type(sx.stx_mode);
|
||||
de[i]->d_type = IFTODT(sx.stx_mode);
|
||||
}
|
||||
|
||||
if (sx.stx_mask & STATX_INO)
|
||||
|
Loading…
Reference in New Issue
Block a user