|
| 1 | +#[cfg(windows)] |
| 2 | +use std::io; |
1 | 3 | #[cfg(unix)]
|
2 | 4 | use std::os::unix::io::AsRawFd;
|
| 5 | +#[cfg(windows)] |
| 6 | +use std::os::windows::io::AsRawSocket; |
| 7 | + |
| 8 | +#[cfg(windows)] |
| 9 | +use winapi::shared::minwindef::DWORD; |
| 10 | +#[cfg(windows)] |
| 11 | +use winapi::um::handleapi::GetHandleInformation; |
| 12 | +#[cfg(windows)] |
| 13 | +use winapi::um::winbase::HANDLE_FLAG_INHERIT; |
3 | 14 |
|
4 | 15 | use socket2::{Domain, Socket, Type};
|
5 | 16 |
|
@@ -28,7 +39,7 @@ fn set_nonblocking() {
|
28 | 39 | ))]
|
29 | 40 | #[test]
|
30 | 41 | fn type_nonblocking() {
|
31 |
| - let ty = Type::Stream.nonblocking(); |
| 42 | + let ty = Type::STREAM.nonblocking(); |
32 | 43 | let socket = Socket::new(Domain::IPV4, ty, None).unwrap();
|
33 | 44 | assert_nonblocking(&socket, true);
|
34 | 45 | }
|
@@ -76,17 +87,58 @@ fn set_cloexec() {
|
76 | 87 | ))]
|
77 | 88 | #[test]
|
78 | 89 | fn type_cloexec() {
|
79 |
| - let ty = Type::Stream.cloexec(); |
| 90 | + let ty = Type::STREAM.cloexec(); |
80 | 91 | let socket = Socket::new(Domain::IPV4, ty, None).unwrap();
|
81 | 92 | assert_close_on_exec(&socket, true);
|
82 | 93 | }
|
83 | 94 |
|
84 | 95 | /// Assert that `CLOEXEC` is set on `socket`.
|
85 | 96 | #[cfg(unix)]
|
| 97 | +#[track_caller] |
86 | 98 | pub fn assert_close_on_exec<S>(socket: &S, want: bool)
|
87 | 99 | where
|
88 | 100 | S: AsRawFd,
|
89 | 101 | {
|
90 | 102 | let flags = unsafe { libc::fcntl(socket.as_raw_fd(), libc::F_GETFD) };
|
91 | 103 | assert_eq!(flags & libc::FD_CLOEXEC != 0, want, "CLOEXEC option");
|
92 | 104 | }
|
| 105 | + |
| 106 | +#[cfg(windows)] |
| 107 | +#[test] |
| 108 | +fn set_no_inherit() { |
| 109 | + let socket = Socket::new(Domain::IPV4, Type::STREAM, None).unwrap(); |
| 110 | + assert_flag_inherit(&socket, false); |
| 111 | + |
| 112 | + socket.set_no_inherit(true).unwrap(); |
| 113 | + assert_flag_inherit(&socket, true); |
| 114 | + |
| 115 | + socket.set_no_inherit(false).unwrap(); |
| 116 | + assert_flag_inherit(&socket, false); |
| 117 | +} |
| 118 | + |
| 119 | +#[cfg(all(feature = "all", windows))] |
| 120 | +#[test] |
| 121 | +fn type_no_inherit() { |
| 122 | + let ty = Type::STREAM.no_inherit(); |
| 123 | + let socket = Socket::new(Domain::IPV4, ty, None).unwrap(); |
| 124 | + assert_flag_inherit(&socket, true); |
| 125 | +} |
| 126 | + |
| 127 | +/// Assert that `FLAG_INHERIT` is set on `socket`. |
| 128 | +#[cfg(windows)] |
| 129 | +#[track_caller] |
| 130 | +pub fn assert_flag_inherit<S>(socket: &S, want: bool) |
| 131 | +where |
| 132 | + S: AsRawSocket, |
| 133 | +{ |
| 134 | + let mut flags: DWORD = 0; |
| 135 | + if unsafe { GetHandleInformation(socket.as_raw_socket() as _, &mut flags) } == 0 { |
| 136 | + let err = io::Error::last_os_error(); |
| 137 | + panic!("unexpected error: {}", err); |
| 138 | + } |
| 139 | + assert_eq!( |
| 140 | + flags & HANDLE_FLAG_INHERIT != 0, |
| 141 | + want, |
| 142 | + "FLAG_INHERIT option" |
| 143 | + ); |
| 144 | +} |
0 commit comments