Don't reopen stdout on startup

If it's not a TTY we should just exit, because then the user probably
ran edit by accident anyway. It doesn't make much sense to redirect
the output of any interactive application.
This commit is contained in:
Leonard Hecker
2025-04-03 23:58:06 +02:00
parent 2965ab42a5
commit e45c504ab0
2 changed files with 28 additions and 27 deletions

View File

@@ -45,9 +45,6 @@ pub fn init() -> apperr::Result<Deinit> {
if libc::isatty(STATE.stdin) == 0 {
STATE.stdin = check_int_return(libc::open(c"/dev/tty".as_ptr(), libc::O_RDONLY))?;
}
if libc::isatty(STATE.stdout) == 0 {
STATE.stdout = check_int_return(libc::open(c"/dev/tty".as_ptr(), libc::O_WRONLY))?;
}
// Store the stdin flags so we can more easily toggle `O_NONBLOCK` later on.
STATE.stdin_flags = check_int_return(libc::fcntl(STATE.stdin, libc::F_GETFL))?;
@@ -288,7 +285,8 @@ pub fn write_stdout(text: &str) {
pub fn open_stdin_if_redirected() -> Option<File> {
unsafe {
if libc::isatty(libc::STDIN_FILENO) == 0 {
// Did we reopen stdin during `init()`?
if STATE.stdin != libc::STDIN_FILENO {
Some(File::from_raw_fd(libc::STDIN_FILENO))
} else {
None

View File

@@ -80,24 +80,27 @@ pub fn init() -> apperr::Result<Deinit> {
let kernel32 = LibraryLoader::GetModuleHandleW(w!("kernel32.dll"));
STATE.read_console_input_ex = get_proc_address(kernel32, c"ReadConsoleInputExW")?;
STATE.stdin = FileSystem::CreateFileW(
w!("CONIN$"),
Foundation::GENERIC_READ | Foundation::GENERIC_WRITE,
FileSystem::FILE_SHARE_READ | FileSystem::FILE_SHARE_WRITE,
null_mut(),
FileSystem::OPEN_EXISTING,
0,
null_mut(),
);
STATE.stdout = FileSystem::CreateFileW(
w!("CONOUT$"),
Foundation::GENERIC_READ | Foundation::GENERIC_WRITE,
FileSystem::FILE_SHARE_READ | FileSystem::FILE_SHARE_WRITE,
null_mut(),
FileSystem::OPEN_EXISTING,
0,
null_mut(),
);
STATE.stdin = Console::GetStdHandle(Console::STD_INPUT_HANDLE);
STATE.stdout = Console::GetStdHandle(Console::STD_OUTPUT_HANDLE);
// Reopen stdin if it's redirected (= piped input).
if !ptr::eq(STATE.stdin, Foundation::INVALID_HANDLE_VALUE)
&& matches!(
FileSystem::GetFileType(STATE.stdin),
FileSystem::FILE_TYPE_DISK | FileSystem::FILE_TYPE_PIPE
)
{
STATE.stdin = FileSystem::CreateFileW(
w!("CONIN$"),
Foundation::GENERIC_READ | Foundation::GENERIC_WRITE,
FileSystem::FILE_SHARE_READ | FileSystem::FILE_SHARE_WRITE,
null_mut(),
FileSystem::OPEN_EXISTING,
0,
null_mut(),
);
}
if ptr::eq(STATE.stdin, Foundation::INVALID_HANDLE_VALUE)
|| ptr::eq(STATE.stdout, Foundation::INVALID_HANDLE_VALUE)
{
@@ -379,11 +382,11 @@ pub fn write_stdout(text: &str) {
pub fn open_stdin_if_redirected() -> Option<File> {
unsafe {
let handle = Console::GetStdHandle(Console::STD_INPUT_HANDLE);
match FileSystem::GetFileType(handle) {
FileSystem::FILE_TYPE_DISK | FileSystem::FILE_TYPE_PIPE => {
Some(File::from_raw_handle(handle))
}
_ => None,
// Did we reopen stdin during `init()`?
if !std::ptr::eq(STATE.stdin, handle) {
Some(File::from_raw_handle(handle))
} else {
None
}
}
}