|
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,43 @@ 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 |
| - |
702 |
| - if feat_atomic { |
703 |
| - ty |= flags.bits(); |
704 |
| - } |
705 |
| - |
706 |
| - // 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 | 698 |
|
719 |
| - if !feat_atomic { |
720 |
| - if flags.contains(SockFlag::SOCK_CLOEXEC) { |
721 |
| - try!(fcntl(res, F_SETFD(FdFlag::FD_CLOEXEC))); |
722 |
| - } |
| 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(); |
723 | 704 |
|
724 |
| - if flags.contains(SockFlag::SOCK_NONBLOCK) { |
725 |
| - try!(fcntl(res, F_SETFL(OFlag::O_NONBLOCK))); |
726 |
| - } |
727 |
| - } |
728 |
| - } |
| 705 | + let res = unsafe { libc::socket(domain as c_int, ty, protocol) }; |
729 | 706 |
|
730 |
| - Ok(res) |
| 707 | + Errno::result(res) |
731 | 708 | }
|
732 | 709 |
|
733 | 710 | /// Create a pair of connected sockets
|
734 | 711 | ///
|
735 | 712 | /// [Further reading](http://pubs.opengroup.org/onlinepubs/9699919799/functions/socketpair.html)
|
736 | 713 | pub fn socketpair<T: Into<Option<SockProtocol>>>(domain: AddressFamily, ty: SockType, protocol: T,
|
737 | 714 | flags: SockFlag) -> Result<(RawFd, RawFd)> {
|
738 |
| - let mut ty = ty as c_int; |
739 | 715 | let protocol = match protocol.into() {
|
740 | 716 | None => 0,
|
741 | 717 | Some(p) => p as c_int,
|
742 | 718 | };
|
743 |
| - let feat_atomic = features::socket_atomic_cloexec(); |
744 | 719 |
|
745 |
| - if feat_atomic { |
746 |
| - ty |= flags.bits(); |
747 |
| - } |
| 720 | + // SockFlags are usually embedded into `ty`, but we don't do that in `nix` because it's a |
| 721 | + // little easier to understand by separating it out. So we have to merge these bitfields |
| 722 | + // here. |
| 723 | + let mut ty = ty as c_int; |
| 724 | + ty |= flags.bits(); |
| 725 | + |
748 | 726 | 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 | 727 |
|
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 |
| - } |
| 728 | + let res = unsafe { libc::socketpair(domain as c_int, ty, protocol, fds.as_mut_ptr()) }; |
| 729 | + Errno::result(res)?; |
769 | 730 |
|
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 | 731 | Ok((fds[0], fds[1]))
|
777 | 732 | }
|
778 | 733 |
|
@@ -809,46 +764,14 @@ pub fn accept(sockfd: RawFd) -> Result<RawFd> {
|
809 | 764 | /// Accept a connection on a socket
|
810 | 765 | ///
|
811 | 766 | /// [Further reading](http://man7.org/linux/man-pages/man2/accept.2.html)
|
| 767 | +#[cfg(any(target_os = "android", |
| 768 | + target_os = "freebsd", |
| 769 | + target_os = "linux", |
| 770 | + target_os = "openbsd"))] |
812 | 771 | 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 |
| - } |
| 772 | + let res = unsafe { libc::accept4(sockfd, ptr::null_mut(), ptr::null_mut(), flags.bits()) }; |
849 | 773 |
|
850 |
| - |
851 |
| - Ok(res) |
| 774 | + Errno::result(res) |
852 | 775 | }
|
853 | 776 |
|
854 | 777 | /// Initiate a connection on a socket
|
|
0 commit comments