X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Futil.c;h=6fa9dec3a6532cf4de57ba8b554c1bda1de3680a;hb=bb00e604097fba830af1dc078d78aff278dfcd37;hp=0988675f09be39f291cd565b446ffeb0dba4dd1f;hpb=ef2f1067d0ca0e6d7346aa3e082048821b670b54;p=elogind.git diff --git a/src/util.c b/src/util.c index 0988675f0..6fa9dec3a 100644 --- a/src/util.c +++ b/src/util.c @@ -446,12 +446,12 @@ int get_parent_of_pid(pid_t pid, pid_t *_ppid) { int r; FILE *f; char fn[132], line[256], *p; - long long unsigned ppid; + long unsigned ppid; assert(pid >= 0); assert(_ppid); - assert_se(snprintf(fn, sizeof(fn)-1, "/proc/%llu/stat", (unsigned long long) pid) < (int) (sizeof(fn)-1)); + assert_se(snprintf(fn, sizeof(fn)-1, "/proc/%lu/stat", (unsigned long) pid) < (int) (sizeof(fn)-1)); fn[sizeof(fn)-1] = 0; if (!(f = fopen(fn, "r"))) @@ -476,11 +476,11 @@ int get_parent_of_pid(pid_t pid, pid_t *_ppid) { if (sscanf(p, " " "%*c " /* state */ - "%llu ", /* ppid */ + "%lu ", /* ppid */ &ppid) != 1) return -EIO; - if ((long long unsigned) (pid_t) ppid != ppid) + if ((long unsigned) (pid_t) ppid != ppid) return -ERANGE; *_ppid = (pid_t) ppid; @@ -552,7 +552,7 @@ int get_process_name(pid_t pid, char **name) { assert(pid >= 1); assert(name); - if (asprintf(&p, "/proc/%llu/comm", (unsigned long long) pid) < 0) + if (asprintf(&p, "/proc/%lu/comm", (unsigned long) pid) < 0) return -ENOMEM; r = read_one_line_file(p, name); @@ -893,6 +893,53 @@ int mkdir_p(const char *path, mode_t mode) { return 0; } +int rmdir_parents(const char *path, const char *stop) { + size_t l; + int r = 0; + + assert(path); + assert(stop); + + l = strlen(path); + + /* Skip trailing slashes */ + while (l > 0 && path[l-1] == '/') + l--; + + while (l > 0) { + char *t; + + /* Skip last component */ + while (l > 0 && path[l-1] != '/') + l--; + + /* Skip trailing slashes */ + while (l > 0 && path[l-1] == '/') + l--; + + if (l <= 0) + break; + + if (!(t = strndup(path, l))) + return -ENOMEM; + + if (path_startswith(stop, t)) { + free(t); + return 0; + } + + r = rmdir(t); + free(t); + + if (r < 0) + if (errno != ENOENT) + return -errno; + } + + return 0; +} + + char hexchar(int x) { static const char table[16] = "0123456789abcdef"; @@ -1452,7 +1499,7 @@ char *format_timestamp(char *buf, size_t l, usec_t t) { if (t <= 0) return NULL; - sec = (time_t) t / USEC_PER_SEC; + 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; @@ -1964,7 +2011,7 @@ int close_pipe(int p[]) { return a < 0 ? a : b; } -ssize_t loop_read(int fd, void *buf, size_t nbytes) { +ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) { uint8_t *p; ssize_t n = 0; @@ -1978,10 +2025,10 @@ ssize_t loop_read(int fd, void *buf, size_t nbytes) { if ((k = read(fd, p, nbytes)) <= 0) { - if (errno == EINTR) + if (k < 0 && errno == EINTR) continue; - if (errno == EAGAIN) { + if (k < 0 && errno == EAGAIN && do_poll) { struct pollfd pollfd; zero(pollfd); @@ -2012,6 +2059,54 @@ ssize_t loop_read(int fd, void *buf, size_t nbytes) { return n; } +ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) { + const uint8_t *p; + ssize_t n = 0; + + assert(fd >= 0); + assert(buf); + + p = buf; + + while (nbytes > 0) { + ssize_t k; + + if ((k = write(fd, p, nbytes)) <= 0) { + + if (k < 0 && errno == EINTR) + continue; + + if (k < 0 && errno == EAGAIN && do_poll) { + struct pollfd pollfd; + + zero(pollfd); + pollfd.fd = fd; + pollfd.events = POLLOUT; + + if (poll(&pollfd, 1, -1) < 0) { + if (errno == EINTR) + continue; + + return n > 0 ? n : -errno; + } + + if (pollfd.revents != POLLOUT) + return n > 0 ? n : -EIO; + + continue; + } + + return n > 0 ? n : (k < 0 ? -errno : 0); + } + + p += k; + nbytes -= k; + n += k; + } + + return n; +} + int path_is_mount_point(const char *t) { struct stat a, b; char *copy; @@ -2182,7 +2277,7 @@ unsigned long long random_ull(void) { if ((fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY)) < 0) goto fallback; - r = loop_read(fd, &ull, sizeof(ull)); + r = loop_read(fd, &ull, sizeof(ull), true); close_nointr_nofail(fd); if (r != sizeof(ull))