]> git.proxmox.com Git - rustc.git/blob - library/std/src/os/unix/net/tests.rs
New upstream version 1.62.1+dfsg1
[rustc.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 }