X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fshared%2Futil.c;h=def576de2130981cbc51ea64b74e2397f996949d;hb=d1122ad5e3222cc17bfb556c23273598a5fb60fa;hp=7f41fc4f5ece08f14e66aa463510029947ffd24b;hpb=6bb92a169e8a65e7def5545798001e0dbecc7d4f;p=elogind.git diff --git a/src/shared/util.c b/src/shared/util.c index 7f41fc4f5..def576de2 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -6,16 +6,16 @@ Copyright 2010 Lennart Poettering systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. systemd is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. + Lesser General Public License for more details. - You should have received a copy of the GNU General Public License + You should have received a copy of the GNU Lesser General Public License along with systemd; If not, see . ***/ @@ -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 */ @@ -6036,7 +6049,7 @@ int fd_inc_rcvbuf(int fd, size_t n) { return 1; } -int fork_agent(pid_t *pid, const char *path, ...) { +int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) { pid_t parent_pid, agent_pid; int fd; bool stdout_is_tty, stderr_is_tty; @@ -6073,7 +6086,7 @@ int fork_agent(pid_t *pid, const char *path, ...) { _exit(EXIT_SUCCESS); /* Don't leak fds to the agent */ - close_all_fds(NULL, 0); + close_all_fds(except, n_except); stdout_is_tty = isatty(STDOUT_FILENO); stderr_is_tty = isatty(STDERR_FILENO); @@ -6120,3 +6133,38 @@ int fork_agent(pid_t *pid, const char *path, ...) { 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); +}