mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Update errno listings. Update ai flags in std::net. Fix incorrect socket error results on Win32. Change behaviour Socket set_option. TcpSocket/TcpServerSocket/UdpSocket. Rename "TimeDuration" to "Duration". Allow @if on enum values.
This commit is contained in:
committed by
Christoffer Lerno
parent
ed70f39da8
commit
6c60b0d2a6
@@ -12,13 +12,13 @@ struct StackTrace
|
||||
uint line;
|
||||
}
|
||||
|
||||
struct VirtualAny
|
||||
struct AnyStruct
|
||||
{
|
||||
void* ptr;
|
||||
typeid type_id;
|
||||
typeid type;
|
||||
}
|
||||
|
||||
struct SubArrayContainer
|
||||
struct SubArrayStruct
|
||||
{
|
||||
void* ptr;
|
||||
usz len;
|
||||
|
||||
@@ -420,160 +420,154 @@ const CLOCKS_PER_SEC = 1000000;
|
||||
|
||||
module libc::errno;
|
||||
|
||||
const Errno OK = 0;
|
||||
const Errno EPERM = 1; // Operation not permitted
|
||||
const Errno ENOENT = 2; // No such file or directory
|
||||
const Errno ESRCH = 3; // No such process
|
||||
const Errno EINTR = 4; // Interrupted system call
|
||||
const Errno EIO = 5; // I/O error
|
||||
const Errno ENXIO = 6; // No such device or address
|
||||
const Errno E2BIG = 7; // Argument list too long
|
||||
const Errno ENOEXEC = 8; // Exec format error
|
||||
const Errno EBADF = 9; // Bad file number
|
||||
const Errno ECHILD = 10; // No child processes
|
||||
const Errno OK = 0;
|
||||
const Errno EPERM = 1; // Operation not permitted
|
||||
const Errno ENOENT = 2; // No such file or directory
|
||||
const Errno ESRCH = 3; // No such process
|
||||
const Errno EINTR = 4; // Interrupted system call
|
||||
const Errno EIO = 5; // I/O error
|
||||
const Errno ENXIO = 6; // No such device or address
|
||||
const Errno E2BIG = 7; // Argument list too long
|
||||
const Errno ENOEXEC = 8; // Exec format error
|
||||
const Errno EBADF = 9; // Bad file number
|
||||
const Errno ECHILD = 10; // No child processes
|
||||
|
||||
|
||||
const Errno EAGAIN @if(env::DARWIN) = 35; // Try again Macos
|
||||
const Errno EAGAIN @if(!env::DARWIN) = 11; // Try again
|
||||
const Errno EAGAIN @if(env::DARWIN) = 35; // Try again Macos
|
||||
const Errno EAGAIN @if(!env::DARWIN) = 11; // Try again
|
||||
|
||||
const Errno ENOMEM = 12; // Out of memory
|
||||
const Errno EACCES = 13; // Permission denied
|
||||
const Errno EFAULT = 14; // Bad address
|
||||
const Errno ENOTBLK = 15; // Block device required, not on Win32
|
||||
const Errno EBUSY = 16; // Device or resource busy
|
||||
const Errno EEXIST = 17; // File exists
|
||||
const Errno EXDEV = 18; // Cross-device link
|
||||
const Errno ENODEV = 19; // No such device
|
||||
const Errno ENOTDIR = 20; // Not a directory
|
||||
const Errno EISDIR = 21; // Is a directory
|
||||
const Errno EINVAL = 22; // Invalid argument
|
||||
const Errno ENFILE = 23; // File table overflow
|
||||
const Errno EMFILE = 24; // Too many open files
|
||||
const Errno ENOTTY = 25; // Not a typewriter
|
||||
const Errno ETXTBSY = 26; // Text file busy, not on Win32
|
||||
const Errno EFBIG = 27; // File too large
|
||||
const Errno ENOSPC = 28; // No space left on device
|
||||
const Errno ESPIPE = 29; // Illegal seek
|
||||
const Errno EROFS = 30; // Read-only file system
|
||||
const Errno EMLINK = 31; // Too many links
|
||||
const Errno EPIPE = 32; // Broken pipe
|
||||
const Errno EDOM = 33; // Math argument out of domain of func
|
||||
const Errno ERANGE = 34; // Math result not representable
|
||||
const Errno ENOMEM = 12; // Out of memory
|
||||
const Errno EACCES = 13; // Permission denied
|
||||
const Errno EFAULT = 14; // Bad address
|
||||
const Errno ENOTBLK = 15; // Block device required, not on Win32
|
||||
const Errno EBUSY = 16; // Device or resource busy
|
||||
const Errno EEXIST = 17; // File exists
|
||||
const Errno EXDEV = 18; // Cross-device link
|
||||
const Errno ENODEV = 19; // No such device
|
||||
const Errno ENOTDIR = 20; // Not a directory
|
||||
const Errno EISDIR = 21; // Is a directory
|
||||
const Errno EINVAL = 22; // Invalid argument
|
||||
const Errno ENFILE = 23; // File table overflow
|
||||
const Errno EMFILE = 24; // Too many open files
|
||||
const Errno ENOTTY = 25; // Not a typewriter
|
||||
const Errno ETXTBSY = 26; // Text file busy, not on Win32
|
||||
const Errno EFBIG = 27; // File too large
|
||||
const Errno ENOSPC = 28; // No space left on device
|
||||
const Errno ESPIPE = 29; // Illegal seek
|
||||
const Errno EROFS = 30; // Read-only file system
|
||||
const Errno EMLINK = 31; // Too many links
|
||||
const Errno EPIPE = 32; // Broken pipe
|
||||
const Errno EDOM = 33; // Math argument out of domain of func
|
||||
const Errno ERANGE = 34; // Math result not representable
|
||||
|
||||
// https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/intro.2.html
|
||||
module libc::errno @if(env::DARWIN);
|
||||
const Errno EWOULDBLOCK = EAGAIN; // Operation would block
|
||||
const Errno EDEADLK = 11; // Resource deadlock would occur
|
||||
const Errno EINPROGRESS = 36; // Operation now in progress
|
||||
const Errno EALREADY = 37; // Operation already in progress
|
||||
const Errno ENOTSOCK = 38; // Socket operation on non-socket
|
||||
const Errno EDESTADDRREQ = 39; // Destination address required
|
||||
const Errno EMSGSIZE = 40; // Message too long
|
||||
const Errno EPROTOTYPE = 41; // Protocol wrong type for socket
|
||||
const Errno ENOPROTOOPT = 42; // Protocol not available
|
||||
const Errno EPROTONOSUPPORT = 43; // Protocol not supported
|
||||
const Errno ESOCKTNOSUPPORT = 44; // Socket type not supported
|
||||
const Errno ENOTSUP = 45; // Not supported
|
||||
const Errno EPFNOSUPPORT = 46; // Protocol family not supported
|
||||
const Errno EAFNOSUPPORT = 47; // Address family not supported by protocol family
|
||||
const Errno EADDRINUSE = 48; // Address already in use
|
||||
const Errno EADDRNOTAVAIL = 49; // Cannot assign requested address
|
||||
const Errno ENETDOWN = 50; // Network is down
|
||||
const Errno ENETUNREACH = 51; // Network is unreachable
|
||||
const Errno ENETRESET = 52; // Network dropped connection on reset
|
||||
const Errno ECONNABORTED = 53; // Software caused connection abort
|
||||
const Errno ECONNRESET = 54; // Connection reset by peer
|
||||
const Errno ENOBUFS = 55; // No buffer space available
|
||||
const Errno EISCONN = 56; // Socket is already connected
|
||||
const Errno ENOTCONN = 57; // Socket is not connected
|
||||
const Errno ESHUTDOWN = 58; // Cannot send after socket shutdown
|
||||
const Errno ETIMEDOUT = 60; // Operation timed out
|
||||
const Errno ECONNREFUSED = 61; // Connection refused
|
||||
const Errno ELOOP = 62; // Too many levels of symbolic links
|
||||
const Errno ENAMETOOLONG = 63; // File name too long
|
||||
const Errno EHOSTDOWN = 64; // Host is down
|
||||
const Errno EHOSTUNREACH = 65; // No route to host
|
||||
const Errno ENOTEMPTY = 66; // Directory not empty
|
||||
const Errno EPROCLIM = 67; // Too many processes
|
||||
const Errno EUSERS = 68; // Too many users
|
||||
const Errno EDQUOT = 69; // Disc quota exceeded
|
||||
const Errno ESTALE = 70; // Stale NFS file handle
|
||||
const Errno EBADRPC = 72; // RPC struct is bad
|
||||
const Errno ERPCMISMATCH = 73; // RPC version wrong
|
||||
const Errno EPROGUNAVAIL = 74; // RPC prog. not avail
|
||||
const Errno EPROGMISMATCH = 75; // Program version wrong
|
||||
const Errno EPROCUNAVAIL = 76; // Bad procedure for program
|
||||
const Errno ENOLCK = 77; // No locks available
|
||||
const Errno ENOSYS = 78; // Function not implemented
|
||||
const Errno EFTYPE = 79; // Inappropriate file type or format
|
||||
const Errno EAUTH = 80; // Authentication error
|
||||
const Errno ENEEDAUTH = 81; // Need authenticator
|
||||
const Errno EPWROFF = 82; // Device power is off
|
||||
const Errno EDEVERR = 83; // Device error
|
||||
const Errno EOVERFLOW = 84; // Value too large to be stored in data type
|
||||
const Errno EBADEXEC = 85; // Bad executable (or shared library)
|
||||
const Errno EBADARCH = 86; // Bad CPU type in executable
|
||||
const Errno ESHLIBVERS = 87; // Shared library version mismatch
|
||||
const Errno EBADMACHO = 88; // Malformed Mach-o file
|
||||
const Errno ECANCELED = 89; // Operation canceled
|
||||
const Errno EIDRM = 90; // Identifier removed
|
||||
const Errno ENOMSG = 91; // No message of desired type
|
||||
const Errno EILSEQ = 92; // Illegal byte sequence
|
||||
const Errno ENOATTR = 93; // Attribute not found
|
||||
const Errno EBADMSG = 94; // Bad message
|
||||
const Errno EMULTIHOP = 95; // Reserved
|
||||
const Errno ENODATA = 96; // No message available
|
||||
const Errno ENOLINK = 97; // Reserved
|
||||
const Errno ENOSR = 98; // No STREAM resources
|
||||
const Errno ENOSTR = 99; // Not a STREAM
|
||||
const Errno EPROTO = 100; // Protocol error
|
||||
const Errno ETIME = 101; // STREAM ioctl() timeout
|
||||
const Errno EOPNOTSUPP = 102; // Operation not supported on socket
|
||||
const Errno EWOULDBLOCK = EAGAIN; // Operation would block
|
||||
const Errno EDEADLK = 11; // Resource deadlock would occur
|
||||
const Errno EINPROGRESS = 36; // Operation now in progress
|
||||
const Errno EALREADY = 37; // Operation already in progress
|
||||
const Errno ENOTSOCK = 38; // Socket operation on non-socket
|
||||
const Errno EDESTADDRREQ = 39; // Destination address required
|
||||
const Errno EMSGSIZE = 40; // Message too long
|
||||
const Errno EPROTOTYPE = 41; // Protocol wrong type for socket
|
||||
const Errno ENOPROTOOPT = 42; // Protocol not available
|
||||
const Errno EPROTONOSUPPORT = 43; // Protocol not supported
|
||||
const Errno ESOCKTNOSUPPORT = 44; // Socket type not supported
|
||||
const Errno ENOTSUP = 45; // Not supported
|
||||
const Errno EPFNOSUPPORT = 46; // Protocol family not supported
|
||||
const Errno EAFNOSUPPORT = 47; // Address family not supported by protocol family
|
||||
const Errno EADDRINUSE = 48; // Address already in use
|
||||
const Errno EADDRNOTAVAIL = 49; // Cannot assign requested address
|
||||
const Errno ENETDOWN = 50; // Network is down
|
||||
const Errno ENETUNREACH = 51; // Network is unreachable
|
||||
const Errno ENETRESET = 52; // Network dropped connection on reset
|
||||
const Errno ECONNABORTED = 53; // Software caused connection abort
|
||||
const Errno ECONNRESET = 54; // Connection reset by peer
|
||||
const Errno ENOBUFS = 55; // No buffer space available
|
||||
const Errno EISCONN = 56; // Socket is already connected
|
||||
const Errno ENOTCONN = 57; // Socket is not connected
|
||||
const Errno ESHUTDOWN = 58; // Cannot send after socket shutdown
|
||||
const Errno ETIMEDOUT = 60; // Operation timed out
|
||||
const Errno ECONNREFUSED = 61; // Connection refused
|
||||
const Errno ELOOP = 62; // Too many levels of symbolic links
|
||||
const Errno ENAMETOOLONG = 63; // File name too long
|
||||
const Errno EHOSTDOWN = 64; // Host is down
|
||||
const Errno EHOSTUNREACH = 65; // No route to host
|
||||
const Errno ENOTEMPTY = 66; // Directory not empty
|
||||
const Errno EPROCLIM = 67; // Too many processes
|
||||
const Errno EUSERS = 68; // Too many users
|
||||
const Errno EDQUOT = 69; // Disc quota exceeded
|
||||
const Errno ESTALE = 70; // Stale NFS file handle
|
||||
const Errno EBADRPC = 72; // RPC struct is bad
|
||||
const Errno ERPCMISMATCH = 73; // RPC version wrong
|
||||
const Errno EPROGUNAVAIL = 74; // RPC prog. not avail
|
||||
const Errno EPROGMISMATCH = 75; // Program version wrong
|
||||
const Errno EPROCUNAVAIL = 76; // Bad procedure for program
|
||||
const Errno ENOLCK = 77; // No locks available
|
||||
const Errno ENOSYS = 78; // Function not implemented
|
||||
const Errno EFTYPE = 79; // Inappropriate file type or format
|
||||
const Errno EAUTH = 80; // Authentication error
|
||||
const Errno ENEEDAUTH = 81; // Need authenticator
|
||||
const Errno EPWROFF = 82; // Device power is off
|
||||
const Errno EDEVERR = 83; // Device error
|
||||
const Errno EOVERFLOW = 84; // Value too large to be stored in data type
|
||||
const Errno EBADEXEC = 85; // Bad executable (or shared library)
|
||||
const Errno EBADARCH = 86; // Bad CPU type in executable
|
||||
const Errno ESHLIBVERS = 87; // Shared library version mismatch
|
||||
const Errno EBADMACHO = 88; // Malformed Mach-o file
|
||||
const Errno ECANCELED = 89; // Operation canceled
|
||||
const Errno EIDRM = 90; // Identifier removed
|
||||
const Errno ENOMSG = 91; // No message of desired type
|
||||
const Errno EILSEQ = 92; // Illegal byte sequence
|
||||
const Errno ENOATTR = 93; // Attribute not found
|
||||
const Errno EBADMSG = 94; // Bad message
|
||||
const Errno EMULTIHOP = 95; // Reserved
|
||||
const Errno ENODATA = 96; // No message available
|
||||
const Errno ENOLINK = 97; // Reserved
|
||||
const Errno ENOSR = 98; // No STREAM resources
|
||||
const Errno ENOSTR = 99; // Not a STREAM
|
||||
const Errno EPROTO = 100; // Protocol error
|
||||
const Errno ETIME = 101; // STREAM ioctl() timeout
|
||||
const Errno EOPNOTSUPP = 102; // Operation not supported on socket
|
||||
|
||||
module libc::errno @if(env::WIN32);
|
||||
const Errno EDEADLK = 36; // Resource deadlock would occur Win32
|
||||
const Errno ENAMETOOLONG = 38; // File name too long Win32
|
||||
const Errno ELOOP = 114; // Too many symbolic links encountered
|
||||
const Errno EOVERFLOW = 132; // Value too large for defined data type
|
||||
const Errno ENETDOWN = 116; // Network is down
|
||||
const Errno ECONNRESET = 108; // Connection reset by peer
|
||||
const Errno ENETUNREACH = 118; // Network is unreachable
|
||||
const Errno ENETRESET = 117; // Network dropped connection because of reset
|
||||
const Errno EOPNOTSUPP = 130; // Operation not supported on transport endpoint
|
||||
const Errno ENOTEMPTY = 41; // Directory not empty
|
||||
const Errno ETIMEDOUT = 138; // Connection timed out
|
||||
const Errno EALREADY = 103; // Operation already in progress
|
||||
const Errno EINPROGRESS = 112; // Operation now in progress Win32
|
||||
const Errno EDQUOT = -122; // Quota exceeded, not in Win32
|
||||
const Errno EWOULDBLOCK = 140; // Operation would block
|
||||
// https://learn.microsoft.com/en-us/windows/win32/winsock/windows-sockets-error-codes-2
|
||||
const Errno ENOTSOCK = 10038; // Network is unreachable
|
||||
//const Errno EOPNOTSUPP = 10045; // Operation not supported on transport endpoint
|
||||
const Errno EADDRINUSE = 10048; // Address already in use
|
||||
const Errno EISCONN = 10056; // Socket is already connected
|
||||
const Errno ECONNREFUSED = 10061; // Connection refused
|
||||
//const Errno ENETUNREACH = 10065; // Network is unreachable
|
||||
const Errno EDEADLK = 36; // Resource deadlock would occur Win32
|
||||
const Errno ENAMETOOLONG = 38; // File name too long Win32
|
||||
const Errno ENOTEMPTY = 41; // Directory not empty
|
||||
const Errno ELOOP = 114; // Too many symbolic links encountered
|
||||
const Errno EOVERFLOW = 132; // Value too large for defined data type
|
||||
const Errno ENETDOWN = 116; // Network is down
|
||||
const Errno ECONNRESET = 108; // Connection reset by peer
|
||||
const Errno ENETUNREACH = 118; // Network is unreachable
|
||||
const Errno ENETRESET = 117; // Network dropped connection because of reset
|
||||
const Errno EOPNOTSUPP = 130; // Operation not supported on transport endpoint
|
||||
const Errno ETIMEDOUT = 138; // Connection timed out
|
||||
const Errno EALREADY = 103; // Operation already in progress
|
||||
const Errno EINPROGRESS = 112; // Operation now in progress Win32
|
||||
const Errno EDQUOT = -122; // Quota exceeded, not in Win32
|
||||
const Errno EWOULDBLOCK = 140; // Operation would block
|
||||
|
||||
module libc::errno @if(!env::WIN32 && !env::DARWIN);
|
||||
const Errno EDEADLK = 35; // Resource deadlock would occur Linux (others?)
|
||||
const Errno ENAMETOOLONG = 36; // File name too long Linux (others?)
|
||||
const Errno ENOTEMPTY = 39; // Directory not empty
|
||||
const Errno ELOOP = 40; // Too many symbolic links encountered
|
||||
const Errno EWOULDBLOCK = EAGAIN; // Operation would block
|
||||
const Errno EOVERFLOW = 75; // Value too large for defined data type
|
||||
const Errno ENOTSOCK = 88; // Socket operation on non-socket
|
||||
const Errno EOPNOTSUPP = 95; // Operation not supported on transport endpoint
|
||||
const Errno EADDRINUSE = 98; // Address already in use
|
||||
const Errno ENETDOWN = 100; // Network is down
|
||||
const Errno ENETUNREACH = 101; // Network is unreachable
|
||||
const Errno ENETRESET = 102; // Network dropped connection because of reset
|
||||
const Errno ECONNRESET = 104; // Connection reset by peer
|
||||
const Errno EISCONN = 106; // Socket is already connected
|
||||
const Errno ETIMEDOUT = 110; // Connection timed out
|
||||
const Errno ECONNREFUSED = 111; // Connection refused
|
||||
const Errno EALREADY = 114; // Operation already in progress
|
||||
const Errno EINPROGRESS = 115; // Operation now in progress
|
||||
const Errno EDQUOT = 122; // Quota exceeded
|
||||
const Errno EDEADLK = 35; // Resource deadlock would occur Linux (others?)
|
||||
const Errno ENAMETOOLONG = 36; // File name too long Linux (others?)
|
||||
const Errno ENOTEMPTY = 39; // Directory not empty
|
||||
const Errno ELOOP = 40; // Too many symbolic links encountered
|
||||
const Errno EWOULDBLOCK = EAGAIN; // Operation would block
|
||||
const Errno EOVERFLOW = 75; // Value too large for defined data type
|
||||
const Errno ENOTSOCK = 88; // Socket operation on non-socket
|
||||
const Errno EOPNOTSUPP = 95; // Operation not supported on transport endpoint
|
||||
const Errno EADDRINUSE = 98; // Address already in use
|
||||
const Errno EADDRNOTAVAIL = 99; // Cannot assign requested address
|
||||
const Errno ENETDOWN = 100; // Network is down
|
||||
const Errno ENETUNREACH = 101; // Network is unreachable
|
||||
const Errno ENETRESET = 102; // Network dropped connection because of reset
|
||||
const Errno ECONNRESET = 104; // Connection reset by peer
|
||||
const Errno EISCONN = 106; // Socket is already connected
|
||||
const Errno ETIMEDOUT = 110; // Connection timed out
|
||||
const Errno ECONNREFUSED = 111; // Connection refused
|
||||
const Errno EALREADY = 114; // Operation already in progress
|
||||
const Errno EINPROGRESS = 115; // Operation now in progress
|
||||
const Errno EDQUOT = 122; // Quota exceeded
|
||||
|
||||
|
||||
/*
|
||||
@@ -635,7 +629,6 @@ const Errno ESOCKTNOSUPPORT = 94; /* Socket type not supported */
|
||||
const Errno EPFNOSUPPORT = 96; /* Protocol family not supported */
|
||||
const Errno EAFNOSUPPORT = 97; /* Address family not supported by protocol */
|
||||
const Errno EADDRINUSE = 98; /* Address already in use */
|
||||
const Errno EADDRNOTAVAIL = 99; /* Cannot assign requested address */
|
||||
const Errno ECONNABORTED = 103; /* Software caused connection abort */
|
||||
const Errno ENOBUFS = 105; /* No buffer space available */
|
||||
const Errno EISCONN = 106; /* Transport endpoint is already connected */
|
||||
|
||||
@@ -2,6 +2,13 @@ module std::net;
|
||||
import std::io;
|
||||
import std::ascii;
|
||||
|
||||
enum IpProtocol : char (AIFamily ai_family)
|
||||
{
|
||||
UNSPECIFIED (os::AF_UNSPEC),
|
||||
IPV4 (os::AF_INET),
|
||||
IPV6 (os::AF_INET6),
|
||||
}
|
||||
|
||||
struct InetAddress
|
||||
{
|
||||
bool is_ipv6;
|
||||
@@ -250,3 +257,18 @@ fn bool InetAddress.is_multicast_link_local(InetAddress* addr)
|
||||
}
|
||||
return addr.ipv4.a == 224 && addr.ipv4.b == 0 && addr.ipv4.c == 0;
|
||||
}
|
||||
|
||||
fn AddrInfo*! addrinfo(String host, uint port, AIFamily ai_family, AISockType ai_socktype) @if(os::SUPPORTS_INET)
|
||||
{
|
||||
@pool()
|
||||
{
|
||||
ZString zhost = host.zstr_tcopy();
|
||||
DString str;
|
||||
str.tinit();
|
||||
str.printf("%d", port);
|
||||
AddrInfo hints = { .ai_family = ai_family, .ai_socktype = ai_socktype };
|
||||
AddrInfo* ai;
|
||||
if (os::getaddrinfo(zhost, str.copy_zstr(mem::temp()), &hints, &ai)) return NetError.ADDRINFO_FAILED?;
|
||||
return ai;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
module std::net;
|
||||
import std::net::os;
|
||||
|
||||
fault NetError
|
||||
{
|
||||
@@ -16,6 +15,8 @@ fault NetError
|
||||
READ_FAILED,
|
||||
SOCKOPT_FAILED,
|
||||
|
||||
SOCKETS_NOT_INITIALIZED,
|
||||
STILL_PROCESSING_CALLBACK,
|
||||
BAD_SOCKET_DESCRIPTOR,
|
||||
NOT_A_SOCKET,
|
||||
CONNECTION_REFUSED,
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
module std::net::os;
|
||||
const bool SUPPORTS_INET = env::LIBC && (env::WIN32 || env::DARWIN || env::LINUX);
|
||||
|
||||
def AIFamily = distinct CInt;
|
||||
def AIProtocol = distinct CInt;
|
||||
def AISockType = distinct CInt;
|
||||
def AIFlags = distinct CInt;
|
||||
|
||||
def Socklen_t = CUInt @if(!env::WIN32);
|
||||
def Socklen_t = usz @if(env::WIN32);
|
||||
|
||||
@@ -8,10 +13,10 @@ def SockAddrPtr = distinct void*;
|
||||
|
||||
struct AddrInfo
|
||||
{
|
||||
CInt ai_flags;
|
||||
CInt ai_family;
|
||||
CInt ai_socktype;
|
||||
CInt ai_protocol;
|
||||
AIFlags ai_flags;
|
||||
AIFamily ai_family;
|
||||
AISockType ai_socktype;
|
||||
AIProtocol ai_protocol;
|
||||
Socklen_t ai_addrlen;
|
||||
struct @if(env::WIN32 || env::DARWIN)
|
||||
{
|
||||
@@ -26,26 +31,35 @@ struct AddrInfo
|
||||
AddrInfo* ai_next;
|
||||
}
|
||||
|
||||
|
||||
const PLATFORM_O_NONBLOCK @if(!$defined(PLATFORM_O_NONBLOCK)) = 0;
|
||||
|
||||
const int PLATFORM_AF_UNIX = 1;
|
||||
const int PLATFORM_AF_INET = 2;
|
||||
const int PLATFORM_AF_INET6 @if(env::WIN32) = 23;
|
||||
const int PLATFORM_AF_INET6 @if(env::DARWIN) = 30;
|
||||
const int PLATFORM_AF_INET6 @if(env::LINUX) = 10;
|
||||
const AISockType SOCK_STREAM = 1; // Stream
|
||||
const AISockType SOCK_DGRAM = 2; // Datagram
|
||||
const AISockType SOCK_RAW = 3; // Raw
|
||||
const AISockType SOCK_RDM = 4; // Reliably delivered
|
||||
const AISockType SOCK_SEQPACKET = 5; // Sequential packet
|
||||
|
||||
const AI_PASSIVE = 0x1;
|
||||
const AI_CANONNAME = 0x2;
|
||||
const AI_NUMERICHOST = 0x4;
|
||||
const AIFlags AI_PASSIVE = 0x1;
|
||||
const AIFlags AI_CANONNAME = 0x2;
|
||||
const AIFlags AI_NUMERICHOST = 0x4;
|
||||
|
||||
const int AF_UNSPEC = 0;
|
||||
const int AF_INET @if(SUPPORTS_INET) = PLATFORM_AF_INET;
|
||||
const int AF_APPLETALK @if(SUPPORTS_INET) = PLATFORM_AF_APPLETALK;
|
||||
const int AF_IPX @if(SUPPORTS_INET) = PLATFORM_AF_IPX;
|
||||
const int AF_INET6 @if(SUPPORTS_INET) = PLATFORM_AF_INET6;
|
||||
const AIFamily AF_UNSPEC = 0;
|
||||
const AIFamily AF_UNIX = 1;
|
||||
const AIFamily AF_INET = 2;
|
||||
const AIFamily AF_INET6 = PLATFORM_AF_INET6;
|
||||
const AIFamily AF_IPX = PLATFORM_AF_IPX;
|
||||
const AIFamily AF_APPLETALK = PLATFORM_AF_APPLETALK;
|
||||
|
||||
const O_NONBLOCK = PLATFORM_O_NONBLOCK;
|
||||
|
||||
extern fn CInt getaddrinfo(ZString nodename, ZString servname, AddrInfo* hints, AddrInfo** res) @if(SUPPORTS_INET);
|
||||
extern fn void freeaddrinfo(AddrInfo* res) @if(SUPPORTS_INET);
|
||||
extern fn CInt setsockopt(NativeSocket socket, CInt level, CInt optname, void* optval, Socklen_t optlen) @if(SUPPORTS_INET);
|
||||
extern fn CInt getsockopt(NativeSocket socket, CInt level, CInt optname, void* optval, Socklen_t optlen) @if(SUPPORTS_INET);
|
||||
|
||||
module std::net::os @if(!env::LIBC || !(env::WIN32 || env::DARWIN || env::LINUX));
|
||||
|
||||
const AIFamily PLATFORM_AF_INET6 = 0;
|
||||
const AIFamily PLATFORM_AF_IPX = 0;
|
||||
const AIFamily PLATFORM_AF_APPLETALK = 0;
|
||||
|
||||
@@ -1,54 +1,85 @@
|
||||
module std::net::os @if(env::DARWIN);
|
||||
import libc;
|
||||
|
||||
const AI_NUMERICSERV = 0x1000;
|
||||
const AI_ALL = 0x100;
|
||||
const AI_V4MAPPED_CFG = 0x200;
|
||||
const AI_ADDRCONFIG = 0x400;
|
||||
const AI_V4MAPPED = 0x800;
|
||||
const AI_UNUSABLE = 0x10000000;
|
||||
const AI_DEFAULT = AI_V4MAPPED_CFG | AI_ADDRCONFIG;
|
||||
const AIFlags AI_NUMERICSERV = 0x1000;
|
||||
const AIFlags AI_ALL = 0x100;
|
||||
const AIFlags AI_V4MAPPED_CFG = 0x200;
|
||||
const AIFlags AI_ADDRCONFIG = 0x400;
|
||||
const AIFlags AI_V4MAPPED = 0x800;
|
||||
const AIFlags AI_UNUSABLE = 0x10000000;
|
||||
const AIFlags AI_DEFAULT = AI_V4MAPPED_CFG | AI_ADDRCONFIG;
|
||||
|
||||
const AIFamily PLATFORM_AF_IMPLINK = 3;
|
||||
const AIFamily PLATFORM_AF_PUP = 4;
|
||||
const AIFamily PLATFORM_AF_CHAOS = 5;
|
||||
const AIFamily PLATFORM_AF_NS = 6;
|
||||
const AIFamily PLATFORM_AF_ISO = 7;
|
||||
const AIFamily PLATFORM_AF_ECMA = 8;
|
||||
const AIFamily PLATFORM_AF_DATAKIT = 9;
|
||||
const AIFamily PLATFORM_AF_CCITT = 10;
|
||||
const AIFamily PLATFORM_AF_SNA = 11;
|
||||
const AIFamily PLATFORM_AF_DECNET = 12;
|
||||
const AIFamily PLATFORM_AF_DLI = 13;
|
||||
const AIFamily PLATFORM_AF_LAT = 14;
|
||||
const AIFamily PLATFORM_AF_HYLINK = 15;
|
||||
const AIFamily PLATFORM_AF_APPLETALK = 16;
|
||||
const AIFamily PLATFORM_AF_ROUTE = 17;
|
||||
const AIFamily PLATFORM_AF_LINK = 18;
|
||||
const AIFamily PLATFORM_PSEUDO_AF_XTP = 19;
|
||||
const AIFamily PLATFORM_AF_COIP = 20;
|
||||
const AIFamily PLATFORM_AF_CNT = 21;
|
||||
const AIFamily PLATFORM_PSEUDO_AF_RTIP = 22;
|
||||
const AIFamily PLATFORM_AF_IPX = 23;
|
||||
const AIFamily PLATFORM_AF_SIP = 24;
|
||||
const AIFamily PLATFORM_PSEUDO_AF_PIP = 25;
|
||||
const AIFamily PLATFORM_AF_NDRV = 27;
|
||||
const AIFamily PLATFORM_AF_ISDN = 28;
|
||||
const AIFamily PLATFORM_PSEUDO_AF_KEY = 29;
|
||||
const AIFamily PLATFORM_AF_INET6 = 30;
|
||||
const AIFamily PLATFORM_AF_NATM = 31;
|
||||
const AIFamily PLATFORM_AF_SYSTEM = 32;
|
||||
const AIFamily PLATFORM_AF_NETBIOS = 33;
|
||||
const AIFamily PLATFORM_AF_PPP = 34;
|
||||
const AIFamily PLATFORM_PSEUDO_AF_HDRCMPLT = 35;
|
||||
const AIFamily PLATFORM_AF_IEEE80211 = 37;
|
||||
const AIFamily PLATFORM_AF_UTUN = 38;
|
||||
const AIFamily PLATFORM_AF_VSOCK = 40;
|
||||
const AIFamily PLATFORM_AF_MAX = 41;
|
||||
|
||||
const int PLATFORM_AF_IMPLINK = 3;
|
||||
const int PLATFORM_AF_PUP = 4;
|
||||
const int PLATFORM_AF_CHAOS = 5;
|
||||
const int PLATFORM_AF_NS = 6;
|
||||
const int PLATFORM_AF_ISO = 7;
|
||||
const int PLATFORM_AF_ECMA = 8;
|
||||
const int PLATFORM_AF_DATAKIT = 9;
|
||||
const int PLATFORM_AF_CCITT = 10;
|
||||
const int PLATFORM_AF_SNA = 11;
|
||||
const int PLATFORM_AF_DECNET = 12;
|
||||
const int PLATFORM_AF_DLI = 13;
|
||||
const int PLATFORM_AF_LAT = 14;
|
||||
const int PLATFORM_AF_HYLINK = 15;
|
||||
const int PLATFORM_AF_APPLETALK = 16;
|
||||
const int PLATFORM_AF_ROUTE = 17;
|
||||
const int PLATFORM_AF_LINK = 18;
|
||||
const int PLATFORM_PSEUDO_AF_XTP = 19;
|
||||
const int PLATFORM_AF_COIP = 20;
|
||||
const int PLATFORM_AF_CNT = 21;
|
||||
const int PLATFORM_PSEUDO_AF_RTIP = 22;
|
||||
const int PLATFORM_AF_IPX = 23;
|
||||
const int PLATFORM_AF_SIP = 24;
|
||||
const int PLATFORM_PSEUDO_AF_PIP = 25;
|
||||
const int PLATFORM_AF_NDRV = 27;
|
||||
const int PLATFORM_AF_ISDN = 28;
|
||||
const int PLATFORM_PSEUDO_AF_KEY = 29;
|
||||
const int PLATFORM_AF_NATM = 31;
|
||||
const int PLATFORM_AF_SYSTEM = 32;
|
||||
const int PLATFORM_AF_NETBIOS = 33;
|
||||
const int PLATFORM_AF_PPP = 34;
|
||||
const int PLATFORM_PSEUDO_AF_HDRCMPLT = 35;
|
||||
const int PLATFORM_AF_IEEE80211 = 37;
|
||||
const int PLATFORM_AF_UTUN = 38;
|
||||
const int PLATFORM_AF_VSOCK = 40;
|
||||
const int PLATFORM_AF_MAX = 41;
|
||||
const int PLATFORM_O_NONBLOCK = 0x30;
|
||||
|
||||
// https://opensource.apple.com/source/xnu/xnu-4570.41.2/bsd/sys/socket.h.auto.html
|
||||
const int SOL_SOCKET = 0xffff;
|
||||
const int SO_REUSEADDR = 0x0004;
|
||||
const int SO_KEEPALIVE = 0x0008;
|
||||
const int SO_BROADCAST = 0x0020;
|
||||
const int SO_REUSEPORT = 0x0200;
|
||||
const int SOL_SOCKET = 0xffff;
|
||||
const int SO_DEBUG = 0x0001; // turn on debugging info recording
|
||||
const int SO_ACCEPTCONN = 0x0002; // socket has had listen()
|
||||
const int SO_REUSEADDR = 0x0004; // allow local address reuse
|
||||
const int SO_KEEPALIVE = 0x0008; // keep connections alive
|
||||
const int SO_DONTROUTE = 0x0010; // just use interface addresses
|
||||
const int SO_BROADCAST = 0x0020; // permit sending of broadcast msgs
|
||||
const int SO_USELOOPBACK = 0x0040; // bypass hardware when possible
|
||||
const int SO_LINGER = 0x0080; // linger on close if data present (in ticks)
|
||||
const int SO_OOBINLINE = 0x0100; // leave received OOB data in line
|
||||
const int SO_REUSEPORT = 0x0200; // allow local address & port reuse
|
||||
const int SO_TIMESTAMP = 0x0400; // timestamp received dgram traffic
|
||||
const int SO_TIMESTAMP_MONOTONIC = 0x0800; // Monotonically increasing timestamp on rcvd dgram
|
||||
const int SO_DONTTRUNC = 0x2000; // Apple Retain unread data
|
||||
const int SO_WANTMORE = 0x4000; // Apple: Give hint when more data ready
|
||||
const int SO_WANTOOBFLAG = 0x8000; // Apple: Want OOB in MSG_FLAG on receive
|
||||
|
||||
const int SO_SNDBUF = 0x1001; // Send buffer size
|
||||
const int SO_RCVBUF = 0x1002; // Recieve buffer size
|
||||
const int SO_SNDLOWAT = 0x1003; // Send low-water mark
|
||||
const int SO_RCVLOWAT = 0x1004; // Receive low-water mark
|
||||
const int SO_SNDTIMEO = 0x1005; // Send timeout
|
||||
const int SO_RCVTIMEO = 0x1006; // Receive timeout
|
||||
const int SO_ERROR = 0x1007; // Get error status and clear
|
||||
const int SO_TYPE = 0x1008; // Socket type
|
||||
const int SO_LABEL = 0x1010; // Socket MAC label
|
||||
const int SO_PEERLABEL = 0x1011; // Socket peer MAC label
|
||||
const int SO_NREAD = 0x1020; // Apple: get 1st-packet byte count
|
||||
const int SO_NKE = 0x1021; // Apple: Install socket-level NKE
|
||||
const int SO_NOSIGPIPE = 0x1022; // Apple: No SIGPIPE on EPIPE
|
||||
const int SO_NOADDRERR = 0x1023; // Apple: Returns EADDRNOTAVAIL when src is not available anymore
|
||||
const int SO_NWRITE = 0x1024; // Apple: Get number of bytes currently in send socket buffer
|
||||
const int SO_REUSESHAREUID = 0x1025; // Apple: Allow reuse of port/socket by different userids
|
||||
const int SO_LINGER_SEC = 0x1080; // linger on close if data present (in seconds)
|
||||
@@ -1,19 +1,80 @@
|
||||
module std::net::os @if(env::LINUX);
|
||||
import libc;
|
||||
|
||||
const int PLATFORM_AF_AX25 = 3;
|
||||
const int PLATFORM_AF_IPX = 4;
|
||||
const int PLATFORM_AF_APPLETALK = 5;
|
||||
const int PLATFORM_AF_NETROM = 6;
|
||||
const int PLATFORM_AF_BRIDGE = 7;
|
||||
const int PLATFORM_AF_AAL5 = 8;
|
||||
const int PLATFORM_AF_X25 = 9;
|
||||
const AIFamily PLATFORM_AF_AX25 = 3;
|
||||
const AIFamily PLATFORM_AF_IPX = 4;
|
||||
const AIFamily PLATFORM_AF_APPLETALK = 5;
|
||||
const AIFamily PLATFORM_AF_NETROM = 6;
|
||||
const AIFamily PLATFORM_AF_BRIDGE = 7;
|
||||
const AIFamily PLATFORM_AF_AAL5 = 8;
|
||||
const AIFamily PLATFORM_AF_X25 = 9;
|
||||
const AIFamily PLATFORM_AF_INET6 = 10;
|
||||
|
||||
const PLATFORM_O_NONBLOCK = 0o4000;
|
||||
|
||||
// https://git.sr.ht/~sircmpwn/hare/tree/master/item/rt/+linux/socket.ha
|
||||
// https://github.com/torvalds/linux/blob/master/include/uapi/asm-generic/socket.h
|
||||
const int SOL_SOCKET = 1;
|
||||
const int SO_REUSEADDR = 2;
|
||||
const int SO_BROADCAST = 6;
|
||||
const int SO_KEEPALIVE = 9;
|
||||
const int SO_REUSEPORT = 15;
|
||||
|
||||
const int SO_DEBUG = 1; // turn on debugging info recording
|
||||
const int SO_REUSEADDR = 2; // allow local address reuse
|
||||
const int SO_TYPE = 3;
|
||||
const int SO_ERROR = 4;
|
||||
const int SO_DONTROUTE = 5; // just use interface addresses
|
||||
const int SO_BROADCAST = 6; // permit sending of broadcast msgs
|
||||
const int SO_SNDBUF = 7; // Send buffer size
|
||||
const int SO_RCVBUF = 8; // Recieve buffer size
|
||||
const int SO_KEEPALIVE = 9; // keep connections alive
|
||||
const int SO_OOBINLINE = 10; // leave received OOB data in line
|
||||
const int SO_NO_CHECK = 11;
|
||||
const int SO_PRIORITY = 12;
|
||||
const int SO_LINGER = 13; // linger on close if data present (in ticks)
|
||||
const int SO_BSDCOMPAT = 14;
|
||||
const int SO_REUSEPORT = 15; // allow local address & port reuse
|
||||
const int SO_RCVLOWAT = 18;
|
||||
const int SO_SNDLOWAT = 19;
|
||||
const int SO_RCVTIMEO = 20; // IMPORTANT Verify before use
|
||||
const int SO_SNDTIMEO = 21; // IMPORTANT Verify before use
|
||||
const int SO_BINDTODEVICE = 25;
|
||||
const int SO_ATTACH_FILTER = 26;
|
||||
const int SO_DETACH_FILTER = 27;
|
||||
const int SO_PEERNAME = 28;
|
||||
const int SO_TIMESTAMP = 29; // IMPORTANT Verify before use timestamp received dgram traffic
|
||||
const int SO_ACCEPTCONN = 30;
|
||||
const int SO_PEERSEC = 31;
|
||||
const int SO_SNDBUFFORCE = 32;
|
||||
const int SO_RCVBUFFORCE = 33;
|
||||
const int SO_PASSSEC = 34;
|
||||
const int SO_MARK = 36;
|
||||
const int SO_PROTOCOL = 38;
|
||||
const int SO_DOMAIN = 39;
|
||||
const int SO_RXQ_OVFL = 40;
|
||||
const int SO_WIFI_STATUS = 41;
|
||||
const int SO_PEEK_OFF = 42;
|
||||
const int SO_NOFCS = 43;
|
||||
const int SO_LOCK_FILTER = 44;
|
||||
const int SO_SELECT_ERR_QUEUE = 45;
|
||||
const int SO_BUSY_POLL = 46;
|
||||
const int SO_MAX_PACING_RATE = 47;
|
||||
const int SO_BPF_EXTENSIONS = 48;
|
||||
const int SO_INCOMING_CPU = 49;
|
||||
const int SO_ATTACH_BPF = 50;
|
||||
const int SO_ATTACH_REUSEPORT_CBPF = 51;
|
||||
const int SO_ATTACH_REUSEPORT_EBPF = 52;
|
||||
const int SO_CNX_ADVICE = 53;
|
||||
const int SO_MEMINFO = 55;
|
||||
const int SO_INCOMING_NAPI_ID = 56;
|
||||
const int SO_COOKIE = 57;
|
||||
const int SO_PEERGROUPS = 59;
|
||||
const int SO_ZEROCOPY = 60;
|
||||
const int SO_TXTIME = 61;
|
||||
const int SO_BINDTOIFINDEX = 62;
|
||||
const int SO_DETACH_REUSEPORT_BPF = 68;
|
||||
const int SO_PREFER_BUSY_POLL = 69;
|
||||
const int SO_BUSY_POLL_BUDGET = 70;
|
||||
const int SO_NETNS_COOKIE = 71;
|
||||
const int SO_BUF_LOCK = 72;
|
||||
const int SO_RESERVE_MEM = 73;
|
||||
const int SO_TXREHASH = 74;
|
||||
const int SO_RCVMARK = 75;
|
||||
const int SO_PASSPIDFD = 76;
|
||||
const int SO_PEERPIDFD = 77;
|
||||
@@ -6,13 +6,34 @@ const int F_SETFL = 4;
|
||||
|
||||
def NativeSocket = distinct inline Fd;
|
||||
|
||||
|
||||
extern fn CInt connect(NativeSocket socket, SockAddrPtr address, Socklen_t address_len);
|
||||
extern fn NativeSocket socket(CInt af, CInt type, CInt protocol) @extern("socket");
|
||||
extern fn NativeSocket socket(AIFamily af, AISockType type, AIProtocol protocol) @extern("socket");
|
||||
extern fn int fcntl(NativeSocket socket, int cmd, ...) @extern("fcntl");
|
||||
extern fn CInt bind(NativeSocket socket, SockAddrPtr address, Socklen_t address_len) @extern("bind");
|
||||
extern fn CInt listen(NativeSocket socket, CInt backlog) @extern("listen");
|
||||
extern fn NativeSocket accept(NativeSocket socket, SockAddrPtr address, Socklen_t* address_len) @extern("accept");
|
||||
|
||||
fn anyfault socket_error()
|
||||
{
|
||||
switch (libc::errno())
|
||||
{
|
||||
case errno::EACCES: return IoError.NO_PERMISSION;
|
||||
case errno::EADDRINUSE: return NetError.ADDRESS_IN_USE;
|
||||
case errno::EALREADY: return NetError.CONNECTION_ALREADY_IN_PROGRESS;
|
||||
case errno::EBADF: return NetError.BAD_SOCKET_DESCRIPTOR;
|
||||
case errno::ECONNREFUSED: return NetError.CONNECTION_REFUSED;
|
||||
case errno::EISCONN: return NetError.ALREADY_CONNECTED;
|
||||
case errno::ENETUNREACH: return NetError.NETWORK_UNREACHABLE;
|
||||
case errno::ENOTSOCK: return NetError.NOT_A_SOCKET;
|
||||
case errno::EINTR: return IoError.INTERRUPTED;
|
||||
case errno::EWOULDBLOCK: return IoError.WOULD_BLOCK;
|
||||
case errno::EOPNOTSUPP: return NetError.OPERATION_NOT_SUPPORTED_ON_SOCKET;
|
||||
case errno::ETIMEDOUT: return NetError.CONNECTION_TIMED_OUT;
|
||||
default: return IoError.GENERAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
macro void! NativeSocket.close(self)
|
||||
{
|
||||
if (libc::close(self))
|
||||
|
||||
@@ -1,35 +1,74 @@
|
||||
module std::net::os @if(env::WIN32);
|
||||
import std::os::win32;
|
||||
import libc;
|
||||
|
||||
const int PLATFORM_AF_IPX = 6;
|
||||
const int PLATFORM_AF_APPLETALK = 16;
|
||||
const int PLATFORM_AF_NETBIOS = 17;
|
||||
const int PLATFORM_AF_IRDA = 26;
|
||||
const int PLATFORM_AF_BTH = 32;
|
||||
const AIFamily PLATFORM_AF_IPX = 6;
|
||||
const AIFamily PLATFORM_AF_APPLETALK = 16;
|
||||
const AIFamily PLATFORM_AF_NETBIOS = 17;
|
||||
const AIFamily PLATFORM_AF_INET6 = 23;
|
||||
const AIFamily PLATFORM_AF_IRDA = 26;
|
||||
const AIFamily PLATFORM_AF_BTH = 32;
|
||||
|
||||
def NativeSocket = distinct uptr;
|
||||
|
||||
extern fn int wsa_startup(int, void*) @extern("WSAStartup");
|
||||
extern fn int ioctlsocket(NativeSocket, long cmd, ulong *argp);
|
||||
extern fn int closesocket(NativeSocket);
|
||||
extern fn NativeSocket socket(int af, int type, int protocol);
|
||||
extern fn WSAError closesocket(NativeSocket);
|
||||
extern fn NativeSocket socket(AIFamily af, AISockType type, AIProtocol protocol);
|
||||
extern fn int connect(NativeSocket, SockAddrPtr address, Socklen_t address_len);
|
||||
extern fn int bind(NativeSocket, SockAddrPtr address, Socklen_t address_len);
|
||||
extern fn int listen(NativeSocket, int backlog);
|
||||
extern fn NativeSocket accept(NativeSocket, SockAddrPtr address, Socklen_t* address_len);
|
||||
|
||||
macro NativeSocket.close(self)
|
||||
macro void! NativeSocket.close(self)
|
||||
{
|
||||
if (int err = closesocket(self))
|
||||
{
|
||||
if (err == WSAENOTSOCK) return NetError.INVALID_SOCKET?;
|
||||
return NetError.GENERAL_ERROR?;
|
||||
}
|
||||
WSAError error = closesocket(self);
|
||||
if (error) return convert_error(error)?;
|
||||
}
|
||||
|
||||
const int WSAENOTSOCK = 10038;
|
||||
|
||||
// https://github.com/wine-mirror/wine/blob/master/include/winsock.h
|
||||
const int SOL_SOCKET = 0xffff;
|
||||
const int SO_REUSEADDR = 0x0004;
|
||||
const int SO_KEEPALIVE = 0x0008;
|
||||
const int SO_BROADCAST = 0x0200;
|
||||
const int SOL_SOCKET = 0xffff;
|
||||
const int SO_DEBUG = 0x0001;
|
||||
const int SO_ACCEPTCONN = 0x0002;
|
||||
const int SO_REUSEADDR = 0x0004;
|
||||
const int SO_KEEPALIVE = 0x0008;
|
||||
const int SO_DONTROUTE = 0x0010;
|
||||
const int SO_BROADCAST = 0x0020;
|
||||
const int SO_USELOOPBACK = 0x0040;
|
||||
const int SO_LINGER = 0x0080;
|
||||
const int SO_OOBINLINE = 0x0100;
|
||||
const int SO_SNDBUF = 0x1001;
|
||||
const int SO_RCVBUF = 0x1002;
|
||||
const int SO_SNDLOWAT = 0x1003;
|
||||
const int SO_RCVLOWAT = 0x1004;
|
||||
const int SO_SNDTIMEO = 0x1005;
|
||||
const int SO_RCVTIMEO = 0x1006;
|
||||
const int SO_ERROR = 0x1007;
|
||||
const int SO_TYPE = 0x1008;
|
||||
|
||||
fn anyfault convert_error(WSAError error)
|
||||
{
|
||||
switch (error)
|
||||
{
|
||||
case wsa::NOTINITIALISED: return NetError.SOCKETS_NOT_INITIALIZED;
|
||||
case wsa::ENETDOWN: return NetError.NETWORK_UNREACHABLE;
|
||||
case wsa::INVALID_HANDLE: return NetError.BAD_SOCKET_DESCRIPTOR;
|
||||
case wsa::EACCESS: return IoError.NO_PERMISSION;
|
||||
case wsa::EINPROGRESS: return NetError.STILL_PROCESSING_CALLBACK;
|
||||
case wsa::EADDRINUSE: return NetError.ADDRESS_IN_USE;
|
||||
case wsa::EALREADY: return NetError.CONNECTION_ALREADY_IN_PROGRESS;
|
||||
case wsa::EBADF: return NetError.BAD_SOCKET_DESCRIPTOR;
|
||||
case wsa::EINTR: return IoError.INTERRUPTED;
|
||||
case wsa::EWOULDBLOCK: return IoError.WOULD_BLOCK;
|
||||
case wsa::ECONNREFUSED: return NetError.CONNECTION_REFUSED;
|
||||
case wsa::EISCONN: return NetError.ALREADY_CONNECTED;
|
||||
case wsa::ENETUNREACH: return NetError.NETWORK_UNREACHABLE;
|
||||
case wsa::ENOTSOCK: return NetError.NOT_A_SOCKET;
|
||||
case wsa::EOPNOTSUPP: return NetError.OPERATION_NOT_SUPPORTED_ON_SOCKET;
|
||||
case wsa::ETIMEDOUT: return NetError.CONNECTION_TIMED_OUT;
|
||||
default: return IoError.GENERAL_ERROR;
|
||||
}
|
||||
}
|
||||
fn anyfault socket_error()
|
||||
{
|
||||
return convert_error(win32_WSAGetLastError());
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
module std::net;
|
||||
import std::io;
|
||||
import libc;
|
||||
|
||||
const int SOCK_STREAM = 1; // Stream
|
||||
const int SOCK_DGRAM = 2; // Datagram
|
||||
const int SOCK_RAW = 3; // Raw
|
||||
const int SOCK_RDM = 4; // Reliably delivered
|
||||
const int SOCK_SEQPACKET = 5; // Sequential packet
|
||||
@@ -2,14 +2,38 @@ module std::net @if(os::SUPPORTS_INET);
|
||||
import std::io;
|
||||
import libc;
|
||||
|
||||
enum Network : char (int domain, int type)
|
||||
enum Network : char (AIFamily domain, AISockType type)
|
||||
{
|
||||
TCP (os::AF_INET, SOCK_STREAM),
|
||||
TCP6 (os::AF_INET6, SOCK_STREAM),
|
||||
UDP (os::AF_INET, SOCK_DGRAM),
|
||||
UDP6 (os::AF_INET6, SOCK_DGRAM),
|
||||
TCP (os::AF_INET, os::SOCK_STREAM),
|
||||
TCP6 (os::AF_INET6, os::SOCK_STREAM),
|
||||
UDP (os::AF_INET, os::SOCK_DGRAM),
|
||||
UDP6 (os::AF_INET6, os::SOCK_DGRAM),
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct Socket
|
||||
{
|
||||
NativeSocket sock;
|
||||
Socklen_t ai_addrlen;
|
||||
// TODO proper way to get the size of sockaddr_storage
|
||||
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms740504(v=vs.85)
|
||||
char[128] ai_addr_storage;
|
||||
}
|
||||
|
||||
fn Socket! _connect(AddrInfo* addrinfo, SocketOption[] options)
|
||||
{
|
||||
@loop_over_ai(addrinfo; NativeSocket sockfd, AddrInfo* ai)
|
||||
{
|
||||
apply_sockoptions(sockfd, options)!;
|
||||
int errcode = os::connect(sockfd, ai.ai_addr, ai.ai_addrlen);
|
||||
// Keep the first successful connection.
|
||||
if (!errcode) return network_socket(sockfd, ai);
|
||||
};
|
||||
return os::socket_error()?;
|
||||
}
|
||||
|
||||
|
||||
fn Socket! Network.connect(&self, String host, String port, SocketOption... options)
|
||||
{
|
||||
@network_loop_over_ai(self, host, port; NativeSocket sockfd, AddrInfo* ai)
|
||||
@@ -19,20 +43,7 @@ fn Socket! Network.connect(&self, String host, String port, SocketOption... opti
|
||||
// Keep the first successful connection.
|
||||
if (errcode == 0) return network_socket(sockfd, ai);
|
||||
}!;
|
||||
switch (libc::errno())
|
||||
{
|
||||
case errno::EACCES: return IoError.NO_PERMISSION?;
|
||||
case errno::EADDRINUSE: return NetError.ADDRESS_IN_USE?;
|
||||
case errno::EALREADY: return NetError.CONNECTION_ALREADY_IN_PROGRESS?;
|
||||
case errno::EBADF: return NetError.BAD_SOCKET_DESCRIPTOR?;
|
||||
case errno::ECONNREFUSED: return NetError.CONNECTION_REFUSED?;
|
||||
case errno::EISCONN: return NetError.ALREADY_CONNECTED?;
|
||||
case errno::ENETUNREACH: return NetError.NETWORK_UNREACHABLE?;
|
||||
case errno::ENOTSOCK: return NetError.NOT_A_SOCKET?;
|
||||
case errno::EOPNOTSUPP: return NetError.OPERATION_NOT_SUPPORTED_ON_SOCKET?;
|
||||
case errno::ETIMEDOUT: return NetError.CONNECTION_TIMED_OUT?;
|
||||
}
|
||||
return NetError.CONNECT_FAILED?;
|
||||
return os::socket_error()?;
|
||||
}
|
||||
|
||||
fn Socket! Network.listen(&self, String host, String port, int backlog, SocketOption... options)
|
||||
@@ -48,14 +59,7 @@ fn Socket! Network.listen(&self, String host, String port, int backlog, SocketOp
|
||||
if (errcode == 0) return network_socket(sockfd, ai);
|
||||
}
|
||||
}!;
|
||||
switch (libc::errno())
|
||||
{
|
||||
case errno::EADDRINUSE: return NetError.ADDRESS_IN_USE?;
|
||||
case errno::EBADF: return NetError.BAD_SOCKET_DESCRIPTOR?;
|
||||
case errno::ENOTSOCK: return NetError.NOT_A_SOCKET?;
|
||||
case errno::EOPNOTSUPP: return NetError.OPERATION_NOT_SUPPORTED_ON_SOCKET?;
|
||||
}
|
||||
return NetError.LISTEN_FAILED?;
|
||||
return os::socket_error()?;
|
||||
}
|
||||
|
||||
fn AddrInfo*! Network.addrinfo(&self, String host, String port) @private
|
||||
@@ -69,10 +73,23 @@ fn AddrInfo*! Network.addrinfo(&self, String host, String port) @private
|
||||
return ai;
|
||||
}
|
||||
|
||||
macro apply_sockoptions(sockfd, options) @private
|
||||
macro apply_sockoptions(sockfd, options)
|
||||
{
|
||||
Socket sock = { .sock = sockfd };
|
||||
foreach (o : options) sock.set_option(o)!;
|
||||
foreach (o : options) sock.set_option(o, true)!;
|
||||
}
|
||||
|
||||
macro void @loop_over_ai(AddrInfo* ai; @body(NativeSocket fd, AddrInfo* ai))
|
||||
{
|
||||
while (ai)
|
||||
{
|
||||
NativeSocket sockfd = os::socket(ai.ai_family, ai.ai_socktype, ai.ai_protocol);
|
||||
if (sockfd > 0)
|
||||
{
|
||||
@body(sockfd, ai);
|
||||
}
|
||||
ai = ai.ai_next;
|
||||
}
|
||||
}
|
||||
|
||||
macro @network_loop_over_ai(network, host, port; @body(fd, ai)) @private
|
||||
@@ -91,7 +108,7 @@ macro @network_loop_over_ai(network, host, port; @body(fd, ai)) @private
|
||||
}
|
||||
}
|
||||
|
||||
macro Socket network_socket(fd, ai) @private
|
||||
macro Socket network_socket(fd, ai)
|
||||
{
|
||||
Socket sock = { .sock = fd, .ai_addrlen = ai.ai_addrlen };
|
||||
assert(sock.ai_addr_storage.len >= ai.ai_addrlen, "storage %d < addrlen %d", sock.ai_addr_storage.len, ai.ai_addrlen);
|
||||
@@ -99,28 +116,17 @@ macro Socket network_socket(fd, ai) @private
|
||||
return sock;
|
||||
}
|
||||
|
||||
enum SocketOption : char (CInt value) @if(!env::WIN32)
|
||||
{
|
||||
REUSEADDR (os::SO_REUSEADDR),
|
||||
REUSEPORT (os::SO_REUSEPORT),
|
||||
KEEPALIVE (os::SO_KEEPALIVE),
|
||||
BROADCAST (os::SO_BROADCAST),
|
||||
}
|
||||
enum SocketOption : char (CInt value) @if(env::WIN32)
|
||||
enum SocketOption : char (CInt value)
|
||||
{
|
||||
REUSEADDR (os::SO_REUSEADDR),
|
||||
REUSEPORT (os::SO_REUSEPORT) @if(!env::WIN32),
|
||||
KEEPALIVE (os::SO_KEEPALIVE),
|
||||
BROADCAST (os::SO_BROADCAST),
|
||||
OOBINLINE (os::SO_OOBINLINE),
|
||||
DONTROUTE (os::SO_DONTROUTE),
|
||||
}
|
||||
|
||||
struct Socket
|
||||
{
|
||||
NativeSocket sock;
|
||||
Socklen_t ai_addrlen;
|
||||
// TODO proper way to get the size of sockaddr_storage
|
||||
// https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms740504(v=vs.85)
|
||||
char[128] ai_addr_storage;
|
||||
}
|
||||
|
||||
|
||||
fn Stream Socket.as_stream(&self)
|
||||
{
|
||||
@@ -133,18 +139,37 @@ StreamInterface socketstream_interface = {
|
||||
.close_fn = fn(s) => ((Socket*)s.data).close(),
|
||||
};
|
||||
|
||||
fn void! Socket.set_option(&self, SocketOption option)
|
||||
fn bool! Socket.get_broadcast(&self) => self.get_option(BROADCAST);
|
||||
fn bool! Socket.get_keepalive(&self) => self.get_option(KEEPALIVE);
|
||||
fn bool! Socket.get_reuseaddr(&self) => self.get_option(REUSEADDR);
|
||||
fn bool! Socket.get_dontroute(&self) => self.get_option(DONTROUTE);
|
||||
fn bool! Socket.get_oobinline(&self) => self.get_option(OOBINLINE);
|
||||
|
||||
fn void! Socket.set_broadcast(&self, bool value) => self.set_option(BROADCAST, value);
|
||||
fn void! Socket.set_keepalive(&self, bool value) => self.set_option(KEEPALIVE, value);
|
||||
fn void! Socket.set_reuseaddr(&self, bool value) => self.set_option(REUSEADDR, value);
|
||||
fn void! Socket.set_dontroute(&self, bool value) => self.set_option(DONTROUTE, value);
|
||||
fn void! Socket.set_oobinline(&self, bool value) => self.set_option(OOBINLINE, value);
|
||||
|
||||
fn void! Socket.set_option(&self, SocketOption option, bool value)
|
||||
{
|
||||
CInt flag = 1;
|
||||
CInt flag = (CInt)value;
|
||||
int errcode = os::setsockopt(self.sock, os::SOL_SOCKET, option.value, &flag, CInt.sizeof);
|
||||
if (errcode != 0) return NetError.SOCKOPT_FAILED?;
|
||||
}
|
||||
|
||||
fn void! Socket.unset_option(&self, SocketOption option)
|
||||
macro void! @set_option_value(NativeSocket sock, CInt option, value)
|
||||
{
|
||||
CInt flag = 0;
|
||||
var val = value;
|
||||
if (os::setsockopt(sock, os::SOL_SOCKET, option, &val, $sizeof(val))) return NetError.SOCKOPT_FAILED?;
|
||||
}
|
||||
|
||||
fn bool! Socket.get_option(&self, SocketOption option)
|
||||
{
|
||||
CInt flag;
|
||||
int errcode = os::setsockopt(self.sock, os::SOL_SOCKET, option.value, &flag, CInt.sizeof);
|
||||
if (errcode != 0) return NetError.SOCKOPT_FAILED?;
|
||||
return (bool)flag;
|
||||
}
|
||||
|
||||
fn usz! Socket.read(&self, char[] bytes)
|
||||
|
||||
45
lib/std/net/tcp.c3
Normal file
45
lib/std/net/tcp.c3
Normal file
@@ -0,0 +1,45 @@
|
||||
module std::net::tcp @if(os::SUPPORTS_INET);
|
||||
import libc;
|
||||
|
||||
def TcpSocket = distinct inline Socket;
|
||||
def TcpServerSocket = distinct inline Socket;
|
||||
|
||||
fn TcpSocket! connect(String host, uint port, SocketOption... options, IpProtocol protocol = UNSPECIFIED)
|
||||
{
|
||||
AddrInfo* ai = net::addrinfo(host, port, protocol.ai_family, os::SOCK_STREAM)!;
|
||||
defer os::freeaddrinfo(ai);
|
||||
return connect_to(ai, ...options);
|
||||
}
|
||||
|
||||
fn TcpSocket! connect_to(AddrInfo* ai, SocketOption... options)
|
||||
{
|
||||
return (TcpSocket)net::_connect(ai, options);
|
||||
}
|
||||
|
||||
fn TcpServerSocket! listen(String host, uint port, uint backlog, SocketOption... options, IpProtocol protocol = UNSPECIFIED)
|
||||
{
|
||||
AddrInfo* ai = net::addrinfo(host, port, protocol.ai_family, os::SOCK_STREAM)!;
|
||||
defer os::freeaddrinfo(ai);
|
||||
return listen_to(ai, backlog, ...options);
|
||||
}
|
||||
|
||||
fn TcpSocket! accept(TcpServerSocket* server_socket)
|
||||
{
|
||||
TcpSocket socket;
|
||||
socket.sock = os::accept(server_socket.sock, (SockAddrPtr)&socket.ai_addr_storage, &socket.ai_addrlen);
|
||||
if (socket.sock < 0) return NetError.ACCEPT_FAILED?;
|
||||
return socket;
|
||||
}
|
||||
|
||||
fn TcpServerSocket! listen_to(AddrInfo* ai, uint backlog, SocketOption... options)
|
||||
{
|
||||
net::@loop_over_ai(ai; NativeSocket sockfd, AddrInfo* ai_candidate)
|
||||
{
|
||||
net::apply_sockoptions(sockfd, options)!;
|
||||
bool err = os::bind(sockfd, ai_candidate.ai_addr, ai_candidate.ai_addrlen) || os::listen(sockfd, backlog);
|
||||
if (!err) return (TcpServerSocket)net::network_socket(sockfd, ai_candidate);
|
||||
};
|
||||
return os::socket_error()?;
|
||||
}
|
||||
|
||||
|
||||
15
lib/std/net/udp.c3
Normal file
15
lib/std/net/udp.c3
Normal file
@@ -0,0 +1,15 @@
|
||||
module std::net::udp @if(os::SUPPORTS_INET);
|
||||
|
||||
def UdpSocket = distinct inline Socket;
|
||||
|
||||
fn UdpSocket! connect(String host, uint port, SocketOption... options, IpProtocol protocol = UNSPECIFIED)
|
||||
{
|
||||
AddrInfo* ai = net::addrinfo(host, port, protocol.ai_family, os::SOCK_DGRAM)!;
|
||||
defer os::freeaddrinfo(ai);
|
||||
return connect_to(ai, ...options);
|
||||
}
|
||||
|
||||
fn UdpSocket! connect_to(AddrInfo* ai, SocketOption... options)
|
||||
{
|
||||
return (UdpSocket)net::_connect(ai, options);
|
||||
}
|
||||
@@ -2,30 +2,105 @@ module std::os::win32 @if(env::WIN32);
|
||||
|
||||
def WSAError = distinct int;
|
||||
|
||||
extern fn WSAError win32_WSAGetLastError() @extern("WSAGetLastError");
|
||||
extern fn void win32_WSASetLastError(WSAError error) @extern("WSASetLastError");
|
||||
extern fn WSAError win32_WSAGetLastError() @extern("WSAGetLastError") @builtin;
|
||||
extern fn void win32_WSASetLastError(WSAError error) @extern("WSASetLastError") @builtin;
|
||||
extern fn CInt win32_WSAStartup(Win32_WORD, void*) @extern("WSAStartup") @builtin;
|
||||
|
||||
module std::os::win32::wsa @if(env::WIN32);
|
||||
|
||||
const WSAError INVALID_HANDLE = 6;
|
||||
const WSAError NOT_ENOUGHT_MEMORY = 8;
|
||||
const WSAError INVALID_PARAMETER = 87;
|
||||
const WSAError OPERATION_ABORTED = 995;
|
||||
const WSAError IO_INCOMPLETE = 996;
|
||||
const WSAError IO_PENDING = 997;
|
||||
const WSAError EINTR = 10004;
|
||||
const WSAError EBADF = 10009;
|
||||
const WSAError ACCESS = 10013;
|
||||
const WSAError EFAULT = 10014;
|
||||
const WSAError EINVAL = 10022;
|
||||
const WSAError EMFILE = 10024;
|
||||
const WSAError EWOULDBLOCK = 10035;
|
||||
const WSAError EINPROGRESS = 10036;
|
||||
const WSAError EALREADY = 10037;
|
||||
const WSAError ENOTSOCK = 10038;
|
||||
const WSAError EDESTADDRREQ = 10039;
|
||||
const WSAError EMSGSIZE = 10040;
|
||||
const WSAError EPROTOTYPE = 10041;
|
||||
const WSAError ENOPROTOOPT = 10042;
|
||||
const WSAError EPROTONOSUPPORT = 10043;
|
||||
const WSAError ESOCKTNOSUPPORT = 10044;
|
||||
const WSAError NO_ERROR = 0;
|
||||
const WSAError INVALID_HANDLE = 6;
|
||||
const WSAError NOT_ENOUGH_MEMORY = 8;
|
||||
const WSAError INVALID_PARAMETER = 87;
|
||||
const WSAError OPERATION_ABORTED = 995;
|
||||
const WSAError IO_INCOMPLETE = 996;
|
||||
const WSAError IO_PENDING = 997;
|
||||
const WSAError EINTR = 10004;
|
||||
const WSAError EBADF = 10009;
|
||||
const WSAError EACCESS = 10013;
|
||||
const WSAError EFAULT = 10014;
|
||||
const WSAError EINVAL = 10022;
|
||||
const WSAError EMFILE = 10024;
|
||||
const WSAError EWOULDBLOCK = 10035;
|
||||
const WSAError EINPROGRESS = 10036;
|
||||
const WSAError EALREADY = 10037;
|
||||
const WSAError ENOTSOCK = 10038;
|
||||
const WSAError EDESTADDRREQ = 10039;
|
||||
const WSAError EMSGSIZE = 10040;
|
||||
const WSAError EPROTOTYPE = 10041;
|
||||
const WSAError ENOPROTOOPT = 10042;
|
||||
const WSAError EPROTONOSUPPORT = 10043;
|
||||
const WSAError ESOCKTNOSUPPORT = 10044;
|
||||
const WSAError EOPNOTSUPP = 10045;
|
||||
const WSAError EPFNOSUPPORT = 10046;
|
||||
const WSAError EAFNOSUPPORT = 10047;
|
||||
const WSAError EADDRINUSE = 10048;
|
||||
const WSAError EADDRNOTAVAIL = 10049;
|
||||
const WSAError ENETDOWN = 10050;
|
||||
const WSAError ENETUNREACH = 10051;
|
||||
const WSAError ENETRESET = 10052;
|
||||
const WSAError ECONNABORTED = 10053;
|
||||
const WSAError ECONNRESET = 10054;
|
||||
const WSAError ENOBUFS = 10055;
|
||||
const WSAError EISCONN = 10056;
|
||||
const WSAError ENOTCONN = 10057;
|
||||
const WSAError ESHUTDOWN = 10058;
|
||||
const WSAError ETOOMANYREFS = 10059;
|
||||
const WSAError ETIMEDOUT = 10060;
|
||||
const WSAError ECONNREFUSED = 10061;
|
||||
const WSAError ELOOP = 10062;
|
||||
const WSAError ENAMETOOLONG = 10063;
|
||||
const WSAError EHOSTDOWN = 10064;
|
||||
const WSAError EHOSTUNREACH = 10065;
|
||||
const WSAError ENOTEMPTY = 10066;
|
||||
const WSAError EPROCLIM = 10067;
|
||||
const WSAError EUSERS = 10068;
|
||||
const WSAError EDQUOT = 10069;
|
||||
const WSAError ESTALE = 10070;
|
||||
const WSAError EREMOTE = 10071;
|
||||
const WSAError SYSNOTREADY = 10091;
|
||||
const WSAError VERNOTSUPPORTED = 10092;
|
||||
const WSAError NOTINITIALISED = 10093;
|
||||
const WSAError EDISCON = 10101;
|
||||
const WSAError ENOMORE = 10102;
|
||||
const WSAError ECANCELLED = 10103;
|
||||
const WSAError EINVALIDPROCTABLE = 10104;
|
||||
const WSAError EINVALIDPROVIDER = 10105;
|
||||
const WSAError EPROVIDERFAILEDINIT = 10106;
|
||||
const WSAError SYSCALLFAILURE = 10107;
|
||||
const WSAError SERVICE_NOT_FOUND = 10108;
|
||||
const WSAError TYPE_NOT_FOUND = 10109;
|
||||
const WSAError E_NO_MORE = 10110;
|
||||
const WSAError E_CANCELLED = 10111;
|
||||
const WSAError REFUSED = 10112;
|
||||
const WSAError HOST_NOT_FOUND = 11001;
|
||||
const WSAError TRY_AGAIN = 11002;
|
||||
const WSAError NO_RECOVERY = 11003;
|
||||
const WSAError NO_DATA = 11004;
|
||||
const WSAError QOS_RECEIVERS = 11005;
|
||||
const WSAError QOS_SENDERS = 11006;
|
||||
const WSAError QOS_NO_SENDERS = 11007;
|
||||
const WSAError QOS_NO_RECEIVERS = 11008;
|
||||
const WSAError QOS_REQUEST_CONFIRMED = 11009;
|
||||
const WSAError QOS_ADMISSION_FAILURE = 11010;
|
||||
const WSAError QOS_POLICY_FAILURE = 11011;
|
||||
const WSAError QOS_BAD_STYLE = 11012;
|
||||
const WSAError QOS_BAD_OBJECT = 11013;
|
||||
const WSAError QOS_TRAFFIC_CTRL_ERROR = 11014;
|
||||
const WSAError QOS_GENERIC_ERROR = 11015;
|
||||
const WSAError QOS_ESERVICETYPE = 11016;
|
||||
const WSAError QOS_EFLOWSPEC = 11017;
|
||||
const WSAError QOS_EPROVSPECBUF = 11018;
|
||||
const WSAError QOS_EFILTERSTYLE = 11019;
|
||||
const WSAError QOS_EFILTERTYPE = 11020;
|
||||
const WSAError QOS_EFILTERCOUNT = 11021;
|
||||
const WSAError QOS_EOBJLENGTH = 11022;
|
||||
const WSAError QOS_EFLOWCOUNT = 11023;
|
||||
const WSAError QOS_EUNKOWNPSOBJ = 11024;
|
||||
const WSAError QOS_EPOLICYOBJ = 11025;
|
||||
const WSAError QOS_EFLOWDESC = 11026;
|
||||
const WSAError QOS_EPSFLOWSPEC = 11027;
|
||||
const WSAError QOS_EPSFILTERSPEC = 11028;
|
||||
const WSAError QOS_ESDMODEOBJ = 11029;
|
||||
const WSAError QOS_ESHAPERATEOBJ = 11030;
|
||||
const WSAError QOS_RESERVED_PETYPE = 11031;
|
||||
|
||||
@@ -164,7 +164,7 @@ fn double DateTime.diff_sec(self, DateTime from)
|
||||
{
|
||||
return (double)self.time.diff_us(from.time) / (double)time::MICROSECONDS_PER_SECOND;
|
||||
}
|
||||
fn TimeDuration DateTime.diff_us(self, DateTime from)
|
||||
fn Duration DateTime.diff_us(self, DateTime from)
|
||||
{
|
||||
return self.time.diff_us(from.time);
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
module std::time;
|
||||
|
||||
def Time = distinct long @inline;
|
||||
def TimeDuration = distinct long @inline;
|
||||
def Duration = distinct long @inline;
|
||||
def Clock = distinct ulong @inline;
|
||||
def NanoDuration = distinct long @inline;
|
||||
|
||||
const TimeDuration MICROSECONDS_PER_SECOND = 1_000_000;
|
||||
const TimeDuration MICROSECONDS_PER_MINUTE = MICROSECONDS_PER_SECOND * 60;
|
||||
const TimeDuration MICROSECONDS_PER_HOUR = MICROSECONDS_PER_MINUTE * 60;
|
||||
const TimeDuration MICROSECONDS_PER_DAY = MICROSECONDS_PER_HOUR * 24;
|
||||
const TimeDuration MICROSECONDS_PER_WEEK = MICROSECONDS_PER_DAY * 7;
|
||||
const Duration MICROSECONDS_PER_SECOND = 1_000_000;
|
||||
const Duration MICROSECONDS_PER_MINUTE = MICROSECONDS_PER_SECOND * 60;
|
||||
const Duration MICROSECONDS_PER_HOUR = MICROSECONDS_PER_MINUTE * 60;
|
||||
const Duration MICROSECONDS_PER_DAY = MICROSECONDS_PER_HOUR * 24;
|
||||
const Duration MICROSECONDS_PER_WEEK = MICROSECONDS_PER_DAY * 7;
|
||||
|
||||
struct DateTime
|
||||
{
|
||||
@@ -74,7 +74,7 @@ fn Time Time.add_hours(time, long hours) => time + (Time)(hours * (long)MICROSEC
|
||||
fn Time Time.add_days(time, long days) => time + (Time)(days * (long)MICROSECONDS_PER_DAY);
|
||||
fn Time Time.add_weeks(time, long weeks) => time + (Time)(weeks * (long)MICROSECONDS_PER_WEEK);
|
||||
fn double Time.to_seconds(time) => (long)time / (double)MICROSECONDS_PER_SECOND;
|
||||
fn TimeDuration Time.diff_us(time, Time other) => (TimeDuration)(time - other);
|
||||
fn Duration Time.diff_us(time, Time other) => (Duration)(time - other);
|
||||
fn double Time.diff_sec(time, Time other) => (long)time.diff_us(other) / (double)MICROSECONDS_PER_SECOND;
|
||||
fn double Time.diff_min(time, Time other) => (long)time.diff_us(other) / (double)MICROSECONDS_PER_MINUTE;
|
||||
fn double Time.diff_hour(time, Time other) => (long)time.diff_us(other) / (double)MICROSECONDS_PER_HOUR;
|
||||
@@ -83,8 +83,8 @@ fn double Time.diff_weeks(time, Time other) => (long)time.diff_us(other) / (doub
|
||||
|
||||
fn double NanoDuration.to_sec(nd) => (double)nd / 1_000_000_000.0;
|
||||
fn long NanoDuration.to_ms(nd) => (long)nd / 1_000_000;
|
||||
fn TimeDuration NanoDuration.to_duration(nd) => (TimeDuration)nd / 1_000;
|
||||
fn NanoDuration TimeDuration.to_nano(td) => (NanoDuration)td * 1_000;
|
||||
fn Duration NanoDuration.to_duration(nd) => (Duration)nd / 1_000;
|
||||
fn NanoDuration Duration.to_nano(td) => (NanoDuration)td * 1_000;
|
||||
|
||||
fn void! NanoDuration.to_format(&self, Formatter* formatter) @dynamic
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user