1
1
/*
2
- * Copyright (C) 2021-2022 The Aero Project Developers.
2
+ * Copyright (C) 2021-2022 The Aero Project Developers.
3
3
*
4
4
* This file is part of The Aero Project.
5
5
*
@@ -23,18 +23,29 @@ use std::os::fd::AsRawFd;
23
23
use std:: process:: Command ;
24
24
25
25
const TTY_PATH : & str = "/dev/tty" ;
26
+ const DEV_NULL : & str = "/dev/null" ;
26
27
27
- fn remove_cloexec ( file : & File ) {
28
- // By default rust automatically sets the close-on-exe flag to prevent
29
- // leaking file descriptors.
30
- //
31
- // OpenOptions::custom_flags() only allows insertion of flags and are
32
- // overwritten by the flags set by the standard library. So here, we
33
- // need to manually update the flags after opening the file.
34
- let fd = file. as_raw_fd ( ) ;
28
+ struct FileSet < const N : usize > ( [ File ; N ] ) ;
35
29
36
- unsafe {
37
- assert ! ( libc:: fcntl( fd, libc:: F_SETFD , 0 /* flags */ ) == 0 ) ;
30
+ impl < const N : usize > FileSet < N > {
31
+ fn new ( files : [ File ; N ] ) -> Self {
32
+ Self ( files)
33
+ }
34
+
35
+ fn remove_cloexec ( & self ) {
36
+ for file in self . 0 . iter ( ) {
37
+ // By default rust automatically sets the close-on-exe flag to prevent
38
+ // leaking file descriptors.
39
+ //
40
+ // OpenOptions::custom_flags() only allows insertion of flags and are
41
+ // overwritten by the flags set by the standard library. So here, we
42
+ // need to manually update the flags after opening the file.
43
+ let fd = file. as_raw_fd ( ) ;
44
+
45
+ unsafe {
46
+ assert ! ( libc:: fcntl( fd, libc:: F_SETFD , 0 /* flags */ ) == 0 ) ;
47
+ }
48
+ }
38
49
}
39
50
}
40
51
@@ -44,17 +55,21 @@ fn main() -> Result<(), Box<dyn Error>> {
44
55
let stdout = OpenOptions :: new ( ) . write ( true ) . open ( TTY_PATH ) ?; // fd=1
45
56
let stderr = OpenOptions :: new ( ) . write ( true ) . open ( TTY_PATH ) ?; // fd=2
46
57
47
- remove_cloexec ( & stdin) ;
48
- remove_cloexec ( & stdout) ;
49
- remove_cloexec ( & stderr) ;
58
+ {
59
+ let stdset = FileSet :: new ( [ stdin, stdout, stderr] ) ;
60
+ stdset. remove_cloexec ( ) ;
61
+
62
+ Command :: new ( "dhcpd" ) . spawn ( ) ?;
63
+ }
50
64
51
- Command :: new ( "dhcpd" ) . spawn ( ) ?;
65
+ // Swap the `/dev/tty` std{in,out,err} file descriptors with `/dev/null` to suppress the Xorg
66
+ // server logs.
67
+ let stdin = OpenOptions :: new ( ) . read ( true ) . open ( DEV_NULL ) ?; // fd=0
68
+ let stdout = OpenOptions :: new ( ) . write ( true ) . open ( DEV_NULL ) ?; // fd=1
69
+ let stderr = OpenOptions :: new ( ) . write ( true ) . open ( DEV_NULL ) ?; // fd=2
52
70
53
- // Close the std{in,out,err} file descriptors, since now we are going to
54
- // start an X session.
55
- drop ( stdin) ;
56
- drop ( stdout) ;
57
- drop ( stderr) ;
71
+ let stdset = FileSet :: new ( [ stdin, stdout, stderr] ) ;
72
+ stdset. remove_cloexec ( ) ;
58
73
59
74
Command :: new ( "startx" )
60
75
. env ( "RUST_BACKTRACE" , "full" )
0 commit comments