X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Futil.c;h=e5d845609defb295e7e03f3dc087f3337f1c51f8;hp=69eb14be615f656609dbe383c9956875c8da97c9;hb=2edd4434e5bc6e5c7948df742d82f4bcd6c415f3;hpb=c6c18be35bb1d300d0b62a568783cc1c477f7151 diff --git a/src/util.c b/src/util.c index 69eb14be6..e5d845609 100644 --- a/src/util.c +++ b/src/util.c @@ -47,6 +47,7 @@ #include #include #include +#include #include "macro.h" #include "util.h" @@ -609,8 +610,22 @@ int get_process_cmdline(pid_t pid, size_t max_length, char **line) { fclose(f); - if (r[0] == 0) - return get_process_name(pid, line); + /* Kernel threads have no argv[] */ + if (r[0] == 0) { + char *t; + int h; + + free(r); + + if ((h = get_process_name(pid, &t)) < 0) + return h; + + h = asprintf(&r, "[%s]", t); + free(t); + + if (h < 0) + return -ENOMEM; + } *line = r; return 0; @@ -698,6 +713,48 @@ int readlink_and_make_absolute(const char *p, char **r) { return 0; } +int parent_of_path(const char *path, char **_r) { + const char *e, *a = NULL, *b = NULL, *p; + char *r; + bool slash = false; + + assert(path); + assert(_r); + + if (!*path) + return -EINVAL; + + for (e = path; *e; e++) { + + if (!slash && *e == '/') { + a = b; + b = e; + slash = true; + } else if (slash && *e != '/') + slash = false; + } + + if (*(e-1) == '/') + p = a; + else + p = b; + + if (!p) + return -EINVAL; + + if (p == path) + r = strdup("/"); + else + r = strndup(path, p-path); + + if (!r) + return -ENOMEM; + + *_r = r; + return 0; +} + + char *file_name_from_path(const char *p) { char *r; @@ -1788,10 +1845,22 @@ int ask(char *ret, const char *replies, const char *text, ...) { int reset_terminal(int fd) { struct termios termios; int r = 0; + long arg; + + /* Set terminal to some sane defaults */ assert(fd >= 0); - /* Set terminal to some sane defaults */ + /* First, unlock termios */ + zero(termios); + ioctl(fd, TIOCSLCKTRMIOS, &termios); + + /* Disable exclusive mode, just in case */ + ioctl(fd, TIOCNXCL); + + /* Enable console unicode mode */ + arg = K_UNICODE; + ioctl(fd, KDSKBMODE, &arg); if (tcgetattr(fd, &termios) < 0) { r = -errno; @@ -1974,7 +2043,7 @@ int acquire_terminal(const char *name, bool fail, bool force, bool ignore_tiocst } if (e.wd != wd || !(e.mask & IN_CLOSE)) { - r = -errno; + r = -EIO; goto fail; } @@ -2201,25 +2270,24 @@ ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) { int path_is_mount_point(const char *t) { struct stat a, b; - char *copy; + char *parent; + int r; if (lstat(t, &a) < 0) { - if (errno == ENOENT) return 0; return -errno; } - if (!(copy = strdup(t))) - return -ENOMEM; + if ((r = parent_of_path(t, &parent)) < 0) + return r; - if (lstat(dirname(copy), &b) < 0) { - free(copy); - return -errno; - } + r = lstat(parent, &b); + free(parent); - free(copy); + if (r < 0) + return -errno; return a.st_dev != b.st_dev; }