X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=util.c;h=a0f26762dc39b87b3f6cb3c24acb50db14849512;hp=7306ddde34c4ee26db5cac1389f5647cfb05d409;hb=db12775d59ab709f8afc361eaa30c9d54a0a8d7c;hpb=5af98f828476716954f327c479c4cf6321ae3fe4 diff --git a/util.c b/util.c index 7306ddde3..a0f26762d 100644 --- a/util.c +++ b/util.c @@ -32,6 +32,8 @@ #include #include #include +#include +#include #include "macro.h" #include "util.h" @@ -609,6 +611,23 @@ char *strstrip(char *s) { } +char *delete_chars(char *s, const char *bad) { + char *f, *t; + + /* Drops all whitespace, regardless where in the string */ + + for (f = s, t = s; *f; f++) { + if (strchr(bad, *f)) + continue; + + *(t++) = *f; + } + + *t = 0; + + return s; +} + char *file_in_same_dir(const char *path, const char *filename) { char *e, *r; size_t k; @@ -1058,16 +1077,16 @@ bool path_startswith(const char *path, const char *prefix) { } } -char *ascii_strlower(char *path) { +char *ascii_strlower(char *t) { char *p; - assert(path); + assert(t); - for (p = path; *p; p++) + for (p = t; *p; p++) if (*p >= 'A' && *p <= 'Z') *p = *p - 'A' + 'a'; - return p; + return t; } bool ignore_file(const char *filename) { @@ -1084,6 +1103,107 @@ bool ignore_file(const char *filename) { endswith(filename, ".swp"); } +int fd_nonblock(int fd, bool nonblock) { + int flags; + + assert(fd >= 0); + + if ((flags = fcntl(fd, F_GETFL, 0)) < 0) + return -errno; + + if (nonblock) + flags |= O_NONBLOCK; + else + flags &= ~O_NONBLOCK; + + if (fcntl(fd, F_SETFL, flags) < 0) + return -errno; + + return 0; +} + +int fd_cloexec(int fd, bool cloexec) { + int flags; + + assert(fd >= 0); + + if ((flags = fcntl(fd, F_GETFD, 0)) < 0) + return -errno; + + if (cloexec) + flags |= FD_CLOEXEC; + else + flags &= ~FD_CLOEXEC; + + if (fcntl(fd, F_SETFD, flags) < 0) + return -errno; + + return 0; +} + +int close_all_fds(const int except[], unsigned n_except) { + DIR *d; + struct dirent *de; + int r = 0; + + if (!(d = opendir("/proc/self/fd"))) + return -errno; + + while ((de = readdir(d))) { + int fd = -1; + + if (de->d_name[0] == '.') + continue; + + if ((r = safe_atoi(de->d_name, &fd)) < 0) + goto finish; + + if (fd < 3) + continue; + + if (fd == dirfd(d)) + continue; + + if (except) { + bool found; + unsigned i; + + found = false; + for (i = 0; i < n_except; i++) + if (except[i] == fd) { + found = true; + break; + } + + if (found) + continue; + } + + if ((r = close_nointr(fd)) < 0) { + /* Valgrind has its own FD and doesn't want to have it closed */ + if (errno != EBADF) + goto finish; + } + } + + r = 0; + +finish: + closedir(d); + return r; +} + +bool chars_intersect(const char *a, const char *b) { + const char *p; + + /* Returns true if any of the chars in a are in b. */ + for (p = a; *p; p++) + if (strchr(b, *p)) + return true; + + return false; +} + static const char *const ioprio_class_table[] = { [IOPRIO_CLASS_NONE] = "none", [IOPRIO_CLASS_RT] = "realtime",