mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
- Order of attribute declaration is changed for `alias`. - Added `LANGUAGE_DEV_VERSION` env constant. - Rename `anyfault` -> `fault`. - Changed `fault` -> `faultdef`. - Added `attrdef` instead of `alias` for attribute aliases.
97 lines
2.6 KiB
Plaintext
97 lines
2.6 KiB
Plaintext
module std::net::os @if(env::POSIX && SUPPORTS_INET);
|
|
import std::io, libc;
|
|
|
|
const int F_GETFL = 3;
|
|
const int F_SETFL = 4;
|
|
|
|
typedef NativeSocket = inline Fd;
|
|
|
|
struct Posix_pollfd
|
|
{
|
|
CInt fd;
|
|
CUShort events;
|
|
CUShort revents;
|
|
}
|
|
|
|
alias Posix_nfds_t = CUInt;
|
|
|
|
extern fn CInt connect(NativeSocket socket, SockAddrPtr address, Socklen_t address_len);
|
|
extern fn NativeSocket socket(AIFamily af, AISockType type, AIProtocol ip_protocol);
|
|
extern fn int fcntl(NativeSocket socket, int cmd, ...);
|
|
extern fn CInt bind(NativeSocket socket, SockAddrPtr address, Socklen_t address_len);
|
|
extern fn CInt listen(NativeSocket socket, CInt backlog);
|
|
extern fn NativeSocket accept(NativeSocket socket, SockAddrPtr address, Socklen_t* address_len);
|
|
extern fn CInt poll(Posix_pollfd* fds, Posix_nfds_t nfds, CInt timeout);
|
|
|
|
const CUShort POLLIN = 0x0001;
|
|
const CUShort POLLPRI = 0x0002;
|
|
const CUShort POLLOUT = 0x0004;
|
|
const CUShort POLLERR = 0x0008;
|
|
const CUShort POLLHUP = 0x0010;
|
|
const CUShort POLLNVAL = 0x0020;
|
|
|
|
fn fault convert_error(Errno error)
|
|
{
|
|
switch (error)
|
|
{
|
|
case errno::EACCES: return io::NO_PERMISSION;
|
|
case errno::EADDRINUSE: return net::ADDRESS_IN_USE;
|
|
case errno::EALREADY: return net::CONNECTION_ALREADY_IN_PROGRESS;
|
|
case errno::EBADF: return net::BAD_SOCKET_DESCRIPTOR;
|
|
case errno::ECONNREFUSED: return net::CONNECTION_REFUSED;
|
|
case errno::ECONNRESET: return net::CONNECTION_RESET;
|
|
case errno::EISCONN: return net::ALREADY_CONNECTED;
|
|
case errno::ENETUNREACH: return net::NETWORK_UNREACHABLE;
|
|
case errno::ENOTSOCK: return net::NOT_A_SOCKET;
|
|
case errno::EINTR: return io::INTERRUPTED;
|
|
case errno::EWOULDBLOCK: return io::WOULD_BLOCK;
|
|
case errno::EOPNOTSUPP: return net::OPERATION_NOT_SUPPORTED_ON_SOCKET;
|
|
case errno::ETIMEDOUT: return net::CONNECTION_TIMED_OUT;
|
|
default: return io::GENERAL_ERROR;
|
|
}
|
|
}
|
|
|
|
fn fault socket_error()
|
|
{
|
|
return convert_error(libc::errno());
|
|
}
|
|
|
|
macro bool NativeSocket.is_valid(self)
|
|
{
|
|
return (iptr)self >= 0;
|
|
}
|
|
|
|
macro void? NativeSocket.close(self)
|
|
{
|
|
if (libc::close(self))
|
|
{
|
|
if (libc::errno() == errno::EBADF) return net::INVALID_SOCKET?;
|
|
return net::GENERAL_ERROR?;
|
|
}
|
|
}
|
|
|
|
macro void? NativeSocket.set_non_blocking(self, bool non_blocking)
|
|
{
|
|
int flags = fcntl(self, F_GETFL, 0);
|
|
if (non_blocking)
|
|
{
|
|
if (flags & O_NONBLOCK) return;
|
|
flags |= O_NONBLOCK;
|
|
}
|
|
else
|
|
{
|
|
if (!(flags & O_NONBLOCK)) return;
|
|
flags &= ~(int)O_NONBLOCK;
|
|
}
|
|
if (fcntl(self, F_SETFL, flags) == -1)
|
|
{
|
|
if (libc::errno() == errno::EBADF) return net::INVALID_SOCKET?;
|
|
return net::GENERAL_ERROR?;
|
|
}
|
|
}
|
|
|
|
macro bool NativeSocket.is_non_blocking(self)
|
|
{
|
|
return fcntl(self, F_GETFL, 0) & O_NONBLOCK != 0;
|
|
}
|