X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;ds=sidebyside;f=util.c;h=f3161bd7f3e888b4a4b34e8ded2b1a4fde652f13;hb=206bf5c294d300cf05ee7b17c5bf42a21f6a52c0;hp=f3af9567cf49cb79043977511e52b2112e0361b9;hpb=a0d40ac588701010ea6a9366f6a874e83844858e;p=elogind.git diff --git a/util.c b/util.c index f3af9567c..f3161bd7f 100644 --- a/util.c +++ b/util.c @@ -42,6 +42,19 @@ #include "log.h" #include "strv.h" +bool streq_ptr(const char *a, const char *b) { + + /* Like streq(), but tries to make sense of NULL pointers */ + + if (a && b) + return streq(a, b); + + if (!a && !b) + return true; + + return false; +} + usec_t now(clockid_t clock_id) { struct timespec ts; @@ -412,7 +425,7 @@ finish: int read_one_line_file(const char *fn, char **line) { FILE *f; int r; - char t[64], *c; + char t[2048], *c; assert(fn); assert(line); @@ -438,6 +451,33 @@ finish: return r; } +char *truncate_nl(char *s) { + assert(s); + + s[strcspn(s, NEWLINE)] = 0; + return s; +} + +int get_process_name(pid_t pid, char **name) { + char *p; + int r; + + assert(pid >= 1); + assert(name); + + if (asprintf(&p, "/proc/%llu/comm", (unsigned long long) pid) < 0) + return -ENOMEM; + + r = read_one_line_file(p, name); + free(p); + + if (r < 0) + return r; + + truncate_nl(*name); + return 0; +} + char *strappend(const char *s, const char *suffix) { size_t a, b; char *r; @@ -611,6 +651,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; @@ -671,6 +728,20 @@ int mkdir_parents(const char *path, mode_t mode) { } } +int mkdir_p(const char *path, mode_t mode) { + int r; + + /* Like mkdir -p */ + + if ((r = mkdir_parents(path, mode)) < 0) + return r; + + if (mkdir(path, mode) < 0) + return -errno; + + return 0; +} + char hexchar(int x) { static const char table[16] = "0123456789abcdef"; @@ -1133,7 +1204,7 @@ int close_all_fds(const int except[], unsigned n_except) { return -errno; while ((de = readdir(d))) { - int fd; + int fd = -1; if (de->d_name[0] == '.') continue; @@ -1162,15 +1233,67 @@ int close_all_fds(const int except[], unsigned n_except) { continue; } - if ((r = close_nointr(fd)) < 0) - goto finish; + 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; +} + +char *format_timestamp(char *buf, size_t l, usec_t t) { + struct tm tm; + time_t sec; + + assert(buf); + assert(l > 0); + + if (t <= 0) + return NULL; + + sec = (time_t) t / USEC_PER_SEC; + + if (strftime(buf, l, "%a, %d %b %Y %H:%M:%S %z", localtime_r(&sec, &tm)) <= 0) + return NULL; + + return buf; +} + +bool fstype_is_network(const char *fstype) { + static const char * const table[] = { + "cifs", + "smbfs", + "ncpfs", + "nfs", + "nfs4" + }; + + unsigned i; + + for (i = 0; i < ELEMENTSOF(table); i++) + if (streq(table[i], fstype)) + return true; + + return false; +} + static const char *const ioprio_class_table[] = { [IOPRIO_CLASS_NONE] = "none", [IOPRIO_CLASS_RT] = "realtime",