diff --git a/src/openrc-run/openrc-run.c b/src/openrc-run/openrc-run.c index 380d4c7f9..39a84d1a7 100644 --- a/src/openrc-run/openrc-run.c +++ b/src/openrc-run/openrc-run.c @@ -416,6 +416,11 @@ svc_exec(const char *command) return 1; } + if (slave_tty >= 0) { + close(slave_tty); + slave_tty = -1; + } + posix_spawn_file_actions_destroy(&tty); free(openrc_sh); @@ -432,9 +437,22 @@ svc_exec(const char *command) break; } - if (fd[1].revents & (POLLIN | POLLHUP)) { + if (master_tty >= 0 && + (fd[1].revents & (POLLIN | POLLHUP))) { char buffer[BUFSIZ]; - write_prefix(buffer, read(master_tty, buffer, BUFSIZ), &prefixed); + ssize_t bytes; + + bytes = read(master_tty, buffer, BUFSIZ); + if (bytes > 0) + write_prefix(buffer, (size_t)bytes, &prefixed); + else if (bytes == 0 || + (bytes == -1 && errno != EINTR)) { + if (bytes == -1 && errno != EIO) + eerror("%s: read: %s", applet, strerror(errno)); + close(master_tty); + master_tty = -1; + fd[1].fd = -1; + } } /* signal_pipe receives service_pid's exit status */ diff --git a/src/openrc/rc-logger.c b/src/openrc/rc-logger.c index e57d38037..f90286c8b 100644 --- a/src/openrc/rc-logger.c +++ b/src/openrc/rc-logger.c @@ -155,6 +155,7 @@ rc_logger_open(const char *level) struct pollfd fd[2]; int s = 0; size_t bytes; + ssize_t bytes_read; FILE *log = NULL; FILE *plog = NULL; const char *logfile; @@ -191,6 +192,8 @@ rc_logger_open(const char *level) rc_in_logger = true; close(signal_pipe[1]); signal_pipe[1] = -1; + close(slave_tty); + slave_tty = -1; runlevel = level; xasprintf(&tmplog, "%s/rc.log", rc_svcdir()); @@ -217,25 +220,36 @@ rc_logger_open(const char *level) } else if (s == 0) continue; - if (fd[1].revents & (POLLIN | POLLHUP)) { + if (rc_logger_tty >= 0 && + (fd[1].revents & (POLLIN | POLLHUP))) { memset(buffer, 0, BUFSIZ); - bytes = read(rc_logger_tty, buffer, BUFSIZ); - if (write(STDOUT_FILENO, buffer, bytes) == -1) - eerror("write: %s", strerror(errno)); - - if (log) - write_log(fileno (log), buffer, bytes); - else { - if (logbuf_size - logbuf_len < bytes) { - logbuf_size += BUFSIZ * 10; - logbuf = xrealloc(logbuf, - sizeof(char ) * - logbuf_size); + bytes_read = read(rc_logger_tty, buffer, BUFSIZ); + if (bytes_read > 0) { + bytes = (size_t)bytes_read; + if (write(STDOUT_FILENO, buffer, bytes) == -1) + eerror("write: %s", strerror(errno)); + + if (log) + write_log(fileno (log), buffer, bytes); + else { + if (logbuf_size - logbuf_len < bytes) { + logbuf_size += BUFSIZ * 10; + logbuf = xrealloc(logbuf, + sizeof(char ) * + logbuf_size); + } + + memcpy(logbuf + logbuf_len, + buffer, bytes); + logbuf_len += bytes; } - - memcpy(logbuf + logbuf_len, - buffer, bytes); - logbuf_len += bytes; + } else if (bytes_read == 0 || + (bytes_read == -1 && errno != EINTR)) { + if (bytes_read == -1 && errno != EIO) + eerror("read: %s", strerror(errno)); + close(rc_logger_tty); + rc_logger_tty = -1; + fd[1].fd = -1; } }