From 880c664a24e0852dfc4d45f8b8acddbb7ccb74f8 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Tue, 7 Feb 2017 20:38:21 -0700 Subject: [PATCH] Better failure detection in getty --- src/bin/getty.rs | 60 +++++++++++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 21 deletions(-) diff --git a/src/bin/getty.rs b/src/bin/getty.rs index 09a46a37dc..7a84727a5d 100644 --- a/src/bin/getty.rs +++ b/src/bin/getty.rs @@ -3,7 +3,40 @@ extern crate syscall; use std::process::Command; -use std::{env, str}; +use std::{env, process, str}; +use std::io::{self, Write}; + +fn set_tty(tty: &str) -> syscall::Result<()> { + let stdin = syscall::open(tty, syscall::flag::O_RDONLY)?; + let stdout = syscall::open(tty, syscall::flag::O_WRONLY)?; + let stderr = syscall::open(tty, syscall::flag::O_WRONLY)?; + + syscall::dup2(stdin, 0, &[])?; + syscall::dup2(stdout, 1, &[])?; + syscall::dup2(stderr, 2, &[])?; + + let _ = syscall::close(stdin); + let _ = syscall::close(stdout); + let _ = syscall::close(stderr); + + Ok(()) +} + +fn daemon() { + loop { + if clear { + syscall::write(1, b"\x1Bc").unwrap(); + } + syscall::fsync(1).unwrap(); + match Command::new("login").spawn() { + Ok(mut child) => match child.wait() { + Ok(_status) => (), //println!("getty: waited for login: {:?}", status.code()), + Err(err) => panic!("getty: failed to wait for login: {}", err) + }, + Err(err) => panic!("getty: failed to execute login: {}", err) + } + } +} pub fn main() { let mut tty_option = None; @@ -20,13 +53,10 @@ pub fn main() { } if let Some(tty) = tty_option { - let _ = syscall::close(2); - let _ = syscall::close(1); - let _ = syscall::close(0); - - let _ = syscall::open(&tty, syscall::flag::O_RDWR); - let _ = syscall::open(&tty, syscall::flag::O_RDWR); - let _ = syscall::open(&tty, syscall::flag::O_RDWR); + if let Err(err) = set_tty(&tty) { + writeln!(io::stderr(), "getty: failed to open TTY {}: {}", tty, err).unwrap(); + process::exit(1); + } env::set_var("TTY", &tty); { @@ -44,19 +74,7 @@ pub fn main() { } if unsafe { syscall::clone(0).unwrap() } == 0 { - loop { - if clear { - syscall::write(1, b"\x1Bc").unwrap(); - } - syscall::fsync(1).unwrap(); - match Command::new("login").spawn() { - Ok(mut child) => match child.wait() { - Ok(_status) => (), //println!("getty: waited for login: {:?}", status.code()), - Err(err) => panic!("getty: failed to wait for login: {}", err) - }, - Err(err) => panic!("getty: failed to execute login: {}", err) - } - } + daemon(); } } else { panic!("getty: no tty provided");