mirror of
https://github.com/systemd/systemd.git
synced 2024-11-27 20:23:36 +08:00
Merge pull request #34044 from poettering/isatty-fixes
fixes around isatty() handling
This commit is contained in:
commit
41f5e66cf2
@ -33,7 +33,7 @@ int verb_srk(int argc, char *argv[], void *userdata) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to marshal SRK: %m");
|
||||
|
||||
if (isatty(STDOUT_FILENO))
|
||||
if (isatty_safe(STDOUT_FILENO))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EIO),
|
||||
"Refusing to write binary data to TTY, please redirect output to file.");
|
||||
|
||||
|
@ -65,6 +65,12 @@ bool isatty_safe(int fd) {
|
||||
if (isatty(fd))
|
||||
return true;
|
||||
|
||||
/* Linux/glibc returns EIO for hung up TTY on isatty(). Which is wrong, the thing doesn't stop being
|
||||
* a TTY after all, just because it is temporarily hung up. Let's work around this here, until this
|
||||
* is fixed in glibc. See: https://sourceware.org/bugzilla/show_bug.cgi?id=32103 */
|
||||
if (errno == EIO)
|
||||
return true;
|
||||
|
||||
/* Be resilient if we're working on stdio, since they're set up by parent process. */
|
||||
assert(errno != EBADF || IN_SET(fd, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO));
|
||||
|
||||
@ -281,7 +287,7 @@ int open_terminal(const char *name, int mode) {
|
||||
}
|
||||
|
||||
if (!isatty_safe(fd))
|
||||
return negative_errno();
|
||||
return -ENOTTY;
|
||||
|
||||
return TAKE_FD(fd);
|
||||
}
|
||||
@ -1046,8 +1052,8 @@ bool on_tty(void) {
|
||||
|
||||
if (cached_on_tty < 0)
|
||||
cached_on_tty =
|
||||
isatty(STDOUT_FILENO) > 0 &&
|
||||
isatty(STDERR_FILENO) > 0;
|
||||
isatty_safe(STDOUT_FILENO) &&
|
||||
isatty_safe(STDERR_FILENO);
|
||||
|
||||
return cached_on_tty;
|
||||
}
|
||||
@ -1502,7 +1508,7 @@ int vt_restore(int fd) {
|
||||
assert(fd >= 0);
|
||||
|
||||
if (!isatty_safe(fd))
|
||||
return log_debug_errno(errno, "Asked to restore the VT for an fd that does not refer to a terminal: %m");
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(ENOTTY), "Asked to restore the VT for an fd that does not refer to a terminal: %m");
|
||||
|
||||
if (ioctl(fd, KDSETMODE, KD_TEXT) < 0)
|
||||
RET_GATHER(ret, log_debug_errno(errno, "Failed to set VT to text mode, ignoring: %m"));
|
||||
@ -1529,7 +1535,7 @@ int vt_release(int fd, bool restore) {
|
||||
* VT-switching modes. */
|
||||
|
||||
if (!isatty_safe(fd))
|
||||
return log_debug_errno(errno, "Asked to release the VT for an fd that does not refer to a terminal: %m");
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(ENOTTY), "Asked to release the VT for an fd that does not refer to a terminal: %m");
|
||||
|
||||
if (ioctl(fd, VT_RELDISP, 1) < 0)
|
||||
return -errno;
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "random-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "terminal-util.h"
|
||||
#include "user-util.h"
|
||||
#include "utf8.h"
|
||||
|
||||
@ -120,7 +121,7 @@ char* getlogname_malloc(void) {
|
||||
uid_t uid;
|
||||
struct stat st;
|
||||
|
||||
if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
|
||||
if (isatty_safe(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
|
||||
uid = st.st_uid;
|
||||
else
|
||||
uid = getuid();
|
||||
|
@ -1401,7 +1401,7 @@ static int verb_capture(int argc, char **argv, void *userdata) {
|
||||
"busctl (systemd) " PROJECT_VERSION_FULL " (Git " GIT_VERSION ")";
|
||||
int r;
|
||||
|
||||
if (isatty(STDOUT_FILENO))
|
||||
if (isatty_safe(STDOUT_FILENO))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Refusing to write message data to console, please redirect output to a file.");
|
||||
|
||||
|
@ -354,7 +354,7 @@ static int setup_input(
|
||||
return -errno;
|
||||
|
||||
/* Try to make this the controlling tty, if it is a tty */
|
||||
if (isatty(STDIN_FILENO))
|
||||
if (isatty_safe(STDIN_FILENO))
|
||||
(void) ioctl(STDIN_FILENO, TIOCSCTTY, context->std_input == EXEC_INPUT_TTY_FORCE);
|
||||
|
||||
return STDIN_FILENO;
|
||||
|
@ -718,7 +718,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
if (!IN_SET(arg_action, ACTION_DISSECT, ACTION_LIST, ACTION_MTREE, ACTION_COPY_FROM, ACTION_COPY_TO, ACTION_DISCOVER, ACTION_VALIDATE) && geteuid() != 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Need to be root.");
|
||||
|
||||
SET_FLAG(arg_flags, DISSECT_IMAGE_ALLOW_INTERACTIVE_AUTH, isatty(STDIN_FILENO));
|
||||
SET_FLAG(arg_flags, DISSECT_IMAGE_ALLOW_INTERACTIVE_AUTH, isatty_safe(STDIN_FILENO));
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -1639,7 +1639,7 @@ static int action_list_or_mtree_or_copy_or_make_archive(DissectedImage *m, LoopD
|
||||
|
||||
r = sym_archive_write_open_FILE(a, f);
|
||||
} else {
|
||||
if (isatty(STDOUT_FILENO))
|
||||
if (isatty_safe(STDOUT_FILENO))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EBADF), "Refusing to write archive to TTY.");
|
||||
|
||||
r = sym_archive_write_open_fd(a, STDOUT_FILENO);
|
||||
@ -1999,12 +1999,12 @@ static int action_validate(void) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (isatty(STDOUT_FILENO) && emoji_enabled())
|
||||
if (isatty_safe(STDOUT_FILENO) && emoji_enabled())
|
||||
printf("%s ", special_glyph(SPECIAL_GLYPH_SPARKLES));
|
||||
|
||||
printf("%sOK%s", ansi_highlight_green(), ansi_normal());
|
||||
|
||||
if (isatty(STDOUT_FILENO) && emoji_enabled())
|
||||
if (isatty_safe(STDOUT_FILENO) && emoji_enabled())
|
||||
printf(" %s", special_glyph(SPECIAL_GLYPH_SPARKLES));
|
||||
|
||||
putc('\n', stdout);
|
||||
|
@ -95,7 +95,7 @@ static int verify_tty(const char *name) {
|
||||
return -errno;
|
||||
|
||||
if (!isatty_safe(fd))
|
||||
return -errno;
|
||||
return -ENOTTY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ static int run(int argc, char *argv[]) {
|
||||
* daemon when it comes to logging hence LOG_TARGET_AUTO won't do the right thing for
|
||||
* us. Hence explicitly log to the console if we're started from a console or to kmsg
|
||||
* otherwise. */
|
||||
log_target = isatty(STDERR_FILENO) ? LOG_TARGET_CONSOLE : LOG_TARGET_KMSG;
|
||||
log_target = isatty_safe(STDERR_FILENO) ? LOG_TARGET_CONSOLE : LOG_TARGET_KMSG;
|
||||
|
||||
log_set_prohibit_ipc(true); /* better safe than sorry */
|
||||
log_set_target(log_target);
|
||||
|
@ -290,7 +290,7 @@ static int handle_arg_console(const char *arg) {
|
||||
else if (streq(arg, "passive"))
|
||||
arg_console_mode = CONSOLE_PASSIVE;
|
||||
else if (streq(arg, "pipe")) {
|
||||
if (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO))
|
||||
if (isatty_safe(STDIN_FILENO) && isatty(STDOUT_FILENO))
|
||||
log_full(arg_quiet ? LOG_DEBUG : LOG_NOTICE,
|
||||
"Console mode 'pipe' selected, but standard input/output are connected to an interactive TTY. "
|
||||
"Most likely you want to use 'interactive' console mode for proper interactivity and shell job control. "
|
||||
@ -298,7 +298,7 @@ static int handle_arg_console(const char *arg) {
|
||||
|
||||
arg_console_mode = CONSOLE_PIPE;
|
||||
} else if (streq(arg, "autopipe")) {
|
||||
if (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO))
|
||||
if (isatty_safe(STDIN_FILENO) && isatty(STDOUT_FILENO))
|
||||
arg_console_mode = CONSOLE_INTERACTIVE;
|
||||
else
|
||||
arg_console_mode = CONSOLE_PIPE;
|
||||
@ -5883,7 +5883,7 @@ static int run(int argc, char *argv[]) {
|
||||
umask(0022);
|
||||
|
||||
if (arg_console_mode < 0)
|
||||
arg_console_mode = isatty(STDIN_FILENO) && isatty(STDOUT_FILENO) ?
|
||||
arg_console_mode = isatty_safe(STDIN_FILENO) && isatty(STDOUT_FILENO) ?
|
||||
CONSOLE_INTERACTIVE : CONSOLE_READ_ONLY;
|
||||
|
||||
if (arg_console_mode == CONSOLE_PIPE) /* if we pass STDERR on to the container, don't add our own logs into it too */
|
||||
|
@ -7701,7 +7701,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
if (arg_pretty < 0 && isatty(STDOUT_FILENO))
|
||||
if (arg_pretty < 0 && isatty_safe(STDOUT_FILENO))
|
||||
arg_pretty = true;
|
||||
|
||||
if (arg_architecture >= 0) {
|
||||
|
@ -674,7 +674,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
/* If we both --pty and --pipe are specified we'll automatically pick --pty if we are connected fully
|
||||
* to a TTY and pick direct fd passing otherwise. This way, we automatically adapt to usage in a shell
|
||||
* pipeline, but we are neatly interactive with tty-level isolation otherwise. */
|
||||
arg_stdio = isatty(STDIN_FILENO) && isatty(STDOUT_FILENO) && isatty(STDERR_FILENO) ?
|
||||
arg_stdio = isatty_safe(STDIN_FILENO) && isatty(STDOUT_FILENO) && isatty(STDERR_FILENO) ?
|
||||
ARG_STDIO_PTY :
|
||||
ARG_STDIO_DIRECT;
|
||||
|
||||
@ -908,7 +908,7 @@ static int parse_argv_sudo_mode(int argc, char *argv[]) {
|
||||
arg_wait = true;
|
||||
arg_aggressive_gc = true;
|
||||
|
||||
arg_stdio = isatty(STDIN_FILENO) && isatty(STDOUT_FILENO) && isatty(STDERR_FILENO) ? ARG_STDIO_PTY : ARG_STDIO_DIRECT;
|
||||
arg_stdio = isatty_safe(STDIN_FILENO) && isatty(STDOUT_FILENO) && isatty(STDERR_FILENO) ? ARG_STDIO_PTY : ARG_STDIO_DIRECT;
|
||||
arg_expand_environment = false;
|
||||
arg_send_sighup = true;
|
||||
|
||||
@ -1176,7 +1176,7 @@ static int transient_service_set_properties(sd_bus_message *m, const char *pty_p
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
send_term = isatty(STDIN_FILENO) || isatty(STDOUT_FILENO) || isatty(STDERR_FILENO);
|
||||
send_term = isatty_safe(STDIN_FILENO) || isatty(STDOUT_FILENO) || isatty(STDERR_FILENO);
|
||||
}
|
||||
|
||||
if (send_term) {
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "exec-util.h"
|
||||
#include "log.h"
|
||||
#include "process-util.h"
|
||||
#include "terminal-util.h"
|
||||
|
||||
static pid_t agent_pid = 0;
|
||||
|
||||
@ -17,9 +18,8 @@ int ask_password_agent_open(void) {
|
||||
if (agent_pid > 0)
|
||||
return 0;
|
||||
|
||||
/* We check STDIN here, not STDOUT, since this is about input,
|
||||
* not output */
|
||||
if (!isatty(STDIN_FILENO))
|
||||
/* We check STDIN here, not STDOUT, since this is about input, not output */
|
||||
if (!isatty_safe(STDIN_FILENO))
|
||||
return 0;
|
||||
|
||||
if (!is_main_thread())
|
||||
|
@ -988,14 +988,14 @@ int ask_password_auto(
|
||||
|
||||
if (FLAGS_SET(flags, ASK_PASSWORD_ACCEPT_CACHED) &&
|
||||
req && req->keyring &&
|
||||
(FLAGS_SET(flags, ASK_PASSWORD_NO_TTY) || !isatty(STDIN_FILENO)) &&
|
||||
(FLAGS_SET(flags, ASK_PASSWORD_NO_TTY) || !isatty_safe(STDIN_FILENO)) &&
|
||||
FLAGS_SET(flags, ASK_PASSWORD_NO_AGENT)) {
|
||||
r = ask_password_keyring(req, flags, ret);
|
||||
if (r != -ENOKEY)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (!FLAGS_SET(flags, ASK_PASSWORD_NO_TTY) && isatty(STDIN_FILENO))
|
||||
if (!FLAGS_SET(flags, ASK_PASSWORD_NO_TTY) && isatty_safe(STDIN_FILENO))
|
||||
return ask_password_tty(-EBADF, req, until, flags, NULL, ret);
|
||||
|
||||
if (!FLAGS_SET(flags, ASK_PASSWORD_NO_AGENT))
|
||||
|
@ -555,8 +555,8 @@ int _fork_agent(const char *name, const int except[], size_t n_except, pid_t *re
|
||||
|
||||
/* In the child: */
|
||||
|
||||
stdout_is_tty = isatty(STDOUT_FILENO);
|
||||
stderr_is_tty = isatty(STDERR_FILENO);
|
||||
stdout_is_tty = isatty_safe(STDOUT_FILENO);
|
||||
stderr_is_tty = isatty_safe(STDERR_FILENO);
|
||||
|
||||
if (!stdout_is_tty || !stderr_is_tty) {
|
||||
int fd;
|
||||
|
@ -2391,7 +2391,7 @@ int table_print(Table *t, FILE *f) {
|
||||
if (t->width != 0 && t->width != SIZE_MAX)
|
||||
table_effective_width = t->width;
|
||||
else if (t->width == 0 ||
|
||||
((pass > 0 || !any_soft) && (pager_have() || !isatty(STDOUT_FILENO))))
|
||||
((pass > 0 || !any_soft) && (pager_have() || !isatty_safe(STDOUT_FILENO))))
|
||||
table_effective_width = table_requested_width;
|
||||
else
|
||||
table_effective_width = MIN(table_requested_width, columns());
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "polkit-agent.h"
|
||||
#include "process-util.h"
|
||||
#include "stdio-util.h"
|
||||
#include "terminal-util.h"
|
||||
#include "time-util.h"
|
||||
|
||||
#if ENABLE_POLKIT
|
||||
@ -31,7 +32,7 @@ int polkit_agent_open(void) {
|
||||
return 0;
|
||||
|
||||
/* We check STDIN here, not STDOUT, since this is about input, not output */
|
||||
if (!isatty(STDIN_FILENO))
|
||||
if (!isatty_safe(STDIN_FILENO))
|
||||
return 0;
|
||||
|
||||
if (!is_main_thread())
|
||||
|
@ -32,7 +32,7 @@ static int write_to_terminal(const char *tty, const char *message) {
|
||||
return -errno;
|
||||
|
||||
if (!isatty_safe(fd))
|
||||
return -errno;
|
||||
return -ENOTTY;
|
||||
|
||||
return loop_write_full(fd, message, SIZE_MAX, TIMEOUT_USEC);
|
||||
}
|
||||
|
@ -1065,7 +1065,7 @@ static int on_display_refresh(sd_event_source *s, uint64_t usec, void *userdata)
|
||||
|
||||
c->display_refresh_scheduled = false;
|
||||
|
||||
if (isatty(STDERR_FILENO))
|
||||
if (isatty_safe(STDERR_FILENO))
|
||||
fputs(ANSI_HOME_CLEAR, stderr);
|
||||
|
||||
/* If we have both IPv4 and IPv6, we display IPv4 info via Plymouth, since it doesn't have much
|
||||
@ -1247,7 +1247,7 @@ static int run(int argc, char* argv[]) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to subscribe to RTM_DELADDR events: %m");
|
||||
|
||||
if (isatty(STDIN_FILENO))
|
||||
if (isatty_safe(STDIN_FILENO))
|
||||
log_info("Hit Ctrl-C to exit target mode.");
|
||||
|
||||
_unused_ _cleanup_(notify_on_cleanup) const char *notify_message =
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "json-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "terminal-util.h"
|
||||
#include "tests.h"
|
||||
#include "time-util.h"
|
||||
|
||||
@ -562,7 +563,7 @@ TEST(table) {
|
||||
assert_se(table_format(t, &formatted) >= 0);
|
||||
printf("%s\n", formatted);
|
||||
|
||||
if (isatty(STDOUT_FILENO))
|
||||
if (isatty_safe(STDOUT_FILENO))
|
||||
assert_se(streq(formatted,
|
||||
"no a long f… no a long f… a long fi…\n"
|
||||
"no fäää no fäää fäää\n"
|
||||
|
@ -504,7 +504,7 @@ static int verb_call(int argc, char *argv[], void *userdata) {
|
||||
/* <argv[4]> is correct, as dispatch_verb() shifts arguments by one for the verb. */
|
||||
r = sd_json_parse_with_source(parameter, source, 0, &jp, &line, &column);
|
||||
} else {
|
||||
if (isatty(STDIN_FILENO) > 0 && !arg_quiet)
|
||||
if (isatty_safe(STDIN_FILENO) && !arg_quiet)
|
||||
log_notice("Expecting method call parameter JSON object on standard input. (Provide empty string or {} for no parameters.)");
|
||||
|
||||
source = "<stdin>";
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "process-util.h"
|
||||
#include "socket-util.h"
|
||||
#include "string-util.h"
|
||||
#include "terminal-util.h"
|
||||
#include "vmspawn-register.h"
|
||||
#include "varlink-util.h"
|
||||
|
||||
@ -73,7 +74,7 @@ int register_machine(
|
||||
SD_JSON_BUILD_PAIR_CONDITION(!!directory, "rootDirectory", SD_JSON_BUILD_STRING(directory)),
|
||||
SD_JSON_BUILD_PAIR_CONDITION(!!address, "sshAddress", SD_JSON_BUILD_STRING(address)),
|
||||
SD_JSON_BUILD_PAIR_CONDITION(!!key_path, "sshPrivateKeyPath", SD_JSON_BUILD_STRING(key_path)),
|
||||
SD_JSON_BUILD_PAIR_CONDITION(isatty(STDIN_FILENO), "allowInteractiveAuthentication", SD_JSON_BUILD_BOOLEAN(true)),
|
||||
SD_JSON_BUILD_PAIR_CONDITION(isatty_safe(STDIN_FILENO), "allowInteractiveAuthentication", SD_JSON_BUILD_BOOLEAN(true)),
|
||||
SD_JSON_BUILD_PAIR_CONDITION(!keep_unit, "allocateUnit", SD_JSON_BUILD_BOOLEAN(true)));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user