Skip to content

Commit fd61f0d

Browse files
committed
Use NoCtty when opening /dev/tty
POSIX.1-2024 Job control specifications are written in the assumption that a job-control shell may not have a control terminal. The shell should not make an arbitrary terminal its control terminal. To make sure that the shell only opens an existing control terminal, this commit adds the `OpenFlag::NoCtty` flag passed to the `open` system call when opening `/dev/tty`.
1 parent 39fd2fd commit fd61f0d

File tree

2 files changed

+29
-6
lines changed

2 files changed

+29
-6
lines changed

yash-env/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4141

4242
### Changed
4343

44+
- `Env::get_tty` now uses `system::OpenFlag::NoCtty` when opening the terminal
45+
device file.
4446
- `System::getpwnam_dir` now takes a `&CStr` parameter instead of a `&str`.
4547
- The `builtin::Builtin` struct is now `non_exhaustive`.
4648
- The `origin` field of the `trap::TrapState` struct is now `trap::Origin`.

yash-env/src/lib.rs

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ use self::semantics::ExitStatus;
4747
use self::stack::Frame;
4848
use self::stack::Stack;
4949
use self::system::Errno;
50+
use self::system::Mode;
51+
use self::system::OfdAccess;
52+
use self::system::OpenFlag;
5053
pub use self::system::SharedSystem;
5154
pub use self::system::System;
5255
use self::system::SystemEx;
@@ -295,12 +298,30 @@ impl Env {
295298
return Ok(fd);
296299
}
297300

298-
let first_fd = self.system.open(
299-
c"/dev/tty",
300-
crate::system::OfdAccess::ReadWrite,
301-
crate::system::OpenFlag::CloseOnExec.into(),
302-
crate::system::Mode::empty(),
303-
)?;
301+
let first_fd = {
302+
// POSIX.1-2024 Job control specifications are written in the
303+
// assumption that a job-control shell may not have a control
304+
// terminal. The shell should not make an arbitrary terminal its
305+
// control terminal, so we open /dev/tty with NoCtty.
306+
let mut result = self.system.open(
307+
c"/dev/tty",
308+
OfdAccess::ReadWrite,
309+
OpenFlag::CloseOnExec | OpenFlag::NoCtty,
310+
Mode::empty(),
311+
);
312+
if result == Err(Errno::EINVAL) {
313+
// However, some systems do not support NoCtty. In that case,
314+
// we open /dev/tty without NoCtty.
315+
result = self.system.open(
316+
c"/dev/tty",
317+
OfdAccess::ReadWrite,
318+
OpenFlag::CloseOnExec.into(),
319+
Mode::empty(),
320+
);
321+
}
322+
result?
323+
};
324+
304325
let final_fd = self.system.move_fd_internal(first_fd);
305326
self.tty = final_fd.ok();
306327
final_fd

0 commit comments

Comments
 (0)