]>
Commit | Line | Data |
---|---|---|
fc512014 | 1 | use super::*; |
1b1a35ee | 2 | use crate::io::prelude::*; |
fc512014 | 3 | use crate::io::{self, ErrorKind, IoSlice, IoSliceMut}; |
923072b8 | 4 | #[cfg(any(target_os = "android", target_os = "linux"))] |
fc512014 | 5 | use crate::os::unix::io::AsRawFd; |
1b1a35ee XL |
6 | use crate::sys_common::io::test::tmpdir; |
7 | use crate::thread; | |
8 | use crate::time::Duration; | |
9 | ||
1b1a35ee XL |
10 | macro_rules! or_panic { |
11 | ($e:expr) => { | |
12 | match $e { | |
13 | Ok(e) => e, | |
5e7ed085 | 14 | Err(e) => panic!("{e}"), |
1b1a35ee XL |
15 | } |
16 | }; | |
17 | } | |
18 | ||
19 | #[test] | |
20 | fn basic() { | |
21 | let dir = tmpdir(); | |
22 | let socket_path = dir.path().join("sock"); | |
23 | let msg1 = b"hello"; | |
24 | let msg2 = b"world!"; | |
25 | ||
26 | let listener = or_panic!(UnixListener::bind(&socket_path)); | |
27 | let thread = thread::spawn(move || { | |
28 | let mut stream = or_panic!(listener.accept()).0; | |
29 | let mut buf = [0; 5]; | |
30 | or_panic!(stream.read(&mut buf)); | |
31 | assert_eq!(&msg1[..], &buf[..]); | |
32 | or_panic!(stream.write_all(msg2)); | |
33 | }); | |
34 | ||
35 | let mut stream = or_panic!(UnixStream::connect(&socket_path)); | |
36 | assert_eq!(Some(&*socket_path), stream.peer_addr().unwrap().as_pathname()); | |
37 | or_panic!(stream.write_all(msg1)); | |
38 | let mut buf = vec![]; | |
39 | or_panic!(stream.read_to_end(&mut buf)); | |
40 | assert_eq!(&msg2[..], &buf[..]); | |
41 | drop(stream); | |
42 | ||
43 | thread.join().unwrap(); | |
44 | } | |
45 | ||
46 | #[test] | |
47 | fn vectored() { | |
48 | let (mut s1, mut s2) = or_panic!(UnixStream::pair()); | |
49 | ||
50 | let len = or_panic!(s1.write_vectored(&[ | |
51 | IoSlice::new(b"hello"), | |
52 | IoSlice::new(b" "), | |
53 | IoSlice::new(b"world!") | |
54 | ],)); | |
55 | assert_eq!(len, 12); | |
56 | ||
57 | let mut buf1 = [0; 6]; | |
58 | let mut buf2 = [0; 7]; | |
59 | let len = | |
60 | or_panic!(s2.read_vectored(&mut [IoSliceMut::new(&mut buf1), IoSliceMut::new(&mut buf2)],)); | |
61 | assert_eq!(len, 12); | |
62 | assert_eq!(&buf1, b"hello "); | |
63 | assert_eq!(&buf2, b"world!\0"); | |
64 | } | |
65 | ||
66 | #[test] | |
67 | fn pair() { | |
68 | let msg1 = b"hello"; | |
69 | let msg2 = b"world!"; | |
70 | ||
71 | let (mut s1, mut s2) = or_panic!(UnixStream::pair()); | |
72 | let thread = thread::spawn(move || { | |
73 | // s1 must be moved in or the test will hang! | |
74 | let mut buf = [0; 5]; | |
75 | or_panic!(s1.read(&mut buf)); | |
76 | assert_eq!(&msg1[..], &buf[..]); | |
77 | or_panic!(s1.write_all(msg2)); | |
78 | }); | |
79 | ||
80 | or_panic!(s2.write_all(msg1)); | |
81 | let mut buf = vec![]; | |
82 | or_panic!(s2.read_to_end(&mut buf)); | |
83 | assert_eq!(&msg2[..], &buf[..]); | |
84 | drop(s2); | |
85 | ||
86 | thread.join().unwrap(); | |
87 | } | |
88 | ||
89 | #[test] | |
90 | fn try_clone() { | |
91 | let dir = tmpdir(); | |
92 | let socket_path = dir.path().join("sock"); | |
93 | let msg1 = b"hello"; | |
94 | let msg2 = b"world"; | |
95 | ||
96 | let listener = or_panic!(UnixListener::bind(&socket_path)); | |
97 | let thread = thread::spawn(move || { | |
98 | let mut stream = or_panic!(listener.accept()).0; | |
99 | or_panic!(stream.write_all(msg1)); | |
100 | or_panic!(stream.write_all(msg2)); | |
101 | }); | |
102 | ||
103 | let mut stream = or_panic!(UnixStream::connect(&socket_path)); | |
104 | let mut stream2 = or_panic!(stream.try_clone()); | |
105 | ||
106 | let mut buf = [0; 5]; | |
107 | or_panic!(stream.read(&mut buf)); | |
108 | assert_eq!(&msg1[..], &buf[..]); | |
109 | or_panic!(stream2.read(&mut buf)); | |
110 | assert_eq!(&msg2[..], &buf[..]); | |
111 | ||
112 | thread.join().unwrap(); | |
113 | } | |
114 | ||
115 | #[test] | |
116 | fn iter() { | |
117 | let dir = tmpdir(); | |
118 | let socket_path = dir.path().join("sock"); | |
119 | ||
120 | let listener = or_panic!(UnixListener::bind(&socket_path)); | |
121 | let thread = thread::spawn(move || { | |
122 | for stream in listener.incoming().take(2) { | |
123 | let mut stream = or_panic!(stream); | |
124 | let mut buf = [0]; | |
125 | or_panic!(stream.read(&mut buf)); | |
126 | } | |
127 | }); | |
128 | ||
129 | for _ in 0..2 { | |
130 | let mut stream = or_panic!(UnixStream::connect(&socket_path)); | |
131 | or_panic!(stream.write_all(&[0])); | |
132 | } | |
133 | ||
134 | thread.join().unwrap(); | |
135 | } | |
136 | ||
137 | #[test] | |
138 | fn long_path() { | |
139 | let dir = tmpdir(); | |
140 | let socket_path = dir.path().join( | |
141 | "asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfa\ | |
142 | sasdfasdfasdasdfasdfasdfadfasdfasdfasdfasdfasdf", | |
143 | ); | |
144 | match UnixStream::connect(&socket_path) { | |
145 | Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {} | |
5e7ed085 | 146 | Err(e) => panic!("unexpected error {e}"), |
1b1a35ee XL |
147 | Ok(_) => panic!("unexpected success"), |
148 | } | |
149 | ||
150 | match UnixListener::bind(&socket_path) { | |
151 | Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {} | |
5e7ed085 | 152 | Err(e) => panic!("unexpected error {e}"), |
1b1a35ee XL |
153 | Ok(_) => panic!("unexpected success"), |
154 | } | |
155 | ||
156 | match UnixDatagram::bind(&socket_path) { | |
157 | Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {} | |
5e7ed085 | 158 | Err(e) => panic!("unexpected error {e}"), |
1b1a35ee XL |
159 | Ok(_) => panic!("unexpected success"), |
160 | } | |
161 | } | |
162 | ||
163 | #[test] | |
164 | fn timeouts() { | |
165 | let dir = tmpdir(); | |
166 | let socket_path = dir.path().join("sock"); | |
167 | ||
168 | let _listener = or_panic!(UnixListener::bind(&socket_path)); | |
169 | ||
170 | let stream = or_panic!(UnixStream::connect(&socket_path)); | |
171 | let dur = Duration::new(15410, 0); | |
172 | ||
173 | assert_eq!(None, or_panic!(stream.read_timeout())); | |
174 | ||
175 | or_panic!(stream.set_read_timeout(Some(dur))); | |
176 | assert_eq!(Some(dur), or_panic!(stream.read_timeout())); | |
177 | ||
178 | assert_eq!(None, or_panic!(stream.write_timeout())); | |
179 | ||
180 | or_panic!(stream.set_write_timeout(Some(dur))); | |
181 | assert_eq!(Some(dur), or_panic!(stream.write_timeout())); | |
182 | ||
183 | or_panic!(stream.set_read_timeout(None)); | |
184 | assert_eq!(None, or_panic!(stream.read_timeout())); | |
185 | ||
186 | or_panic!(stream.set_write_timeout(None)); | |
187 | assert_eq!(None, or_panic!(stream.write_timeout())); | |
188 | } | |
189 | ||
190 | #[test] | |
191 | fn test_read_timeout() { | |
192 | let dir = tmpdir(); | |
193 | let socket_path = dir.path().join("sock"); | |
194 | ||
195 | let _listener = or_panic!(UnixListener::bind(&socket_path)); | |
196 | ||
197 | let mut stream = or_panic!(UnixStream::connect(&socket_path)); | |
198 | or_panic!(stream.set_read_timeout(Some(Duration::from_millis(1000)))); | |
199 | ||
200 | let mut buf = [0; 10]; | |
201 | let kind = stream.read_exact(&mut buf).err().expect("expected error").kind(); | |
202 | assert!( | |
203 | kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut, | |
204 | "unexpected_error: {:?}", | |
205 | kind | |
206 | ); | |
207 | } | |
208 | ||
209 | #[test] | |
210 | fn test_read_with_timeout() { | |
211 | let dir = tmpdir(); | |
212 | let socket_path = dir.path().join("sock"); | |
213 | ||
214 | let listener = or_panic!(UnixListener::bind(&socket_path)); | |
215 | ||
216 | let mut stream = or_panic!(UnixStream::connect(&socket_path)); | |
217 | or_panic!(stream.set_read_timeout(Some(Duration::from_millis(1000)))); | |
218 | ||
219 | let mut other_end = or_panic!(listener.accept()).0; | |
220 | or_panic!(other_end.write_all(b"hello world")); | |
221 | ||
222 | let mut buf = [0; 11]; | |
223 | or_panic!(stream.read(&mut buf)); | |
224 | assert_eq!(b"hello world", &buf[..]); | |
225 | ||
226 | let kind = stream.read_exact(&mut buf).err().expect("expected error").kind(); | |
227 | assert!( | |
228 | kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut, | |
229 | "unexpected_error: {:?}", | |
230 | kind | |
231 | ); | |
232 | } | |
233 | ||
234 | // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors | |
235 | // when passed zero Durations | |
236 | #[test] | |
237 | fn test_unix_stream_timeout_zero_duration() { | |
238 | let dir = tmpdir(); | |
239 | let socket_path = dir.path().join("sock"); | |
240 | ||
241 | let listener = or_panic!(UnixListener::bind(&socket_path)); | |
242 | let stream = or_panic!(UnixStream::connect(&socket_path)); | |
243 | ||
244 | let result = stream.set_write_timeout(Some(Duration::new(0, 0))); | |
245 | let err = result.unwrap_err(); | |
246 | assert_eq!(err.kind(), ErrorKind::InvalidInput); | |
247 | ||
248 | let result = stream.set_read_timeout(Some(Duration::new(0, 0))); | |
249 | let err = result.unwrap_err(); | |
250 | assert_eq!(err.kind(), ErrorKind::InvalidInput); | |
251 | ||
252 | drop(listener); | |
253 | } | |
254 | ||
255 | #[test] | |
256 | fn test_unix_datagram() { | |
257 | let dir = tmpdir(); | |
258 | let path1 = dir.path().join("sock1"); | |
259 | let path2 = dir.path().join("sock2"); | |
260 | ||
261 | let sock1 = or_panic!(UnixDatagram::bind(&path1)); | |
262 | let sock2 = or_panic!(UnixDatagram::bind(&path2)); | |
263 | ||
264 | let msg = b"hello world"; | |
265 | or_panic!(sock1.send_to(msg, &path2)); | |
266 | let mut buf = [0; 11]; | |
267 | or_panic!(sock2.recv_from(&mut buf)); | |
268 | assert_eq!(msg, &buf[..]); | |
269 | } | |
270 | ||
271 | #[test] | |
272 | fn test_unnamed_unix_datagram() { | |
273 | let dir = tmpdir(); | |
274 | let path1 = dir.path().join("sock1"); | |
275 | ||
276 | let sock1 = or_panic!(UnixDatagram::bind(&path1)); | |
277 | let sock2 = or_panic!(UnixDatagram::unbound()); | |
278 | ||
279 | let msg = b"hello world"; | |
280 | or_panic!(sock2.send_to(msg, &path1)); | |
281 | let mut buf = [0; 11]; | |
282 | let (usize, addr) = or_panic!(sock1.recv_from(&mut buf)); | |
283 | assert_eq!(usize, 11); | |
284 | assert!(addr.is_unnamed()); | |
285 | assert_eq!(msg, &buf[..]); | |
286 | } | |
287 | ||
c295e0f8 XL |
288 | #[test] |
289 | fn test_unix_datagram_connect_to_recv_addr() { | |
290 | let dir = tmpdir(); | |
291 | let path1 = dir.path().join("sock1"); | |
292 | let path2 = dir.path().join("sock2"); | |
293 | ||
294 | let sock1 = or_panic!(UnixDatagram::bind(&path1)); | |
295 | let sock2 = or_panic!(UnixDatagram::bind(&path2)); | |
296 | ||
297 | let msg = b"hello world"; | |
298 | let sock1_addr = or_panic!(sock1.local_addr()); | |
299 | or_panic!(sock2.send_to_addr(msg, &sock1_addr)); | |
300 | let mut buf = [0; 11]; | |
301 | let (_, addr) = or_panic!(sock1.recv_from(&mut buf)); | |
302 | ||
303 | let new_msg = b"hello back"; | |
304 | let mut new_buf = [0; 10]; | |
305 | or_panic!(sock2.connect_addr(&addr)); | |
306 | or_panic!(sock2.send(new_msg)); // set by connect_addr | |
307 | let usize = or_panic!(sock2.recv(&mut new_buf)); | |
308 | assert_eq!(usize, 10); | |
309 | assert_eq!(new_msg, &new_buf[..]); | |
310 | } | |
311 | ||
1b1a35ee XL |
312 | #[test] |
313 | fn test_connect_unix_datagram() { | |
314 | let dir = tmpdir(); | |
315 | let path1 = dir.path().join("sock1"); | |
316 | let path2 = dir.path().join("sock2"); | |
317 | ||
318 | let bsock1 = or_panic!(UnixDatagram::bind(&path1)); | |
319 | let bsock2 = or_panic!(UnixDatagram::bind(&path2)); | |
320 | let sock = or_panic!(UnixDatagram::unbound()); | |
321 | or_panic!(sock.connect(&path1)); | |
322 | ||
323 | // Check send() | |
324 | let msg = b"hello there"; | |
325 | or_panic!(sock.send(msg)); | |
326 | let mut buf = [0; 11]; | |
327 | let (usize, addr) = or_panic!(bsock1.recv_from(&mut buf)); | |
328 | assert_eq!(usize, 11); | |
329 | assert!(addr.is_unnamed()); | |
330 | assert_eq!(msg, &buf[..]); | |
331 | ||
332 | // Changing default socket works too | |
333 | or_panic!(sock.connect(&path2)); | |
334 | or_panic!(sock.send(msg)); | |
335 | or_panic!(bsock2.recv_from(&mut buf)); | |
336 | } | |
337 | ||
338 | #[test] | |
339 | fn test_unix_datagram_recv() { | |
340 | let dir = tmpdir(); | |
341 | let path1 = dir.path().join("sock1"); | |
342 | ||
343 | let sock1 = or_panic!(UnixDatagram::bind(&path1)); | |
344 | let sock2 = or_panic!(UnixDatagram::unbound()); | |
345 | or_panic!(sock2.connect(&path1)); | |
346 | ||
347 | let msg = b"hello world"; | |
348 | or_panic!(sock2.send(msg)); | |
349 | let mut buf = [0; 11]; | |
350 | let size = or_panic!(sock1.recv(&mut buf)); | |
351 | assert_eq!(size, 11); | |
352 | assert_eq!(msg, &buf[..]); | |
353 | } | |
354 | ||
355 | #[test] | |
356 | fn datagram_pair() { | |
357 | let msg1 = b"hello"; | |
358 | let msg2 = b"world!"; | |
359 | ||
360 | let (s1, s2) = or_panic!(UnixDatagram::pair()); | |
361 | let thread = thread::spawn(move || { | |
362 | // s1 must be moved in or the test will hang! | |
363 | let mut buf = [0; 5]; | |
364 | or_panic!(s1.recv(&mut buf)); | |
365 | assert_eq!(&msg1[..], &buf[..]); | |
366 | or_panic!(s1.send(msg2)); | |
367 | }); | |
368 | ||
369 | or_panic!(s2.send(msg1)); | |
370 | let mut buf = [0; 6]; | |
371 | or_panic!(s2.recv(&mut buf)); | |
372 | assert_eq!(&msg2[..], &buf[..]); | |
373 | drop(s2); | |
374 | ||
375 | thread.join().unwrap(); | |
376 | } | |
377 | ||
378 | // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors | |
379 | // when passed zero Durations | |
380 | #[test] | |
381 | fn test_unix_datagram_timeout_zero_duration() { | |
382 | let dir = tmpdir(); | |
383 | let path = dir.path().join("sock"); | |
384 | ||
385 | let datagram = or_panic!(UnixDatagram::bind(&path)); | |
386 | ||
387 | let result = datagram.set_write_timeout(Some(Duration::new(0, 0))); | |
388 | let err = result.unwrap_err(); | |
389 | assert_eq!(err.kind(), ErrorKind::InvalidInput); | |
390 | ||
391 | let result = datagram.set_read_timeout(Some(Duration::new(0, 0))); | |
392 | let err = result.unwrap_err(); | |
393 | assert_eq!(err.kind(), ErrorKind::InvalidInput); | |
394 | } | |
395 | ||
396 | #[test] | |
c295e0f8 | 397 | fn abstract_namespace_not_allowed_connect() { |
1b1a35ee XL |
398 | assert!(UnixStream::connect("\0asdf").is_err()); |
399 | } | |
400 | ||
c295e0f8 XL |
401 | #[cfg(any(target_os = "android", target_os = "linux"))] |
402 | #[test] | |
403 | fn test_abstract_stream_connect() { | |
404 | let msg1 = b"hello"; | |
405 | let msg2 = b"world"; | |
406 | ||
407 | let socket_addr = or_panic!(SocketAddr::from_abstract_namespace(b"namespace")); | |
408 | let listener = or_panic!(UnixListener::bind_addr(&socket_addr)); | |
409 | ||
410 | let thread = thread::spawn(move || { | |
411 | let mut stream = or_panic!(listener.accept()).0; | |
412 | let mut buf = [0; 5]; | |
413 | or_panic!(stream.read(&mut buf)); | |
414 | assert_eq!(&msg1[..], &buf[..]); | |
415 | or_panic!(stream.write_all(msg2)); | |
416 | }); | |
417 | ||
418 | let mut stream = or_panic!(UnixStream::connect_addr(&socket_addr)); | |
419 | ||
420 | let peer = or_panic!(stream.peer_addr()); | |
421 | assert_eq!(peer.as_abstract_namespace().unwrap(), b"namespace"); | |
422 | ||
423 | or_panic!(stream.write_all(msg1)); | |
424 | let mut buf = vec![]; | |
425 | or_panic!(stream.read_to_end(&mut buf)); | |
426 | assert_eq!(&msg2[..], &buf[..]); | |
427 | drop(stream); | |
428 | ||
429 | thread.join().unwrap(); | |
430 | } | |
431 | ||
432 | #[cfg(any(target_os = "android", target_os = "linux"))] | |
433 | #[test] | |
434 | fn test_abstract_stream_iter() { | |
435 | let addr = or_panic!(SocketAddr::from_abstract_namespace(b"hidden")); | |
436 | let listener = or_panic!(UnixListener::bind_addr(&addr)); | |
437 | ||
438 | let thread = thread::spawn(move || { | |
439 | for stream in listener.incoming().take(2) { | |
440 | let mut stream = or_panic!(stream); | |
441 | let mut buf = [0]; | |
442 | or_panic!(stream.read(&mut buf)); | |
443 | } | |
444 | }); | |
445 | ||
446 | for _ in 0..2 { | |
447 | let mut stream = or_panic!(UnixStream::connect_addr(&addr)); | |
448 | or_panic!(stream.write_all(&[0])); | |
449 | } | |
450 | ||
451 | thread.join().unwrap(); | |
452 | } | |
453 | ||
454 | #[cfg(any(target_os = "android", target_os = "linux"))] | |
455 | #[test] | |
456 | fn test_abstract_datagram_bind_send_to_addr() { | |
457 | let addr1 = or_panic!(SocketAddr::from_abstract_namespace(b"ns1")); | |
458 | let sock1 = or_panic!(UnixDatagram::bind_addr(&addr1)); | |
459 | ||
460 | let local = or_panic!(sock1.local_addr()); | |
461 | assert_eq!(local.as_abstract_namespace().unwrap(), b"ns1"); | |
462 | ||
463 | let addr2 = or_panic!(SocketAddr::from_abstract_namespace(b"ns2")); | |
464 | let sock2 = or_panic!(UnixDatagram::bind_addr(&addr2)); | |
465 | ||
466 | let msg = b"hello world"; | |
467 | or_panic!(sock1.send_to_addr(msg, &addr2)); | |
468 | let mut buf = [0; 11]; | |
469 | let (len, addr) = or_panic!(sock2.recv_from(&mut buf)); | |
470 | assert_eq!(msg, &buf[..]); | |
471 | assert_eq!(len, 11); | |
472 | assert_eq!(addr.as_abstract_namespace().unwrap(), b"ns1"); | |
473 | } | |
474 | ||
475 | #[cfg(any(target_os = "android", target_os = "linux"))] | |
476 | #[test] | |
477 | fn test_abstract_datagram_connect_addr() { | |
478 | let addr1 = or_panic!(SocketAddr::from_abstract_namespace(b"ns3")); | |
479 | let bsock1 = or_panic!(UnixDatagram::bind_addr(&addr1)); | |
480 | ||
481 | let sock = or_panic!(UnixDatagram::unbound()); | |
482 | or_panic!(sock.connect_addr(&addr1)); | |
483 | ||
484 | let msg = b"hello world"; | |
485 | or_panic!(sock.send(msg)); | |
486 | let mut buf = [0; 11]; | |
487 | let (len, addr) = or_panic!(bsock1.recv_from(&mut buf)); | |
488 | assert_eq!(len, 11); | |
489 | assert_eq!(addr.is_unnamed(), true); | |
490 | assert_eq!(msg, &buf[..]); | |
491 | ||
492 | let addr2 = or_panic!(SocketAddr::from_abstract_namespace(b"ns4")); | |
493 | let bsock2 = or_panic!(UnixDatagram::bind_addr(&addr2)); | |
494 | ||
495 | or_panic!(sock.connect_addr(&addr2)); | |
496 | or_panic!(sock.send(msg)); | |
497 | or_panic!(bsock2.recv_from(&mut buf)); | |
498 | } | |
499 | ||
500 | #[cfg(any(target_os = "android", target_os = "linux"))] | |
501 | #[test] | |
502 | fn test_abstract_namespace_too_long() { | |
503 | match SocketAddr::from_abstract_namespace( | |
504 | b"abcdefghijklmnopqrstuvwxyzabcdefghijklmn\ | |
505 | opqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghi\ | |
506 | jklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz", | |
507 | ) { | |
508 | Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {} | |
5e7ed085 | 509 | Err(e) => panic!("unexpected error {e}"), |
c295e0f8 XL |
510 | Ok(_) => panic!("unexpected success"), |
511 | } | |
512 | } | |
513 | ||
514 | #[cfg(any(target_os = "android", target_os = "linux"))] | |
515 | #[test] | |
516 | fn test_abstract_namespace_no_pathname_and_not_unnamed() { | |
517 | let namespace = b"local"; | |
518 | let addr = or_panic!(SocketAddr::from_abstract_namespace(&namespace[..])); | |
519 | assert_eq!(addr.as_pathname(), None); | |
520 | assert_eq!(addr.as_abstract_namespace(), Some(&namespace[..])); | |
521 | assert_eq!(addr.is_unnamed(), false); | |
522 | } | |
523 | ||
1b1a35ee XL |
524 | #[test] |
525 | fn test_unix_stream_peek() { | |
526 | let (txdone, rxdone) = crate::sync::mpsc::channel(); | |
527 | ||
528 | let dir = tmpdir(); | |
529 | let path = dir.path().join("sock"); | |
530 | ||
531 | let listener = or_panic!(UnixListener::bind(&path)); | |
532 | let thread = thread::spawn(move || { | |
533 | let mut stream = or_panic!(listener.accept()).0; | |
534 | or_panic!(stream.write_all(&[1, 3, 3, 7])); | |
535 | or_panic!(rxdone.recv()); | |
536 | }); | |
537 | ||
538 | let mut stream = or_panic!(UnixStream::connect(&path)); | |
539 | let mut buf = [0; 10]; | |
540 | for _ in 0..2 { | |
541 | assert_eq!(or_panic!(stream.peek(&mut buf)), 4); | |
542 | } | |
543 | assert_eq!(or_panic!(stream.read(&mut buf)), 4); | |
544 | ||
545 | or_panic!(stream.set_nonblocking(true)); | |
546 | match stream.peek(&mut buf) { | |
547 | Ok(_) => panic!("expected error"), | |
548 | Err(ref e) if e.kind() == ErrorKind::WouldBlock => {} | |
5e7ed085 | 549 | Err(e) => panic!("unexpected error: {e}"), |
1b1a35ee XL |
550 | } |
551 | ||
552 | or_panic!(txdone.send(())); | |
553 | thread.join().unwrap(); | |
554 | } | |
555 | ||
556 | #[test] | |
557 | fn test_unix_datagram_peek() { | |
558 | let dir = tmpdir(); | |
559 | let path1 = dir.path().join("sock"); | |
560 | ||
561 | let sock1 = or_panic!(UnixDatagram::bind(&path1)); | |
562 | let sock2 = or_panic!(UnixDatagram::unbound()); | |
563 | or_panic!(sock2.connect(&path1)); | |
564 | ||
565 | let msg = b"hello world"; | |
566 | or_panic!(sock2.send(msg)); | |
567 | for _ in 0..2 { | |
568 | let mut buf = [0; 11]; | |
569 | let size = or_panic!(sock1.peek(&mut buf)); | |
570 | assert_eq!(size, 11); | |
571 | assert_eq!(msg, &buf[..]); | |
572 | } | |
573 | ||
574 | let mut buf = [0; 11]; | |
575 | let size = or_panic!(sock1.recv(&mut buf)); | |
576 | assert_eq!(size, 11); | |
577 | assert_eq!(msg, &buf[..]); | |
578 | } | |
579 | ||
580 | #[test] | |
581 | fn test_unix_datagram_peek_from() { | |
582 | let dir = tmpdir(); | |
583 | let path1 = dir.path().join("sock"); | |
584 | ||
585 | let sock1 = or_panic!(UnixDatagram::bind(&path1)); | |
586 | let sock2 = or_panic!(UnixDatagram::unbound()); | |
587 | or_panic!(sock2.connect(&path1)); | |
588 | ||
589 | let msg = b"hello world"; | |
590 | or_panic!(sock2.send(msg)); | |
591 | for _ in 0..2 { | |
592 | let mut buf = [0; 11]; | |
593 | let (size, _) = or_panic!(sock1.peek_from(&mut buf)); | |
594 | assert_eq!(size, 11); | |
595 | assert_eq!(msg, &buf[..]); | |
596 | } | |
597 | ||
598 | let mut buf = [0; 11]; | |
599 | let size = or_panic!(sock1.recv(&mut buf)); | |
600 | assert_eq!(size, 11); | |
601 | assert_eq!(msg, &buf[..]); | |
602 | } | |
fc512014 | 603 | |
923072b8 | 604 | #[cfg(any(target_os = "android", target_os = "linux"))] |
fc512014 XL |
605 | #[test] |
606 | fn test_send_vectored_fds_unix_stream() { | |
607 | let (s1, s2) = or_panic!(UnixStream::pair()); | |
608 | ||
6a06907d XL |
609 | let buf1 = [1; 8]; |
610 | let bufs_send = &[IoSlice::new(&buf1[..])][..]; | |
fc512014 XL |
611 | |
612 | let mut ancillary1_buffer = [0; 128]; | |
613 | let mut ancillary1 = SocketAncillary::new(&mut ancillary1_buffer[..]); | |
614 | assert!(ancillary1.add_fds(&[s1.as_raw_fd()][..])); | |
615 | ||
6a06907d | 616 | let usize = or_panic!(s1.send_vectored_with_ancillary(&bufs_send, &mut ancillary1)); |
fc512014 XL |
617 | assert_eq!(usize, 8); |
618 | ||
619 | let mut buf2 = [0; 8]; | |
620 | let mut bufs_recv = &mut [IoSliceMut::new(&mut buf2[..])][..]; | |
621 | ||
622 | let mut ancillary2_buffer = [0; 128]; | |
623 | let mut ancillary2 = SocketAncillary::new(&mut ancillary2_buffer[..]); | |
624 | ||
625 | let usize = or_panic!(s2.recv_vectored_with_ancillary(&mut bufs_recv, &mut ancillary2)); | |
626 | assert_eq!(usize, 8); | |
627 | assert_eq!(buf1, buf2); | |
628 | ||
629 | let mut ancillary_data_vec = Vec::from_iter(ancillary2.messages()); | |
630 | assert_eq!(ancillary_data_vec.len(), 1); | |
631 | if let AncillaryData::ScmRights(scm_rights) = ancillary_data_vec.pop().unwrap().unwrap() { | |
632 | let fd_vec = Vec::from_iter(scm_rights); | |
633 | assert_eq!(fd_vec.len(), 1); | |
634 | unsafe { | |
635 | libc::close(fd_vec[0]); | |
636 | } | |
637 | } else { | |
638 | unreachable!("must be ScmRights"); | |
639 | } | |
640 | } | |
641 | ||
923072b8 | 642 | #[cfg(any(target_os = "android", target_os = "linux",))] |
fc512014 XL |
643 | #[test] |
644 | fn test_send_vectored_with_ancillary_to_unix_datagram() { | |
645 | fn getpid() -> libc::pid_t { | |
646 | unsafe { libc::getpid() } | |
647 | } | |
648 | ||
649 | fn getuid() -> libc::uid_t { | |
650 | unsafe { libc::getuid() } | |
651 | } | |
652 | ||
653 | fn getgid() -> libc::gid_t { | |
654 | unsafe { libc::getgid() } | |
655 | } | |
656 | ||
657 | let dir = tmpdir(); | |
658 | let path1 = dir.path().join("sock1"); | |
659 | let path2 = dir.path().join("sock2"); | |
660 | ||
661 | let bsock1 = or_panic!(UnixDatagram::bind(&path1)); | |
662 | let bsock2 = or_panic!(UnixDatagram::bind(&path2)); | |
663 | ||
664 | or_panic!(bsock2.set_passcred(true)); | |
665 | ||
6a06907d XL |
666 | let buf1 = [1; 8]; |
667 | let bufs_send = &[IoSlice::new(&buf1[..])][..]; | |
fc512014 XL |
668 | |
669 | let mut ancillary1_buffer = [0; 128]; | |
670 | let mut ancillary1 = SocketAncillary::new(&mut ancillary1_buffer[..]); | |
671 | let mut cred1 = SocketCred::new(); | |
672 | cred1.set_pid(getpid()); | |
673 | cred1.set_uid(getuid()); | |
674 | cred1.set_gid(getgid()); | |
675 | assert!(ancillary1.add_creds(&[cred1.clone()][..])); | |
676 | ||
677 | let usize = | |
6a06907d | 678 | or_panic!(bsock1.send_vectored_with_ancillary_to(&bufs_send, &mut ancillary1, &path2)); |
fc512014 XL |
679 | assert_eq!(usize, 8); |
680 | ||
681 | let mut buf2 = [0; 8]; | |
682 | let mut bufs_recv = &mut [IoSliceMut::new(&mut buf2[..])][..]; | |
683 | ||
684 | let mut ancillary2_buffer = [0; 128]; | |
685 | let mut ancillary2 = SocketAncillary::new(&mut ancillary2_buffer[..]); | |
686 | ||
687 | let (usize, truncated, _addr) = | |
688 | or_panic!(bsock2.recv_vectored_with_ancillary_from(&mut bufs_recv, &mut ancillary2)); | |
689 | assert_eq!(ancillary2.truncated(), false); | |
690 | assert_eq!(usize, 8); | |
691 | assert_eq!(truncated, false); | |
692 | assert_eq!(buf1, buf2); | |
693 | ||
694 | let mut ancillary_data_vec = Vec::from_iter(ancillary2.messages()); | |
695 | assert_eq!(ancillary_data_vec.len(), 1); | |
696 | if let AncillaryData::ScmCredentials(scm_credentials) = | |
697 | ancillary_data_vec.pop().unwrap().unwrap() | |
698 | { | |
699 | let cred_vec = Vec::from_iter(scm_credentials); | |
700 | assert_eq!(cred_vec.len(), 1); | |
701 | assert_eq!(cred1.get_pid(), cred_vec[0].get_pid()); | |
702 | assert_eq!(cred1.get_uid(), cred_vec[0].get_uid()); | |
703 | assert_eq!(cred1.get_gid(), cred_vec[0].get_gid()); | |
704 | } else { | |
705 | unreachable!("must be ScmCredentials"); | |
706 | } | |
707 | } | |
708 | ||
923072b8 | 709 | #[cfg(any(target_os = "android", target_os = "linux"))] |
fc512014 XL |
710 | #[test] |
711 | fn test_send_vectored_with_ancillary_unix_datagram() { | |
712 | let dir = tmpdir(); | |
713 | let path1 = dir.path().join("sock1"); | |
714 | let path2 = dir.path().join("sock2"); | |
715 | ||
716 | let bsock1 = or_panic!(UnixDatagram::bind(&path1)); | |
717 | let bsock2 = or_panic!(UnixDatagram::bind(&path2)); | |
718 | ||
6a06907d XL |
719 | let buf1 = [1; 8]; |
720 | let bufs_send = &[IoSlice::new(&buf1[..])][..]; | |
fc512014 XL |
721 | |
722 | let mut ancillary1_buffer = [0; 128]; | |
723 | let mut ancillary1 = SocketAncillary::new(&mut ancillary1_buffer[..]); | |
724 | assert!(ancillary1.add_fds(&[bsock1.as_raw_fd()][..])); | |
725 | ||
726 | or_panic!(bsock1.connect(&path2)); | |
6a06907d | 727 | let usize = or_panic!(bsock1.send_vectored_with_ancillary(&bufs_send, &mut ancillary1)); |
fc512014 XL |
728 | assert_eq!(usize, 8); |
729 | ||
730 | let mut buf2 = [0; 8]; | |
731 | let mut bufs_recv = &mut [IoSliceMut::new(&mut buf2[..])][..]; | |
732 | ||
733 | let mut ancillary2_buffer = [0; 128]; | |
734 | let mut ancillary2 = SocketAncillary::new(&mut ancillary2_buffer[..]); | |
735 | ||
736 | let (usize, truncated) = | |
737 | or_panic!(bsock2.recv_vectored_with_ancillary(&mut bufs_recv, &mut ancillary2)); | |
738 | assert_eq!(usize, 8); | |
739 | assert_eq!(truncated, false); | |
740 | assert_eq!(buf1, buf2); | |
741 | ||
742 | let mut ancillary_data_vec = Vec::from_iter(ancillary2.messages()); | |
743 | assert_eq!(ancillary_data_vec.len(), 1); | |
744 | if let AncillaryData::ScmRights(scm_rights) = ancillary_data_vec.pop().unwrap().unwrap() { | |
745 | let fd_vec = Vec::from_iter(scm_rights); | |
746 | assert_eq!(fd_vec.len(), 1); | |
747 | unsafe { | |
748 | libc::close(fd_vec[0]); | |
749 | } | |
750 | } else { | |
751 | unreachable!("must be ScmRights"); | |
752 | } | |
753 | } |