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