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 "dirent-util.h"
|
||||||
#include "path-util.h"
|
#include "path-util.h"
|
||||||
|
#include "stat-util.h"
|
||||||
#include "string-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) {
|
static int dirent_ensure_type(DIR *d, struct dirent *de) {
|
||||||
struct stat st;
|
STRUCT_STATX_DEFINE(sx);
|
||||||
|
int r;
|
||||||
|
|
||||||
assert(d);
|
assert(d);
|
||||||
assert(de);
|
assert(de);
|
||||||
@ -33,10 +23,17 @@ static int dirent_ensure_type(DIR *d, struct dirent *de) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
|
/* Let's ask only for the type, nothing else. */
|
||||||
return -errno;
|
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;
|
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 *readdir_ensure_type(DIR *d) {
|
||||||
struct dirent *de;
|
int r;
|
||||||
|
|
||||||
assert(d);
|
assert(d);
|
||||||
|
|
||||||
errno = 0;
|
/* Like readdir(), but fills in .d_type if it is DT_UNKNOWN */
|
||||||
de = readdir(d);
|
|
||||||
if (de)
|
|
||||||
(void) dirent_ensure_type(d, de);
|
|
||||||
return de;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dirent *readdir_no_dot(DIR *dirp) {
|
|
||||||
struct dirent *d;
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
d = readdir_ensure_type(dirp);
|
struct dirent *de;
|
||||||
if (d && dot_or_dot_dot(d->d_name))
|
|
||||||
continue;
|
errno = 0;
|
||||||
return d;
|
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 "macro.h"
|
||||||
#include "path-util.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(const struct dirent *de) _pure_;
|
||||||
bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) _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 */
|
/* Copy over the data we acquired through statx() if we acquired any */
|
||||||
if (sx.stx_mask & STATX_TYPE) {
|
if (sx.stx_mask & STATX_TYPE) {
|
||||||
assert(!!subdir == !!S_ISDIR(sx.stx_mode));
|
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)
|
if (sx.stx_mask & STATX_INO)
|
||||||
|
Loading…
Reference in New Issue
Block a user