| ... | @@ -1476,17 +1476,46 @@ pub const AcceptError = error{ | ... | @@ -1476,17 +1476,46 @@ pub const AcceptError = error{ |
| 1476 | BlockedByFirewall, | 1476 | BlockedByFirewall, |
| 1477 | } || UnexpectedError; | 1477 | } || UnexpectedError; |
| 1478 | | 1478 | |
| 1479 | /// Accept a connection on a socket. `fd` must be opened in blocking mode. | 1479 | /// Accept a connection on a socket. |
| 1480 | /// See also `accept4_async`. | 1480 | /// If the application has a global event loop enabled, EAGAIN is handled |
| 1481 | pub fn accept4(fd: i32, addr: *sockaddr, addrSize: *usize, flags: u32) AcceptError!i32 { | 1481 | /// via the event loop. Otherwise EAGAIN results in error.WouldBlock. |
| | 1482 | pub fn accept4( |
| | 1483 | /// This argument is a socket that has been created with `socket`, bound to a local address |
| | 1484 | /// with `bind`, and is listening for connections after a `listen`. |
| | 1485 | sockfd: i32, |
| | 1486 | /// This argument is a pointer to a sockaddr structure. This structure is filled in with the |
| | 1487 | /// address of the peer socket, as known to the communications layer. The exact format of the |
| | 1488 | /// address returned addr is determined by the socket's address family (see `socket` and the |
| | 1489 | /// respective protocol man pages). |
| | 1490 | addr: *sockaddr, |
| | 1491 | /// This argument is a value-result argument: the caller must initialize it to contain the |
| | 1492 | /// size (in bytes) of the structure pointed to by addr; on return it will contain the actual size |
| | 1493 | /// of the peer address. |
| | 1494 | /// |
| | 1495 | /// The returned address is truncated if the buffer provided is too small; in this case, `addr_size` |
| | 1496 | /// will return a value greater than was supplied to the call. |
| | 1497 | addr_size: *usize, |
| | 1498 | /// If flags is 0, then `accept4` is the same as `accept`. The following values can be bitwise |
| | 1499 | /// ORed in flags to obtain different behavior: |
| | 1500 | /// * `SOCK_NONBLOCK` - Set the `O_NONBLOCK` file status flag on the open file description (see `open`) |
| | 1501 | /// referred to by the new file descriptor. Using this flag saves extra calls to `fcntl` to achieve |
| | 1502 | /// the same result. |
| | 1503 | /// * `SOCK_CLOEXEC` - Set the close-on-exec (`FD_CLOEXEC`) flag on the new file descriptor. See the |
| | 1504 | /// description of the `O_CLOEXEC` flag in `open` for reasons why this may be useful. |
| | 1505 | flags: u32, |
| | 1506 | ) AcceptError!i32 { |
| 1482 | while (true) { | 1507 | while (true) { |
| 1483 | const rc = system.accept4(fd, addr, addrSize, flags); | 1508 | const rc = system.accept4(sockfd, addr, addr_size, flags); |
| 1484 | switch (errno(rc)) { | 1509 | switch (errno(rc)) { |
| 1485 | 0 => return @intCast(i32, rc), | 1510 | 0 => return @intCast(i32, rc), |
| 1486 | EINTR => continue, | 1511 | EINTR => continue, |
| 1487 | else => |err| return unexpectedErrno(err), | | |
| 1488 | | 1512 | |
| 1489 | EAGAIN => unreachable, // This function is for blocking only. | 1513 | EAGAIN => if (std.event.Loop.instance) |loop| { |
| | 1514 | loop.waitUntilFdReadable(sockfd) catch return error.WouldBlock; |
| | 1515 | continue; |
| | 1516 | } else { |
| | 1517 | return error.WouldBlock; |
| | 1518 | }, |
| 1490 | EBADF => unreachable, // always a race condition | 1519 | EBADF => unreachable, // always a race condition |
| 1491 | ECONNABORTED => return error.ConnectionAborted, | 1520 | ECONNABORTED => return error.ConnectionAborted, |
| 1492 | EFAULT => unreachable, | 1521 | EFAULT => unreachable, |
| ... | @@ -1499,33 +1528,8 @@ pub fn accept4(fd: i32, addr: *sockaddr, addrSize: *usize, flags: u32) AcceptErr | ... | @@ -1499,33 +1528,8 @@ pub fn accept4(fd: i32, addr: *sockaddr, addrSize: *usize, flags: u32) AcceptErr |
| 1499 | EOPNOTSUPP => return error.OperationNotSupported, | 1528 | EOPNOTSUPP => return error.OperationNotSupported, |
| 1500 | EPROTO => return error.ProtocolFailure, | 1529 | EPROTO => return error.ProtocolFailure, |
| 1501 | EPERM => return error.BlockedByFirewall, | 1530 | EPERM => return error.BlockedByFirewall, |
| 1502 | } | | |
| 1503 | } | | |
| 1504 | } | | |
| 1505 | | 1531 | |
| 1506 | /// This is the same as `accept4` except `fd` is expected to be non-blocking. | | |
| 1507 | /// Returns -1 if would block. | | |
| 1508 | pub fn accept4_async(fd: i32, addr: *sockaddr, addrSize: *usize, flags: u32) AcceptError!i32 { | | |
| 1509 | while (true) { | | |
| 1510 | const rc = system.accept4(fd, addr, addrSize, flags); | | |
| 1511 | switch (errno(rc)) { | | |
| 1512 | 0 => return @intCast(i32, rc), | | |
| 1513 | EINTR => continue, | | |
| 1514 | else => |err| return unexpectedErrno(err), | 1532 | else => |err| return unexpectedErrno(err), |
| 1515 | | | |
| 1516 | EAGAIN => return -1, | | |
| 1517 | EBADF => unreachable, // always a race condition | | |
| 1518 | ECONNABORTED => return error.ConnectionAborted, | | |
| 1519 | EFAULT => unreachable, | | |
| 1520 | EINVAL => unreachable, | | |
| 1521 | EMFILE => return error.ProcessFdQuotaExceeded, | | |
| 1522 | ENFILE => return error.SystemFdQuotaExceeded, | | |
| 1523 | ENOBUFS => return error.SystemResources, | | |
| 1524 | ENOMEM => return error.SystemResources, | | |
| 1525 | ENOTSOCK => return error.FileDescriptorNotASocket, | | |
| 1526 | EOPNOTSUPP => return error.OperationNotSupported, | | |
| 1527 | EPROTO => return error.ProtocolFailure, | | |
| 1528 | EPERM => return error.BlockedByFirewall, | | |
| 1529 | } | 1533 | } |
| 1530 | } | 1534 | } |
| 1531 | } | 1535 | } |