X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshared%2Futil.c;h=ba2456283962574753eaa1670c6f3373bfe1ee46;hp=a3873a931818ec4595e5e1f538c629b5768c0439;hb=ab94af9201496ea3aa59bbf2a01eb750fbd1c08a;hpb=5430f7f2bc7330f3088b894166bf3524a067e3d8 diff --git a/src/shared/util.c b/src/shared/util.c index a3873a931..ba2456283 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -56,6 +56,7 @@ #include #include #include +#include #include "macro.h" #include "util.h" @@ -1690,7 +1691,8 @@ char *cescape(const char *s) { /* Does C style string escaping. */ - if (!(r = new(char, strlen(s)*4 + 1))) + r = new(char, strlen(s)*4 + 1); + if (!r) return NULL; for (f = s, t = r; *f; f++) @@ -4285,6 +4287,15 @@ bool tty_is_vc(const char *tty) { return vtnr_from_tty(tty) >= 0; } +bool tty_is_console(const char *tty) { + assert(tty); + + if (startswith(tty, "/dev/")) + tty += 5; + + return streq(tty, "console"); +} + int vtnr_from_tty(const char *tty) { int i, r; @@ -4318,8 +4329,10 @@ bool tty_is_vc_resolve(const char *tty) { if (startswith(tty, "/dev/")) tty += 5; - /* Resolve where /dev/console is pointing to */ - if (streq(tty, "console")) + /* Resolve where /dev/console is pointing to, if /sys is + * actually ours (i.e. not read-only-mounted which is a sign + * for container setups) */ + if (streq(tty, "console") && path_is_read_only_fs("/sys") <= 0) if (read_one_line_file("/sys/class/tty/console/active", &active) >= 0) { /* If multiple log outputs are configured the * last one is what /dev/console points to */ @@ -4339,7 +4352,7 @@ bool tty_is_vc_resolve(const char *tty) { const char *default_term_for_tty(const char *tty) { assert(tty); - return tty_is_vc_resolve(tty) ? "TERM=linux" : "TERM=vt100"; + return tty_is_vc_resolve(tty) ? "TERM=linux" : "TERM=vt102"; } bool dirent_is_file(const struct dirent *de) { @@ -6120,3 +6133,100 @@ int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *pa execv(path, l); _exit(EXIT_FAILURE); } + +int setrlimit_closest(int resource, const struct rlimit *rlim) { + struct rlimit highest, fixed; + + assert(rlim); + + if (setrlimit(resource, rlim) >= 0) + return 0; + + if (errno != EPERM) + return -errno; + + /* So we failed to set the desired setrlimit, then let's try + * to get as close as we can */ + assert_se(getrlimit(resource, &highest) == 0); + + fixed.rlim_cur = MIN(rlim->rlim_cur, highest.rlim_max); + fixed.rlim_max = MIN(rlim->rlim_max, highest.rlim_max); + + if (setrlimit(resource, &fixed) < 0) + return -errno; + + return 0; +} + +int path_is_read_only_fs(const char *path) { + struct statvfs st; + + assert(path); + + if (statvfs(path, &st) < 0) + return -errno; + + return !!(st.f_flag & ST_RDONLY); +} + +int getenv_for_pid(pid_t pid, const char *field, char **_value) { + char path[sizeof("/proc/")-1+10+sizeof("/environ")], *value = NULL; + int r; + FILE *f; + bool done = false; + size_t l; + + assert(field); + assert(_value); + + if (pid == 0) + pid = getpid(); + + snprintf(path, sizeof(path), "/proc/%lu/environ", (unsigned long) pid); + char_array_0(path); + + f = fopen(path, "re"); + if (!f) + return -errno; + + l = strlen(field); + r = 0; + + do { + char line[LINE_MAX]; + unsigned i; + + for (i = 0; i < sizeof(line)-1; i++) { + int c; + + c = getc(f); + if (_unlikely_(c == EOF)) { + done = true; + break; + } else if (c == 0) + break; + + line[i] = c; + } + line[i] = 0; + + if (memcmp(line, field, l) == 0 && line[l] == '=') { + value = strdup(line + l + 1); + if (!value) { + r = -ENOMEM; + break; + } + + r = 1; + break; + } + + } while (!done); + + fclose(f); + + if (r >= 0) + *_value = value; + + return r; +}