diff options
Diffstat (limited to 'libphobos/src/std/socket.d')
-rw-r--r-- | libphobos/src/std/socket.d | 695 |
1 files changed, 432 insertions, 263 deletions
diff --git a/libphobos/src/std/socket.d b/libphobos/src/std/socket.d index d7de153..be0aeba 100644 --- a/libphobos/src/std/socket.d +++ b/libphobos/src/std/socket.d @@ -1,32 +1,12 @@ // Written in the D programming language +// NOTE: When working on this module, be sure to run tests with -debug=std_socket +// E.g.: dmd -version=StdUnittest -debug=std_socket -unittest -main -run socket +// This will enable some tests which are too slow or flaky to run as part of CI. + /* Copyright (C) 2004-2011 Christopher E. Miller - Boost Software License - Version 1.0 - August 17th, 2003 - - Permission is hereby granted, free of charge, to any person or organization - obtaining a copy of the software and accompanying documentation covered by - this license (the "Software") to use, reproduce, display, distribute, - execute, and transmit the Software, and to prepare derivative works of the - Software, and to permit third-parties to whom the Software is furnished to - do so, all subject to the following: - - The copyright notices in the Software and this entire statement, including - the above license grant, this restriction and the following disclaimer, - must be included in all copies of the Software, in whole or in part, and - all derivative works of the Software, unless such copies or derivative - works are solely in the form of machine-executable object code generated by - a source language processor. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - socket.d 1.4 Jan 2011 @@ -39,7 +19,7 @@ * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). * Authors: Christopher E. Miller, $(HTTP klickverbot.at, David Nadlinger), * $(HTTP thecybershadow.net, Vladimir Panteleev) - * Source: $(PHOBOSSRC std/_socket.d) + * Source: $(PHOBOSSRC std/socket.d) */ module std.socket; @@ -52,6 +32,12 @@ import std.exception; import std.internal.cstring; +version (iOS) + version = iOSDerived; +else version (TVOS) + version = iOSDerived; +else version (WatchOS) + version = iOSDerived; @safe: @@ -60,7 +46,7 @@ version (Windows) pragma (lib, "ws2_32.lib"); pragma (lib, "wsock32.lib"); - import core.sys.windows.windows, std.windows.syserror; + import core.sys.windows.winbase, std.windows.syserror; public import core.sys.windows.winsock2; private alias _ctimeval = core.sys.windows.winsock2.timeval; private alias _clinger = core.sys.windows.winsock2.linger; @@ -100,7 +86,7 @@ else version (Posix) import core.stdc.errno; - enum socket_t : int32_t { init = -1 } + enum socket_t : int32_t { _init = -1 } private const int _SOCKET_ERROR = -1; private enum : int @@ -117,30 +103,28 @@ else version (Posix) } else { - static assert(0); // No socket support yet. + static assert(0, "No socket support for this platform yet."); } -version (unittest) +version (StdUnittest) { - static assert(is(uint32_t == uint)); - static assert(is(uint16_t == ushort)); - - import std.stdio : writefln; - // Print a message on exception instead of failing the unittest. private void softUnittest(void delegate() @safe test, int line = __LINE__) @trusted { - try + debug (std_socket) test(); - catch (Throwable e) + else { - writefln(" --- std.socket(%d) test fails depending on environment ---", line); - writefln(" (%s)", e); + import std.stdio : writefln; + try + test(); + catch (Throwable e) + writefln("Ignoring std.socket(%d) test failure (likely caused by flaky environment): %s", line, e.msg); } } } -/// Base exception thrown by $(D std.socket). +/// Base exception thrown by `std.socket`. class SocketException: Exception { mixin basicExceptionCtors; @@ -262,17 +246,29 @@ class SocketFeatureException: SocketException /** * Returns: - * $(D true) if the last socket operation failed because the socket - * was in non-blocking mode and the operation would have blocked. + * `true` if the last socket operation failed because the socket + * was in non-blocking mode and the operation would have blocked, + * or if the socket is in blocking mode and set a SNDTIMEO or RCVTIMEO, + * and the operation timed out. */ bool wouldHaveBlocked() nothrow @nogc { version (Windows) - return _lasterr() == WSAEWOULDBLOCK; + return _lasterr() == WSAEWOULDBLOCK || _lasterr() == WSAETIMEDOUT; else version (Posix) return _lasterr() == EAGAIN; else - static assert(0); + static assert(0, "No socket support for this platform yet."); +} + +@safe unittest +{ + auto sockets = socketPair(); + auto s = sockets[0]; + s.setOption(SocketOptionLevel.SOCKET, SocketOption.RCVTIMEO, dur!"msecs"(10)); + ubyte[] buffer = new ubyte[](16); + auto rec = s.receive(buffer); + assert(rec == -1 && wouldHaveBlocked()); } @@ -329,7 +325,7 @@ shared static ~this() @system nothrow @nogc /** * The communication domain used to resolve an address. */ -enum AddressFamily: int +enum AddressFamily: ushort { UNSPEC = AF_UNSPEC, /// Unspecified address family UNIX = AF_UNIX, /// Local communication @@ -372,7 +368,7 @@ enum ProtocolType: int /** - * $(D Protocol) is a class for retrieving protocol information. + * `Protocol` is a class for retrieving protocol information. * * Example: * --- @@ -424,7 +420,7 @@ class Protocol } /** Returns: false on failure */ - bool getProtocolByName(in char[] name) @trusted nothrow + bool getProtocolByName(scope const(char)[] name) @trusted nothrow { protoent* proto; proto = getprotobyname(name.tempCString()); @@ -454,6 +450,7 @@ class Protocol version (CRuntime_Bionic) {} else @safe unittest { + // import std.stdio : writefln; softUnittest({ Protocol proto = new Protocol; assert(proto.getProtocolByType(ProtocolType.TCP)); @@ -470,7 +467,7 @@ version (CRuntime_Bionic) {} else /** - * $(D Service) is a class for retrieving service information. + * `Service` is a class for retrieving service information. * * Example: * --- @@ -529,7 +526,7 @@ class Service * If a protocol name is omitted, any protocol will be matched. * Returns: false on failure. */ - bool getServiceByName(in char[] name, in char[] protocolName = null) @trusted nothrow + bool getServiceByName(scope const(char)[] name, scope const(char)[] protocolName = null) @trusted nothrow { servent* serv; serv = getservbyname(name.tempCString(), protocolName.tempCString()); @@ -541,7 +538,7 @@ class Service /// ditto - bool getServiceByPort(ushort port, in char[] protocolName = null) @trusted nothrow + bool getServiceByPort(ushort port, scope const(char)[] protocolName = null) @trusted nothrow { servent* serv; serv = getservbyport(port, protocolName.tempCString()); @@ -555,6 +552,7 @@ class Service @safe unittest { + import std.stdio : writefln; softUnittest({ Service serv = new Service; if (serv.getServiceByName("epmap", "tcp")) @@ -710,7 +708,7 @@ class InternetHost * Resolve host name. * Returns: false if unable to resolve. */ - bool getHostByName(in char[] name) @trusted + bool getHostByName(scope const(char)[] name) @trusted { static if (is(typeof(gethostbyname_r))) { @@ -760,7 +758,7 @@ class InternetHost * dotted-decimal form $(I a.b.c.d). * Returns: false if unable to resolve. */ - bool getHostByAddr(in char[] addr) @trusted + bool getHostByAddr(scope const(char)[] addr) @trusted { return getHost!q{ auto x = inet_addr(param.tempCString()); @@ -799,30 +797,30 @@ class InternetHost } -/// Holds information about a socket _address retrieved by $(D getAddressInfo). +/// Holds information about a socket _address retrieved by `getAddressInfo`. struct AddressInfo { AddressFamily family; /// Address _family SocketType type; /// Socket _type ProtocolType protocol; /// Protocol Address address; /// Socket _address - string canonicalName; /// Canonical name, when $(D AddressInfoFlags.CANONNAME) is used. + string canonicalName; /// Canonical name, when `AddressInfoFlags.CANONNAME` is used. } /** * A subset of flags supported on all platforms with getaddrinfo. - * Specifies option flags for $(D getAddressInfo). + * Specifies option flags for `getAddressInfo`. */ enum AddressInfoFlags: int { - /// The resulting addresses will be used in a call to $(D Socket.bind). + /// The resulting addresses will be used in a call to `Socket.bind`. PASSIVE = AI_PASSIVE, - /// The canonical name is returned in $(D canonicalName) member in the first $(D AddressInfo). + /// The canonical name is returned in `canonicalName` member in the first `AddressInfo`. CANONNAME = AI_CANONNAME, /** - * The $(D node) parameter passed to $(D getAddressInfo) must be a numeric string. + * The `node` parameter passed to `getAddressInfo` must be a numeric string. * This will suppress any potentially lengthy network host address lookups. */ NUMERICHOST = AI_NUMERICHOST, @@ -849,21 +847,21 @@ private string formatGaiError(int err) @trusted /** * Provides _protocol-independent translation from host names to socket * addresses. If advanced functionality is not required, consider using - * $(D getAddress) for compatibility with older systems. + * `getAddress` for compatibility with older systems. * - * Returns: Array with one $(D AddressInfo) per socket address. + * Returns: Array with one `AddressInfo` per socket address. * - * Throws: $(D SocketOSException) on failure, or $(D SocketFeatureException) + * Throws: `SocketOSException` on failure, or `SocketFeatureException` * if this functionality is not available on the current system. * * Params: * node = string containing host name or numeric address * options = optional additional parameters, identified by type: - * $(UL $(LI $(D string) - service name or port number) - * $(LI $(D AddressInfoFlags) - option flags) - * $(LI $(D AddressFamily) - address family to filter by) - * $(LI $(D SocketType) - socket type to filter by) - * $(LI $(D ProtocolType) - protocol to filter by)) + * $(UL $(LI `string` - service name or port number) + * $(LI `AddressInfoFlags` - option flags) + * $(LI `AddressFamily` - address family to filter by) + * $(LI `SocketType` - socket type to filter by) + * $(LI `ProtocolType` - protocol to filter by)) * * Example: * --- @@ -898,16 +896,16 @@ private string formatGaiError(int err) @trusted * AddressFamily.INET6); * --- */ -AddressInfo[] getAddressInfo(T...)(in char[] node, T options) +AddressInfo[] getAddressInfo(T...)(scope const(char)[] node, scope T options) { const(char)[] service = null; addrinfo hints; hints.ai_family = AF_UNSPEC; - foreach (option; options) + foreach (i, option; options) { static if (is(typeof(option) : const(char)[])) - service = option; + service = options[i]; else static if (is(typeof(option) == AddressInfoFlags)) hints.ai_flags |= option; @@ -943,7 +941,7 @@ AddressInfo[] getAddressInfo(T...)(in char[] node, T options) }), "getAddressInfo breaks @safe"); } -private AddressInfo[] getAddressInfoImpl(in char[] node, in char[] service, addrinfo* hints) @system +private AddressInfo[] getAddressInfoImpl(scope const(char)[] node, scope const(char)[] service, addrinfo* hints) @system { import std.array : appender; @@ -1019,7 +1017,7 @@ private AddressInfo[] getAddressInfoImpl(in char[] node, in char[] service, addr } -private ushort serviceToPort(in char[] service) +private ushort serviceToPort(scope const(char)[] service) { if (service == "") return InternetAddress.PORT_ANY; @@ -1036,12 +1034,12 @@ private ushort serviceToPort(in char[] service) /** * Provides _protocol-independent translation from host names to socket - * addresses. Uses $(D getAddressInfo) if the current system supports it, - * and $(D InternetHost) otherwise. + * addresses. Uses `getAddressInfo` if the current system supports it, + * and `InternetHost` otherwise. * - * Returns: Array with one $(D Address) instance per socket address. + * Returns: Array with one `Address` instance per socket address. * - * Throws: $(D SocketOSException) on failure. + * Throws: `SocketOSException` on failure. * * Example: * --- @@ -1056,7 +1054,7 @@ private ushort serviceToPort(in char[] service) * writefln(" Lookup failed: %s", e.msg); * --- */ -Address[] getAddress(in char[] hostname, in char[] service = null) +Address[] getAddress(scope const(char)[] hostname, scope const(char)[] service = null) { if (getaddrinfoPointer && freeaddrinfoPointer) { @@ -1073,7 +1071,7 @@ Address[] getAddress(in char[] hostname, in char[] service = null) } /// ditto -Address[] getAddress(in char[] hostname, ushort port) +Address[] getAddress(scope const(char)[] hostname, ushort port) { if (getaddrinfoPointer && freeaddrinfoPointer) return getAddress(hostname, to!string(port)); @@ -1115,13 +1113,13 @@ Address[] getAddress(in char[] hostname, ushort port) /** * Provides _protocol-independent parsing of network addresses. Does not - * attempt name resolution. Uses $(D getAddressInfo) with - * $(D AddressInfoFlags.NUMERICHOST) if the current system supports it, and - * $(D InternetAddress) otherwise. + * attempt name resolution. Uses `getAddressInfo` with + * `AddressInfoFlags.NUMERICHOST` if the current system supports it, and + * `InternetAddress` otherwise. * - * Returns: An $(D Address) instance representing specified address. + * Returns: An `Address` instance representing specified address. * - * Throws: $(D SocketException) on failure. + * Throws: `SocketException` on failure. * * Example: * --- @@ -1150,7 +1148,7 @@ Address[] getAddress(in char[] hostname, ushort port) * } * --- */ -Address parseAddress(in char[] hostaddr, in char[] service = null) +Address parseAddress(scope const(char)[] hostaddr, scope const(char)[] service = null) { if (getaddrinfoPointer && freeaddrinfoPointer) return getAddressInfo(hostaddr, service, AddressInfoFlags.NUMERICHOST)[0].address; @@ -1159,7 +1157,7 @@ Address parseAddress(in char[] hostaddr, in char[] service = null) } /// ditto -Address parseAddress(in char[] hostaddr, ushort port) +Address parseAddress(scope const(char)[] hostaddr, ushort port) { if (getaddrinfoPointer && freeaddrinfoPointer) return parseAddress(hostaddr, to!string(port)); @@ -1196,7 +1194,7 @@ Address parseAddress(in char[] hostaddr, ushort port) /** - * Class for exceptions thrown from an $(D Address). + * Class for exceptions thrown from an `Address`. */ class AddressException: SocketOSException { @@ -1205,7 +1203,7 @@ class AddressException: SocketOSException /** - * $(D Address) is an abstract class for representing a socket addresses. + * `Address` is an abstract class for representing a socket addresses. * * Example: * --- @@ -1230,11 +1228,11 @@ class AddressException: SocketOSException */ abstract class Address { - /// Returns pointer to underlying $(D sockaddr) structure. + /// Returns pointer to underlying `sockaddr` structure. abstract @property sockaddr* name() pure nothrow @nogc; abstract @property const(sockaddr)* name() const pure nothrow @nogc; /// ditto - /// Returns actual size of underlying $(D sockaddr) structure. + /// Returns actual size of underlying `sockaddr` structure. abstract @property socklen_t nameLen() const pure nothrow @nogc; // Socket.remoteAddress, Socket.localAddress, and Socket.receiveFrom @@ -1321,7 +1319,7 @@ abstract class Address /** * Attempts to retrieve the host address as a human-readable string. * - * Throws: $(D AddressException) on failure, or $(D SocketFeatureException) + * Throws: `AddressException` on failure, or `SocketFeatureException` * if address retrieval for this address family is not available on the * current system. */ @@ -1333,10 +1331,10 @@ abstract class Address /** * Attempts to retrieve the host name as a fully qualified domain name. * - * Returns: The FQDN corresponding to this $(D Address), or $(D null) if + * Returns: The FQDN corresponding to this `Address`, or `null` if * the host name did not resolve. * - * Throws: $(D AddressException) on error, or $(D SocketFeatureException) + * Throws: `AddressException` on error, or `SocketFeatureException` * if host name lookup for this address family is not available on the * current system. */ @@ -1348,7 +1346,7 @@ abstract class Address /** * Attempts to retrieve the numeric port number as a string. * - * Throws: $(D AddressException) on failure, or $(D SocketFeatureException) + * Throws: `AddressException` on failure, or `SocketFeatureException` * if port number retrieval for this address family is not available on the * current system. */ @@ -1360,7 +1358,7 @@ abstract class Address /** * Attempts to retrieve the service name as a string. * - * Throws: $(D AddressException) on failure, or $(D SocketFeatureException) + * Throws: `AddressException` on failure, or `SocketFeatureException` * if service name lookup for this address family is not available on the * current system. */ @@ -1387,7 +1385,7 @@ abstract class Address } /** - * $(D UnknownAddress) encapsulates an unknown socket address. + * `UnknownAddress` encapsulates an unknown socket address. */ class UnknownAddress: Address { @@ -1396,12 +1394,12 @@ protected: public: - override @property sockaddr* name() + override @property sockaddr* name() return { return &sa; } - override @property const(sockaddr)* name() const + override @property const(sockaddr)* name() const return { return &sa; } @@ -1416,7 +1414,7 @@ public: /** - * $(D UnknownAddressReference) encapsulates a reference to an arbitrary + * `UnknownAddressReference` encapsulates a reference to an arbitrary * socket address. */ class UnknownAddressReference: Address @@ -1426,14 +1424,14 @@ protected: socklen_t len; public: - /// Constructs an $(D Address) with a reference to the specified $(D sockaddr). + /// Constructs an `Address` with a reference to the specified `sockaddr`. this(sockaddr* sa, socklen_t len) pure nothrow @nogc { this.sa = sa; this.len = len; } - /// Constructs an $(D Address) with a copy of the specified $(D sockaddr). + /// Constructs an `Address` with a copy of the specified `sockaddr`. this(const(sockaddr)* sa, socklen_t len) @system pure nothrow { this.sa = cast(sockaddr*) (cast(ubyte*) sa)[0 .. len].dup.ptr; @@ -1459,10 +1457,10 @@ public: /** - * $(D InternetAddress) encapsulates an IPv4 (Internet Protocol version 4) + * `InternetAddress` encapsulates an IPv4 (Internet Protocol version 4) * socket address. * - * Consider using $(D getAddress), $(D parseAddress) and $(D Address) methods + * Consider using `getAddress`, `parseAddress` and `Address` methods * instead of using this class directly. */ class InternetAddress: Address @@ -1477,12 +1475,12 @@ protected: public: - override @property sockaddr* name() + override @property sockaddr* name() return { return cast(sockaddr*)&sin; } - override @property const(sockaddr)* name() const + override @property const(sockaddr)* name() const return { return cast(const(sockaddr)*)&sin; } @@ -1511,14 +1509,14 @@ public: } /** - * Construct a new $(D InternetAddress). + * Construct a new `InternetAddress`. * Params: * addr = an IPv4 address string in the dotted-decimal form a.b.c.d, - * or a host name which will be resolved using an $(D InternetHost) + * or a host name which will be resolved using an `InternetHost` * object. - * port = port number, may be $(D PORT_ANY). + * port = port number, may be `PORT_ANY`. */ - this(in char[] addr, ushort port) + this(scope const(char)[] addr, ushort port) { uint uiaddr = parse(addr); if (ADDR_NONE == uiaddr) @@ -1536,10 +1534,10 @@ public: } /** - * Construct a new $(D InternetAddress). + * Construct a new `InternetAddress`. * Params: - * addr = (optional) an IPv4 address in host byte order, may be $(D ADDR_ANY). - * port = port number, may be $(D PORT_ANY). + * addr = (optional) an IPv4 address in host byte order, may be `ADDR_ANY`. + * port = port number, may be `PORT_ANY`. */ this(uint addr, ushort port) pure nothrow @nogc { @@ -1557,13 +1555,13 @@ public: } /** - * Construct a new $(D InternetAddress). + * Construct a new `InternetAddress`. * Params: * addr = A sockaddr_in as obtained from lower-level API calls such as getifaddrs. */ this(sockaddr_in addr) pure nothrow @nogc { - assert(addr.sin_family == AddressFamily.INET); + assert(addr.sin_family == AddressFamily.INET, "Socket address is not of INET family."); sin = addr; } @@ -1582,10 +1580,10 @@ public: /** * Attempts to retrieve the host name as a fully qualified domain name. * - * Returns: The FQDN corresponding to this $(D InternetAddress), or - * $(D null) if the host name did not resolve. + * Returns: The FQDN corresponding to this `InternetAddress`, or + * `null` if the host name did not resolve. * - * Throws: $(D AddressException) on error. + * Throws: `AddressException` on error. */ override string toHostNameString() const { @@ -1634,9 +1632,9 @@ public: * Parse an IPv4 address string in the dotted-decimal form $(I a.b.c.d) * and return the number. * Returns: If the string is not a legitimate IPv4 address, - * $(D ADDR_NONE) is returned. + * `ADDR_NONE` is returned. */ - static uint parse(in char[] addr) @trusted nothrow + static uint parse(scope const(char)[] addr) @trusted nothrow { return ntohl(inet_addr(addr.tempCString())); } @@ -1693,18 +1691,18 @@ public: } }); - version (SlowTests) + debug (std_socket) softUnittest({ // test failing reverse lookup - const InternetAddress ia = new InternetAddress("127.114.111.120", 80); + const InternetAddress ia = new InternetAddress("255.255.255.255", 80); assert(ia.toHostNameString() is null); if (getnameinfoPointer) { // test failing reverse lookup, via gethostbyaddr auto getnameinfoPointerBackup = getnameinfoPointer; - getnameinfoPointer = null; - scope(exit) getnameinfoPointer = getnameinfoPointerBackup; + cast() getnameinfoPointer = null; + scope(exit) cast() getnameinfoPointer = getnameinfoPointerBackup; assert(ia.toHostNameString() is null); } @@ -1713,10 +1711,10 @@ public: /** - * $(D Internet6Address) encapsulates an IPv6 (Internet Protocol version 6) + * `Internet6Address` encapsulates an IPv6 (Internet Protocol version 6) * socket address. * - * Consider using $(D getAddress), $(D parseAddress) and $(D Address) methods + * Consider using `getAddress`, `parseAddress` and `Address` methods * instead of using this class directly. */ class Internet6Address: Address @@ -1731,12 +1729,12 @@ protected: public: - override @property sockaddr* name() + override @property sockaddr* name() return { return cast(sockaddr*)&sin6; } - override @property const(sockaddr)* name() const + override @property const(sockaddr)* name() const return { return cast(const(sockaddr)*)&sin6; } @@ -1751,16 +1749,19 @@ public: /// Any IPv6 host address. static @property ref const(ubyte)[16] ADDR_ANY() pure nothrow @nogc { - const(ubyte)[16]* addr; static if (is(typeof(IN6ADDR_ANY))) { - addr = &IN6ADDR_ANY.s6_addr; - return *addr; + version (Windows) + { + static immutable addr = IN6ADDR_ANY.s6_addr; + return addr; + } + else + return IN6ADDR_ANY.s6_addr; } else static if (is(typeof(in6addr_any))) { - addr = &in6addr_any.s6_addr; - return *addr; + return in6addr_any.s6_addr; } else static assert(0); @@ -1782,13 +1783,13 @@ public: } /** - * Construct a new $(D Internet6Address). + * Construct a new `Internet6Address`. * Params: * addr = an IPv6 host address string in the form described in RFC 2373, - * or a host name which will be resolved using $(D getAddressInfo). + * or a host name which will be resolved using `getAddressInfo`. * service = (optional) service name. */ - this(in char[] addr, in char[] service = null) @trusted + this(scope const(char)[] addr, scope const(char)[] service = null) @trusted { auto results = getAddressInfo(addr, service, AddressFamily.INET6); assert(results.length && results[0].family == AddressFamily.INET6); @@ -1796,13 +1797,13 @@ public: } /** - * Construct a new $(D Internet6Address). + * Construct a new `Internet6Address`. * Params: * addr = an IPv6 host address string in the form described in RFC 2373, - * or a host name which will be resolved using $(D getAddressInfo). - * port = port number, may be $(D PORT_ANY). + * or a host name which will be resolved using `getAddressInfo`. + * port = port number, may be `PORT_ANY`. */ - this(in char[] addr, ushort port) + this(scope const(char)[] addr, ushort port) { if (port == PORT_ANY) this(addr); @@ -1811,11 +1812,11 @@ public: } /** - * Construct a new $(D Internet6Address). + * Construct a new `Internet6Address`. * Params: * addr = (optional) an IPv6 host address in host byte order, or - * $(D ADDR_ANY). - * port = port number, may be $(D PORT_ANY). + * `ADDR_ANY`. + * port = port number, may be `PORT_ANY`. */ this(ubyte[16] addr, ushort port) pure nothrow @nogc { @@ -1833,7 +1834,7 @@ public: } /** - * Construct a new $(D Internet6Address). + * Construct a new `Internet6Address`. * Params: * addr = A sockaddr_in6 as obtained from lower-level API calls such as getifaddrs. */ @@ -1846,9 +1847,9 @@ public: /** * Parse an IPv6 host address string as described in RFC 2373, and return the * address. - * Throws: $(D SocketException) on error. + * Throws: `SocketException` on error. */ - static ubyte[16] parse(in char[] addr) @trusted + static ubyte[16] parse(scope const(char)[] addr) @trusted { // Although we could use inet_pton here, it's only available on Windows // versions starting with Vista, so use getAddressInfo with NUMERICHOST @@ -1895,8 +1896,8 @@ version (StdDdoc) } /** - * $(D UnixAddress) encapsulates an address for a Unix domain socket - * ($(D AF_UNIX)), i.e. a socket bound to a path name in the file system. + * `UnixAddress` encapsulates an address for a Unix domain socket + * (`AF_UNIX`), i.e. a socket bound to a path name in the file system. * Available only on supported systems. * * Linux also supports an abstract address namespace, in which addresses @@ -1917,11 +1918,11 @@ version (StdDdoc) { private this() pure nothrow @nogc {} - /// Construct a new $(D UnixAddress) from the specified path. - this(in char[] path) { } + /// Construct a new `UnixAddress` from the specified path. + this(scope const(char)[] path) { } /** - * Construct a new $(D UnixAddress). + * Construct a new `UnixAddress`. * Params: * addr = A sockaddr_un as obtained from lower-level API calls. */ @@ -1968,12 +1969,12 @@ static if (is(sockaddr_un)) } public: - override @property sockaddr* name() + override @property sockaddr* name() return { return cast(sockaddr*)&sun; } - override @property const(sockaddr)* name() const + override @property const(sockaddr)* name() const return { return cast(const(sockaddr)*)&sun; } @@ -1983,7 +1984,7 @@ static if (is(sockaddr_un)) return _nameLen; } - this(in char[] path) @trusted pure + this(scope const(char)[] path) @trusted pure { enforce(path.length <= sun.sun_path.sizeof, new SocketParameterException("Path too long")); sun.sun_family = AddressFamily.UNIX; @@ -2011,6 +2012,8 @@ static if (is(sockaddr_un)) @property string path() @trusted const pure { auto len = _nameLen - sockaddr_un.init.sun_path.offsetof; + if (len == 0) + return null; // An empty path may be returned from getpeername // For pathname socket address we need to strip off the terminating '\0' if (sun.sun_path.ptr[0]) --len; @@ -2026,14 +2029,33 @@ static if (is(sockaddr_un)) @safe unittest { import core.stdc.stdio : remove; - import std.file : deleteme; + + version (iOSDerived) + { + // Slightly different version of `std.file.deleteme` to reduce the path + // length on iOS derived platforms. Due to the sandbox, the length + // of paths can quickly become too long. + static string deleteme() + { + import std.conv : text; + import std.process : thisProcessID; + import std.file : tempDir; + + return text(tempDir, thisProcessID); + } + } + + else + import std.file : deleteme; immutable ubyte[] data = [1, 2, 3, 4]; Socket[2] pair; - auto names = [ deleteme ~ "-unix-socket" ]; + const basePath = deleteme; + auto names = [ basePath ~ "-socket" ]; version (linux) - names ~= "\0" ~ deleteme ~ "-abstract\0unix\0socket"; + names ~= "\0" ~ basePath ~ "-abstract\0unix\0socket"; + foreach (name; names) { auto address = new UnixAddress(name); @@ -2060,13 +2082,19 @@ static if (is(sockaddr_un)) auto buf = new ubyte[data.length]; pair[1].receive(buf); assert(buf == data); + + // getpeername is free to return an empty name for a unix + // domain socket pair or unbound socket. Let's confirm it + // returns successfully and doesn't throw anything. + // See https://issues.dlang.org/show_bug.cgi?id=20544 + assertNotThrown(pair[1].remoteAddress().toString()); } } } /** - * Class for exceptions thrown by $(D Socket.accept). + * Class for exceptions thrown by `Socket.accept`. */ class SocketAcceptException: SocketOSException { @@ -2132,10 +2160,10 @@ struct TimeVal /** - * A collection of sockets for use with $(D Socket.select). + * A collection of sockets for use with `Socket.select`. * - * $(D SocketSet) wraps the platform $(D fd_set) type. However, unlike - * $(D fd_set), $(D SocketSet) is not statically limited to $(D FD_SETSIZE) + * `SocketSet` wraps the platform `fd_set` type. However, unlike + * `fd_set`, `SocketSet` is not statically limited to `FD_SETSIZE` * or any other limit, and grows as needed. */ class SocketSet @@ -2243,7 +2271,7 @@ public: /** * Create a SocketSet with a specific initial capacity (defaults to - * $(D FD_SETSIZE), the system's default capacity). + * `FD_SETSIZE`, the system's default capacity). */ this(size_t size = FD_SETSIZE) pure nothrow { @@ -2251,7 +2279,7 @@ public: reset(); } - /// Reset the $(D SocketSet) so that there are 0 $(D Socket)s in the collection. + /// Reset the `SocketSet` so that there are 0 `Socket`s in the collection. void reset() pure nothrow @nogc { version (Windows) @@ -2294,7 +2322,7 @@ public: } /** - * Add a $(D Socket) to the collection. + * Add a `Socket` to the collection. * The socket must not already be in the collection. */ void add(Socket s) pure nothrow @@ -2324,7 +2352,7 @@ public: /** - * Remove this $(D Socket) from the collection. + * Remove this `Socket` from the collection. * Does nothing if the socket is not in the collection already. */ void remove(Socket s) pure nothrow @@ -2349,7 +2377,7 @@ public: } - /// Return nonzero if this $(D Socket) is in the collection. + /// Return nonzero if this `Socket` is in the collection. int isSet(Socket s) const pure nothrow @nogc { return isSet(s.sock); @@ -2358,12 +2386,12 @@ public: /** * Returns: - * The current capacity of this $(D SocketSet). The exact + * The current capacity of this `SocketSet`. The exact * meaning of the return value varies from platform to platform. * * Note: * Since D 2.065, this value does not indicate a - * restriction, and $(D SocketSet) will grow its capacity as + * restriction, and `SocketSet` will grow its capacity as * needed automatically. */ @property uint max() const pure nothrow @nogc @@ -2415,12 +2443,21 @@ public: @safe unittest { - softUnittest({ + version (iOSDerived) + { + enum PAIRS = 256; + enum LIMIT = 1024; + } + else + { enum PAIRS = 768; + enum LIMIT = 2048; + } + + softUnittest({ version (Posix) () @trusted { - enum LIMIT = 2048; static assert(LIMIT > PAIRS*2); import core.sys.posix.sys.resource; rlimit fileLimit; @@ -2477,18 +2514,28 @@ public: assert(!errorSet.isSet(testPair[1])); ubyte[1] b; - testPair[0].send(b[]); + // Socket.send can't be marked with `scope` + // -> @safe DIP1000 code can't use it - see https://github.com/dlang/phobos/pull/6204 + () @trusted { + testPair[0].send(b[]); + }(); fillSets(); n = Socket.select(readSet, null, null); assert(n == 1); // testPair[1] assert(readSet.isSet(testPair[1])); assert(!readSet.isSet(testPair[0])); - testPair[1].receive(b[]); + // Socket.receive can't be marked with `scope` + // -> @safe DIP1000 code can't use it - see https://github.com/dlang/phobos/pull/6204 + () @trusted { + testPair[1].receive(b[]); + }(); } }); } -@safe unittest // Issue 14012, 14013 +// https://issues.dlang.org/show_bug.cgi?id=14012 +// https://issues.dlang.org/show_bug.cgi?id=14013 +@safe unittest { auto set = new SocketSet(1); assert(set.max >= 0); @@ -2570,7 +2617,7 @@ enum SocketOption: int /** - * $(D Socket) is a class that creates a network communication endpoint using + * `Socket` is a class that creates a network communication endpoint using * the Berkeley sockets interface. */ class Socket @@ -2591,9 +2638,9 @@ private: @safe unittest { - version (SlowTests) + debug (std_socket) softUnittest({ - import std.datetime; + import std.datetime.stopwatch; import std.typecons; enum msecs = 1000; @@ -2611,7 +2658,7 @@ private: sock.getOption(SocketOptionLevel.SOCKET, SocketOption.RCVTIMEO, readBack); assert(readBack.total!"msecs" == msecs); - assert(sw.peek().msecs > msecs-100 && sw.peek().msecs < msecs+100); + assert(sw.peek().total!"msecs" > msecs - 100 && sw.peek().total!"msecs" < msecs + 100); }); } @@ -2639,7 +2686,7 @@ public: /** * Create a blocking socket. If a single protocol type exists to support - * this socket type within the address family, the $(D ProtocolType) may be + * this socket type within the address family, the `ProtocolType` may be * omitted. */ this(AddressFamily af, SocketType type, ProtocolType protocol) @trusted @@ -2662,7 +2709,7 @@ public: /// ditto - this(AddressFamily af, SocketType type, in char[] protocolName) @trusted + this(AddressFamily af, SocketType type, scope const(char)[] protocolName) @trusted { protoent* proto; proto = getprotobyname(protocolName.tempCString()); @@ -2674,9 +2721,9 @@ public: /** * Create a blocking socket using the parameters from the specified - * $(D AddressInfo) structure. + * `AddressInfo` structure. */ - this(in AddressInfo info) + this(const scope AddressInfo info) { this(info.family, info.type, info.protocol); } @@ -2764,7 +2811,14 @@ public: return !getsockopt(sock, SOL_SOCKET, SO_TYPE, cast(char*)&type, &typesize); } - /// Associate a local address with this socket. + /** + * Associate a local address with this socket. + * + * Params: + * addr = The $(LREF Address) to associate this socket with. + * + * Throws: $(LREF SocketOSException) when unable to bind the socket. + */ void bind(Address addr) @trusted { if (_SOCKET_ERROR == .bind(sock, addr.name, addr.nameLen)) @@ -2805,9 +2859,9 @@ public: } /** - * Listen for an incoming connection. $(D bind) must be called before you - * can $(D listen). The $(D backlog) is a request of how many pending - * incoming connections are queued until $(D accept)ed. + * Listen for an incoming connection. `bind` must be called before you + * can `listen`. The `backlog` is a request of how many pending + * incoming connections are queued until `accept`ed. */ void listen(int backlog) @trusted { @@ -2816,10 +2870,10 @@ public: } /** - * Called by $(D accept) when a new $(D Socket) must be created for a new + * Called by `accept` when a new `Socket` must be created for a new * connection. To use a derived class, override this method and return an - * instance of your class. The returned $(D Socket)'s handle must not be - * set; $(D Socket) has a protected constructor $(D this()) to use in this + * instance of your class. The returned `Socket`'s handle must not be + * set; `Socket` has a protected constructor `this()` to use in this * situation. * * Override to use a derived class. @@ -2831,9 +2885,9 @@ public: } /** - * Accept an incoming connection. If the socket is blocking, $(D accept) - * waits for a connection request. Throws $(D SocketAcceptException) if - * unable to _accept. See $(D accepting) for use with derived classes. + * Accept an incoming connection. If the socket is blocking, `accept` + * waits for a connection request. Throws `SocketAcceptException` if + * unable to _accept. See `accepting` for use with derived classes. */ Socket accept() @trusted { @@ -2883,10 +2937,8 @@ public: /** * Immediately drop any connections and release socket resources. - * Calling $(D shutdown) before $(D close) is recommended for - * connection-oriented sockets. The $(D Socket) object is no longer - * usable after $(D close). - * Calling shutdown() before this is recommended + * The `Socket` object is no longer usable after `close`. + * Calling `shutdown` before `close` is recommended * for connection-oriented sockets. */ void close() @trusted nothrow @nogc @@ -2907,7 +2959,7 @@ public: return to!string(result.ptr); } - /// Remote endpoint $(D Address). + /// Remote endpoint `Address`. @property Address remoteAddress() @trusted { Address addr = createAddress(); @@ -2919,7 +2971,7 @@ public: return addr; } - /// Local endpoint $(D Address). + /// Local endpoint `Address`. @property Address localAddress() @trusted { Address addr = createAddress(); @@ -2932,8 +2984,8 @@ public: } /** - * Send or receive error code. See $(D wouldHaveBlocked), - * $(D lastSocketError) and $(D Socket.getErrorText) for obtaining more + * Send or receive error code. See `wouldHaveBlocked`, + * `lastSocketError` and `Socket.getErrorText` for obtaining more * information about the error. */ enum int ERROR = _SOCKET_ERROR; @@ -2949,8 +3001,8 @@ public: /** * Send data on the connection. If the socket is blocking and there is no - * buffer space left, $(D send) waits. - * Returns: The number of bytes actually sent, or $(D Socket.ERROR) on + * buffer space left, `send` waits. + * Returns: The number of bytes actually sent, or `Socket.ERROR` on * failure. */ ptrdiff_t send(const(void)[] buf, SocketFlags flags) @trusted @@ -2975,8 +3027,8 @@ public: /** * Send data to a specific destination Address. If the destination address is * not specified, a connection must have been made and that address is used. - * If the socket is blocking and there is no buffer space left, $(D sendTo) waits. - * Returns: The number of bytes actually sent, or $(D Socket.ERROR) on + * If the socket is blocking and there is no buffer space left, `sendTo` waits. + * Returns: The number of bytes actually sent, or `Socket.ERROR` on * failure. */ ptrdiff_t sendTo(const(void)[] buf, SocketFlags flags, Address to) @trusted @@ -3025,10 +3077,10 @@ public: /** - * Receive data on the connection. If the socket is blocking, $(D receive) + * Receive data on the connection. If the socket is blocking, `receive` * waits until there is data to be received. - * Returns: The number of bytes actually received, $(D 0) if the remote side - * has closed the connection, or $(D Socket.ERROR) on failure. + * Returns: The number of bytes actually received, `0` if the remote side + * has closed the connection, or `Socket.ERROR` on failure. */ ptrdiff_t receive(void[] buf, SocketFlags flags) @trusted { @@ -3053,11 +3105,11 @@ public: } /** - * Receive data and get the remote endpoint $(D Address). - * If the socket is blocking, $(D receiveFrom) waits until there is data to + * Receive data and get the remote endpoint `Address`. + * If the socket is blocking, `receiveFrom` waits until there is data to * be received. - * Returns: The number of bytes actually received, $(D 0) if the remote side - * has closed the connection, or $(D Socket.ERROR) on failure. + * Returns: The number of bytes actually received, `0` if the remote side + * has closed the connection, or `Socket.ERROR` on failure. */ ptrdiff_t receiveFrom(void[] buf, SocketFlags flags, ref Address from) @trusted { @@ -3123,7 +3175,7 @@ public: /** * Get a socket option. - * Returns: The number of bytes written to $(D result). + * Returns: The number of bytes written to `result`. * The length, in bytes, of the actual result - very different from getsockopt() */ int getOption(SocketOptionLevel level, SocketOption option, void[] result) @trusted @@ -3197,8 +3249,8 @@ public: } /** - * Sets a timeout (duration) option, i.e. $(D SocketOption.SNDTIMEO) or - * $(D RCVTIMEO). Zero indicates no timeout. + * Sets a timeout (duration) option, i.e. `SocketOption.SNDTIMEO` or + * `RCVTIMEO`. Zero indicates no timeout. * * In a typical application, you might also want to consider using * a non-blocking socket instead of setting a timeout on a blocking one. @@ -3207,17 +3259,17 @@ public: * on *nix systems even for smaller durations, there are two issues to * be aware of on Windows: First, although undocumented, the effective * timeout duration seems to be the one set on the socket plus half - * a second. $(D setOption()) tries to compensate for that, but still, + * a second. `setOption()` tries to compensate for that, but still, * timeouts under 500ms are not possible on Windows. Second, be aware * that the actual amount of time spent until a blocking call returns * randomly varies on the order of 10ms. * * Params: * level = The level at which a socket option is defined. - * option = Either $(D SocketOption.SNDTIMEO) or $(D SocketOption.RCVTIMEO). + * option = Either `SocketOption.SNDTIMEO` or `SocketOption.RCVTIMEO`. * value = The timeout duration to set. Must not be negative. * - * Throws: $(D SocketException) if setting the options fails. + * Throws: `SocketException` if setting the options fails. * * Example: * --- @@ -3284,8 +3336,8 @@ public: * interval = Number of seconds between when successive keep-alive * packets are sent if no acknowledgement is received. * - * Throws: $(D SocketOSException) if setting the options fails, or - * $(D SocketFeatureException) if setting keep-alive parameters is + * Throws: `SocketOSException` if setting the options fails, or + * `SocketFeatureException` if setting keep-alive parameters is * unsupported on the current platform. */ void setKeepAlive(int time, int interval) @trusted @@ -3317,12 +3369,12 @@ public: /** * Wait for a socket to change status. A wait timeout of $(REF Duration, core, time) or - * $(D TimeVal), may be specified; if a timeout is not specified or the - * $(D TimeVal) is $(D null), the maximum timeout is used. The $(D TimeVal) - * timeout has an unspecified value when $(D select) returns. - * Returns: The number of sockets with status changes, $(D 0) on timeout, - * or $(D -1) on interruption. If the return value is greater than $(D 0), - * the $(D SocketSets) are updated to only contain the sockets having status + * `TimeVal`, may be specified; if a timeout is not specified or the + * `TimeVal` is `null`, the maximum timeout is used. The `TimeVal` + * timeout has an unspecified value when `select` returns. + * Returns: The number of sockets with status changes, `0` on timeout, + * or `-1` on interruption. If the return value is greater than `0`, + * the `SocketSets` are updated to only contain the sockets having status * changes. For a connecting socket, a write status change means the * connection is established and it's able to send. For a listening socket, * a read status change means there is an incoming connection request and @@ -3367,7 +3419,7 @@ public: assert(checkWrite !is checkError); } } - body + do { fd_set* fr, fw, fe; int n = 0; @@ -3481,7 +3533,7 @@ public: } -/// $(D TcpSocket) is a shortcut class for a TCP Socket. +/// `TcpSocket` is a shortcut class for a TCP Socket. class TcpSocket: Socket { /// Constructs a blocking TCP Socket. @@ -3498,7 +3550,7 @@ class TcpSocket: Socket //shortcut - /// Constructs a blocking TCP Socket and connects to an $(D Address). + /// Constructs a blocking TCP Socket and connects to an `Address`. this(Address connectTo) { this(connectTo.addressFamily); @@ -3507,7 +3559,7 @@ class TcpSocket: Socket } -/// $(D UdpSocket) is a shortcut class for a UDP Socket. +/// `UdpSocket` is a shortcut class for a UDP Socket. class UdpSocket: Socket { /// Constructs a blocking UDP Socket. @@ -3524,50 +3576,167 @@ class UdpSocket: Socket } } -// Issue 16514 +// https://issues.dlang.org/show_bug.cgi?id=16514 @safe unittest { + void checkAttributes(string attributes)() + { + mixin(attributes ~ q{ void function() fun = {};}); + fun(); + } + class TestSocket : Socket { override { - const pure nothrow @nogc @property @safe socket_t handle() { assert(0); } - const nothrow @nogc @property @trusted bool blocking() { assert(0); } - @property @trusted void blocking(bool byes) { assert(0); } - @property @safe AddressFamily addressFamily() { assert(0); } - const @property @trusted bool isAlive() { assert(0); } - @trusted void bind(Address addr) { assert(0); } - @trusted void connect(Address to) { assert(0); } - @trusted void listen(int backlog) { assert(0); } - protected pure nothrow @safe Socket accepting() { assert(0); } - @trusted Socket accept() { assert(0); } - nothrow @nogc @trusted void shutdown(SocketShutdown how) { assert(0); } - nothrow @nogc @trusted void close() { assert(0); } - @property @trusted Address remoteAddress() { assert(0); } - @property @trusted Address localAddress() { assert(0); } - @trusted ptrdiff_t send(const(void)[] buf, SocketFlags flags) { assert(0); } - @safe ptrdiff_t send(const(void)[] buf) { assert(0); } - @trusted ptrdiff_t sendTo(const(void)[] buf, SocketFlags flags, Address to) { assert(0); } - @safe ptrdiff_t sendTo(const(void)[] buf, Address to) { assert(0); } - @trusted ptrdiff_t sendTo(const(void)[] buf, SocketFlags flags) { assert(0); } - @safe ptrdiff_t sendTo(const(void)[] buf) { assert(0); } - @trusted ptrdiff_t receive(void[] buf, SocketFlags flags) { assert(0); } - @safe ptrdiff_t receive(void[] buf) { assert(0); } - @trusted ptrdiff_t receiveFrom(void[] buf, SocketFlags flags, ref Address from) { assert(0); } - @safe ptrdiff_t receiveFrom(void[] buf, ref Address from) { assert(0); } - @trusted ptrdiff_t receiveFrom(void[] buf, SocketFlags flags) { assert(0); } - @safe ptrdiff_t receiveFrom(void[] buf) { assert(0); } - @trusted int getOption(SocketOptionLevel level, SocketOption option, void[] result) { assert(0); } - @trusted int getOption(SocketOptionLevel level, SocketOption option, out int32_t result) { assert(0); } - @trusted int getOption(SocketOptionLevel level, SocketOption option, out Linger result) { assert(0); } - @trusted void getOption(SocketOptionLevel level, SocketOption option, out Duration result) { assert(0); } - @trusted void setOption(SocketOptionLevel level, SocketOption option, void[] value) { assert(0); } - @trusted void setOption(SocketOptionLevel level, SocketOption option, int32_t value) { assert(0); } - @trusted void setOption(SocketOptionLevel level, SocketOption option, Linger value) { assert(0); } - @trusted void setOption(SocketOptionLevel level, SocketOption option, Duration value) { assert(0); } - @safe string getErrorText() { assert(0); } - @trusted void setKeepAlive(int time, int interval) { assert(0); } - protected pure nothrow @safe Address createAddress() { assert(0); } + @property pure nothrow @nogc @safe socket_t handle() const + { + checkAttributes!q{pure nothrow @nogc @safe}; assert(0); + } + @property nothrow @nogc @trusted bool blocking() const + { + checkAttributes!q{nothrow @nogc @trusted}; assert(0); + } + @property @trusted void blocking(bool byes) + { + checkAttributes!q{@trusted}; + } + @property @safe AddressFamily addressFamily() + { + checkAttributes!q{@safe}; assert(0); + } + @property @trusted bool isAlive() const + { + checkAttributes!q{@trusted}; assert(0); + } + @trusted void bind(Address addr) + { + checkAttributes!q{@trusted}; + } + @trusted void connect(Address to) + { + checkAttributes!q{@trusted}; + } + @trusted void listen(int backlog) + { + checkAttributes!q{@trusted}; + } + protected pure nothrow @safe Socket accepting() + { + checkAttributes!q{pure nothrow @safe}; assert(0); + } + @trusted Socket accept() + { + checkAttributes!q{@trusted}; assert(0); + } + nothrow @nogc @trusted void shutdown(SocketShutdown how) + { + checkAttributes!q{nothrow @nogc @trusted}; + } + nothrow @nogc @trusted void close() + { + checkAttributes!q{nothrow @nogc @trusted}; + } + @property @trusted Address remoteAddress() + { + checkAttributes!q{@trusted}; assert(0); + } + @property @trusted Address localAddress() + { + checkAttributes!q{@trusted}; assert(0); + } + @trusted ptrdiff_t send(const(void)[] buf, SocketFlags flags) + { + checkAttributes!q{@trusted}; assert(0); + } + @safe ptrdiff_t send(const(void)[] buf) + { + checkAttributes!q{@safe}; assert(0); + } + @trusted ptrdiff_t sendTo(const(void)[] buf, SocketFlags flags, Address to) + { + checkAttributes!q{@trusted}; assert(0); + } + @safe ptrdiff_t sendTo(const(void)[] buf, Address to) + { + checkAttributes!q{@safe}; assert(0); + } + @trusted ptrdiff_t sendTo(const(void)[] buf, SocketFlags flags) + { + checkAttributes!q{@trusted}; assert(0); + } + @safe ptrdiff_t sendTo(const(void)[] buf) + { + checkAttributes!q{@safe}; assert(0); + } + @trusted ptrdiff_t receive(void[] buf, SocketFlags flags) + { + checkAttributes!q{@trusted}; assert(0); + } + @safe ptrdiff_t receive(void[] buf) + { + checkAttributes!q{@safe}; assert(0); + } + @trusted ptrdiff_t receiveFrom(void[] buf, SocketFlags flags, ref Address from) + { + checkAttributes!q{@trusted}; assert(0); + } + @safe ptrdiff_t receiveFrom(void[] buf, ref Address from) + { + checkAttributes!q{@safe}; assert(0); + } + @trusted ptrdiff_t receiveFrom(void[] buf, SocketFlags flags) + { + checkAttributes!q{@trusted}; assert(0); + } + @safe ptrdiff_t receiveFrom(void[] buf) + { + checkAttributes!q{@safe}; assert(0); + } + @trusted int getOption(SocketOptionLevel level, SocketOption option, void[] result) + { + checkAttributes!q{@trusted}; assert(0); + } + @trusted int getOption(SocketOptionLevel level, SocketOption option, out int32_t result) + { + checkAttributes!q{@trusted}; assert(0); + } + @trusted int getOption(SocketOptionLevel level, SocketOption option, out Linger result) + { + checkAttributes!q{@trusted}; assert(0); + } + @trusted void getOption(SocketOptionLevel level, SocketOption option, out Duration result) + { + checkAttributes!q{@trusted}; + } + @trusted void setOption(SocketOptionLevel level, SocketOption option, void[] value) + { + checkAttributes!q{@trusted}; + } + @trusted void setOption(SocketOptionLevel level, SocketOption option, int32_t value) + { + checkAttributes!q{@trusted}; + } + @trusted void setOption(SocketOptionLevel level, SocketOption option, Linger value) + { + checkAttributes!q{@trusted}; + } + @trusted void setOption(SocketOptionLevel level, SocketOption option, Duration value) + { + checkAttributes!q{@trusted}; + } + @safe string getErrorText() + { + checkAttributes!q{@safe}; assert(0); + } + @trusted void setKeepAlive(int time, int interval) + { + checkAttributes!q{@trusted}; + } + protected pure nothrow @safe Address createAddress() + { + checkAttributes!q{pure nothrow @safe}; assert(0); + } } } } @@ -3577,7 +3746,7 @@ class UdpSocket: Socket * * The two sockets are indistinguishable. * - * Throws: $(D SocketException) if creation of the sockets fails. + * Throws: `SocketException` if creation of the sockets fails. */ Socket[2] socketPair() @trusted { |