2 use crate::io
::prelude
::*;
3 use crate::io
::{self, ErrorKind, IoSlice, IoSliceMut}
;
6 target_os
= "dragonfly",
7 target_os
= "emscripten",
11 target_os
= "openbsd",
13 use crate::iter
::FromIterator
;
15 target_os
= "android",
16 target_os
= "dragonfly",
17 target_os
= "emscripten",
18 target_os
= "freebsd",
21 target_os
= "openbsd",
23 use crate::os
::unix
::io
::AsRawFd
;
24 use crate::sys_common
::io
::test
::tmpdir
;
26 use crate::time
::Duration
;
28 macro_rules
! or_panic
{
32 Err(e
) => panic
!("{}", e
),
40 let socket_path
= dir
.path().join("sock");
44 let listener
= or_panic
!(UnixListener
::bind(&socket_path
));
45 let thread
= thread
::spawn(move || {
46 let mut stream
= or_panic
!(listener
.accept()).0;
48 or_panic
!(stream
.read(&mut buf
));
49 assert_eq
!(&msg1
[..], &buf
[..]);
50 or_panic
!(stream
.write_all(msg2
));
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
));
57 or_panic
!(stream
.read_to_end(&mut buf
));
58 assert_eq
!(&msg2
[..], &buf
[..]);
61 thread
.join().unwrap();
66 let (mut s1
, mut s2
) = or_panic
!(UnixStream
::pair());
68 let len
= or_panic
!(s1
.write_vectored(&[
69 IoSlice
::new(b
"hello"),
71 IoSlice
::new(b
"world!")
75 let mut buf1
= [0; 6];
76 let mut buf2
= [0; 7];
78 or_panic
!(s2
.read_vectored(&mut [IoSliceMut
::new(&mut buf1
), IoSliceMut
::new(&mut buf2
)],));
80 assert_eq
!(&buf1
, b
"hello ");
81 assert_eq
!(&buf2
, b
"world!\0");
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!
93 or_panic
!(s1
.read(&mut buf
));
94 assert_eq
!(&msg1
[..], &buf
[..]);
95 or_panic
!(s1
.write_all(msg2
));
98 or_panic
!(s2
.write_all(msg1
));
100 or_panic
!(s2
.read_to_end(&mut buf
));
101 assert_eq
!(&msg2
[..], &buf
[..]);
104 thread
.join().unwrap();
110 let socket_path
= dir
.path().join("sock");
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
));
121 let mut stream
= or_panic
!(UnixStream
::connect(&socket_path
));
122 let mut stream2
= or_panic
!(stream
.try_clone());
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
[..]);
130 thread
.join().unwrap();
136 let socket_path
= dir
.path().join("sock");
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
);
143 or_panic
!(stream
.read(&mut buf
));
148 let mut stream
= or_panic
!(UnixStream
::connect(&socket_path
));
149 or_panic
!(stream
.write_all(&[0]));
152 thread
.join().unwrap();
158 let socket_path
= dir
.path().join(
159 "asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfa\
160 sasdfasdfasdasdfasdfasdfadfasdfasdfasdfasdfasdf",
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"),
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"),
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"),
184 let socket_path
= dir
.path().join("sock");
186 let _listener
= or_panic
!(UnixListener
::bind(&socket_path
));
188 let stream
= or_panic
!(UnixStream
::connect(&socket_path
));
189 let dur
= Duration
::new(15410, 0);
191 assert_eq
!(None
, or_panic
!(stream
.read_timeout()));
193 or_panic
!(stream
.set_read_timeout(Some(dur
)));
194 assert_eq
!(Some(dur
), or_panic
!(stream
.read_timeout()));
196 assert_eq
!(None
, or_panic
!(stream
.write_timeout()));
198 or_panic
!(stream
.set_write_timeout(Some(dur
)));
199 assert_eq
!(Some(dur
), or_panic
!(stream
.write_timeout()));
201 or_panic
!(stream
.set_read_timeout(None
));
202 assert_eq
!(None
, or_panic
!(stream
.read_timeout()));
204 or_panic
!(stream
.set_write_timeout(None
));
205 assert_eq
!(None
, or_panic
!(stream
.write_timeout()));
209 fn test_read_timeout() {
211 let socket_path
= dir
.path().join("sock");
213 let _listener
= or_panic
!(UnixListener
::bind(&socket_path
));
215 let mut stream
= or_panic
!(UnixStream
::connect(&socket_path
));
216 or_panic
!(stream
.set_read_timeout(Some(Duration
::from_millis(1000))));
218 let mut buf
= [0; 10];
219 let kind
= stream
.read_exact(&mut buf
).err().expect("expected error").kind();
221 kind
== ErrorKind
::WouldBlock
|| kind
== ErrorKind
::TimedOut
,
222 "unexpected_error: {:?}",
228 fn test_read_with_timeout() {
230 let socket_path
= dir
.path().join("sock");
232 let listener
= or_panic
!(UnixListener
::bind(&socket_path
));
234 let mut stream
= or_panic
!(UnixStream
::connect(&socket_path
));
235 or_panic
!(stream
.set_read_timeout(Some(Duration
::from_millis(1000))));
237 let mut other_end
= or_panic
!(listener
.accept()).0;
238 or_panic
!(other_end
.write_all(b
"hello world"));
240 let mut buf
= [0; 11];
241 or_panic
!(stream
.read(&mut buf
));
242 assert_eq
!(b
"hello world", &buf
[..]);
244 let kind
= stream
.read_exact(&mut buf
).err().expect("expected error").kind();
246 kind
== ErrorKind
::WouldBlock
|| kind
== ErrorKind
::TimedOut
,
247 "unexpected_error: {:?}",
252 // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors
253 // when passed zero Durations
255 fn test_unix_stream_timeout_zero_duration() {
257 let socket_path
= dir
.path().join("sock");
259 let listener
= or_panic
!(UnixListener
::bind(&socket_path
));
260 let stream
= or_panic
!(UnixStream
::connect(&socket_path
));
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
);
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
);
274 fn test_unix_datagram() {
276 let path1
= dir
.path().join("sock1");
277 let path2
= dir
.path().join("sock2");
279 let sock1
= or_panic
!(UnixDatagram
::bind(&path1
));
280 let sock2
= or_panic
!(UnixDatagram
::bind(&path2
));
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
[..]);
290 fn test_unnamed_unix_datagram() {
292 let path1
= dir
.path().join("sock1");
294 let sock1
= or_panic
!(UnixDatagram
::bind(&path1
));
295 let sock2
= or_panic
!(UnixDatagram
::unbound());
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
[..]);
307 fn test_connect_unix_datagram() {
309 let path1
= dir
.path().join("sock1");
310 let path2
= dir
.path().join("sock2");
312 let bsock1
= or_panic
!(UnixDatagram
::bind(&path1
));
313 let bsock2
= or_panic
!(UnixDatagram
::bind(&path2
));
314 let sock
= or_panic
!(UnixDatagram
::unbound());
315 or_panic
!(sock
.connect(&path1
));
318 let msg
= b
"hello there";
319 or_panic
!(sock
.send(msg
));
320 let mut buf
= [0; 11];
321 let (usize, addr
) = or_panic
!(bsock1
.recv_from(&mut buf
));
322 assert_eq
!(usize, 11);
323 assert
!(addr
.is_unnamed());
324 assert_eq
!(msg
, &buf
[..]);
326 // Changing default socket works too
327 or_panic
!(sock
.connect(&path2
));
328 or_panic
!(sock
.send(msg
));
329 or_panic
!(bsock2
.recv_from(&mut buf
));
333 fn test_unix_datagram_recv() {
335 let path1
= dir
.path().join("sock1");
337 let sock1
= or_panic
!(UnixDatagram
::bind(&path1
));
338 let sock2
= or_panic
!(UnixDatagram
::unbound());
339 or_panic
!(sock2
.connect(&path1
));
341 let msg
= b
"hello world";
342 or_panic
!(sock2
.send(msg
));
343 let mut buf
= [0; 11];
344 let size
= or_panic
!(sock1
.recv(&mut buf
));
345 assert_eq
!(size
, 11);
346 assert_eq
!(msg
, &buf
[..]);
352 let msg2
= b
"world!";
354 let (s1
, s2
) = or_panic
!(UnixDatagram
::pair());
355 let thread
= thread
::spawn(move || {
356 // s1 must be moved in or the test will hang!
357 let mut buf
= [0; 5];
358 or_panic
!(s1
.recv(&mut buf
));
359 assert_eq
!(&msg1
[..], &buf
[..]);
360 or_panic
!(s1
.send(msg2
));
363 or_panic
!(s2
.send(msg1
));
364 let mut buf
= [0; 6];
365 or_panic
!(s2
.recv(&mut buf
));
366 assert_eq
!(&msg2
[..], &buf
[..]);
369 thread
.join().unwrap();
372 // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors
373 // when passed zero Durations
375 fn test_unix_datagram_timeout_zero_duration() {
377 let path
= dir
.path().join("sock");
379 let datagram
= or_panic
!(UnixDatagram
::bind(&path
));
381 let result
= datagram
.set_write_timeout(Some(Duration
::new(0, 0)));
382 let err
= result
.unwrap_err();
383 assert_eq
!(err
.kind(), ErrorKind
::InvalidInput
);
385 let result
= datagram
.set_read_timeout(Some(Duration
::new(0, 0)));
386 let err
= result
.unwrap_err();
387 assert_eq
!(err
.kind(), ErrorKind
::InvalidInput
);
391 fn abstract_namespace_not_allowed() {
392 assert
!(UnixStream
::connect("\0asdf").is_err());
396 fn test_unix_stream_peek() {
397 let (txdone
, rxdone
) = crate::sync
::mpsc
::channel();
400 let path
= dir
.path().join("sock");
402 let listener
= or_panic
!(UnixListener
::bind(&path
));
403 let thread
= thread
::spawn(move || {
404 let mut stream
= or_panic
!(listener
.accept()).0;
405 or_panic
!(stream
.write_all(&[1, 3, 3, 7]));
406 or_panic
!(rxdone
.recv());
409 let mut stream
= or_panic
!(UnixStream
::connect(&path
));
410 let mut buf
= [0; 10];
412 assert_eq
!(or_panic
!(stream
.peek(&mut buf
)), 4);
414 assert_eq
!(or_panic
!(stream
.read(&mut buf
)), 4);
416 or_panic
!(stream
.set_nonblocking(true));
417 match stream
.peek(&mut buf
) {
418 Ok(_
) => panic
!("expected error"),
419 Err(ref e
) if e
.kind() == ErrorKind
::WouldBlock
=> {}
420 Err(e
) => panic
!("unexpected error: {}", e
),
423 or_panic
!(txdone
.send(()));
424 thread
.join().unwrap();
428 fn test_unix_datagram_peek() {
430 let path1
= dir
.path().join("sock");
432 let sock1
= or_panic
!(UnixDatagram
::bind(&path1
));
433 let sock2
= or_panic
!(UnixDatagram
::unbound());
434 or_panic
!(sock2
.connect(&path1
));
436 let msg
= b
"hello world";
437 or_panic
!(sock2
.send(msg
));
439 let mut buf
= [0; 11];
440 let size
= or_panic
!(sock1
.peek(&mut buf
));
441 assert_eq
!(size
, 11);
442 assert_eq
!(msg
, &buf
[..]);
445 let mut buf
= [0; 11];
446 let size
= or_panic
!(sock1
.recv(&mut buf
));
447 assert_eq
!(size
, 11);
448 assert_eq
!(msg
, &buf
[..]);
452 fn test_unix_datagram_peek_from() {
454 let path1
= dir
.path().join("sock");
456 let sock1
= or_panic
!(UnixDatagram
::bind(&path1
));
457 let sock2
= or_panic
!(UnixDatagram
::unbound());
458 or_panic
!(sock2
.connect(&path1
));
460 let msg
= b
"hello world";
461 or_panic
!(sock2
.send(msg
));
463 let mut buf
= [0; 11];
464 let (size
, _
) = or_panic
!(sock1
.peek_from(&mut buf
));
465 assert_eq
!(size
, 11);
466 assert_eq
!(msg
, &buf
[..]);
469 let mut buf
= [0; 11];
470 let size
= or_panic
!(sock1
.recv(&mut buf
));
471 assert_eq
!(size
, 11);
472 assert_eq
!(msg
, &buf
[..]);
476 target_os
= "android",
477 target_os
= "dragonfly",
478 target_os
= "emscripten",
479 target_os
= "freebsd",
481 target_os
= "netbsd",
482 target_os
= "openbsd",
485 fn test_send_vectored_fds_unix_stream() {
486 let (s1
, s2
) = or_panic
!(UnixStream
::pair());
489 let bufs_send
= &[IoSlice
::new(&buf1
[..])][..];
491 let mut ancillary1_buffer
= [0; 128];
492 let mut ancillary1
= SocketAncillary
::new(&mut ancillary1_buffer
[..]);
493 assert
!(ancillary1
.add_fds(&[s1
.as_raw_fd()][..]));
495 let usize = or_panic
!(s1
.send_vectored_with_ancillary(&bufs_send
, &mut ancillary1
));
496 assert_eq
!(usize, 8);
498 let mut buf2
= [0; 8];
499 let mut bufs_recv
= &mut [IoSliceMut
::new(&mut buf2
[..])][..];
501 let mut ancillary2_buffer
= [0; 128];
502 let mut ancillary2
= SocketAncillary
::new(&mut ancillary2_buffer
[..]);
504 let usize = or_panic
!(s2
.recv_vectored_with_ancillary(&mut bufs_recv
, &mut ancillary2
));
505 assert_eq
!(usize, 8);
506 assert_eq
!(buf1
, buf2
);
508 let mut ancillary_data_vec
= Vec
::from_iter(ancillary2
.messages());
509 assert_eq
!(ancillary_data_vec
.len(), 1);
510 if let AncillaryData
::ScmRights(scm_rights
) = ancillary_data_vec
.pop().unwrap().unwrap() {
511 let fd_vec
= Vec
::from_iter(scm_rights
);
512 assert_eq
!(fd_vec
.len(), 1);
514 libc
::close(fd_vec
[0]);
517 unreachable
!("must be ScmRights");
521 #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "linux",))]
523 fn test_send_vectored_with_ancillary_to_unix_datagram() {
524 fn getpid() -> libc
::pid_t
{
525 unsafe { libc::getpid() }
528 fn getuid() -> libc
::uid_t
{
529 unsafe { libc::getuid() }
532 fn getgid() -> libc
::gid_t
{
533 unsafe { libc::getgid() }
537 let path1
= dir
.path().join("sock1");
538 let path2
= dir
.path().join("sock2");
540 let bsock1
= or_panic
!(UnixDatagram
::bind(&path1
));
541 let bsock2
= or_panic
!(UnixDatagram
::bind(&path2
));
543 or_panic
!(bsock2
.set_passcred(true));
546 let bufs_send
= &[IoSlice
::new(&buf1
[..])][..];
548 let mut ancillary1_buffer
= [0; 128];
549 let mut ancillary1
= SocketAncillary
::new(&mut ancillary1_buffer
[..]);
550 let mut cred1
= SocketCred
::new();
551 cred1
.set_pid(getpid());
552 cred1
.set_uid(getuid());
553 cred1
.set_gid(getgid());
554 assert
!(ancillary1
.add_creds(&[cred1
.clone()][..]));
557 or_panic
!(bsock1
.send_vectored_with_ancillary_to(&bufs_send
, &mut ancillary1
, &path2
));
558 assert_eq
!(usize, 8);
560 let mut buf2
= [0; 8];
561 let mut bufs_recv
= &mut [IoSliceMut
::new(&mut buf2
[..])][..];
563 let mut ancillary2_buffer
= [0; 128];
564 let mut ancillary2
= SocketAncillary
::new(&mut ancillary2_buffer
[..]);
566 let (usize, truncated
, _addr
) =
567 or_panic
!(bsock2
.recv_vectored_with_ancillary_from(&mut bufs_recv
, &mut ancillary2
));
568 assert_eq
!(ancillary2
.truncated(), false);
569 assert_eq
!(usize, 8);
570 assert_eq
!(truncated
, false);
571 assert_eq
!(buf1
, buf2
);
573 let mut ancillary_data_vec
= Vec
::from_iter(ancillary2
.messages());
574 assert_eq
!(ancillary_data_vec
.len(), 1);
575 if let AncillaryData
::ScmCredentials(scm_credentials
) =
576 ancillary_data_vec
.pop().unwrap().unwrap()
578 let cred_vec
= Vec
::from_iter(scm_credentials
);
579 assert_eq
!(cred_vec
.len(), 1);
580 assert_eq
!(cred1
.get_pid(), cred_vec
[0].get_pid());
581 assert_eq
!(cred1
.get_uid(), cred_vec
[0].get_uid());
582 assert_eq
!(cred1
.get_gid(), cred_vec
[0].get_gid());
584 unreachable
!("must be ScmCredentials");
589 target_os
= "android",
590 target_os
= "dragonfly",
591 target_os
= "emscripten",
592 target_os
= "freebsd",
594 target_os
= "netbsd",
595 target_os
= "openbsd",
598 fn test_send_vectored_with_ancillary_unix_datagram() {
600 let path1
= dir
.path().join("sock1");
601 let path2
= dir
.path().join("sock2");
603 let bsock1
= or_panic
!(UnixDatagram
::bind(&path1
));
604 let bsock2
= or_panic
!(UnixDatagram
::bind(&path2
));
607 let bufs_send
= &[IoSlice
::new(&buf1
[..])][..];
609 let mut ancillary1_buffer
= [0; 128];
610 let mut ancillary1
= SocketAncillary
::new(&mut ancillary1_buffer
[..]);
611 assert
!(ancillary1
.add_fds(&[bsock1
.as_raw_fd()][..]));
613 or_panic
!(bsock1
.connect(&path2
));
614 let usize = or_panic
!(bsock1
.send_vectored_with_ancillary(&bufs_send
, &mut ancillary1
));
615 assert_eq
!(usize, 8);
617 let mut buf2
= [0; 8];
618 let mut bufs_recv
= &mut [IoSliceMut
::new(&mut buf2
[..])][..];
620 let mut ancillary2_buffer
= [0; 128];
621 let mut ancillary2
= SocketAncillary
::new(&mut ancillary2_buffer
[..]);
623 let (usize, truncated
) =
624 or_panic
!(bsock2
.recv_vectored_with_ancillary(&mut bufs_recv
, &mut ancillary2
));
625 assert_eq
!(usize, 8);
626 assert_eq
!(truncated
, false);
627 assert_eq
!(buf1
, buf2
);
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);
635 libc
::close(fd_vec
[0]);
638 unreachable
!("must be ScmRights");