diff options
author | Lennart Poettering <lennart@poettering.net> | 2015-10-26 20:07:55 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2015-10-27 13:25:56 +0100 |
commit | a09561746f15b84da9471b5c4be74e53d19e4f3f (patch) | |
tree | e99301f014ab8d150891d936ca061e369f7bae33 /src/basic | |
parent | 78f22b973fa2c9b09bd974680836df17163d9ee0 (diff) |
util-lib: introduce dirent-util.[ch] for directory entry calls
Also, move a couple of more path-related functions to path-util.c.
Diffstat (limited to 'src/basic')
-rw-r--r-- | src/basic/cgroup-util.c | 1 | ||||
-rw-r--r-- | src/basic/conf-files.c | 1 | ||||
-rw-r--r-- | src/basic/copy.c | 1 | ||||
-rw-r--r-- | src/basic/dirent-util.c | 81 | ||||
-rw-r--r-- | src/basic/dirent-util.h | 51 | ||||
-rw-r--r-- | src/basic/fd-util.c | 1 | ||||
-rw-r--r-- | src/basic/fdset.c | 1 | ||||
-rw-r--r-- | src/basic/locale-util.c | 1 | ||||
-rw-r--r-- | src/basic/path-util.c | 67 | ||||
-rw-r--r-- | src/basic/path-util.h | 7 | ||||
-rw-r--r-- | src/basic/util.c | 121 | ||||
-rw-r--r-- | src/basic/util.h | 32 |
12 files changed, 213 insertions, 152 deletions
diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c index 232d6e8fe2..67dc291192 100644 --- a/src/basic/cgroup-util.c +++ b/src/basic/cgroup-util.c @@ -30,6 +30,7 @@ #include <unistd.h> #include "cgroup-util.h" +#include "dirent-util.h" #include "extract-word.h" #include "fd-util.h" #include "fileio.h" diff --git a/src/basic/conf-files.c b/src/basic/conf-files.c index 3af3fe392c..be9972ffff 100644 --- a/src/basic/conf-files.c +++ b/src/basic/conf-files.c @@ -26,6 +26,7 @@ #include <string.h> #include "conf-files.h" +#include "dirent-util.h" #include "fd-util.h" #include "hashmap.h" #include "log.h" diff --git a/src/basic/copy.c b/src/basic/copy.c index 4b410a74e5..2d2d7ade34 100644 --- a/src/basic/copy.c +++ b/src/basic/copy.c @@ -24,6 +24,7 @@ #include "btrfs-util.h" #include "copy.h" +#include "dirent-util.h" #include "fd-util.h" #include "fileio.h" #include "io-util.h" diff --git a/src/basic/dirent-util.c b/src/basic/dirent-util.c new file mode 100644 index 0000000000..c433d5844a --- /dev/null +++ b/src/basic/dirent-util.c @@ -0,0 +1,81 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010-2012 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <fcntl.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> + +#include "dirent-util.h" +#include "string-util.h" + +int dirent_ensure_type(DIR *d, struct dirent *de) { + struct stat st; + + assert(d); + assert(de); + + if (de->d_type != DT_UNKNOWN) + return 0; + + if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) + return -errno; + + de->d_type = + S_ISREG(st.st_mode) ? DT_REG : + S_ISDIR(st.st_mode) ? DT_DIR : + S_ISLNK(st.st_mode) ? DT_LNK : + S_ISFIFO(st.st_mode) ? DT_FIFO : + S_ISSOCK(st.st_mode) ? DT_SOCK : + S_ISCHR(st.st_mode) ? DT_CHR : + S_ISBLK(st.st_mode) ? DT_BLK : + DT_UNKNOWN; + + return 0; +} + +bool dirent_is_file(const struct dirent *de) { + assert(de); + + if (hidden_file(de->d_name)) + return false; + + if (de->d_type != DT_REG && + de->d_type != DT_LNK && + de->d_type != DT_UNKNOWN) + return false; + + return true; +} + +bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) { + assert(de); + + if (de->d_type != DT_REG && + de->d_type != DT_LNK && + de->d_type != DT_UNKNOWN) + return false; + + if (hidden_file_allow_backup(de->d_name)) + return false; + + return endswith(de->d_name, suffix); +} diff --git a/src/basic/dirent-util.h b/src/basic/dirent-util.h new file mode 100644 index 0000000000..5866a755f4 --- /dev/null +++ b/src/basic/dirent-util.h @@ -0,0 +1,51 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <dirent.h> + +#include "path-util.h" + +int dirent_ensure_type(DIR *d, struct dirent *de); + +bool dirent_is_file(const struct dirent *de) _pure_; +bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) _pure_; + +#define FOREACH_DIRENT(de, d, on_error) \ + for (errno = 0, de = readdir(d);; errno = 0, de = readdir(d)) \ + if (!de) { \ + if (errno > 0) { \ + on_error; \ + } \ + break; \ + } else if (hidden_file((de)->d_name)) \ + continue; \ + else + +#define FOREACH_DIRENT_ALL(de, d, on_error) \ + for (errno = 0, de = readdir(d);; errno = 0, de = readdir(d)) \ + if (!de) { \ + if (errno > 0) { \ + on_error; \ + } \ + break; \ + } else diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c index 76d7e32bfa..f40365ce97 100644 --- a/src/basic/fd-util.c +++ b/src/basic/fd-util.c @@ -22,6 +22,7 @@ #include "fd-util.h" #include "parse-util.h" #include "util.h" +#include "dirent-util.h" int close_nointr(int fd) { assert(fd >= 0); diff --git a/src/basic/fdset.c b/src/basic/fdset.c index ef60f66431..4b11e4ea09 100644 --- a/src/basic/fdset.c +++ b/src/basic/fdset.c @@ -25,6 +25,7 @@ #include "sd-daemon.h" +#include "dirent-util.h" #include "fd-util.h" #include "fdset.h" #include "macro.h" diff --git a/src/basic/locale-util.c b/src/basic/locale-util.c index ccbc147931..08da4b98c5 100644 --- a/src/basic/locale-util.c +++ b/src/basic/locale-util.c @@ -21,6 +21,7 @@ #include <sys/mman.h> +#include "dirent-util.h" #include "fd-util.h" #include "locale-util.h" #include "path-util.h" diff --git a/src/basic/path-util.c b/src/basic/path-util.c index d581f85707..ed30c3d92d 100644 --- a/src/basic/path-util.c +++ b/src/basic/path-util.c @@ -766,3 +766,70 @@ bool path_is_safe(const char *p) { return true; } + +char *file_in_same_dir(const char *path, const char *filename) { + char *e, *ret; + size_t k; + + assert(path); + assert(filename); + + /* This removes the last component of path and appends + * filename, unless the latter is absolute anyway or the + * former isn't */ + + if (path_is_absolute(filename)) + return strdup(filename); + + e = strrchr(path, '/'); + if (!e) + return strdup(filename); + + k = strlen(filename); + ret = new(char, (e + 1 - path) + k + 1); + if (!ret) + return NULL; + + memcpy(mempcpy(ret, path, e + 1 - path), filename, k + 1); + return ret; +} + +bool hidden_file_allow_backup(const char *filename) { + assert(filename); + + return + filename[0] == '.' || + streq(filename, "lost+found") || + streq(filename, "aquota.user") || + streq(filename, "aquota.group") || + endswith(filename, ".rpmnew") || + endswith(filename, ".rpmsave") || + endswith(filename, ".rpmorig") || + endswith(filename, ".dpkg-old") || + endswith(filename, ".dpkg-new") || + endswith(filename, ".dpkg-tmp") || + endswith(filename, ".dpkg-dist") || + endswith(filename, ".dpkg-bak") || + endswith(filename, ".dpkg-backup") || + endswith(filename, ".dpkg-remove") || + endswith(filename, ".swp"); +} + +bool hidden_file(const char *filename) { + assert(filename); + + if (endswith(filename, "~")) + return true; + + return hidden_file_allow_backup(filename); +} + +bool is_device_path(const char *path) { + + /* Returns true on paths that refer to a device, either in + * sysfs or in /dev */ + + return + path_startswith(path, "/dev/") || + path_startswith(path, "/sys/"); +} diff --git a/src/basic/path-util.h b/src/basic/path-util.h index b2acca05fe..193bf72468 100644 --- a/src/basic/path-util.h +++ b/src/basic/path-util.h @@ -105,3 +105,10 @@ char* dirname_malloc(const char *path); bool filename_is_valid(const char *p) _pure_; bool path_is_safe(const char *p) _pure_; + +char *file_in_same_dir(const char *path, const char *filename); + +bool hidden_file_allow_backup(const char *filename); +bool hidden_file(const char *filename) _pure_; + +bool is_device_path(const char *path); diff --git a/src/basic/util.c b/src/basic/util.c index 121ca3376e..e214c6f3dc 100644 --- a/src/basic/util.c +++ b/src/basic/util.c @@ -102,6 +102,7 @@ #include "utf8.h" #include "util.h" #include "virt.h" +#include "dirent-util.h" /* Put this test here for a lack of better place */ assert_cc(EAGAIN == EWOULDBLOCK); @@ -247,33 +248,6 @@ int readlink_and_canonicalize(const char *p, char **r) { return 0; } -char *file_in_same_dir(const char *path, const char *filename) { - char *e, *ret; - size_t k; - - assert(path); - assert(filename); - - /* This removes the last component of path and appends - * filename, unless the latter is absolute anyway or the - * former isn't */ - - if (path_is_absolute(filename)) - return strdup(filename); - - e = strrchr(path, '/'); - if (!e) - return strdup(filename); - - k = strlen(filename); - ret = new(char, (e + 1 - path) + k + 1); - if (!ret) - return NULL; - - memcpy(mempcpy(ret, path, e + 1 - path), filename, k + 1); - return ret; -} - int rmdir_parents(const char *path, const char *stop) { size_t l; int r = 0; @@ -320,36 +294,6 @@ int rmdir_parents(const char *path, const char *stop) { return 0; } -_pure_ static bool hidden_file_allow_backup(const char *filename) { - assert(filename); - - return - filename[0] == '.' || - streq(filename, "lost+found") || - streq(filename, "aquota.user") || - streq(filename, "aquota.group") || - endswith(filename, ".rpmnew") || - endswith(filename, ".rpmsave") || - endswith(filename, ".rpmorig") || - endswith(filename, ".dpkg-old") || - endswith(filename, ".dpkg-new") || - endswith(filename, ".dpkg-tmp") || - endswith(filename, ".dpkg-dist") || - endswith(filename, ".dpkg-bak") || - endswith(filename, ".dpkg-backup") || - endswith(filename, ".dpkg-remove") || - endswith(filename, ".swp"); -} - -bool hidden_file(const char *filename) { - assert(filename); - - if (endswith(filename, "~")) - return true; - - return hidden_file_allow_backup(filename); -} - bool fstype_is_network(const char *fstype) { static const char table[] = "afs\0" @@ -373,16 +317,6 @@ bool fstype_is_network(const char *fstype) { return nulstr_contains(table, fstype); } -bool is_device_path(const char *path) { - - /* Returns true on paths that refer to a device, either in - * sysfs or in /dev */ - - return - path_startswith(path, "/dev/") || - path_startswith(path, "/sys/"); -} - int dir_is_empty(const char *path) { _cleanup_closedir_ DIR *d; struct dirent *de; @@ -615,34 +549,6 @@ int null_or_empty_fd(int fd) { return null_or_empty(&st); } -bool dirent_is_file(const struct dirent *de) { - assert(de); - - if (hidden_file(de->d_name)) - return false; - - if (de->d_type != DT_REG && - de->d_type != DT_LNK && - de->d_type != DT_UNKNOWN) - return false; - - return true; -} - -bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) { - assert(de); - - if (de->d_type != DT_REG && - de->d_type != DT_LNK && - de->d_type != DT_UNKNOWN) - return false; - - if (hidden_file_allow_backup(de->d_name)) - return false; - - return endswith(de->d_name, suffix); -} - static int do_execute(char **directories, usec_t timeout, char *argv[]) { _cleanup_hashmap_free_free_ Hashmap *pids = NULL; _cleanup_set_free_free_ Set *seen = NULL; @@ -950,31 +856,6 @@ int glob_extend(char ***strv, const char *path) { return k; } -int dirent_ensure_type(DIR *d, struct dirent *de) { - struct stat st; - - assert(d); - assert(de); - - if (de->d_type != DT_UNKNOWN) - return 0; - - if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) - return -errno; - - de->d_type = - S_ISREG(st.st_mode) ? DT_REG : - S_ISDIR(st.st_mode) ? DT_DIR : - S_ISLNK(st.st_mode) ? DT_LNK : - S_ISFIFO(st.st_mode) ? DT_FIFO : - S_ISSOCK(st.st_mode) ? DT_SOCK : - S_ISCHR(st.st_mode) ? DT_CHR : - S_ISBLK(st.st_mode) ? DT_BLK : - DT_UNKNOWN; - - return 0; -} - int get_files_in_directory(const char *path, char ***list) { _cleanup_closedir_ DIR *d = NULL; size_t bufsize = 0, n = 0; diff --git a/src/basic/util.h b/src/basic/util.h index 6e5df01450..190d4f5edb 100644 --- a/src/basic/util.h +++ b/src/basic/util.h @@ -22,7 +22,6 @@ ***/ #include <alloca.h> -#include <dirent.h> #include <fcntl.h> #include <inttypes.h> #include <limits.h> @@ -90,15 +89,8 @@ int readlink_value(const char *p, char **ret); int readlink_and_make_absolute(const char *p, char **r); int readlink_and_canonicalize(const char *p, char **r); -char *file_in_same_dir(const char *path, const char *filename); - int rmdir_parents(const char *path, const char *stop); -bool dirent_is_file(const struct dirent *de) _pure_; -bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) _pure_; - -bool hidden_file(const char *filename) _pure_; - /* For basic lookup tables with strictly enumerated entries */ #define _DEFINE_STRING_TABLE_LOOKUP_TO_STRING(name,type,scope) \ scope const char *name##_to_string(type i) { \ @@ -157,8 +149,6 @@ ssize_t string_table_lookup(const char * const *table, size_t len, const char *k bool fstype_is_network(const char *fstype); -bool is_device_path(const char *path); - int dir_is_empty(const char *path); static inline int dir_is_populated(const char *path) { @@ -216,8 +206,6 @@ int socket_from_display(const char *display, char **path); int glob_exists(const char *path); int glob_extend(char ***strv, const char *path); -int dirent_ensure_type(DIR *d, struct dirent *de); - int get_files_in_directory(const char *path, char ***list); bool is_main_thread(void); @@ -332,26 +320,6 @@ const char *draw_special_char(DrawSpecialChar ch); int on_ac_power(void); -#define FOREACH_DIRENT(de, d, on_error) \ - for (errno = 0, de = readdir(d);; errno = 0, de = readdir(d)) \ - if (!de) { \ - if (errno > 0) { \ - on_error; \ - } \ - break; \ - } else if (hidden_file((de)->d_name)) \ - continue; \ - else - -#define FOREACH_DIRENT_ALL(de, d, on_error) \ - for (errno = 0, de = readdir(d);; errno = 0, de = readdir(d)) \ - if (!de) { \ - if (errno > 0) { \ - on_error; \ - } \ - break; \ - } else - static inline void *mempset(void *s, int c, size_t n) { memset(s, c, n); return (uint8_t*)s + n; |