|
3 | 3 | //! [Further reading](http://man7.org/linux/man-pages/man7/socket.7.html) |
4 | 4 | use {Error, Result}; |
5 | 5 | use errno::Errno; |
6 | | -use features; |
7 | 6 | use libc::{self, c_void, c_int, socklen_t, size_t}; |
8 | 7 | use std::{fmt, mem, ptr, slice}; |
9 | 8 | use std::os::unix::io::RawFd; |
@@ -692,87 +691,44 @@ pub fn recvmsg<'a, T>(fd: RawFd, iov: &[IoVec<&mut [u8]>], cmsg_buffer: Option<& |
692 | 691 | /// |
693 | 692 | /// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html) |
694 | 693 | pub fn socket<T: Into<Option<SockProtocol>>>(domain: AddressFamily, ty: SockType, flags: SockFlag, protocol: T) -> Result<RawFd> { |
695 | | - let mut ty = ty as c_int; |
696 | 694 | let protocol = match protocol.into() { |
697 | 695 | None => 0, |
698 | 696 | Some(p) => p as c_int, |
699 | 697 | }; |
700 | | - let feat_atomic = features::socket_atomic_cloexec(); |
701 | 698 |
|
702 | | - if feat_atomic { |
703 | | - ty |= flags.bits(); |
704 | | - } |
| 699 | + // SockFlags are usually embedded into `ty`, but we don't do that in `nix` because it's a |
| 700 | + // little easier to understand by separating it out. So we have to merge these bitfields |
| 701 | + // here. |
| 702 | + let mut ty = ty as c_int; |
| 703 | + ty |= flags.bits(); |
705 | 704 |
|
706 | 705 | // TODO: Check the kernel version |
707 | | - let res = try!(Errno::result(unsafe { libc::socket(domain as c_int, ty, protocol) })); |
708 | | - |
709 | | - #[cfg(any(target_os = "android", |
710 | | - target_os = "dragonfly", |
711 | | - target_os = "freebsd", |
712 | | - target_os = "linux", |
713 | | - target_os = "netbsd", |
714 | | - target_os = "openbsd"))] |
715 | | - { |
716 | | - use fcntl::{fcntl, FdFlag, OFlag}; |
717 | | - use fcntl::FcntlArg::{F_SETFD, F_SETFL}; |
718 | | - |
719 | | - if !feat_atomic { |
720 | | - if flags.contains(SockFlag::SOCK_CLOEXEC) { |
721 | | - try!(fcntl(res, F_SETFD(FdFlag::FD_CLOEXEC))); |
722 | | - } |
723 | | - |
724 | | - if flags.contains(SockFlag::SOCK_NONBLOCK) { |
725 | | - try!(fcntl(res, F_SETFL(OFlag::O_NONBLOCK))); |
726 | | - } |
727 | | - } |
728 | | - } |
| 706 | + let res = unsafe { libc::socket(domain as c_int, ty, protocol) }; |
729 | 707 |
|
730 | | - Ok(res) |
| 708 | + Errno::result(res) |
731 | 709 | } |
732 | 710 |
|
733 | 711 | /// Create a pair of connected sockets |
734 | 712 | /// |
735 | 713 | /// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/socketpair.html) |
736 | 714 | pub fn socketpair<T: Into<Option<SockProtocol>>>(domain: AddressFamily, ty: SockType, protocol: T, |
737 | 715 | flags: SockFlag) -> Result<(RawFd, RawFd)> { |
738 | | - let mut ty = ty as c_int; |
739 | 716 | let protocol = match protocol.into() { |
740 | 717 | None => 0, |
741 | 718 | Some(p) => p as c_int, |
742 | 719 | }; |
743 | | - let feat_atomic = features::socket_atomic_cloexec(); |
744 | 720 |
|
745 | | - if feat_atomic { |
746 | | - ty |= flags.bits(); |
747 | | - } |
| 721 | + // SockFlags are usually embedded into `ty`, but we don't do that in `nix` because it's a |
| 722 | + // little easier to understand by separating it out. So we have to merge these bitfields |
| 723 | + // here. |
| 724 | + let mut ty = ty as c_int; |
| 725 | + ty |= flags.bits(); |
| 726 | + |
748 | 727 | let mut fds = [-1, -1]; |
749 | | - let res = unsafe { |
750 | | - libc::socketpair(domain as c_int, ty, protocol, fds.as_mut_ptr()) |
751 | | - }; |
752 | | - try!(Errno::result(res)); |
753 | | - |
754 | | - #[cfg(any(target_os = "android", |
755 | | - target_os = "dragonfly", |
756 | | - target_os = "freebsd", |
757 | | - target_os = "linux", |
758 | | - target_os = "netbsd", |
759 | | - target_os = "openbsd"))] |
760 | | - { |
761 | | - use fcntl::{fcntl, FdFlag, OFlag}; |
762 | | - use fcntl::FcntlArg::{F_SETFD, F_SETFL}; |
763 | 728 |
|
764 | | - if !feat_atomic { |
765 | | - if flags.contains(SockFlag::SOCK_CLOEXEC) { |
766 | | - try!(fcntl(fds[0], F_SETFD(FdFlag::FD_CLOEXEC))); |
767 | | - try!(fcntl(fds[1], F_SETFD(FdFlag::FD_CLOEXEC))); |
768 | | - } |
| 729 | + let res = unsafe { libc::socketpair(domain as c_int, ty, protocol, fds.as_mut_ptr()) }; |
| 730 | + Errno::result(res)?; |
769 | 731 |
|
770 | | - if flags.contains(SockFlag::SOCK_NONBLOCK) { |
771 | | - try!(fcntl(fds[0], F_SETFL(OFlag::O_NONBLOCK))); |
772 | | - try!(fcntl(fds[1], F_SETFL(OFlag::O_NONBLOCK))); |
773 | | - } |
774 | | - } |
775 | | - } |
776 | 732 | Ok((fds[0], fds[1])) |
777 | 733 | } |
778 | 734 |
|
@@ -810,45 +766,9 @@ pub fn accept(sockfd: RawFd) -> Result<RawFd> { |
810 | 766 | /// |
811 | 767 | /// [Further reading](http://man7.org/linux/man-pages/man2/accept.2.html) |
812 | 768 | pub fn accept4(sockfd: RawFd, flags: SockFlag) -> Result<RawFd> { |
813 | | - accept4_polyfill(sockfd, flags) |
814 | | -} |
815 | | - |
816 | | -#[inline] |
817 | | -fn accept4_polyfill(sockfd: RawFd, flags: SockFlag) -> Result<RawFd> { |
818 | | - let res = try!(Errno::result(unsafe { libc::accept(sockfd, ptr::null_mut(), ptr::null_mut()) })); |
819 | | - |
820 | | - #[cfg(any(target_os = "android", |
821 | | - target_os = "dragonfly", |
822 | | - target_os = "freebsd", |
823 | | - target_os = "linux", |
824 | | - target_os = "netbsd", |
825 | | - target_os = "openbsd"))] |
826 | | - { |
827 | | - use fcntl::{fcntl, FdFlag, OFlag}; |
828 | | - use fcntl::FcntlArg::{F_SETFD, F_SETFL}; |
829 | | - |
830 | | - if flags.contains(SockFlag::SOCK_CLOEXEC) { |
831 | | - try!(fcntl(res, F_SETFD(FdFlag::FD_CLOEXEC))); |
832 | | - } |
833 | | - |
834 | | - if flags.contains(SockFlag::SOCK_NONBLOCK) { |
835 | | - try!(fcntl(res, F_SETFL(OFlag::O_NONBLOCK))); |
836 | | - } |
837 | | - } |
838 | | - |
839 | | - // Disable unused variable warning on some platforms |
840 | | - #[cfg(not(any(target_os = "android", |
841 | | - target_os = "dragonfly", |
842 | | - target_os = "freebsd", |
843 | | - target_os = "linux", |
844 | | - target_os = "netbsd", |
845 | | - target_os = "openbsd")))] |
846 | | - { |
847 | | - let _ = flags; |
848 | | - } |
| 769 | + let res = unsafe { libc::accept4(sockfd, ptr::null_mut(), ptr::null_mut(), flags.bits()) }; |
849 | 770 |
|
850 | | - |
851 | | - Ok(res) |
| 771 | + Errno::result(res) |
852 | 772 | } |
853 | 773 |
|
854 | 774 | /// Initiate a connection on a socket |
|
0 commit comments