X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshared%2Futil.c;h=e0156868ade4e4259af439ab3fa5b9c77236cfa6;hp=6a40cf1d805d0d991a2b2dc6df244f76fa4f1a90;hb=585314e84c1a2e8941309874088963985e063213;hpb=73836c5c430f48838fec2606b1729dda371edd2d diff --git a/src/shared/util.c b/src/shared/util.c index 6a40cf1d8..e0156868a 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -70,6 +70,7 @@ int saved_argc = 0; char **saved_argv = NULL; +int parsed_columns = 0; size_t page_size(void) { static __thread size_t pgsz = 0; @@ -1108,7 +1109,7 @@ int get_process_exe(pid_t pid, char **name) { return r; } -int get_process_uid(pid_t pid, uid_t *uid) { +static int get_process_id(pid_t pid, const char *field, uid_t *uid) { char *p; FILE *f; int r; @@ -1140,8 +1141,8 @@ int get_process_uid(pid_t pid, uid_t *uid) { l = strstrip(line); - if (startswith(l, "Uid:")) { - l += 4; + if (startswith(l, field)) { + l += strlen(field); l += strspn(l, WHITESPACE); l[strcspn(l, WHITESPACE)] = 0; @@ -1159,6 +1160,14 @@ finish: return r; } +int get_process_uid(pid_t pid, uid_t *uid) { + return get_process_id(pid, "Uid:", uid); +} + +int get_process_gid(pid_t pid, gid_t *gid) { + return get_process_id(pid, "Gid:", gid); +} + char *strnappend(const char *s, const char *suffix, size_t b) { size_t a; char *r; @@ -1176,8 +1185,11 @@ char *strnappend(const char *s, const char *suffix, size_t b) { assert(suffix); a = strlen(s); + if (b > ((size_t) -1) - a) + return NULL; - if (!(r = new(char, a+b+1))) + r = new(char, a+b+1); + if (!r) return NULL; memcpy(r, s, a); @@ -2948,9 +2960,10 @@ int dir_is_empty(const char *path) { return -errno; for (;;) { - struct dirent buf, *de; + struct dirent *de; + union dirent_storage buf; - r = readdir_r(d, &buf, &de); + r = readdir_r(d, &buf.de, &de); if (r > 0) return -r; @@ -3252,12 +3265,13 @@ int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct } for (;;) { - struct dirent buf, *de; + struct dirent *de; + union dirent_storage buf; bool is_dir, keep_around; struct stat st; int r; - r = readdir_r(d, &buf, &de); + r = readdir_r(d, &buf.de, &de); if (r != 0 && ret == 0) { ret = -r; break; @@ -3488,10 +3502,10 @@ cpu_set_t* cpu_set_malloc(unsigned *ncpus) { } } -void status_vprintf(const char *status, bool ellipse, const char *format, va_list ap) { - char *s = NULL; +int status_vprintf(const char *status, bool ellipse, const char *format, va_list ap) { static const char status_indent[] = " "; /* "[" STATUS "] " */ - int fd = -1; + _cleanup_free_ char *s = NULL; + _cleanup_close_ int fd = -1; struct iovec iovec[5]; int n = 0; @@ -3501,11 +3515,11 @@ void status_vprintf(const char *status, bool ellipse, const char *format, va_lis * optional and go exclusively to the console. */ if (vasprintf(&s, format, ap) < 0) - goto finish; + return log_oom(); fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC); if (fd < 0) - goto finish; + return fd; if (ellipse) { char *e; @@ -3516,7 +3530,7 @@ void status_vprintf(const char *status, bool ellipse, const char *format, va_lis if (c <= 0) c = 80; - sl = status ? strlen(status_indent) : 0; + sl = status ? sizeof(status_indent)-1 : 0; emax = c - sl - 1; if (emax < 3) @@ -3543,53 +3557,40 @@ void status_vprintf(const char *status, bool ellipse, const char *format, va_lis IOVEC_SET_STRING(iovec[n++], s); IOVEC_SET_STRING(iovec[n++], "\n"); - writev(fd, iovec, n); - -finish: - free(s); + if (writev(fd, iovec, n) < 0) + return -errno; - if (fd >= 0) - close_nointr_nofail(fd); + return 0; } -void status_printf(const char *status, bool ellipse, const char *format, ...) { +int status_printf(const char *status, bool ellipse, const char *format, ...) { va_list ap; + int r; assert(format); va_start(ap, format); - status_vprintf(status, ellipse, format, ap); + r = status_vprintf(status, ellipse, format, ap); va_end(ap); + + return r; } -void status_welcome(void) { - char *pretty_name = NULL, *ansi_color = NULL; - const char *const_pretty = NULL, *const_color = NULL; +int status_welcome(void) { int r; + _cleanup_free_ char *pretty_name = NULL, *ansi_color = NULL; - if ((r = parse_env_file("/etc/os-release", NEWLINE, - "PRETTY_NAME", &pretty_name, - "ANSI_COLOR", &ansi_color, - NULL)) < 0) { + r = parse_env_file("/etc/os-release", NEWLINE, + "PRETTY_NAME", &pretty_name, + "ANSI_COLOR", &ansi_color, + NULL); + if (r < 0 && r != -ENOENT) + log_warning("Failed to read /etc/os-release: %s", strerror(-r)); - if (r != -ENOENT) - log_warning("Failed to read /etc/os-release: %s", strerror(-r)); - } - - if (!pretty_name && !const_pretty) - const_pretty = "Linux"; - - if (!ansi_color && !const_color) - const_color = "1"; - - status_printf(NULL, - false, - "\nWelcome to \x1B[%sm%s\x1B[0m!\n", - const_color ? const_color : ansi_color, - const_pretty ? const_pretty : pretty_name); - - free(ansi_color); - free(pretty_name); + return status_printf(NULL, false, + "\nWelcome to \x1B[%sm%s\x1B[0m!\n", + isempty(ansi_color) ? "1" : ansi_color, + isempty(pretty_name) ? "Linux" : pretty_name); } char *replace_env(const char *format, char **env) { @@ -3740,7 +3741,7 @@ int fd_columns(int fd) { } static unsigned columns_cached(bool cached) { - static __thread int parsed_columns = 0, env_columns = -1; + static __thread int env_columns = -1; const char *e; if (_likely_(parsed_columns > 0 && cached)) @@ -3776,6 +3777,11 @@ unsigned columns_uncached(void) { return columns_cached(false); } +/* intended to be used as a SIGWINCH sighandler */ +void columns_cache_reset(int signum) { + parsed_columns = 0; +} + int fd_lines(int fd) { struct winsize ws; zero(ws); @@ -3886,7 +3892,8 @@ char *unquote(const char *s, const char* quotes) { /* This is rather stupid, simply removes the heading and * trailing quotes if there is one. Doesn't care about - * escaping or anything. */ + * escaping or anything. We should make this smarter one + * day...*/ l = strlen(s); if (l < 2) @@ -3899,39 +3906,40 @@ char *unquote(const char *s, const char* quotes) { } char *normalize_env_assignment(const char *s) { - char *name, *value, *p, *r; + _cleanup_free_ char *name = NULL, *value = NULL, *p = NULL; + char *eq, *r; - p = strchr(s, '='); + eq = strchr(s, '='); + if (!eq) { + char *t; - if (!p) { - if (!(r = strdup(s))) + r = strdup(s); + if (!r) return NULL; - return strstrip(r); + t = strstrip(r); + if (t == r) + return r; + + memmove(r, t, strlen(t) + 1); + return r; } - if (!(name = strndup(s, p - s))) + name = strndup(s, eq - s); + if (!name) return NULL; - if (!(p = strdup(p+1))) { - free(name); + p = strdup(eq + 1); + if (!p) return NULL; - } value = unquote(strstrip(p), QUOTES); - free(p); - - if (!value) { - free(name); + if (!value) return NULL; - } - if (asprintf(&r, "%s=%s", name, value) < 0) + if (asprintf(&r, "%s=%s", strstrip(name), value) < 0) r = NULL; - free(value); - free(name); - return r; } @@ -4110,6 +4118,8 @@ static char *tag_to_udev_node(const char *tagvalue, const char *by) { } char *fstab_node_to_udev_node(const char *p) { + assert(p); + if (startswith(p, "LABEL=")) return tag_to_udev_node(p+6, "label"); @@ -4644,49 +4654,9 @@ int copy_file(const char *from, const char *to) { return 0; } -int symlink_or_copy(const char *from, const char *to) { - char *pf = NULL, *pt = NULL; - struct stat a, b; - int r; - - assert(from); - assert(to); - - if (path_get_parent(from, &pf) < 0 || - path_get_parent(to, &pt) < 0) { - r = -ENOMEM; - goto finish; - } - - if (stat(pf, &a) < 0 || - stat(pt, &b) < 0) { - r = -errno; - goto finish; - } - - if (a.st_dev != b.st_dev) { - free(pf); - free(pt); - - return copy_file(from, to); - } - - if (symlink(from, to) < 0) { - r = -errno; - goto finish; - } - - r = 0; - -finish: - free(pf); - free(pt); - - return r; -} - -int symlink_or_copy_atomic(const char *from, const char *to) { - char *t, *x; +int symlink_atomic(const char *from, const char *to) { + char *x; + _cleanup_free_ char *t; const char *fn; size_t k; unsigned long long ull; @@ -4714,22 +4684,16 @@ int symlink_or_copy_atomic(const char *from, const char *to) { *x = 0; - r = symlink_or_copy(from, t); - if (r < 0) { - unlink(t); - free(t); - return r; - } + if (symlink(from, t) < 0) + return -errno; if (rename(t, to) < 0) { r = -errno; unlink(t); - free(t); return r; } - free(t); - return r; + return 0; } bool display_is_local(const char *display) { @@ -4989,10 +4953,11 @@ int get_files_in_directory(const char *path, char ***list) { return -errno; for (;;) { - struct dirent buffer, *de; + struct dirent *de; + union dirent_storage buf; int k; - k = readdir_r(d, &buffer, &de); + k = readdir_r(d, &buf.de, &de); if (k != 0) { r = -k; goto finish; @@ -5058,12 +5023,19 @@ char *strjoin(const char *x, ...) { for (;;) { const char *t; + size_t n; t = va_arg(ap, const char *); if (!t) break; - l += strlen(t); + n = strlen(t); + if (n > ((size_t) -1) - l) { + va_end(ap); + return NULL; + } + + l += n; } } else l = 0; @@ -5335,7 +5307,7 @@ int signal_from_string(const char *s) { int offset = 0; unsigned u; - signo =__signal_from_string(s); + signo = __signal_from_string(s); if (signo > 0) return signo; @@ -5727,7 +5699,7 @@ void warn_melody(void) { if (fd < 0) return; - /* Yeah, this is synchronous. Kinda sucks. Bute well... */ + /* Yeah, this is synchronous. Kinda sucks. But well... */ ioctl(fd, KIOCSOUND, (int)(1193180/440)); usleep(125*USEC_PER_MSEC); @@ -5873,3 +5845,7 @@ void closedirp(DIR **d) { if (*d) closedir(*d); } + +void umaskp(mode_t *u) { + umask(*u); +}