X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=util.c;h=e9f7813b8b378d13af2b7e322a5aaf9a3f612362;hb=2146621ba3812a78e2f0f589776f1bc4cce07d34;hp=e32e2f2566399e131e5dd5cd5dea965a70f16602;hpb=80876c20f64f87765242bc35895977ab6a855729;p=elogind.git diff --git a/util.c b/util.c index e32e2f256..e9f7813b8 100644 --- a/util.c +++ b/util.c @@ -41,6 +41,7 @@ #include #include #include +#include #include "macro.h" #include "util.h" @@ -658,7 +659,6 @@ char *strstrip(char *s) { *s = 0; return s; - } char *delete_chars(char *s, const char *bad) { @@ -1042,16 +1042,15 @@ char *bus_path_escape(const char *s) { return r; } -char *bus_path_unescape(const char *s) { +char *bus_path_unescape(const char *f) { char *r, *t; - const char *f; - assert(s); + assert(f); - if (!(r = new(char, strlen(s)+1))) + if (!(r = strdup(f))) return NULL; - for (f = s, t = r; *f; f++) { + for (t = r; *f; f++) { if (*f == '_') { int a, b; @@ -1141,6 +1140,39 @@ bool path_startswith(const char *path, const char *prefix) { } } +bool path_equal(const char *a, const char *b) { + assert(a); + assert(b); + + if ((a[0] == '/') != (b[0] == '/')) + return false; + + for (;;) { + size_t j, k; + + a += strspn(a, "/"); + b += strspn(b, "/"); + + if (*a == 0 && *b == 0) + return true; + + if (*a == 0 || *b == 0) + return false; + + j = strcspn(a, "/"); + k = strcspn(b, "/"); + + if (j != k) + return false; + + if (memcmp(a, b, j) != 0) + return false; + + a += j; + b += k; + } +} + char *ascii_strlower(char *t) { char *p; @@ -1216,7 +1248,7 @@ int close_all_fds(const int except[], unsigned n_except) { while ((de = readdir(d))) { int fd = -1; - if (de->d_name[0] == '.') + if (ignore_file(de->d_name)) continue; if ((r = safe_atoi(de->d_name, &fd)) < 0) @@ -1325,7 +1357,7 @@ int chvt(int vt) { if (ioctl(fd, VT_ACTIVATE, vt) < 0) r = -errno; - close_nointr(r); + close_nointr_nofail(r); return r; } @@ -1423,14 +1455,18 @@ int reset_terminal(int fd) { assert(fd >= 0); - /* Set terminal up for job control */ + /* Set terminal to some sane defaults */ if (tcgetattr(fd, &termios) < 0) { r = -errno; goto finish; } - termios.c_iflag &= ~(IGNBRK | BRKINT); + /* We only reset the stuff that matters to the software. How + * hardware is set up we don't touch assuming that somebody + * else will do that for us */ + + termios.c_iflag &= ~(IGNBRK | BRKINT | ISTRIP | INLCR | IGNCR | IUCLC); termios.c_iflag |= ICRNL | IMAXBEL | IUTF8; termios.c_oflag |= ONLCR; termios.c_cflag |= CREAD; @@ -1447,6 +1483,8 @@ int reset_terminal(int fd) { termios.c_cc[VLNEXT] = 026; /* ^V */ termios.c_cc[VWERASE] = 027; /* ^W */ termios.c_cc[VREPRINT] = 022; /* ^R */ + termios.c_cc[VEOL] = 0; + termios.c_cc[VEOL2] = 0; termios.c_cc[VTIME] = 0; termios.c_cc[VMIN] = 1; @@ -1607,7 +1645,7 @@ int acquire_terminal(const char *name, bool fail, bool force) { } if (notify >= 0) - close_nointr(notify); + close_nointr_nofail(notify); if ((r = reset_terminal(fd)) < 0) log_warning("Failed to reset terminal: %s", strerror(-r)); @@ -1616,10 +1654,10 @@ int acquire_terminal(const char *name, bool fail, bool force) { fail: if (fd >= 0) - close_nointr(fd); + close_nointr_nofail(fd); if (notify >= 0) - close_nointr(notify); + close_nointr_nofail(notify); return r; } @@ -1637,6 +1675,107 @@ int release_terminal(void) { return r; } +int ignore_signal(int sig) { + struct sigaction sa; + + zero(sa); + sa.sa_handler = SIG_IGN; + sa.sa_flags = SA_RESTART; + + return sigaction(sig, &sa, NULL); +} + +int close_pipe(int p[]) { + int a = 0, b = 0; + + assert(p); + + if (p[0] >= 0) { + a = close_nointr(p[0]); + p[0] = -1; + } + + if (p[1] >= 0) { + b = close_nointr(p[1]); + p[1] = -1; + } + + return a < 0 ? a : b; +} + +ssize_t loop_read(int fd, void *buf, size_t nbytes) { + uint8_t *p; + ssize_t n = 0; + + assert(fd >= 0); + assert(buf); + + p = buf; + + while (nbytes > 0) { + ssize_t k; + + if ((k = read(fd, p, nbytes)) <= 0) { + + if (errno == EINTR) + continue; + + if (errno == EAGAIN) { + struct pollfd pollfd; + + zero(pollfd); + pollfd.fd = fd; + pollfd.events = POLLIN; + + if (poll(&pollfd, 1, -1) < 0) { + if (errno == EINTR) + continue; + + return n > 0 ? n : -errno; + } + + if (pollfd.revents != POLLIN) + 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; + + if (lstat(t, &a) < 0) { + + if (errno == ENOENT) + return 0; + + return -errno; + } + + if (!(copy = strdup(t))) + return -ENOMEM; + + if (lstat(dirname(copy), &b) < 0) { + free(copy); + return -errno; + } + + free(copy); + + return a.st_dev != b.st_dev; +} + static const char *const ioprio_class_table[] = { [IOPRIO_CLASS_NONE] = "none", [IOPRIO_CLASS_RT] = "realtime",