Skip to content

Add links to OS documentation, attempt 3 #319

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Aug 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,56 @@ macro_rules! from {
};
}

/// Link to online documentation for (almost) all supported OSs.
#[rustfmt::skip]
macro_rules! man_links {
// Links to all OSs.
($syscall: tt ( $section: tt ) ) => {
concat!(
man_links!(__ intro),
man_links!(__ unix $syscall($section)),
man_links!(__ windows $syscall($section)),
)
};
// Links to Unix-like OSs.
(unix: $syscall: tt ( $section: tt ) ) => {
concat!(
man_links!(__ intro),
man_links!(__ unix $syscall($section)),
)
};
// Links to Windows only.
(windows: $syscall: tt ( $section: tt ) ) => {
concat!(
man_links!(__ intro),
man_links!(__ windows $syscall($section)),
)
};
// Internals.
(__ intro) => {
"\n\nAdditional documentation can be found in manual of the OS:\n\n"
};
// List for Unix-like OSs.
(__ unix $syscall: tt ( $section: tt ) ) => {
concat!(
" * DragonFly BSD: <https://man.dragonflybsd.org/?command=", stringify!($syscall), "&section=", stringify!($section), ">\n",
" * FreeBSD: <https://www.freebsd.org/cgi/man.cgi?query=", stringify!($syscall), "&sektion=", stringify!($section), ">\n",
" * Linux: <https://man7.org/linux/man-pages/man", stringify!($section), "/", stringify!($syscall), ".", stringify!($section), ".html>\n",
" * macOS: <https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/", stringify!($syscall), ".", stringify!($section), ".html> (archived, actually for iOS)\n",
" * NetBSD: <https://man.netbsd.org/", stringify!($syscall), ".", stringify!($section), ">\n",
" * OpenBSD: <https://man.openbsd.org/", stringify!($syscall), ".", stringify!($section), ">\n",
" * iOS: <https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/", stringify!($syscall), ".", stringify!($section), ".html> (archived)\n",
" * illumos: <https://illumos.org/man/3SOCKET/", stringify!($syscall), ">\n",
)
};
// List for Window (so just Windows).
(__ windows $syscall: tt ( $section: tt ) ) => {
concat!(
" * Windows: <https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-", stringify!($syscall), ">\n",
)
};
}

