X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshared%2Futil.c;h=e7ff0f8840fdbe5d85c82e0c55d0367a4833c2b7;hp=d93a9680fde3890ad26a3dc808063e211d556ceb;hb=e1d758033dc7e101ab32323a0f1649d8daf56a22;hpb=45c196a76b2d883552c90807386d9bed40da822b diff --git a/src/shared/util.c b/src/shared/util.c index d93a9680f..e7ff0f884 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -1440,7 +1440,7 @@ _pure_ static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) { } int close_all_fds(const int except[], unsigned n_except) { - DIR *d; + _cleanup_closedir_ DIR *d = NULL; struct dirent *de; int r = 0; @@ -1495,7 +1495,6 @@ int close_all_fds(const int except[], unsigned n_except) { } } - closedir(d); return r; } @@ -1514,6 +1513,7 @@ bool fstype_is_network(const char *fstype) { static const char table[] = "cifs\0" "smbfs\0" + "sshfs\0" "ncpfs\0" "ncp\0" "nfs\0" @@ -2671,7 +2671,7 @@ finish: } int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) { - DIR *d; + _cleanup_closedir_ DIR *d = NULL; int ret = 0; assert(fd >= 0); @@ -2694,15 +2694,12 @@ int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct errno = 0; de = readdir(d); - if (!de && errno != 0) { - if (ret == 0) + if (!de) { + if (errno != 0 && ret == 0) ret = -errno; - break; + return ret; } - if (!de) - break; - if (streq(de->d_name, ".") || streq(de->d_name, "..")) continue; @@ -2758,10 +2755,6 @@ int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct } } } - - closedir(d); - - return ret; } _pure_ static int is_temporary_fs(struct statfs *s) { @@ -3619,9 +3612,6 @@ char *fstab_node_to_udev_node(const char *p) { bool tty_is_vc(const char *tty) { assert(tty); - if (startswith(tty, "/dev/")) - tty += 5; - return vtnr_from_tty(tty) >= 0; } @@ -4013,7 +4003,7 @@ int fopen_temporary(const char *path, FILE **_f, char **_temp_path) { assert(_f); assert(_temp_path); - t = strappend(path, ".XXXXXX"); + t = tempfn_xxxxxx(path); if (!t) return -ENOMEM; @@ -4125,42 +4115,61 @@ int vt_disallocate(const char *name) { } int symlink_atomic(const char *from, const char *to) { - char *x; - _cleanup_free_ char *t; - const char *fn; - size_t k; - uint64_t u; - unsigned i; - int r; + _cleanup_free_ char *t = NULL; assert(from); assert(to); - t = new(char, strlen(to) + 1 + 16 + 1); + t = tempfn_random(to); if (!t) return -ENOMEM; - fn = basename(to); - k = fn-to; - memcpy(t, to, k); - t[k] = '.'; - x = stpcpy(t+k+1, fn); + if (symlink(from, t) < 0) + return -errno; - u = random_u64(); - for (i = 0; i < 16; i++) { - *(x++) = hexchar(u & 0xF); - u >>= 4; + if (rename(t, to) < 0) { + unlink_noerrno(t); + return -errno; } - *x = 0; + return 0; +} - if (symlink(from, t) < 0) +int mknod_atomic(const char *path, mode_t mode, dev_t dev) { + _cleanup_free_ char *t = NULL; + + assert(path); + + t = tempfn_random(path); + if (!t) + return -ENOMEM; + + if (mknod(t, mode, dev) < 0) return -errno; - if (rename(t, to) < 0) { - r = -errno; - unlink(t); - return r; + if (rename(t, path) < 0) { + unlink_noerrno(t); + return -errno; + } + + return 0; +} + +int mkfifo_atomic(const char *path, mode_t mode) { + _cleanup_free_ char *t = NULL; + + assert(path); + + t = tempfn_random(path); + if (!t) + return -ENOMEM; + + if (mkfifo(t, mode) < 0) + return -errno; + + if (rename(t, path) < 0) { + unlink_noerrno(t); + return -errno; } return 0; @@ -4444,22 +4453,6 @@ int dirent_ensure_type(DIR *d, struct dirent *de) { return 0; } -int in_search_path(const char *path, char **search) { - char **i; - _cleanup_free_ char *parent = NULL; - int r; - - r = path_get_parent(path, &parent); - if (r < 0) - return r; - - STRV_FOREACH(i, search) - if (path_equal(parent, *i)) - return 1; - - return 0; -} - int get_files_in_directory(const char *path, char ***list) { _cleanup_closedir_ DIR *d = NULL; size_t bufsize = 0, n = 0; @@ -5683,14 +5676,17 @@ static int search_and_fopen_internal(const char *path, const char *mode, const c assert(mode); assert(_f); - if (!path_strv_canonicalize_absolute_uniq(search, root)) + if (!path_strv_resolve_uniq(search, root)) return -ENOMEM; STRV_FOREACH(i, search) { _cleanup_free_ char *p = NULL; FILE *f; - p = strjoin(*i, "/", path, NULL); + if (root) + p = strjoin(root, *i, "/", path, NULL); + else + p = strjoin(*i, "/", path, NULL); if (!p) return -ENOMEM; @@ -6669,3 +6665,51 @@ int fflush_and_check(FILE *f) { return 0; } + +char *tempfn_xxxxxx(const char *p) { + const char *fn; + char *t; + size_t k; + + assert(p); + + t = new(char, strlen(p) + 1 + 6 + 1); + if (!t) + return NULL; + + fn = basename(p); + k = fn - p; + + strcpy(stpcpy(stpcpy(mempcpy(t, p, k), "."), fn), "XXXXXX"); + + return t; +} + +char *tempfn_random(const char *p) { + const char *fn; + char *t, *x; + uint64_t u; + size_t k; + unsigned i; + + assert(p); + + t = new(char, strlen(p) + 1 + 16 + 1); + if (!t) + return NULL; + + fn = basename(p); + k = fn - p; + + x = stpcpy(stpcpy(mempcpy(t, p, k), "."), fn); + + u = random_u64(); + for (i = 0; i < 16; i++) { + *(x++) = hexchar(u & 0xF); + u >>= 4; + } + + *x = 0; + + return t; +}