X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fshared%2Futil.c;h=cef6dbb732f48201c3c26fc21e2804dfd24e6c56;hb=49f43d5f91a99b23f745726aa351d8f159774357;hp=62121b59236abd407acc811157f62ef83cc078c6;hpb=f56d5db919902851535ac1591d5c95ebcd3a0b17;p=elogind.git diff --git a/src/shared/util.c b/src/shared/util.c index 62121b592..cef6dbb73 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -1083,7 +1083,7 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char * if (h < 0) return h; - r = join("[", t, "]", NULL); + r = strjoin("[", t, "]", NULL); free(t); if (!r) @@ -2385,8 +2385,9 @@ int acquire_terminal( bool ignore_tiocstty_eperm, usec_t timeout) { - int fd = -1, notify = -1, r, wd = -1; + int fd = -1, notify = -1, r = 0, wd = -1; usec_t ts = 0; + struct sigaction sa_old, sa_new; assert(name); @@ -2434,17 +2435,26 @@ int acquire_terminal( if (fd < 0) return fd; + /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed + * if we already own the tty. */ + zero(sa_new); + sa_new.sa_handler = SIG_IGN; + sa_new.sa_flags = SA_RESTART; + assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0); + /* First, try to get the tty */ - r = ioctl(fd, TIOCSCTTY, force); + if (ioctl(fd, TIOCSCTTY, force) < 0) + r = -errno; + + assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0); /* Sometimes it makes sense to ignore TIOCSCTTY * returning EPERM, i.e. when very likely we already * are have this controlling terminal. */ - if (r < 0 && errno == EPERM && ignore_tiocstty_eperm) + if (r < 0 && r == -EPERM && ignore_tiocstty_eperm) r = 0; - if (r < 0 && (force || fail || errno != EPERM)) { - r = -errno; + if (r < 0 && (force || fail || r != -EPERM)) { goto fail; } @@ -2940,7 +2950,8 @@ int make_stdio(int fd) { int make_null_stdio(void) { int null_fd; - if ((null_fd = open("/dev/null", O_RDWR|O_NOCTTY)) < 0) + null_fd = open("/dev/null", O_RDWR|O_NOCTTY); + if (null_fd < 0) return -errno; return make_stdio(null_fd); @@ -5144,7 +5155,7 @@ finish: return r; } -char *join(const char *x, ...) { +char *strjoin(const char *x, ...) { va_list ap; size_t l; char *r, *p; @@ -5844,3 +5855,23 @@ void warn_melody(void) { ioctl(fd, KIOCSOUND, 0); close_nointr_nofail(fd); } + +int make_console_stdio(void) { + int fd, r; + + /* Make /dev/console the controlling terminal and stdin/stdout/stderr */ + + fd = acquire_terminal("/dev/console", false, true, true, (usec_t) -1); + if (fd < 0) { + log_error("Failed to acquire terminal: %s", strerror(-fd)); + return fd; + } + + r = make_stdio(fd); + if (r < 0) { + log_error("Failed to duplicate terminal fd: %s", strerror(-r)); + return r; + } + + return 0; +}