mod sockaddr;
mod socket;
mod sockref;
Expand Down
23 changes: 23 additions & 0 deletions src/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ impl Socket {
/// the socket is made non-inheritable.
///
/// [`Socket::new_raw`] can be used if you don't want these flags to be set.
#[doc = man_links!(socket(2))]
pub fn new(domain: Domain, ty: Type, protocol: Option<Protocol>) -> io::Result<Socket> {
let ty = set_common_type(ty);
Socket::new_raw(domain, ty, protocol).and_then(set_common_flags)
Expand All @@ -144,6 +145,7 @@ impl Socket {
///
/// This function sets the same flags as in done for [`Socket::new`],
/// [`Socket::pair_raw`] can be used if you don't want to set those flags.
#[doc = man_links!(unix: socketpair(2))]
#[cfg(any(doc, all(feature = "all", unix)))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "all", unix))))]
pub fn pair(
Expand Down Expand Up @@ -177,6 +179,7 @@ impl Socket {
///
/// This function directly corresponds to the `bind(2)` function on Windows
/// and Unix.
#[doc = man_links!(bind(2))]
pub fn bind(&self, address: &SockAddr) -> io::Result<()> {
sys::bind(self.as_raw(), address)
}
Expand All @@ -188,6 +191,7 @@ impl Socket {
///
/// An error will be returned if `listen` or `connect` has already been
/// called on this builder.
#[doc = man_links!(connect(2))]
///
/// # Notes
///
Expand Down Expand Up @@ -242,6 +246,7 @@ impl Socket {
///
/// An error will be returned if `listen` or `connect` has already been
/// called on this builder.
#[doc = man_links!(listen(2))]
pub fn listen(&self, backlog: c_int) -> io::Result<()> {
sys::listen(self.as_raw(), backlog)
}
Expand All @@ -253,6 +258,7 @@ impl Socket {
///
/// This function sets the same flags as in done for [`Socket::new`],
/// [`Socket::accept_raw`] can be used if you don't want to set those flags.
#[doc = man_links!(accept(2))]
pub fn accept(&self) -> io::Result<(Socket, SockAddr)> {
// Use `accept4` on platforms that support it.
#[cfg(any(
Expand Down Expand Up @@ -299,6 +305,10 @@ impl Socket {

/// Returns the socket address of the local half of this socket.
///
/// This function directly corresponds to the `getsockname(2)` function on
/// Windows and Unix.
#[doc = man_links!(getsockname(2))]
///
/// # Notes
///
/// Depending on the OS this may return an error if the socket is not
Expand All @@ -311,6 +321,10 @@ impl Socket {

/// Returns the socket address of the remote peer of this socket.
///
/// This function directly corresponds to the `getpeername(2)` function on
/// Windows and Unix.
#[doc = man_links!(getpeername(2))]
///
/// # Notes
///
/// This returns an error if the socket is not [`connect`ed].
Expand Down Expand Up @@ -359,6 +373,7 @@ impl Socket {
///
/// This function will cause all pending and future I/O on the specified
/// portions to return immediately with an appropriate value.
#[doc = man_links!(shutdown(2))]
pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
sys::shutdown(self.as_raw(), how)
}
Expand All @@ -368,6 +383,7 @@ impl Socket {
///
/// The [`connect`] method will connect this socket to a remote address.
/// This method might fail if the socket is not connected.
#[doc = man_links!(recv(2))]
///
/// [`connect`]: Socket::connect
///
Expand Down Expand Up @@ -419,6 +435,7 @@ impl Socket {
/// In addition to the number of bytes read, this function returns the flags
/// for the received message. See [`RecvFlags`] for more information about
/// the returned flags.
#[doc = man_links!(recvmsg(2))]
///
/// [`recv`]: Socket::recv
/// [`connect`]: Socket::connect
Expand Down Expand Up @@ -484,6 +501,7 @@ impl Socket {

/// Receives data from the socket. On success, returns the number of bytes
/// read and the address from whence the data came.
#[doc = man_links!(recvfrom(2))]
///
/// # Safety
///
Expand All @@ -510,6 +528,7 @@ impl Socket {
/// Receives data from the socket. Returns the amount of bytes read, the
/// [`RecvFlags`] and the remote address from the data is coming. Unlike
/// [`recv_from`] this allows passing multiple buffers.
#[doc = man_links!(recvmsg(2))]
///
/// [`recv_from`]: Socket::recv_from
///
Expand Down Expand Up @@ -573,6 +592,7 @@ impl Socket {
/// been connected.
///
/// On success returns the number of bytes that were sent.
#[doc = man_links!(send(2))]
pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
self.send_with_flags(buf, 0)
}
Expand All @@ -594,6 +614,7 @@ impl Socket {

/// Identical to [`send_vectored`] but allows for specification of arbitrary
/// flags to the underlying `sendmsg`/`WSASend` call.
#[doc = man_links!(sendmsg(2))]
///
/// [`send_vectored`]: Socket::send_vectored
#[cfg(not(target_os = "redox"))]
Expand Down Expand Up @@ -621,6 +642,7 @@ impl Socket {
/// number of bytes written.
///
/// This is typically used on UDP or datagram-oriented sockets.
#[doc = man_links!(sendto(2))]
pub fn send_to(&self, buf: &[u8], addr: &SockAddr) -> io::Result<usize> {
self.send_to_with_flags(buf, addr, 0)
}
Expand All @@ -640,6 +662,7 @@ impl Socket {

/// Send data to a peer listening on `addr`. Returns the amount of bytes
/// written.
#[doc = man_links!(sendmsg(2))]
#[cfg(not(target_os = "redox"))]
#[cfg_attr(docsrs, doc(cfg(not(target_os = "redox"))))]
pub fn send_to_vectored(&self, bufs: &[IoSlice<'_>], addr: &SockAddr) -> io::Result<usize> {
Expand Down
14 changes: 8 additions & 6 deletions src/sys/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,11 +397,13 @@ impl_debug!(
impl RecvFlags {
/// Check if the message terminates a record.
///
/// Not all socket types support the notion of records.
/// For socket types that do support it (such as [`SEQPACKET`][Type::SEQPACKET]),
/// a record is terminated by sending a message with the end-of-record flag set.
/// Not all socket types support the notion of records. For socket types
/// that do support it (such as [`SEQPACKET`]), a record is terminated by
/// sending a message with the end-of-record flag set.
///
/// On Unix this corresponds to the MSG_EOR flag.
///
/// [`SEQPACKET`]: Type::SEQPACKET
pub const fn is_end_of_record(self) -> bool {
self.0 & libc::MSG_EOR != 0
}
Expand Down Expand Up @@ -522,9 +524,7 @@ impl SockAddr {
}
.map(|(_, addr)| addr)
}
}

impl SockAddr {
/// Constructs a `SockAddr` with the family `AF_VSOCK` and the provided CID/port.
///
/// # Errors
Expand Down Expand Up @@ -1053,6 +1053,7 @@ impl crate::Socket {
/// This function will block the calling thread until a new connection is
/// established. When established, the corresponding `Socket` and the remote
/// peer's address will be returned.
#[doc = man_links!(unix: accept4(2))]
#[cfg(all(
feature = "all",
any(
Expand Down Expand Up @@ -1576,7 +1577,7 @@ impl crate::Socket {
/// If `interface` is `None`, the binding is removed. If the `interface`
/// index is not valid, an error is returned.
///
/// One can use `libc::if_nametoindex` to convert an interface alias to an
/// One can use [`libc::if_nametoindex`] to convert an interface alias to an
/// index.
#[cfg(all(feature = "all", target_vendor = "apple"))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "all", target_vendor = "apple"))))]
Expand Down Expand Up @@ -1806,6 +1807,7 @@ impl crate::Socket {
/// Different OSs support different kinds of `file`s, see the OS
/// documentation for what kind of files are supported. Generally *regular*
/// files are supported by all OSs.
#[doc = man_links!(unix: sendfile(2))]
///
/// The `offset` is the absolute offset into the `file` to use as starting
/// point.
Expand Down
4 changes: 2 additions & 2 deletions tests/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1183,10 +1183,10 @@ test!(IPv4 recv_tos, set_recv_tos(true));
test!(IPv4 broadcast, set_broadcast(true));

test!(IPv6 unicast_hops_v6, set_unicast_hops_v6(20));
#[cfg(not(any(windows, any(target_os = "dragonfly", target_os = "freebsd"))))]
#[cfg(not(any(windows, target_os = "dragonfly", target_os = "freebsd")))]
test!(IPv6 only_v6, set_only_v6(true));
// IPv6 socket are already IPv6 only on FreeBSD and Windows.
#[cfg(any(windows, any(target_os = "freebsd")))]
#[cfg(any(windows, target_os = "freebsd"))]
test!(IPv6 only_v6, set_only_v6(false));

#[cfg(all(
Expand Down