review/correct/cleanup posix linux PR

This commit is contained in:
Laytan
2024-09-30 16:00:46 +02:00
parent c1a67f37e6
commit 5cd1784d41
15 changed files with 265 additions and 332 deletions
+36 -59
View File
@@ -152,66 +152,43 @@ Errno :: enum i32 {
RDONLY flag is not present, because it has the value of 0, i.e. it is the RDONLY flag is not present, because it has the value of 0, i.e. it is the
default, unless WRONLY or RDWR is specified. default, unless WRONLY or RDWR is specified.
*/ */
when ODIN_ARCH != .arm64 && ODIN_ARCH != .arm32 { Open_Flags_Bits :: enum {
Open_Flags_Bits :: enum { WRONLY = 0,
WRONLY = 0, RDWR = 1,
RDWR = 1, CREAT = 6,
CREAT = 6, EXCL = 7,
EXCL = 7, NOCTTY = 8,
NOCTTY = 8, TRUNC = 9,
TRUNC = 9, APPEND = 10,
APPEND = 10, NONBLOCK = 11,
NONBLOCK = 11, DSYNC = 12,
DSYNC = 12, ASYNC = 13,
ASYNC = 13, DIRECT = 14,
DIRECT = 14, LARGEFILE = 15,
LARGEFILE = 15, DIRECTORY = 16,
DIRECTORY = 16, NOFOLLOW = 17,
NOFOLLOW = 17, NOATIME = 18,
NOATIME = 18, CLOEXEC = 19,
CLOEXEC = 19, PATH = 21,
PATH = 21,
}
// https://github.com/torvalds/linux/blob/7367539ad4b0f8f9b396baf02110962333719a48/include/uapi/asm-generic/fcntl.h#L19
#assert(1 << uint(Open_Flags_Bits.WRONLY) == 0o0000000_1)
#assert(1 << uint(Open_Flags_Bits.RDWR) == 0o0000000_2)
#assert(1 << uint(Open_Flags_Bits.CREAT) == 0o00000_100)
#assert(1 << uint(Open_Flags_Bits.EXCL) == 0o00000_200)
#assert(1 << uint(Open_Flags_Bits.NOCTTY) == 0o00000_400)
#assert(1 << uint(Open_Flags_Bits.TRUNC) == 0o0000_1000)
#assert(1 << uint(Open_Flags_Bits.APPEND) == 0o0000_2000)
#assert(1 << uint(Open_Flags_Bits.NONBLOCK) == 0o0000_4000)
#assert(1 << uint(Open_Flags_Bits.DSYNC) == 0o000_10000)
#assert(1 << uint(Open_Flags_Bits.ASYNC) == 0o000_20000)
#assert(1 << uint(Open_Flags_Bits.DIRECT) == 0o000_40000)
#assert(1 << uint(Open_Flags_Bits.LARGEFILE) == 0o00_100000)
#assert(1 << uint(Open_Flags_Bits.DIRECTORY) == 0o00_200000)
#assert(1 << uint(Open_Flags_Bits.NOFOLLOW) == 0o00_400000)
#assert(1 << uint(Open_Flags_Bits.NOATIME) == 0o0_1000000)
#assert(1 << uint(Open_Flags_Bits.CLOEXEC) == 0o0_2000000)
#assert(1 << uint(Open_Flags_Bits.PATH) == 0o_10000000)
} else {
Open_Flags_Bits :: enum {
WRONLY = 0,
RDWR = 1,
CREAT = 6,
EXCL = 7,
NOCTTY = 8,
TRUNC = 9,
APPEND = 10,
NONBLOCK = 11,
DSYNC = 12,
ASYNC = 13,
DIRECTORY = 14,
NOFOLLOW = 15,
DIRECT = 16,
LARGEFILE = 17,
NOATIME = 18,
CLOEXEC = 19,
PATH = 21,
}
} }
// https://github.com/torvalds/linux/blob/7367539ad4b0f8f9b396baf02110962333719a48/include/uapi/asm-generic/fcntl.h#L19
#assert(1 << uint(Open_Flags_Bits.WRONLY) == 0o0000000_1)
#assert(1 << uint(Open_Flags_Bits.RDWR) == 0o0000000_2)
#assert(1 << uint(Open_Flags_Bits.CREAT) == 0o00000_100)
#assert(1 << uint(Open_Flags_Bits.EXCL) == 0o00000_200)
#assert(1 << uint(Open_Flags_Bits.NOCTTY) == 0o00000_400)
#assert(1 << uint(Open_Flags_Bits.TRUNC) == 0o0000_1000)
#assert(1 << uint(Open_Flags_Bits.APPEND) == 0o0000_2000)
#assert(1 << uint(Open_Flags_Bits.NONBLOCK) == 0o0000_4000)
#assert(1 << uint(Open_Flags_Bits.DSYNC) == 0o000_10000)
#assert(1 << uint(Open_Flags_Bits.ASYNC) == 0o000_20000)
#assert(1 << uint(Open_Flags_Bits.DIRECT) == 0o000_40000)
#assert(1 << uint(Open_Flags_Bits.LARGEFILE) == 0o00_100000)
#assert(1 << uint(Open_Flags_Bits.DIRECTORY) == 0o00_200000)
#assert(1 << uint(Open_Flags_Bits.NOFOLLOW) == 0o00_400000)
#assert(1 << uint(Open_Flags_Bits.NOATIME) == 0o0_1000000)
#assert(1 << uint(Open_Flags_Bits.CLOEXEC) == 0o0_2000000)
#assert(1 << uint(Open_Flags_Bits.PATH) == 0o_10000000)
/* /*
Bits for FD_Flags bitset Bits for FD_Flags bitset
+68 -137
View File
@@ -92,120 +92,52 @@ Lock_Type :: enum c.short {
WRLCK = F_WRLCK, WRLCK = F_WRLCK,
} }
// Assertions made to unify this bit set. O_Flag_Bits :: enum c.int {
#assert(O_RDONLY == 0) // Sets FD_CLOEXEC on the file descriptor.
CLOEXEC = log2(O_CLOEXEC),
// If not exists, combined with DIRECTORY will cause creation of a directory, otherwise a regular file.
CREAT = log2(O_CREAT),
// Fails if the opened descriptor would not be a directory.
DIRECTORY = log2(O_DIRECTORY),
// If combined with CREAT, causes a failure if the file already exists.
EXCL = log2(O_EXCL),
// If terminal device, do not make it the controlling terminal for the process.
NOCTTY = log2(O_NOCTTY),
// Don't follow symbolic links, fail with errno ELOOP.
NOFOLLOW = log2(O_NOFOLLOW),
// If exists and regular, truncate the length to 0.
TRUNC = log2(O_TRUNC),
when ODIN_OS == .Linux { // NOTE: use with `posix.O_TTY_INIT + { .OTHER_FLAG, .OTHER_FLAG }`, unfortunately can't be in
// this bit set enum because it is 0 on some platforms and a value on others.
// TTY_INIT = O_TTY_INIT,
O_Flag_Bits :: enum c.int { // Set file offset to end of file prior to each write.
// Sets FD_CLOEXEC on the file descriptor. APPEND = log2(O_APPEND),
CLOEXEC = log2(O_CLOEXEC), // Write I/O shall complete as defined by synchronized I/O data integrity completion.
// If not exists, combined with DIRECTORY will cause creation of a directory, otherwise a regular file. DSYNC = log2(O_DSYNC),
CREAT = log2(O_CREAT), // Causes nonblocking behaviour in various situations.
// Fails if the opened descriptor would not be a directory. NONBLOCK = log2(O_NONBLOCK),
DIRECTORY = log2(O_DIRECTORY), // Write I/O shall complete as defined by synchronized I/O file integrity completion.
// If combined with CREAT, causes a failure if the file already exists. SYNC = log2(O_SYNC),
EXCL = log2(O_EXCL),
// If terminal device, do not make it the controlling terminal for the process.
NOCTTY = log2(O_NOCTTY),
// Don't follow symbolic links, fail with errno ELOOP.
NOFOLLOW = log2(O_NOFOLLOW),
// If exists and regular, truncate the length to 0.
TRUNC = log2(O_TRUNC),
// NOTE: use with `posix.O_TTY_INIT + { .OTHER_FLAG, .OTHER_FLAG }`, unfortunately can't be in // NOTE: use with `posix.O_RSYNC + { .OTHER_FLAG, .OTHER_FLAG }`, unfortunately can't be in
// this bit set enum because it is 0 on some platforms and a value on others. // this bit set enum because it is 0 on some platforms and a value on others.
// TTY_INIT = O_TTY_INIT, // RSYNC = O_RSYNC,
// Set file offset to end of file prior to each write. // Execute only.
APPEND = log2(O_APPEND), EXEC = log2(O_EXEC),
// Write I/O shall complete as defined by synchronized I/O data integrity completion. // Reading and writing.
DSYNC = log2(O_DSYNC), RDWR = log2(O_RDWR),
// Causes nonblocking behaviour in various situations. // Writing only.
NONBLOCK = log2(O_NONBLOCK), WRONLY = log2(O_WRONLY),
// Write I/O shall complete as defined by synchronized I/O file integrity completion. // Reading only.
SYNC = log2(O_SYNC), // RDONLY = 0, // Default
// NOTE: use with `posix.O_RSYNC + { .OTHER_FLAG, .OTHER_FLAG }`, unfortunately can't be in
// this bit set enum because it is 0 on some platforms and a value on others.
// RSYNC = O_RSYNC,
// Execute only.
// NOTE: use with `posix.O_ENTER + { .OTHER_FLAG, .OTHER_FLAG }`, unfortunately can't be in
// this bit set enum because it is 0 on some platforms and a value on others.
// EXEC = O_EXEC
// Reading and writing.
RDWR = log2(O_RDWR),
// Writing only.
WRONLY = log2(O_WRONLY),
// Reading only.
// RDONLY = 0, // Default
}
O_Flags :: bit_set[O_Flag_Bits; c.int]
} else {
O_Flag_Bits :: enum c.int {
// Sets FD_CLOEXEC on the file descriptor.
CLOEXEC = log2(O_CLOEXEC),
// If not exists, combined with DIRECTORY will cause creation of a directory, otherwise a regular file.
CREAT = log2(O_CREAT),
// Fails if the opened descriptor would not be a directory.
DIRECTORY = log2(O_DIRECTORY),
// If combined with CREAT, causes a failure if the file already exists.
EXCL = log2(O_EXCL),
// If terminal device, do not make it the controlling terminal for the process.
NOCTTY = log2(O_NOCTTY),
// Don't follow symbolic links, fail with errno ELOOP.
NOFOLLOW = log2(O_NOFOLLOW),
// If exists and regular, truncate the length to 0.
TRUNC = log2(O_TRUNC),
// NOTE: use with `posix.O_TTY_INIT + { .OTHER_FLAG, .OTHER_FLAG }`, unfortunately can't be in
// this bit set enum because it is 0 on some platforms and a value on others.
// TTY_INIT = O_TTY_INIT,
// Set file offset to end of file prior to each write.
APPEND = log2(O_APPEND),
// Write I/O shall complete as defined by synchronized I/O data integrity completion.
DSYNC = log2(O_DSYNC),
// Causes nonblocking behaviour in various situations.
NONBLOCK = log2(O_NONBLOCK),
// Write I/O shall complete as defined by synchronized I/O file integrity completion.
SYNC = log2(O_SYNC),
// NOTE: use with `posix.O_RSYNC + { .OTHER_FLAG, .OTHER_FLAG }`, unfortunately can't be in
// this bit set enum because it is 0 on some platforms and a value on others.
// RSYNC = O_RSYNC,
// Execute only.
EXEC = log2(O_EXEC),
// Reading and writing.
RDWR = log2(O_RDWR),
// Writing only.
WRONLY = log2(O_WRONLY),
// Reading only.
// RDONLY = 0, // Default
}
O_Flags :: bit_set[O_Flag_Bits; c.int]
} }
// A mask of all the access mode bits. O_Flags :: bit_set[O_Flag_Bits; c.int]
when ODIN_OS == .Linux {
// NOTE: .EXEC and .RDONLY also belong here, but they are 0 on some platforms. O_ACCMODE :: O_Flags{ .EXEC, .RDWR, .WRONLY }
O_ACCMODE :: O_Flags{ .RDWR, .WRONLY }
} else {
// NOTE: .RDONLY also belong here, but they are 0 on some platforms.
O_ACCMODE :: O_Flags{ .EXEC, .RDWR, .WRONLY }
}
AT_Flag_Bits :: enum c.int { AT_Flag_Bits :: enum c.int {
EACCESS = log2(AT_EACCESS), EACCESS = log2(AT_EACCESS),
@@ -265,7 +197,7 @@ when ODIN_OS == .Darwin {
_O_SEARCH :: O_EXEC | O_DIRECTORY _O_SEARCH :: O_EXEC | O_DIRECTORY
O_SEARCH :: O_Flags{.EXEC, .DIRECTORY} O_SEARCH :: O_Flags{.EXEC, .DIRECTORY}
AT_FDCWD: FD : -2 AT_FDCWD: FD: -2
AT_EACCESS :: 0x0010 AT_EACCESS :: 0x0010
AT_SYMLINK_NOFOLLOW :: 0x0020 AT_SYMLINK_NOFOLLOW :: 0x0020
@@ -329,7 +261,7 @@ when ODIN_OS == .Darwin {
_O_SEARCH :: O_EXEC _O_SEARCH :: O_EXEC
O_SEARCH :: O_Flags{ .EXEC } O_SEARCH :: O_Flags{ .EXEC }
AT_FDCWD: FD : -100 AT_FDCWD: FD: -100
AT_EACCESS :: 0x0100 AT_EACCESS :: 0x0100
AT_SYMLINK_NOFOLLOW :: 0x0200 AT_SYMLINK_NOFOLLOW :: 0x0200
@@ -396,7 +328,7 @@ when ODIN_OS == .Darwin {
_O_SEARCH :: 0x00800000 _O_SEARCH :: 0x00800000
O_SEARCH :: O_Flags{O_Flag_Bits(log2(_O_SEARCH))} O_SEARCH :: O_Flags{O_Flag_Bits(log2(_O_SEARCH))}
AT_FDCWD: FD : -100 AT_FDCWD: FD: -100
AT_EACCESS :: 0x100 AT_EACCESS :: 0x100
AT_SYMLINK_NOFOLLOW :: 0x200 AT_SYMLINK_NOFOLLOW :: 0x200
@@ -460,7 +392,7 @@ when ODIN_OS == .Darwin {
_O_SEARCH :: 0 _O_SEARCH :: 0
O_SEARCH :: O_Flags{} // NOTE: not defined in the headers O_SEARCH :: O_Flags{} // NOTE: not defined in the headers
AT_FDCWD: FD : -100 AT_FDCWD: FD: -100
AT_EACCESS :: 0x01 AT_EACCESS :: 0x01
AT_SYMLINK_NOFOLLOW :: 0x02 AT_SYMLINK_NOFOLLOW :: 0x02
@@ -480,21 +412,21 @@ when ODIN_OS == .Darwin {
off_t :: distinct c.int64_t off_t :: distinct c.int64_t
pid_t :: distinct c.int pid_t :: distinct c.int
F_DUPFD :: 0 // Duplicate file descriptor. F_DUPFD :: 0
F_GETFD :: 1 /* Get file descriptor flags. */ F_GETFD :: 1
F_SETFD :: 2 /* Set file descriptor flags. */ F_SETFD :: 2
F_GETFL :: 3 /* Get file status flags. */ F_GETFL :: 3
F_SETFL :: 4 /* Set file status flags. */ F_SETFL :: 4
F_GETLK :: 5 /* Get record locking info. */ F_GETLK :: 5
F_SETLK :: 6 /* Set record locking info (non-blocking). */ F_SETLK :: 6
F_SETLKW :: 7 /* Set record locking info (blocking). */ F_SETLKW :: 7
F_SETOWN :: 8 /* Get owner (process receiving SIGIO). */ F_SETOWN :: 8
F_GETOWN :: 9 /* Set owner (process receiving SIGIO). */ F_GETOWN :: 9
F_RDLCK :: 0 /* Read lock. */ F_RDLCK :: 0
F_UNLCK :: 2 /* Remove lock. */ F_UNLCK :: 2
F_WRLCK :: 1 /* Write lock. */ F_WRLCK :: 1
F_DUPFD_CLOEXEC :: 1030 /* Duplicate file descriptor with close-on-exit set. */ F_DUPFD_CLOEXEC :: 1030
FD_CLOEXEC :: 1 FD_CLOEXEC :: 1
@@ -517,8 +449,7 @@ when ODIN_OS == .Darwin {
_O_RSYNC :: 0 _O_RSYNC :: 0
O_RSYNC :: O_Flags{} O_RSYNC :: O_Flags{}
// NOTE: Not implemented in Linux O_EXEC :: 0x04000000 // NOTE: not defined in the headers
O_EXEC :: 0
O_RDONLY :: 0 O_RDONLY :: 0
O_WRONLY :: 0o1 O_WRONLY :: 0o1
@@ -527,19 +458,19 @@ when ODIN_OS == .Darwin {
_O_SEARCH :: 0 _O_SEARCH :: 0
O_SEARCH :: O_Flags{} O_SEARCH :: O_Flags{}
AT_FDCWD: FD : -100 // Special value used to indicate the *at functions should use the current working directory. AT_FDCWD: FD: -100
AT_EACCESS :: 0x200 // Test access permitted for effective IDs, not real IDs. AT_EACCESS :: 0x200
AT_SYMLINK_NOFOLLOW :: 0x100 // Do not follow symbolic links. AT_SYMLINK_NOFOLLOW :: 0x100
AT_SYMLINK_FOLLOW :: 0x400 // Follow symbolic links. AT_SYMLINK_FOLLOW :: 0x400
AT_REMOVEDIR :: 0x200 // Remove directory instead of unlinking file. AT_REMOVEDIR :: 0x200
flock :: struct { flock :: struct {
l_start: off_t, // [PSX] relative offset in bytes. l_start: off_t, /* [PSX] relative offset in bytes. */
l_len: off_t, // [PSX] size; if 0 then until EOF. l_len: off_t, /* [PSX] size; if 0 then until EOF. */
l_pid: pid_t, // [PSX] process ID of the process holding the lock. l_pid: pid_t, /* [PSX] process ID of the process holding the lock. */
l_type: Lock_Type, // [PSX] type of lock. l_type: Lock_Type, /* [PSX] type of lock. */
l_whence: c.short, // [PSX] flag (Whence) of starting offset. l_whence: c.short, /* [PSX] flag (Whence) of starting offset. */
} }
} else { } else {
+1 -4
View File
@@ -178,15 +178,12 @@ when ODIN_OS == .Darwin {
glob_t :: struct { glob_t :: struct {
gl_pathc: c.size_t, /* [PSX] count of paths matched by pattern */ gl_pathc: c.size_t, /* [PSX] count of paths matched by pattern */
gl_matchc: c.size_t, /* count of paths matching pattern */ gl_pathv: [^]cstring `fmt:"v,gl_pathc"`, /* [PSX] pointer to list of matched pathnames */
gl_offs: c.size_t, /* [PSX] slots to reserve at the beginning of gl_pathv */ gl_offs: c.size_t, /* [PSX] slots to reserve at the beginning of gl_pathv */
gl_flags: Glob_Flags, /* copy of flags parameter to glob */ gl_flags: Glob_Flags, /* copy of flags parameter to glob */
gl_pathv: [^]cstring `fmt:"v,gl_pathc"`, /* [PSX] pointer to list of matched pathnames */
// Non-standard alternate file system access functions: // Non-standard alternate file system access functions:
gl_errfunc: proc "c" (cstring, c.int) -> c.int,
gl_closedir: proc "c" (dirp: DIR), gl_closedir: proc "c" (dirp: DIR),
gl_readdir: proc "c" (dirp: DIR) -> ^dirent, gl_readdir: proc "c" (dirp: DIR) -> ^dirent,
gl_opendir: proc "c" (path: cstring) -> DIR, gl_opendir: proc "c" (path: cstring) -> DIR,
+41 -41
View File
@@ -301,58 +301,58 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD {
DAY_1 :: 0x20_007 DAY_1 :: 0x20_007
DAY_2 :: 0x20_008 DAY_2 :: 0x20_008
DAY_3 :: 0x20_009 DAY_3 :: 0x20_009
DAY_4 :: 0x20_010 DAY_4 :: 0x20_00A
DAY_5 :: 0x20_011 DAY_5 :: 0x20_00B
DAY_6 :: 0x20_012 DAY_6 :: 0x20_00C
DAY_7 :: 0x20_013 DAY_7 :: 0x20_00D
ABMON_1 :: 0x20_014 ABMON_1 :: 0x20_00E
ABMON_2 :: 0x20_015 ABMON_2 :: 0x20_010
ABMON_3 :: 0x20_016 ABMON_3 :: 0x20_011
ABMON_4 :: 0x20_017 ABMON_4 :: 0x20_012
ABMON_5 :: 0x20_018 ABMON_5 :: 0x20_013
ABMON_6 :: 0x20_019 ABMON_6 :: 0x20_014
ABMON_7 :: 0x20_020 ABMON_7 :: 0x20_015
ABMON_8 :: 0x20_021 ABMON_8 :: 0x20_016
ABMON_9 :: 0x20_022 ABMON_9 :: 0x20_017
ABMON_10 :: 0x20_023 ABMON_10 :: 0x20_018
ABMON_11 :: 0x20_024 ABMON_11 :: 0x20_019
ABMON_12 :: 0x20_025 ABMON_12 :: 0x20_01A
MON_1 :: 0x20_026 MON_1 :: 0x20_01B
MON_2 :: 0x20_027 MON_2 :: 0x20_01C
MON_3 :: 0x20_028 MON_3 :: 0x20_01D
MON_4 :: 0x20_029 MON_4 :: 0x20_01E
MON_5 :: 0x20_030 MON_5 :: 0x20_020
MON_6 :: 0x20_031 MON_6 :: 0x20_021
MON_7 :: 0x20_032 MON_7 :: 0x20_022
MON_8 :: 0x20_033 MON_8 :: 0x20_023
MON_9 :: 0x20_034 MON_9 :: 0x20_024
MON_10 :: 0x20_035 MON_10 :: 0x20_025
MON_11 :: 0x20_036 MON_11 :: 0x20_026
MON_12 :: 0x20_037 MON_12 :: 0x20_027
AM_STR :: 0x20_038 AM_STR :: 0x20_028
PM_STR :: 0x20_039 PM_STR :: 0x20_029
D_T_FMT :: 0x20_040 D_T_FMT :: 0x20_02A
D_FMT :: 0x20_041 D_FMT :: 0x20_02B
T_FMT :: 0x20_042 T_FMT :: 0x20_02C
T_FMT_AMPM :: 0x20_043 T_FMT_AMPM :: 0x20_02D
ERA :: 0x20_044 ERA :: 0x20_02E
ERA_D_FMT :: 0x20_045 ERA_D_FMT :: 0x20_030
ALT_DIGITS :: 0x20_046 ALT_DIGITS :: 0x20_031
ERA_D_T_FMT :: 0x20_047 ERA_D_T_FMT :: 0x20_032
ERA_T_FMT :: 0x20_048 ERA_T_FMT :: 0x20_033
// NOTE: CODESET is the 16th member of the enum group starting with value // NOTE: CODESET is the 16th member of the enum group starting with value
// LC_CTYPE << 16, LC_CTYPE is 0. // LC_CTYPE << 16, LC_CTYPE is 0.
CODESET :: 0x15 CODESET :: 0x0F
// NOTE: CRNCYSTR is the 16th member of the enum group starting with value // NOTE: CRNCYSTR is the 16th member of the enum group starting with value
// LC_MONETARY << 16, LC_MONETARY is 4. // LC_MONETARY << 16, LC_MONETARY is 4.
CRNCYSTR :: 0x40_000 CRNCYSTR :: 0x40_00F
// NOTE: RADIXCHAR is the 1st member of the enum group starting with value // NOTE: RADIXCHAR is the 1st member of the enum group starting with value
// LC_NUMERIC << 16, LC_NUMERIC is 1. // LC_NUMERIC << 16, LC_NUMERIC is 1.
+15 -15
View File
@@ -466,24 +466,24 @@ when ODIN_OS == .Darwin {
// AIO_LISTIO_MAX :: sysconf(._AIO_LISTIO_MAX) // AIO_LISTIO_MAX :: sysconf(._AIO_LISTIO_MAX)
// AIO_MAX :: sysconf(._AIO_MAX) // AIO_MAX :: sysconf(._AIO_MAX)
AIO_PRIO_DELTA_MAX :: 20 // AIO_PRIO_DELTA_MAX :: sysconf(._AIO_PRIO_DELTA_MAX)
ARG_MAX :: 131_072 ARG_MAX :: 131_072
// ATEXIT_MAX :: sysconf(._ATEXIT_MAX) // ATEXIT_MAX :: sysconf(._ATEXIT_MAX)
// CHILD_MAX :: sysconf(._POSIX_ARG_MAX) // CHILD_MAX :: sysconf(._POSIX_ARG_MAX)
DELAYTIMER_MAX :: 2_147_483_647 // DELAYTIMER_MAX :: sysconf(._DELAYTIMER_MAX)
HOST_NAME_MAX :: 64 // HOST_NAME_MAX :: sysconf(._HOST_NAME_MAX)
// IOV_MAX :: sysconf(._XOPEN_IOV_MAX) // IOV_MAX :: sysconf(._XOPEN_IOV_MAX)
LOGIN_NAME_MAX :: 256 // LOGIN_NAME_MAX :: sysconf(._LOGIN_NAME_MAX)
// MQ_OPEN_MAX :: sysconf(._MQ_OPEN_MAX) // MQ_OPEN_MAX :: sysconf(._MQ_OPEN_MAX)
// MQ_PRIO_MAX :: sysconf(._MQ_PRIO_MAX) // MQ_PRIO_MAX :: sysconf(._MQ_PRIO_MAX)
// PAGESIZE :: PAGE_SIZE // PAGESIZE :: PAGE_SIZE
// PAGE_SIZE :: sysconf(._PAGE_SIZE) // PAGE_SIZE :: sysconf(._PAGE_SIZE)
PTHREAD_DESTRUCTOR_ITERATIONS :: 4 PTHREAD_DESTRUCTOR_ITERATIONS :: 4
PTHREAD_KEYS_MAX :: 1024 // PTHREAD_KEYS_MAX :: sysconf(._PTHREAD_KEYS_MAX)
PTHREAD_STACK_MIN :: 16_384 // PTHREAD_STACK_MIN :: sysconf(._PTHREAD_STACK_MIN)
RTSIG_MAX :: 32 // RTSIG_MAX :: sysconf(._RTSIG_MAX)
// SEM_NSEMS_MAX :: sysconf(._SEM_NSEMS_MAX) // SEM_NSEMS_MAX :: sysconf(._SEM_NSEMS_MAX)
SEM_VALUE_MAX :: 2_147_483_647 // SEM_VALUE_MAX :: sysconf(._SEM_VALUE_MAX)
// SIGQUEUE_MAX :: sysconf(._SIGQUEUE_MAX) // SIGQUEUE_MAX :: sysconf(._SIGQUEUE_MAX)
// SS_REPL_MAX :: sysconf(._SS_REPL_MAX) // SS_REPL_MAX :: sysconf(._SS_REPL_MAX)
// STREAM_MAX :: sysconf(._STREAM_MAX) // STREAM_MAX :: sysconf(._STREAM_MAX)
@@ -493,7 +493,7 @@ when ODIN_OS == .Darwin {
// TRACE_NAME_MAX :: sysconf(._TRACE_NAME_MAX) // TRACE_NAME_MAX :: sysconf(._TRACE_NAME_MAX)
// TRACE_SYS_MAX :: sysconf(._TRACE_SYS_MAX) // TRACE_SYS_MAX :: sysconf(._TRACE_SYS_MAX)
// TRACE_USER_EVENT_MAX :: sysconf(._TRACE_USER_EVENT_MAX) // TRACE_USER_EVENT_MAX :: sysconf(._TRACE_USER_EVENT_MAX)
TTY_NAME_MAX :: 32 // TTY_NAME_MAX :: sysconf(._TTY_NAME_MAX)
// TZNAME_MAX :: sysconf(._TZNAME_MAX) // TZNAME_MAX :: sysconf(._TZNAME_MAX)
// The values in the following list may be constants within an implementation or may vary from // The values in the following list may be constants within an implementation or may vary from
@@ -518,7 +518,7 @@ when ODIN_OS == .Darwin {
// POSIX_REC_MAX_XFER_SIZE :: sysconf(._POSIX_REC_MAX_XFER_SIZE) // POSIX_REC_MAX_XFER_SIZE :: sysconf(._POSIX_REC_MAX_XFER_SIZE)
// POSIX_REC_MIN_XFER_SIZE :: sysconf(._POSIX_REC_MIN_XFER_SIZE) // POSIX_REC_MIN_XFER_SIZE :: sysconf(._POSIX_REC_MIN_XFER_SIZE)
// POSIX_REC_XFER_ALIGN :: sysconf(._POSIX_REC_XFER_ALIGN) // POSIX_REC_XFER_ALIGN :: sysconf(._POSIX_REC_XFER_ALIGN)
SYMLINK_MAX :: PATH_MAX // SYMLINK_MAX :: pathconf(".", ._SYMLINK_MAX)
// The magnitude limitations in the following list shall be fixed by specific implementations. // The magnitude limitations in the following list shall be fixed by specific implementations.
@@ -536,17 +536,17 @@ when ODIN_OS == .Darwin {
CHARCLASS_NAME_MAX :: 14 CHARCLASS_NAME_MAX :: 14
COLL_WEIGHTS_MAX :: 2 COLL_WEIGHTS_MAX :: 2
EXPR_NEST_MAX :: 32 EXPR_NEST_MAX :: 32
LINE_MAX :: 2048 // LINE_MAX :: sysconf(._LINE_MAX)
NGROUPS_MAX :: 65_536 // NGROUPS_MAX :: sysconf(._NGROUPS_MAX)
RE_DUP_MAX :: 255 RE_DUP_MAX :: 255
// Other limits. // Other limits.
NL_ARGMAX :: 9 NL_ARGMAX :: 9
NL_LANGMAX :: 14 NL_LANGMAX :: 32 // 14 on glibc, 32 on musl
NL_MSGMAX :: 32_767 NL_MSGMAX :: 32_767
NL_SETMAX :: 255 NL_SETMAX :: 255
NL_TEXTMAX :: 255 NL_TEXTMAX :: 2048 // 255 on glibc, 2048 on musl
NZERO :: 20 NZERO :: 20
} else { } else {
+1 -1
View File
@@ -427,7 +427,7 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
NI_NUMERICHOST :: 1 NI_NUMERICHOST :: 1
NI_NAMEREQD :: 8 NI_NAMEREQD :: 8
NI_NUMERICSERV :: 2 NI_NUMERICSERV :: 2
NI_NUMERICSCOPE :: 0 // NOTE: not implemented NI_NUMERICSCOPE :: 0x100
NI_DGRAM :: 16 NI_DGRAM :: 16
} }
+3 -5
View File
@@ -45,20 +45,18 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
} }
when ODIN_OS == .Linux { when ODIN_OS == .Linux {
sockaddr_in :: struct { sockaddr_in :: struct {
sin_family: sa_family_t, /* [PSX] AF_INET (but a smaller size) */ sin_family: sa_family_t, /* [PSX] AF_INET (but a smaller size) */
sin_port: in_port_t, /* [PSX] port number */ sin_port: in_port_t, /* [PSX] port number */
sin_addr: in_addr, /* [PSX] IP address */ sin_addr: in_addr, /* [PSX] IP address */
sin_zero: [size_of(sockaddr) - sin_zero: [8]c.char,
u16 -
size_of(in_port_t) -
size_of(in_addr)]c.char,
} }
sockaddr_in6 :: struct { sockaddr_in6 :: struct {
sin6_family: sa_family_t, /* [PSX] AF_INET6 (but a smaller size) */ sin6_family: sa_family_t, /* [PSX] AF_INET6 (but a smaller size) */
sin6_port: in_port_t, /* [PSX] port number */ sin6_port: in_port_t, /* [PSX] port number */
sin6_flowinfo: u32be, /* [PSX] IPv6 traffic class and flow information */ sin6_flowinfo: u32be, /* [PSX] IPv6 traffic class and flow information */
sin6_addr: in6_addr, /* [PSX] IPv6 address */ sin6_addr: in6_addr, /* [PSX] IPv6 address */
sin6_scope_id: c.uint32_t, /* [PSX] set of interfaces for a scope */ sin6_scope_id: c.uint32_t, /* [PSX] set of interfaces for a scope */
} }
+1 -7
View File
@@ -21,17 +21,11 @@ foreign lib {
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/poll.html ]] [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/poll.html ]]
*/ */
poll :: proc(fds: [^]pollfd, nfds: nfds_t, timeout: c.int) -> Poll_Error --- poll :: proc(fds: [^]pollfd, nfds: nfds_t, timeout: c.int) -> c.int ---
} }
nfds_t :: c.uint nfds_t :: c.uint
Poll_Error :: enum c.int {
EAGAIN = cast(c.int)Errno.EAGAIN,
EINTR = cast(c.int)Errno.EINTR,
EINVAL = cast(c.int)Errno.EINVAL,
}
Poll_Event_Bits :: enum c.short { Poll_Event_Bits :: enum c.short {
// Data other than high-priority data may be read without blocking. // Data other than high-priority data may be read without blocking.
IN = log2(POLLIN), IN = log2(POLLIN),
+3 -1
View File
@@ -1,5 +1,7 @@
/* /*
Bindings for most POSIX APIs. Raw bindings for most POSIX APIs.
Targets glibc and musl compatibility.
APIs that have been left out are due to not being useful, APIs that have been left out are due to not being useful,
being fully replaced (and better) by other Odin packages, being fully replaced (and better) by other Odin packages,
+7 -2
View File
@@ -521,7 +521,7 @@ when ODIN_OS == .Darwin {
PTHREAD_CANCEL_ENABLE :: 0 PTHREAD_CANCEL_ENABLE :: 0
PTHREAD_CANCEL_DISABLE :: 1 PTHREAD_CANCEL_DISABLE :: 1
PTHREAD_CANCELED :: rawptr(uintptr(-1)) PTHREAD_CANCELED :: rawptr(~uintptr(0))
PTHREAD_CREATE_JOINABLE :: 0 PTHREAD_CREATE_JOINABLE :: 0
PTHREAD_CREATE_DETACHED :: 1 PTHREAD_CREATE_DETACHED :: 1
@@ -542,7 +542,7 @@ when ODIN_OS == .Darwin {
pthread_t :: distinct c.ulong pthread_t :: distinct c.ulong
pthread_attr_t :: struct #raw_union { pthread_attr_t :: struct #raw_union {
__size: [56]c.char, __size: [56]c.char, // NOTE: may be smaller depending on libc or arch, but never larger.
__align: c.long, __align: c.long,
} }
@@ -550,6 +550,11 @@ when ODIN_OS == .Darwin {
sched_param :: struct { sched_param :: struct {
sched_priority: c.int, /* [PSX] process or thread execution scheduling priority */ sched_priority: c.int, /* [PSX] process or thread execution scheduling priority */
// NOTE: may be smaller depending on libc or arch, but never larger.
__reserved1: c.int,
__reserved2: [4]c.long,
__reserved3: c.int,
} }
} else { } else {
+54 -42
View File
@@ -220,16 +220,6 @@ foreign lib {
const struct timespec *restrict); const struct timespec *restrict);
int sigwaitinfo(const sigset_t *restrict, siginfo_t *restrict); int sigwaitinfo(const sigset_t *restrict, siginfo_t *restrict);
*/ */
when ODIN_OS == .Linux {
/* Return number of available real-time signal with highest priority. */
@(private)
__libc_current_sigrtmin :: proc() -> result ---
/* Return number of available real-time signal with lowest priority. */
@(private)
__libc_current_sigrtmax :: proc() -> result ---
}
} }
sigval :: struct #raw_union { sigval :: struct #raw_union {
@@ -490,11 +480,6 @@ when ODIN_OS == .Darwin {
uid_t :: distinct c.uint32_t uid_t :: distinct c.uint32_t
sigset_t :: distinct c.uint32_t sigset_t :: distinct c.uint32_t
// NOTE: unimplemented on darwin.
//
// SIGRTMIN ::
// SIGRTMAX ::
SIGHUP :: 1 SIGHUP :: 1
SIGQUIT :: 3 SIGQUIT :: 3
SIGTRAP :: 5 SIGTRAP :: 5
@@ -635,11 +620,6 @@ when ODIN_OS == .Darwin {
__bits: [4]c.uint32_t, __bits: [4]c.uint32_t,
} }
// NOTE: unimplemented on FreeBSD.
//
// SIGRTMIN :: 65
// SIGRTMAX :: 126
SIGHUP :: 1 SIGHUP :: 1
SIGQUIT :: 3 SIGQUIT :: 3
SIGTRAP :: 5 SIGTRAP :: 5
@@ -804,11 +784,6 @@ when ODIN_OS == .Darwin {
__bits: [4]c.uint32_t, __bits: [4]c.uint32_t,
} }
// NOTE: unimplemented on NetBSD.
//
// SIGRTMIN :: 33
// SIGRTMAX :: 63
SIGHUP :: 1 SIGHUP :: 1
SIGQUIT :: 3 SIGQUIT :: 3
SIGTRAP :: 5 SIGTRAP :: 5
@@ -1146,9 +1121,6 @@ when ODIN_OS == .Darwin {
[1024/(8 * size_of(c.ulong))]val, [1024/(8 * size_of(c.ulong))]val,
} }
SIGRTMIN :: __libc_current_sigrtmin()
SIGRTMAX :: __libc_current_sigrtmax()
SIGHUP :: 1 SIGHUP :: 1
SIGQUIT :: 3 SIGQUIT :: 3
SIGTRAP :: 5 SIGTRAP :: 5
@@ -1174,10 +1146,15 @@ when ODIN_OS == .Darwin {
// NOTE: this is actually defined as `sigaction`, but due to the function with the same name // NOTE: this is actually defined as `sigaction`, but due to the function with the same name
// `_t` has been added. // `_t` has been added.
sigaction_t :: struct { sigaction_t :: struct {
sa_handler: proc "c" (Signal), using _: struct #raw_union {
sa_flags: SA_Flags, sa_handler: proc "c" (Signal), /* [PSX] signal-catching function or one of the SIG_IGN or SIG_DFL */
sa_mask: sigset_t, sa_sigaction: proc "c" (Signal, ^siginfo_t, rawptr), /* [PSX] signal-catching function */
},
sa_mask: sigset_t, /* [PSX] set of signals to be blocked during execution of the signal handling function */
sa_flags: SA_Flags, /* [PSX] special flags */
sa_restorer: proc "c" (),
} }
SIG_BLOCK :: 0 SIG_BLOCK :: 0
@@ -1195,8 +1172,13 @@ when ODIN_OS == .Darwin {
SS_ONSTACK :: 1 SS_ONSTACK :: 1
SS_DISABLE :: 2 SS_DISABLE :: 2
MINSIGSTKSZ :: 2048 when ODIN_ARCH == .arm64 {
SIGSTKSZ :: 8192 MINSIGSTKSZ :: 6144
SIGSTKSZ :: 12288
} else {
MINSIGSTKSZ :: 2048
SIGSTKSZ :: 8192
}
stack_t :: struct { stack_t :: struct {
ss_sp: rawptr, /* [PSX] stack base or pointer */ ss_sp: rawptr, /* [PSX] stack base or pointer */
@@ -1204,9 +1186,27 @@ when ODIN_OS == .Darwin {
ss_size: c.size_t, /* [PSX] stack size */ ss_size: c.size_t, /* [PSX] stack size */
} }
// WARNING: This implementaion might be completely wrong and need to be reviewed and corrected. @(private)
siginfo_t :: struct { __SI_MAX_SIZE :: 128
when size_of(int) == 8 {
@(private)
_pad0 :: struct {
_pad0: c.int,
}
@(private)
__SI_PAD_SIZE :: (__SI_MAX_SIZE / size_of(c.int)) - 4
} else {
@(private)
_pad0 :: struct {}
@(private)
__SI_PAD_SIZE :: (__SI_MAX_SIZE / size_of(c.int)) - 3
}
siginfo_t :: struct #align(8) {
si_signo: Signal, /* [PSX] signal number */ si_signo: Signal, /* [PSX] signal number */
si_errno: Errno, /* [PSX] errno value associated with this signal */
si_code: struct #raw_union { /* [PSX] specific more detailed codes per signal */ si_code: struct #raw_union { /* [PSX] specific more detailed codes per signal */
ill: ILL_Code, ill: ILL_Code,
fpe: FPE_Code, fpe: FPE_Code,
@@ -1217,13 +1217,25 @@ when ODIN_OS == .Darwin {
poll: POLL_Code, poll: POLL_Code,
any: Any_Code, any: Any_Code,
}, },
si_errno: Errno, /* [PSX] errno value associated with this signal */ __pad0: _pad0,
si_pid: pid_t, /* [PSX] sending process ID */ using _sifields: struct #raw_union {
si_uid: uid_t, /* [PSX] real user ID of sending process */ _pad: [__SI_PAD_SIZE]c.int,
si_addr: rawptr, /* [PSX] address of faulting instruction */
si_status: c.int, /* [PSX] exit value or signal */ using _: struct {
si_band: c.long, /* [PSX] band event for SIGPOLL */ si_pid: pid_t, /* [PSX] sending process ID */
si_value: sigval, /* [PSX] signal value */ si_uid: uid_t, /* [PSX] real user ID of sending process */
using _: struct #raw_union {
si_status: c.int, /* [PSX] exit value or signal */
si_value: sigval, /* [PSX] signal value */
},
},
using _: struct {
si_addr: rawptr, /* [PSX] address of faulting instruction */
},
using _: struct {
si_band: c.long, /* [PSX] band event for SIGPOLL */
},
},
} }
ILL_ILLOPC :: 1 ILL_ILLOPC :: 1
+27 -1
View File
@@ -36,7 +36,7 @@ IPC_Flag_Bits :: enum c.int {
} }
IPC_Flags :: bit_set[IPC_Flag_Bits; c.int] IPC_Flags :: bit_set[IPC_Flag_Bits; c.int]
when ODIN_OS == .Darwin || ODIN_OS == .Linux { when ODIN_OS == .Darwin {
key_t :: distinct c.int32_t key_t :: distinct c.int32_t
@@ -84,6 +84,32 @@ when ODIN_OS == .Darwin || ODIN_OS == .Linux {
IPC_SET :: 1 IPC_SET :: 1
IPC_STAT :: 2 IPC_STAT :: 2
} else when ODIN_OS == .Linux {
key_t :: distinct c.int32_t
ipc_perm :: struct {
__ipc_perm_key: key_t,
uid: uid_t, /* [PSX] owner's user ID */
gid: gid_t, /* [PSX] owner's group ID */
cuid: uid_t, /* [PSX] creator's user ID */
cgid: gid_t, /* [PSX] creator's group ID */
mode: mode_t, /* [PSX] read/write perms */
__ipc_perm_seq: c.int,
__pad1: c.long,
__pad2: c.long,
}
IPC_CREAT :: 0o01000
IPC_EXCL :: 0o02000
IPC_NOWAIT :: 0o04000
IPC_PRIVATE :: key_t(0)
IPC_RMID :: 0
IPC_SET :: 1
IPC_STAT :: 2
} else { } else {
#panic("posix is unimplemented for the current target") #panic("posix is unimplemented for the current target")
} }
+1 -5
View File
@@ -191,11 +191,7 @@ when ODIN_OS == .Darwin || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS
MCL_CURRENT :: 0x0001 MCL_CURRENT :: 0x0001
MCL_FUTURE :: 0x0002 MCL_FUTURE :: 0x0002
when ODIN_OS == .Linux { MAP_FAILED :: rawptr(~uintptr(0))
MAP_FAILED :: rawptr(~uintptr(-1))
} else {
MAP_FAILED :: rawptr(~uintptr(0))
}
POSIX_MADV_DONTNEED :: 4 POSIX_MADV_DONTNEED :: 4
POSIX_MADV_NORMAL :: 0 POSIX_MADV_NORMAL :: 0
+5 -2
View File
@@ -103,7 +103,7 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
rlim_t :: distinct c.uint64_t rlim_t :: distinct c.uint64_t
RLIM_INFINITY :: max(rlim_t) - 1 when ODIN_OS == .Linux else (rlim_t(1) << 63) - 1 RLIM_INFINITY :: ~rlim_t(0) when ODIN_OS == .Linux else (rlim_t(1) << 63) - 1
RLIM_SAVED_MAX :: RLIM_INFINITY RLIM_SAVED_MAX :: RLIM_INFINITY
RLIM_SAVED_CUR :: RLIM_INFINITY RLIM_SAVED_CUR :: RLIM_INFINITY
@@ -145,10 +145,13 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
RLIMIT_FSIZE :: 1 RLIMIT_FSIZE :: 1
RLIMIT_NOFILE :: 7 when ODIN_OS == .Linux else 8 RLIMIT_NOFILE :: 7 when ODIN_OS == .Linux else 8
RLIMIT_STACK :: 3 RLIMIT_STACK :: 3
when ODIN_OS == .Linux { when ODIN_OS == .Linux {
RLIMIT_AS :: 9 RLIMIT_AS :: 9
} else when ODIN_OS == .Darwin || ODIN_OS == .OpenBSD {
RLIMIT_AS :: 5
} else { } else {
RLIMIT_AS :: 5 when ODIN_OS == .Darwin || ODIN_OS == .OpenBSD else 10 RLIMIT_AS :: 10
} }
} else { } else {
+2 -10
View File
@@ -323,11 +323,7 @@ when ODIN_OS == .NetBSD {
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux { when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux {
when ODIN_OS == .Linux { socklen_t :: distinct c.uint
socklen_t :: distinct c.uint32_t
} else {
socklen_t :: distinct c.uint
}
_sa_family_t :: distinct c.uint8_t _sa_family_t :: distinct c.uint8_t
@@ -518,11 +514,7 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
} }
// The maximum backlog queue length for listen(). // The maximum backlog queue length for listen().
when ODIN_OS == .Linux { SOMAXCONN :: 128
SOMAXCONN :: 4096
} else {
SOMAXCONN :: 128
}
when ODIN_OS == .Linux { when ODIN_OS == .Linux {
MSG_CTRUNC :: 0x008 MSG_CTRUNC :: 0x008