| ... | @@ -1,5 +1,6 @@ | ... | @@ -1,5 +1,6 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| | 3 | const linux = std.os.linux; |
| 3 | | 4 | |
| 4 | pub const errno = struct { | 5 | pub const errno = struct { |
| 5 | pub const Error = error{ | 6 | pub const Error = error{ |
| ... | @@ -924,5 +925,197 @@ pub const errno = struct { | ... | @@ -924,5 +925,197 @@ pub const errno = struct { |
| 924 | }; | 925 | }; |
| 925 | | 926 | |
| 926 | pub const libc = struct { | 927 | pub const libc = struct { |
| | 928 | /// int close(int fildes); |
| | 929 | /// https://pubs.opengroup.org/onlinepubs/9699919799.orig/functions/close.html |
| | 930 | pub extern fn close(fildes: c_int) c_int; |
| | 931 | |
| | 932 | /// void exit(int status); |
| | 933 | /// https://pubs.opengroup.org/onlinepubs/9699919799.orig/functions/exit.html |
| | 934 | pub extern fn exit(status: c_int) noreturn; |
| | 935 | |
| | 936 | /// char *getenv(const char *name); |
| | 937 | /// https://pubs.opengroup.org/onlinepubs/9699919799.orig/functions/getenv.html |
| | 938 | pub extern fn getenv(name: [*:0]const u8) ?[*:0]u8; |
| | 939 | /// pid_t getpid(void); |
| | 940 | /// https://pubs.opengroup.org/onlinepubs/9699919799.orig/functions/getpid.html |
| | 941 | pub extern fn getpid() pid_t; |
| | 942 | /// pthread_t pthread_self(void); |
| | 943 | /// https://pubs.opengroup.org/onlinepubs/9699919799.orig/functions/pthread_self.html |
| | 944 | pub extern fn pthread_self() pthread_t; |
| | 945 | /// int fstat(int fildes, struct stat *buf); |
| | 946 | /// https://pubs.opengroup.org/onlinepubs/9699919799.orig/functions/fstat.html |
| | 947 | pub extern fn fstat(fd: c_int, buf: *struct_stat) c_int; |
| | 948 | /// int mkdirat(int fd, const char *path, mode_t mode); |
| | 949 | /// https://pubs.opengroup.org/onlinepubs/9699919799.orig/functions/mkdirat.html |
| | 950 | pub extern fn mkdirat(fd: c_int, path: [*:0]const u8, mode: mode_t) c_int; |
| | 951 | /// ssize_t readv(int fildes, const struct iovec *iov, int iovcnt); |
| | 952 | /// https://pubs.opengroup.org/onlinepubs/9699919799.orig/functions/readv.html |
| | 953 | pub extern fn readv(fd: c_int, iovec: [*]const struct_iovec, count: c_int) isize; |
| | 954 | /// ssize_t read(int fildes, void *buf, size_t nbyte); |
| | 955 | /// https://pubs.opengroup.org/onlinepubs/9699919799.orig/functions/read.html |
| | 956 | pub extern fn read(fd: c_int, buf: [*]u8, count: usize) isize; |
| | 957 | /// int openat(int fd, const char *path, int oflag, ...); |
| | 958 | /// https://pubs.opengroup.org/onlinepubs/9699919799.orig/functions/openat.html |
| | 959 | pub extern fn openat(fd: c_int, file: [*:0]const u8, oflag: c_int, ...) c_int; |
| | 960 | /// int fstat(int fildes, struct stat *buf); |
| | 961 | /// https://pubs.opengroup.org/onlinepubs/9699919799.orig/functions/fstat.html |
| | 962 | pub extern fn fstat(fd: c_int, buf: *struct_stat) c_int; |
| | 963 | |
| | 964 | |
| | 965 | |
| | 966 | |
| | 967 | |
| | 968 | |
| | 969 | |
| | 970 | |
| | 971 | |
| | 972 | |
| | 973 | // |
| | 974 | // |
| | 975 | |
| 927 | pub extern fn __errno_location() *c_int; | 976 | pub extern fn __errno_location() *c_int; |
| 928 | }; | 977 | }; |
| | 978 | |
| | 979 | pub const clock_t = c_long; |
| | 980 | pub const pid_t = c_int; |
| | 981 | pub const gid_t = c_uint; |
| | 982 | pub const uid_t = c_uint; |
| | 983 | pub const struct_group = opaque {}; |
| | 984 | pub const struct_hostent = opaque {}; |
| | 985 | pub const struct_netent = opaque {}; |
| | 986 | pub const struct_protoent = opaque {}; |
| | 987 | pub const struct_passwd = opaque {}; |
| | 988 | pub const struct_servent = opaque {}; |
| | 989 | pub const struct_utmpx = opaque {}; |
| | 990 | pub const wint_t = c_uint; |
| | 991 | pub const struct_if_nameindex = opaque {}; |
| | 992 | pub const struct_lconv = opaque {}; |
| | 993 | pub const pthread_t = c_ulong; |
| | 994 | pub const FILE = opaque {}; |
| | 995 | pub const locale_t = *const opaque {}; |
| | 996 | pub const nl_catd = *const opaque {}; |
| | 997 | pub const intmax_t = i64; |
| | 998 | pub const wchar_t = c_int; |
| | 999 | pub const mode_t = c_uint; |
| | 1000 | pub const struct_sockaddr = linux.sockaddr; |
| | 1001 | pub const socklen_t = c_uint; |
| | 1002 | pub const clockid_t = c_int; |
| | 1003 | pub const struct_timespec = linux.timespec; |
| | 1004 | pub const DIR = opaque {}; |
| | 1005 | pub const time_t = i64; |
| | 1006 | pub const div_t = extern struct { quot: c_int, rem: c_int }; |
| | 1007 | pub const off_t = linux.off_t; |
| | 1008 | pub const ino_t = linux.ino_t; |
| | 1009 | pub const struct_stat = linux.Stat; |
| | 1010 | pub const struct_iovec = extern struct { base: [*]u8, len: usize }; |
| | 1011 | |
| | 1012 | pub const AT = struct { |
| | 1013 | pub const FDCWD = -100; |
| | 1014 | pub const SYMLINK_NOFOLLOW = 0x100; |
| | 1015 | pub const REMOVEDIR = 0x200; |
| | 1016 | pub const SYMLINK_FOLLOW = 0x400; |
| | 1017 | pub const EACCESS = 0x200; |
| | 1018 | }; |
| | 1019 | |
| | 1020 | pub const O = struct { |
| | 1021 | pub usingnamespace switch (builtin.target.cpu.arch) { |
| | 1022 | .x86_64, |
| | 1023 | => struct { |
| | 1024 | pub const CREAT = 0o100; |
| | 1025 | pub const EXCL = 0o200; |
| | 1026 | pub const NOCTTY = 0o400; |
| | 1027 | pub const TRUNC = 0o1000; |
| | 1028 | pub const APPEND = 0o2000; |
| | 1029 | pub const NONBLOCK = 0o4000; |
| | 1030 | pub const DSYNC = 0o10000; |
| | 1031 | pub const SYNC = 0o4010000; |
| | 1032 | pub const RSYNC = 0o4010000; |
| | 1033 | pub const DIRECTORY = 0o200000; |
| | 1034 | pub const NOFOLLOW = 0o400000; |
| | 1035 | pub const CLOEXEC = 0o2000000; |
| | 1036 | pub const ASYNC = 0o20000; |
| | 1037 | pub const DIRECT = 0o40000; |
| | 1038 | pub const LARGEFILE = 0o100000; |
| | 1039 | pub const NOATIME = 0o1000000; |
| | 1040 | pub const PATH = 0o10000000; |
| | 1041 | pub const TMPFILE = 0o20200000; |
| | 1042 | pub const NDELAY = O.NONBLOCK; |
| | 1043 | }, |
| | 1044 | else => @compileError("TODO"), |
| | 1045 | }; |
| | 1046 | pub const SEARCH = O.PATH; |
| | 1047 | pub const EXEC = O.PATH; |
| | 1048 | pub const TTY_INIT = 0; |
| | 1049 | pub const ACCMODE = (3 | O.SEARCH); |
| | 1050 | pub const RDONLY = 0; |
| | 1051 | pub const WRONLY = 1; |
| | 1052 | pub const RDWR = 2; |
| | 1053 | }; |
| | 1054 | |
| | 1055 | pub const NAME_MAX = 255; |
| | 1056 | pub const PATH_MAX = 4096; |
| | 1057 | pub const NGROUPS_MAX = 32; |
| | 1058 | pub const ARG_MAX = 131072; |
| | 1059 | pub const IOV_MAX = 1024; |
| | 1060 | pub const SYMLOOP_MAX = 40; |
| | 1061 | pub const TZNAME_MAX = 6; |
| | 1062 | pub const TTY_NAME_MAX = 32; |
| | 1063 | pub const HOST_NAME_MAX = 255; |
| | 1064 | |
| | 1065 | pub fn getpid() pid_t { |
| | 1066 | return libc.getpid(); |
| | 1067 | } |
| | 1068 | |
| | 1069 | pub fn exit(status: c_int) noreturn { |
| | 1070 | return libc.exit(status); |
| | 1071 | } |
| | 1072 | |
| | 1073 | pub fn getenv(name: [:0]const u8) ?[:0]u8 { |
| | 1074 | return std.mem.sliceTo(libc.getenv(name.ptr) orelse return null, 0); |
| | 1075 | } |
| | 1076 | |
| | 1077 | pub fn openat(fd: c_int, file: [*:0]const u8, oflag: c_int) errno.Error!c_int { |
| | 1078 | const rc = libc.openat(fd, file, oflag); |
| | 1079 | if (rc == -1) return errno.fromInt(errno.fromLibC()); |
| | 1080 | return rc; |
| | 1081 | } |
| | 1082 | |
| | 1083 | pub fn close(fd: c_int) errno.Error!void { |
| | 1084 | const rc = libc.close(fd); |
| | 1085 | if (rc == -1) return errno.fromInt(errno.fromLibC()); |
| | 1086 | std.debug.assert(rc == 0); |
| | 1087 | } |
| | 1088 | |
| | 1089 | pub fn read(fd: c_int, buf: []u8) errno.Error!usize { |
| | 1090 | const rc = libc.read(fd, buf.ptr, buf.len); |
| | 1091 | if (rc == -1) return errno.fromInt(errno.fromLibC()); |
| | 1092 | std.debug.assert(rc >= 0); |
| | 1093 | return @intCast(rc); |
| | 1094 | } |
| | 1095 | |
| | 1096 | pub fn fstat(fd: c_int) errno.Error!struct_stat { |
| | 1097 | var buf: struct_stat = undefined; |
| | 1098 | const rc = libc.fstat(fd, &buf); |
| | 1099 | if (rc == -1) return errno.fromInt(errno.fromLibC()); |
| | 1100 | std.debug.assert(rc == 0); |
| | 1101 | return buf; |
| | 1102 | } |
| | 1103 | |
| | 1104 | pub fn readv(fd: c_int, bufs: []const struct_iovec) errno.Error!usize { |
| | 1105 | std.debug.assert(bufs.len > 0); |
| | 1106 | std.debug.assert(bufs.len <= IOV_MAX); |
| | 1107 | const rc = libc.readv(fd, bufs.ptr, @intCast(bufs.len)); |
| | 1108 | if (rc == -1) return errno.fromInt(errno.fromLibC()); |
| | 1109 | std.debug.assert(rc >= 0); |
| | 1110 | return @intCast(rc); |
| | 1111 | } |
| | 1112 | |
| | 1113 | pub fn mkdirat(fd: c_int, path: [*:0]const u8, mode: mode_t) errno.Error!void { |
| | 1114 | const rc = libc.mkdirat(fd, path, mode); |
| | 1115 | if (rc == -1) return errno.fromInt(errno.fromLibC()); |
| | 1116 | std.debug.assert(rc == 0); |
| | 1117 | } |
| | 1118 | |
| | 1119 | pub fn pthread_self() pthread_t { |
| | 1120 | return libc.pthread_self(); |
| | 1121 | } |