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