| ... | @@ -1,27 +1,18 @@ | ... | @@ -1,27 +1,18 @@ |
| 1 | //! POSIX API layer. | 1 | //! POSIX API layer. |
| 2 | //! | 2 | //! |
| 3 | //! This is more cross platform than using OS-specific APIs, however, it is | 3 | //! This is more cross platform than using OS-specific APIs, however, it is |
| 4 | //! lower-level and less portable than other namespaces such as `std.fs` and | 4 | //! lower-level and less portable than other namespaces such as `std.Io` and |
| 5 | //! `std.process`. | 5 | //! `std.process`. |
| 6 | //! | 6 | //! |
| 7 | //! These APIs are generally lowered to libc function calls if and only if libc | 7 | //! These APIs are generally lowered to libc function calls if and only if libc |
| 8 | //! is linked. Most operating systems other than Windows, Linux, and WASI | 8 | //! is linked. Most operating systems other than Windows, Linux, and WASI |
| 9 | //! require always linking libc because they use it as the stable syscall ABI. | 9 | //! require always linking libc because they use it as the stable syscall ABI. |
| 10 | //! | | |
| 11 | //! Operating systems that are not POSIX-compliant are sometimes supported by | | |
| 12 | //! this API layer; sometimes not. Generally, an implementation will be | | |
| 13 | //! provided only if such implementation is straightforward on that operating | | |
| 14 | //! system. Otherwise, programmers are expected to use OS-specific logic to | | |
| 15 | //! deal with the exception. | | |
| 16 | | | |
| 17 | const builtin = @import("builtin"); | 10 | const builtin = @import("builtin"); |
| 18 | const native_os = builtin.os.tag; | 11 | const native_os = builtin.os.tag; |
| 19 | | 12 | |
| 20 | const std = @import("std.zig"); | 13 | const std = @import("std.zig"); |
| 21 | const Io = std.Io; | 14 | const Io = std.Io; |
| 22 | const mem = std.mem; | 15 | const mem = std.mem; |
| 23 | const fs = std.fs; | | |
| 24 | const max_path_bytes = std.fs.max_path_bytes; | | |
| 25 | const maxInt = std.math.maxInt; | 16 | const maxInt = std.math.maxInt; |
| 26 | const cast = std.math.cast; | 17 | const cast = std.math.cast; |
| 27 | const assert = std.debug.assert; | 18 | const assert = std.debug.assert; |
| ... | @@ -122,15 +113,14 @@ pub const STDIN_FILENO = system.STDIN_FILENO; | ... | @@ -122,15 +113,14 @@ pub const STDIN_FILENO = system.STDIN_FILENO; |
| 122 | pub const STDOUT_FILENO = system.STDOUT_FILENO; | 113 | pub const STDOUT_FILENO = system.STDOUT_FILENO; |
| 123 | pub const SYS = system.SYS; | 114 | pub const SYS = system.SYS; |
| 124 | pub const Sigaction = system.Sigaction; | 115 | pub const Sigaction = system.Sigaction; |
| | 116 | /// Windows has no concept of `stat`. |
| | 117 | /// |
| | 118 | /// On Linux, the `stat` bits/wrappers are removed due to having to maintain |
| | 119 | /// the different varying stat structs per target and libc, leading to runtime |
| | 120 | /// errors. Users targeting Linux should add a comptime check and use statx, |
| | 121 | /// similar to how `Io.File.stat` does. |
| 125 | pub const Stat = switch (native_os) { | 122 | pub const Stat = switch (native_os) { |
| 126 | // Has no concept of `stat`. | | |
| 127 | .windows => void, | 123 | .windows => void, |
| 128 | // The `stat` bits/wrappers are removed due to having to maintain the | | |
| 129 | // different varying `struct stat`s per target and libc, leading to runtime | | |
| 130 | // errors. | | |
| 131 | // | | |
| 132 | // Users targeting linux should add a comptime check and use `statx`, | | |
| 133 | // similar to how `std.fs.File.stat` does. | | |
| 134 | .linux => void, | 124 | .linux => void, |
| 135 | else => system.Stat, | 125 | else => system.Stat, |
| 136 | }; | 126 | }; |
| ... | @@ -645,26 +635,6 @@ fn setSockFlags(sock: socket_t, flags: u32) !void { | ... | @@ -645,26 +635,6 @@ fn setSockFlags(sock: socket_t, flags: u32) !void { |
| 645 | } | 635 | } |
| 646 | } | 636 | } |
| 647 | | 637 | |
| 648 | pub const EventFdError = error{ | | |
| 649 | SystemResources, | | |
| 650 | ProcessFdQuotaExceeded, | | |
| 651 | SystemFdQuotaExceeded, | | |
| 652 | } || UnexpectedError; | | |
| 653 | | | |
| 654 | pub fn eventfd(initval: u32, flags: u32) EventFdError!i32 { | | |
| 655 | const rc = system.eventfd(initval, flags); | | |
| 656 | switch (errno(rc)) { | | |
| 657 | .SUCCESS => return @intCast(rc), | | |
| 658 | else => |err| return unexpectedErrno(err), | | |
| 659 | | | |
| 660 | .INVAL => unreachable, // invalid parameters | | |
| 661 | .MFILE => return error.ProcessFdQuotaExceeded, | | |
| 662 | .NFILE => return error.SystemFdQuotaExceeded, | | |
| 663 | .NODEV => return error.SystemResources, | | |
| 664 | .NOMEM => return error.SystemResources, | | |
| 665 | } | | |
| 666 | } | | |
| 667 | | | |
| 668 | pub const GetSockNameError = error{ | 638 | pub const GetSockNameError = error{ |
| 669 | /// Insufficient resources were available in the system to perform the operation. | 639 | /// Insufficient resources were available in the system to perform the operation. |
| 670 | SystemResources, | 640 | SystemResources, |
| ... | @@ -707,40 +677,6 @@ pub fn getpeername(sock: socket_t, addr: *sockaddr, addrlen: *socklen_t) GetSock | ... | @@ -707,40 +677,6 @@ pub fn getpeername(sock: socket_t, addr: *sockaddr, addrlen: *socklen_t) GetSock |
| 707 | } | 677 | } |
| 708 | } | 678 | } |
| 709 | | 679 | |
| 710 | pub const ConnectError = std.Io.net.IpAddress.ConnectError || std.Io.net.UnixAddress.ConnectError; | | |
| 711 | | | |
| 712 | pub fn connect(sock: socket_t, sock_addr: *const sockaddr, len: socklen_t) ConnectError!void { | | |
| 713 | if (native_os == .windows) { | | |
| 714 | @compileError("use std.Io instead"); | | |
| 715 | } | | |
| 716 | | | |
| 717 | while (true) { | | |
| 718 | switch (errno(system.connect(sock, sock_addr, len))) { | | |
| 719 | .SUCCESS => return, | | |
| 720 | .ACCES => return error.AccessDenied, | | |
| 721 | .PERM => return error.PermissionDenied, | | |
| 722 | .ADDRNOTAVAIL => return error.AddressUnavailable, | | |
| 723 | .AFNOSUPPORT => return error.AddressFamilyUnsupported, | | |
| 724 | .AGAIN, .INPROGRESS => return error.WouldBlock, | | |
| 725 | .ALREADY => return error.ConnectionPending, | | |
| 726 | .BADF => unreachable, // sockfd is not a valid open file descriptor. | | |
| 727 | .CONNREFUSED => return error.ConnectionRefused, | | |
| 728 | .CONNRESET => return error.ConnectionResetByPeer, | | |
| 729 | .FAULT => unreachable, // The socket structure address is outside the user's address space. | | |
| 730 | .INTR => continue, | | |
| 731 | .ISCONN => @panic("AlreadyConnected"), // The socket is already connected. | | |
| 732 | .HOSTUNREACH => return error.NetworkUnreachable, | | |
| 733 | .NETUNREACH => return error.NetworkUnreachable, | | |
| 734 | .NOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket. | | |
| 735 | .PROTOTYPE => unreachable, // The socket type does not support the requested communications protocol. | | |
| 736 | .TIMEDOUT => return error.Timeout, | | |
| 737 | .NOENT => return error.FileNotFound, // Returned when socket is AF.UNIX and the given path does not exist. | | |
| 738 | .CONNABORTED => unreachable, // Tried to reuse socket that previously received error.ConnectionRefused. | | |
| 739 | else => |err| return unexpectedErrno(err), | | |
| 740 | } | | |
| 741 | } | | |
| 742 | } | | |
| 743 | | | |
| 744 | pub const FStatError = std.Io.File.StatError; | 680 | pub const FStatError = std.Io.File.StatError; |
| 745 | | 681 | |
| 746 | /// Return information about a file descriptor. | 682 | /// Return information about a file descriptor. |