From c0521c6d992afed75a029c4eb1d2df04f83ea08c Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Tue, 20 Aug 2024 20:35:28 -0600 Subject: [PATCH 01/33] Add linux support for errno. --- core/sys/posix/errno.odin | 97 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 94 insertions(+), 3 deletions(-) diff --git a/core/sys/posix/errno.odin b/core/sys/posix/errno.odin index 4ef10aadf..c064c0001 100644 --- a/core/sys/posix/errno.odin +++ b/core/sys/posix/errno.odin @@ -141,7 +141,7 @@ when ODIN_OS == .Darwin { EMLINK :: 31 EPIPE :: 32 EAGAIN :: 35 - EWOULDBLOCK :: 35 + EWOULDBLOCK :: EAGAIN EINPROGRESS :: 36 EALREADY :: 37 ENOTSOCK :: 38 @@ -220,7 +220,7 @@ when ODIN_OS == .Darwin { EMLINK :: 31 EPIPE :: 32 EAGAIN :: 35 - EWOULDBLOCK :: 35 + EWOULDBLOCK :: EAGAIN EINPROGRESS :: 36 EALREADY :: 37 ENOTSOCK :: 38 @@ -301,7 +301,7 @@ when ODIN_OS == .Darwin { EMLINK :: 31 EPIPE :: 32 EAGAIN :: 35 - EWOULDBLOCK :: 35 + EWOULDBLOCK :: EAGAIN EINPROGRESS :: 36 EALREADY :: 37 ENOTSOCK :: 38 @@ -367,6 +367,97 @@ when ODIN_OS == .Darwin { ETIME :: -1 } +} else when ODIN_OS == .Linux { + EPERM :: 1 + ENOENT :: 2 + ESRCH :: 3 + EINTR :: 4 + EIO :: 5 + ENXIO :: 6 + E2BIG :: 7 + ENOEXEC :: 8 + EBADF :: 9 + ECHILD :: 10 + EAGAIN :: 11 + EWOULDBLOCK :: EAGAIN + ENOMEM :: 12 + EACCES :: 13 + EFAULT :: 14 + EBUSY :: 16 + EEXIST :: 17 + EXDEV :: 18 + ENODEV :: 19 + ENOTDIR :: 20 + EISDIR :: 21 + EINVAL :: 22 + ENFILE :: 23 + EMFILE :: 24 + ENOTTY :: 25 + ETXTBSY :: 26 + EFBIG :: 27 + ENOSPC :: 28 + ESPIPE :: 29 + EROFS :: 30 + EMLINK :: 31 + EPIPE :: 32 + + EDEADLK :: 35 + ENAMETOOLONG :: 36 + ENOLCK :: 37 + ENOSYS :: 38 + ENOTEMPTY :: 39 + ELOOP :: 40 + ENOMSG :: 42 + EIDRM :: 43 + + ENOSTR :: 60 + ENODATA :: 61 + ETIME :: 62 + ENOSR :: 63 + + ENOLINK :: 67 + + EPROTO :: 71 + EMULTIHOP :: 72 + EBADMSG :: 74 + EOVERFLOW :: 75 + + ENOTSOCK :: 88 + EDESTADDRREQ :: 89 + EMSGSIZE :: 90 + EPROTOTYPE :: 91 + ENOPROTOOPT :: 92 + EPROTONOSUPPORT :: 93 + + EOPNOTSUPP :: 95 + EAFNOSUPPORT :: 97 + EADDRINUSE :: 98 + EADDRNOTAVAIL :: 99 + ENETDOWN :: 100 + ENETUNREACH :: 101 + ENETRESET :: 102 + ECONNABORTED :: 103 + ECONNRESET :: 104 + ENOBUFS :: 105 + EISCONN :: 106 + ENOTCONN :: 107 + + ETIMEDOUT :: 110 + ECONNREFUSED :: 111 + + EHOSTUNREACH :: 113 + EALREADY :: 114 + EINPROGRESS :: 115 + ESTALE :: 116 + + EDQUOT :: 122 + ECANCELED :: 125 + + EOWNERDEAD :: 130 + ENOTRECOVERABLE :: 131 + + // NOTE: Note defined for linux + ENOTSUP :: -1 } else { #panic("posix is unimplemented for the current target") } From ef06cd93ccfa5ea4cf6f49a46626dd10c959bcaa Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Tue, 20 Aug 2024 20:35:56 -0600 Subject: [PATCH 02/33] Initial implementation of linux-specifig dirent struct. --- core/sys/posix/dirent.odin | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/core/sys/posix/dirent.odin b/core/sys/posix/dirent.odin index bbb5416c5..38ba2e8cf 100644 --- a/core/sys/posix/dirent.odin +++ b/core/sys/posix/dirent.odin @@ -193,11 +193,21 @@ when ODIN_OS == .Darwin { } else when ODIN_OS == .NetBSD { dirent :: struct { - d_ino: ino_t, /* [PSX] file number of entry */ - d_reclen: c.uint16_t, /* length of this record */ - d_namelen: c.uint16_t, /* length of string in d_name */ - d_type: D_Type, /* file type */ - d_name: [512]c.char `fmt:"s,0"`, /* [PSX] entry name */ + d_ino: ino_t, /* [PSX] file number of entry */ + d_reclen: c.uint16_t, /* length of this record */ + d_namelen: c.uint16_t, /* length of string in d_name */ + d_type: D_Type, /* file type */ + d_name: [512]c.char `fmt:"s,0"`, /* [PSX] entry name */ + } + +} else when ODIN_OS == .Linux { + + dirent :: struct { + d_ino: ino_t, /* [PSX] file number of entry */ + d_off: off_t, /* directory offset of the next entry */ + d_reclen: c.uint16_t, /* length of this record */ + d_type: D_Type, /* file type */ + d_name: [256]c.char `fmt:"s,0"` /* [PSX] entry name */ } } else { From 90aa7dff04d51a80fac118ee7006815381f80d7e Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Fri, 23 Aug 2024 19:56:45 -0600 Subject: [PATCH 03/33] Add POSIX dirent struct for Linux. --- core/os/os_linux.odin | 3 +++ core/sys/posix/dirent.odin | 22 +++++++++++++++++++++- core/sys/posix/fcntl.odin | 3 +++ core/sys/posix/sys_stat.odin | 3 +++ 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/core/os/os_linux.odin b/core/os/os_linux.odin index 2f7a5ac43..0a3a2e236 100644 --- a/core/os/os_linux.odin +++ b/core/os/os_linux.odin @@ -26,6 +26,9 @@ Pid :: distinct i32 File_Time :: distinct u64 Socket :: distinct int +ino_t :: u64 +ino_t32 :: u32 + INVALID_HANDLE :: ~Handle(0) _Platform_Error :: linux.Errno diff --git a/core/sys/posix/dirent.odin b/core/sys/posix/dirent.odin index 38ba2e8cf..127f7bc48 100644 --- a/core/sys/posix/dirent.odin +++ b/core/sys/posix/dirent.odin @@ -202,7 +202,27 @@ when ODIN_OS == .Darwin { } else when ODIN_OS == .Linux { - dirent :: struct { + when ODIN_ARCH == .i386 || ODIN_ARCH == .wasm32 || ODIN_ARCH == .arm32 { + + dirent :: struct { + d_ino: ino_t32, /* [PSX] file number of entry */ + d_off: off_t32, /* directory offset of the next entry */ + d_reclen: c.uint16_t, /* length of this record */ + d_type: D_Type, /* file type */ + d_name: [256]c.char `fmt:"s,0"` /* [PSX] entry name */ + } + } else when ODIN_ARCH == .amd64 || ODIN_ARCH == .wasm64p32 || ODIN_ARCH == .arm64 { + + dirent :: struct { + d_ino: ino_t, /* [PSX] file number of entry */ + d_off: off_t, /* directory offset of the next entry */ + d_reclen: c.uint16_t, /* length of this record */ + d_type: D_Type, /* file type */ + d_name: [256]c.char `fmt:"s,0"` /* [PSX] entry name */ + } + } + + dirent64 :: struct { d_ino: ino_t, /* [PSX] file number of entry */ d_off: off_t, /* directory offset of the next entry */ d_reclen: c.uint16_t, /* length of this record */ diff --git a/core/sys/posix/fcntl.odin b/core/sys/posix/fcntl.odin index ca030a9a5..617fa408f 100644 --- a/core/sys/posix/fcntl.odin +++ b/core/sys/posix/fcntl.odin @@ -410,6 +410,9 @@ when ODIN_OS == .Darwin { l_whence: c.short, /* [PSX] flag (Whence) of starting offset */ } +} else when ODIN_OS == .Linux { + off_t :: distinct c.uint64_t + off_t32 :: distinct c.uint32_t } else { #panic("posix is unimplemented for the current target") } diff --git a/core/sys/posix/sys_stat.odin b/core/sys/posix/sys_stat.odin index dd66d7d14..5760175b1 100644 --- a/core/sys/posix/sys_stat.odin +++ b/core/sys/posix/sys_stat.odin @@ -427,6 +427,9 @@ when ODIN_OS == .Darwin { UTIME_NOW :: -2 UTIME_OMIT :: -1 +} when ODIN_OS == .Linux { + ino_t :: distinct c.unit64_t + ino_t32 :: distinct c.unit32_t } else { #panic("posix is unimplemented for the current target") } From 9c06898303bd7625c8d450e0b5ddfdad49356ba4 Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Fri, 23 Aug 2024 20:01:15 -0600 Subject: [PATCH 04/33] Add comma to last dirent struct member. --- core/sys/posix/dirent.odin | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/core/sys/posix/dirent.odin b/core/sys/posix/dirent.odin index 127f7bc48..79b4f87c0 100644 --- a/core/sys/posix/dirent.odin +++ b/core/sys/posix/dirent.odin @@ -205,29 +205,29 @@ when ODIN_OS == .Darwin { when ODIN_ARCH == .i386 || ODIN_ARCH == .wasm32 || ODIN_ARCH == .arm32 { dirent :: struct { - d_ino: ino_t32, /* [PSX] file number of entry */ - d_off: off_t32, /* directory offset of the next entry */ - d_reclen: c.uint16_t, /* length of this record */ - d_type: D_Type, /* file type */ - d_name: [256]c.char `fmt:"s,0"` /* [PSX] entry name */ + d_ino: ino_t32, /* [PSX] file number of entry */ + d_off: off_t32, /* directory offset of the next entry */ + d_reclen: c.uint16_t, /* length of this record */ + d_type: D_Type, /* file type */ + d_name: [256]c.char `fmt:"s,0"`, /* [PSX] entry name */ } } else when ODIN_ARCH == .amd64 || ODIN_ARCH == .wasm64p32 || ODIN_ARCH == .arm64 { dirent :: struct { - d_ino: ino_t, /* [PSX] file number of entry */ - d_off: off_t, /* directory offset of the next entry */ - d_reclen: c.uint16_t, /* length of this record */ - d_type: D_Type, /* file type */ - d_name: [256]c.char `fmt:"s,0"` /* [PSX] entry name */ + d_ino: ino_t, /* [PSX] file number of entry */ + d_off: off_t, /* directory offset of the next entry */ + d_reclen: c.uint16_t, /* length of this record */ + d_type: D_Type, /* file type */ + d_name: [256]c.char `fmt:"s,0"`, /* [PSX] entry name */ } } dirent64 :: struct { - d_ino: ino_t, /* [PSX] file number of entry */ - d_off: off_t, /* directory offset of the next entry */ - d_reclen: c.uint16_t, /* length of this record */ - d_type: D_Type, /* file type */ - d_name: [256]c.char `fmt:"s,0"` /* [PSX] entry name */ + d_ino: ino_t, /* [PSX] file number of entry */ + d_off: off_t, /* directory offset of the next entry */ + d_reclen: c.uint16_t, /* length of this record */ + d_type: D_Type, /* file type */ + d_name: [256]c.char `fmt:"s,0"`, /* [PSX] entry name */ } } else { From d8e4a1b93f6c0e609811b4f9f863180d7ef16c92 Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Fri, 23 Aug 2024 20:02:44 -0600 Subject: [PATCH 05/33] Fix comment typo on POSIX ENOTSUP constant. Co-authored-by: Feoramund <161657516+Feoramund@users.noreply.github.com> --- core/sys/posix/errno.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/sys/posix/errno.odin b/core/sys/posix/errno.odin index c064c0001..91afa4799 100644 --- a/core/sys/posix/errno.odin +++ b/core/sys/posix/errno.odin @@ -456,7 +456,7 @@ when ODIN_OS == .Darwin { EOWNERDEAD :: 130 ENOTRECOVERABLE :: 131 - // NOTE: Note defined for linux + // NOTE: Not defined for Linux ENOTSUP :: -1 } else { #panic("posix is unimplemented for the current target") From 2794eb31d9b955d893a1529defea47e815954aab Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Fri, 23 Aug 2024 20:08:59 -0600 Subject: [PATCH 06/33] On Linux POSIX, ENOTSUP and EOPNOTSUPP have the same value. --- core/sys/posix/errno.odin | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/core/sys/posix/errno.odin b/core/sys/posix/errno.odin index 91afa4799..e670ca889 100644 --- a/core/sys/posix/errno.odin +++ b/core/sys/posix/errno.odin @@ -151,7 +151,7 @@ when ODIN_OS == .Darwin { ENOPROTOOPT :: 42 EPROTONOSUPPORT :: 43 ENOTSUP :: 45 - EOPNOTSUPP :: 45 + EOPNOTSUPP :: ENOTSUP EAFNOSUPPORT :: 47 EADDRINUSE :: 48 EADDRNOTAVAIL :: 49 @@ -230,7 +230,7 @@ when ODIN_OS == .Darwin { ENOPROTOOPT :: 42 EPROTONOSUPPORT :: 43 ENOTSUP :: 45 - EOPNOTSUPP :: 45 + EOPNOTSUPP :: ENOTSUP EAFNOSUPPORT :: 47 EADDRINUSE :: 48 EADDRNOTAVAIL :: 49 @@ -311,7 +311,7 @@ when ODIN_OS == .Darwin { ENOPROTOOPT :: 42 EPROTONOSUPPORT :: 43 ENOTSUP :: 45 - EOPNOTSUPP :: 45 + EOPNOTSUPP :: ENOTSUP EAFNOSUPPORT :: 47 EADDRINUSE :: 48 EADDRNOTAVAIL :: 49 @@ -430,6 +430,7 @@ when ODIN_OS == .Darwin { EPROTONOSUPPORT :: 93 EOPNOTSUPP :: 95 + ENOTSUP :: EOPNOTSUPP EAFNOSUPPORT :: 97 EADDRINUSE :: 98 EADDRNOTAVAIL :: 99 @@ -455,9 +456,6 @@ when ODIN_OS == .Darwin { EOWNERDEAD :: 130 ENOTRECOVERABLE :: 131 - - // NOTE: Not defined for Linux - ENOTSUP :: -1 } else { #panic("posix is unimplemented for the current target") } From e0b78476c584ccee4dcccbdecf8805929c82e545 Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Fri, 23 Aug 2024 20:18:26 -0600 Subject: [PATCH 07/33] Fix else when clause. --- core/sys/posix/sys_stat.odin | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/sys/posix/sys_stat.odin b/core/sys/posix/sys_stat.odin index 5760175b1..aa3737361 100644 --- a/core/sys/posix/sys_stat.odin +++ b/core/sys/posix/sys_stat.odin @@ -427,8 +427,8 @@ when ODIN_OS == .Darwin { UTIME_NOW :: -2 UTIME_OMIT :: -1 -} when ODIN_OS == .Linux { - ino_t :: distinct c.unit64_t +} else when ODIN_OS == .Linux { + ino_t :: distinct c.unit64_t ino_t32 :: distinct c.unit32_t } else { #panic("posix is unimplemented for the current target") From 7d94810d016dc12327cd390aeb618a7753418295 Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Mon, 26 Aug 2024 22:12:05 -0600 Subject: [PATCH 08/33] Fix ino_t and ino_t32 types for POSIX linux. --- core/sys/posix/sys_stat.odin | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/sys/posix/sys_stat.odin b/core/sys/posix/sys_stat.odin index aa3737361..906318bb9 100644 --- a/core/sys/posix/sys_stat.odin +++ b/core/sys/posix/sys_stat.odin @@ -428,8 +428,8 @@ when ODIN_OS == .Darwin { UTIME_OMIT :: -1 } else when ODIN_OS == .Linux { - ino_t :: distinct c.unit64_t - ino_t32 :: distinct c.unit32_t + ino_t :: distinct u64 + ino_t32 :: distinct u32 } else { #panic("posix is unimplemented for the current target") } From f0e631cfa348790294355d3cbc481f5984077254 Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Wed, 28 Aug 2024 19:08:48 -0600 Subject: [PATCH 09/33] Use native types on linux POSIX structs. --- core/os/os_linux.odin | 3 --- core/sys/posix/dirent.odin | 26 +++----------------------- core/sys/posix/fcntl.odin | 3 --- core/sys/posix/sys_stat.odin | 3 --- 4 files changed, 3 insertions(+), 32 deletions(-) diff --git a/core/os/os_linux.odin b/core/os/os_linux.odin index 74a67f366..81ff5077a 100644 --- a/core/os/os_linux.odin +++ b/core/os/os_linux.odin @@ -26,9 +26,6 @@ Pid :: distinct i32 File_Time :: distinct u64 Socket :: distinct int -ino_t :: u64 -ino_t32 :: u32 - INVALID_HANDLE :: ~Handle(0) _Platform_Error :: linux.Errno diff --git a/core/sys/posix/dirent.odin b/core/sys/posix/dirent.odin index 79b4f87c0..254639a3f 100644 --- a/core/sys/posix/dirent.odin +++ b/core/sys/posix/dirent.odin @@ -202,33 +202,13 @@ when ODIN_OS == .Darwin { } else when ODIN_OS == .Linux { - when ODIN_ARCH == .i386 || ODIN_ARCH == .wasm32 || ODIN_ARCH == .arm32 { - dirent :: struct { - d_ino: ino_t32, /* [PSX] file number of entry */ - d_off: off_t32, /* directory offset of the next entry */ - d_reclen: c.uint16_t, /* length of this record */ + d_ino: u64, /* [PSX] file number of entry */ + d_off: i64, /* directory offset of the next entry */ + d_reclen: u16, /* length of this record */ d_type: D_Type, /* file type */ d_name: [256]c.char `fmt:"s,0"`, /* [PSX] entry name */ } - } else when ODIN_ARCH == .amd64 || ODIN_ARCH == .wasm64p32 || ODIN_ARCH == .arm64 { - - dirent :: struct { - d_ino: ino_t, /* [PSX] file number of entry */ - d_off: off_t, /* directory offset of the next entry */ - d_reclen: c.uint16_t, /* length of this record */ - d_type: D_Type, /* file type */ - d_name: [256]c.char `fmt:"s,0"`, /* [PSX] entry name */ - } - } - - dirent64 :: struct { - d_ino: ino_t, /* [PSX] file number of entry */ - d_off: off_t, /* directory offset of the next entry */ - d_reclen: c.uint16_t, /* length of this record */ - d_type: D_Type, /* file type */ - d_name: [256]c.char `fmt:"s,0"`, /* [PSX] entry name */ - } } else { #panic("posix is unimplemented for the current target") diff --git a/core/sys/posix/fcntl.odin b/core/sys/posix/fcntl.odin index 617fa408f..ca030a9a5 100644 --- a/core/sys/posix/fcntl.odin +++ b/core/sys/posix/fcntl.odin @@ -410,9 +410,6 @@ when ODIN_OS == .Darwin { l_whence: c.short, /* [PSX] flag (Whence) of starting offset */ } -} else when ODIN_OS == .Linux { - off_t :: distinct c.uint64_t - off_t32 :: distinct c.uint32_t } else { #panic("posix is unimplemented for the current target") } diff --git a/core/sys/posix/sys_stat.odin b/core/sys/posix/sys_stat.odin index 906318bb9..dd66d7d14 100644 --- a/core/sys/posix/sys_stat.odin +++ b/core/sys/posix/sys_stat.odin @@ -427,9 +427,6 @@ when ODIN_OS == .Darwin { UTIME_NOW :: -2 UTIME_OMIT :: -1 -} else when ODIN_OS == .Linux { - ino_t :: distinct u64 - ino_t32 :: distinct u32 } else { #panic("posix is unimplemented for the current target") } From 4577d541ec2b807df02c40f187a4c44dc7aa2e0f Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Wed, 28 Aug 2024 22:15:11 -0600 Subject: [PATCH 10/33] Add contants RTLD contants on os_linux and posix (dlfcn). --- core/os/os_linux.odin | 11 +++++++---- core/sys/posix/dlfcn.odin | 9 +++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/core/os/os_linux.odin b/core/os/os_linux.odin index 81ff5077a..654748305 100644 --- a/core/os/os_linux.odin +++ b/core/os/os_linux.odin @@ -242,10 +242,13 @@ F_SETFL: int : 4 /* Set file flags */ // NOTE(zangent): These are OS specific! // Do not mix these up! -RTLD_LAZY :: 0x001 -RTLD_NOW :: 0x002 -RTLD_BINDING_MASK :: 0x3 -RTLD_GLOBAL :: 0x100 +RTLD_LAZY :: 0x0001 +RTLD_NOW :: 0x0002 +RTLD_BINDING_MASK :: 0x0003 +RTLD_GLOBAL :: 0x0100 +RTLD_NOLOAD :: 0x0004 +RTLD_DEEPBIND :: 0x0008 +RTLD_NODELETE :: 0x1000 socklen_t :: c.int diff --git a/core/sys/posix/dlfcn.odin b/core/sys/posix/dlfcn.odin index 0ddc41337..6a467a2bd 100644 --- a/core/sys/posix/dlfcn.odin +++ b/core/sys/posix/dlfcn.odin @@ -111,6 +111,15 @@ when ODIN_OS == .Darwin { RTLD_LOCAL :: RTLD_Flags{RTLD_Flag_Bits(log2(_RTLD_LOCAL))} +} else when ODIN_OS == .Linux { + + RTLD_LAZY :: 0x001 + RTLD_NOW :: 0x002 + RTLD_GLOBAL :: 0x100 + + _RTLD_LOCAL :: 0 + RTLD_LOCAL :: RTLD_Flags{} + } else { #panic("posix is unimplemented for the current target") } From 3557955f5374f6395d3bb4e6d6f13899e5a5bde9 Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Thu, 29 Aug 2024 20:17:39 -0600 Subject: [PATCH 11/33] Align the dirent struct for linux --- core/sys/posix/dirent.odin | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/core/sys/posix/dirent.odin b/core/sys/posix/dirent.odin index 254639a3f..48830b030 100644 --- a/core/sys/posix/dirent.odin +++ b/core/sys/posix/dirent.odin @@ -203,11 +203,11 @@ when ODIN_OS == .Darwin { } else when ODIN_OS == .Linux { dirent :: struct { - d_ino: u64, /* [PSX] file number of entry */ - d_off: i64, /* directory offset of the next entry */ - d_reclen: u16, /* length of this record */ - d_type: D_Type, /* file type */ - d_name: [256]c.char `fmt:"s,0"`, /* [PSX] entry name */ + d_ino: u64, /* [PSX] file number of entry */ + d_off: i64, /* directory offset of the next entry */ + d_reclen: u16, /* length of this record */ + d_type: D_Type, /* file type */ + d_name: [256]c.char `fmt:"s,0"`, /* [PSX] entry name */ } } else { From 575aedc3bf08711f30db5ba545007517abdaf02a Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Fri, 30 Aug 2024 19:45:56 -0600 Subject: [PATCH 12/33] Implement POSIX support for Linux for the following facilities: - fnmatch - grp - langinfo - locale --- core/sys/posix/fnmatch.odin | 8 ++ core/sys/posix/glob.odin | 36 ++++++- core/sys/posix/grp.odin | 2 +- core/sys/posix/langinfo.odin | 181 ++++++++++++++++++++++++++++++++++- core/sys/posix/locale.odin | 38 ++++++++ 5 files changed, 260 insertions(+), 5 deletions(-) diff --git a/core/sys/posix/fnmatch.odin b/core/sys/posix/fnmatch.odin index 9e54972e7..1326ce9e4 100644 --- a/core/sys/posix/fnmatch.odin +++ b/core/sys/posix/fnmatch.odin @@ -53,6 +53,14 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS FNM_PERIOD :: 0x04 FNM_NOESCAPE :: 0x01 +} else when ODIN_OS == .Linux { + + FNM_NOMATCH :: 1 + + FNM_PATHNAME :: 0x01 + FNM_NOESCAPE :: 0x02 + FNM_PERIOD :: 0x04 + } else { #panic("posix is unimplemented for the current target") } diff --git a/core/sys/posix/glob.odin b/core/sys/posix/glob.odin index 4f41d83db..b09104900 100644 --- a/core/sys/posix/glob.odin +++ b/core/sys/posix/glob.odin @@ -112,7 +112,7 @@ when ODIN_OS == .Darwin { glob_t :: struct { gl_pathc: c.size_t, /* [PSX] count of paths matched by pattern */ - gl_matchc: c.size_t, /* count of paths matching pattern */ + gl_matchc: c.size_t, /* count of paths matching pattern */ 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_pathv: [^]cstring `fmt:"v,gl_pathc"`, /* [PSX] pointer to list of matched pathnames */ @@ -144,7 +144,7 @@ when ODIN_OS == .Darwin { glob_t :: struct { gl_pathc: c.size_t, /* [PSX] count of paths matched by pattern */ - gl_matchc: c.size_t, /* count of paths matching pattern */ + gl_matchc: c.size_t, /* count of paths matching pattern */ 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_pathv: [^]cstring `fmt:"v,gl_pathc"`, /* [PSX] pointer to list of matched pathnames */ @@ -174,6 +174,38 @@ when ODIN_OS == .Darwin { GLOB_NOMATCH :: -3 GLOB_NOSPACE :: -1 +} else when ODIN_OS == .Linux { + + glob_t :: struct { + gl_pathc: c.size_t, /* [PSX] count of paths matched by pattern */ + gl_matchc: c.size_t, /* count of paths matching pattern */ + 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_pathv: [^]cstring `fmt:"v,gl_pathc"`, /* [PSX] pointer to list of matched pathnames */ + + // Non-standard alternate file system access functions: + + gl_errfunc: proc "c" (cstring, c.int) -> c.int, + + gl_closedir: proc "c" (dirp: DIR), + gl_readdir: proc "c" (dirp: DIR) -> ^dirent, + gl_opendir: proc "c" (path: cstring) -> DIR, + gl_lstat: proc "c" (path: cstring, buf: ^stat_t) -> result, + gl_stat: proc "c" (path: cstring, buf: ^stat_t) -> result, + } + + GLOB_ERR :: 1 << 0 + GLOB_MARK :: 1 << 1 + GLOB_NOSORT :: 1 << 2 + GLOB_DOOFFS :: 1 << 3 + GLOB_NOCHECK :: 1 << 4 + GLOB_APPEND :: 1 << 5 + GLOB_NOESCAPE :: 1 << 6 + + GLOB_NOSPACE :: 1 + GLOB_ABORTED :: 2 + GLOB_NOMATCH :: 3 + } else { #panic("posix is unimplemented for the current target") } diff --git a/core/sys/posix/grp.odin b/core/sys/posix/grp.odin index c8a39de6a..3a78e2c4c 100644 --- a/core/sys/posix/grp.odin +++ b/core/sys/posix/grp.odin @@ -114,7 +114,7 @@ foreign lib { getgrnam_r :: proc(name: cstring, grp: ^group, buffer: [^]byte, bufsize: c.size_t, result: ^^group) -> Errno --- } -when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD { +when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux { gid_t :: distinct c.uint32_t diff --git a/core/sys/posix/langinfo.odin b/core/sys/posix/langinfo.odin index 24ecc917a..ffb83730c 100644 --- a/core/sys/posix/langinfo.odin +++ b/core/sys/posix/langinfo.odin @@ -238,7 +238,7 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD { ABDAY_4 :: 16 ABDAY_5 :: 17 ABDAY_6 :: 18 - ABDAY_7 :: 19 + ABDAY_7 :: 19 MON_1 :: 20 MON_2 :: 21 @@ -278,7 +278,184 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD { YESEXPR :: 47 NOEXPR :: 49 - CRNCYSTR :: 50 + CRNCYSTR :: 50 + +} else when ODIN_OS == .Linux { + + @(private="file") + nl_item :: proc(flag: int) -> int { + return flag << 16 + } + + @(private="file") + _langinfo_values :: enum { + ABDAY_1 = nl_item(LC_TIME), + ABDAY_2, + ABDAY_3, + ABDAY_4, + ABDAY_5, + ABDAY_6, + ABDAY_7, + + DAY_1, + DAY_2, + DAY_3, + DAY_4, + DAY_5, + DAY_6, + DAY_7, + + ABMON_1, + ABMON_2, + ABMON_3, + ABMON_4, + ABMON_5, + ABMON_6, + ABMON_7, + ABMON_8, + ABMON_9, + ABMON_10, + ABMON_11, + ABMON_12, + + MON_1, + MON_2, + MON_3, + MON_4, + MON_5, + MON_6, + MON_7, + MON_8, + MON_9, + MON_10, + MON_11, + MON_12, + + AM_STR, + PM_STR, + + D_T_FMT, + D_FMT, + T_FMT, + T_FMT_AMPM, + + ERA, + _, + ERA_D_FMT, + ALT_DIGITS, + ERA_D_T_FMT, + ERA_T_FMT, + + // These values are defined only to make sure CODESET below gets the correct value. + _NL_CTYPE_CLASS = nl_item(LC_CTYPE), + _NL_CTYPE_TOUPPER, + _NL_CTYPE_GAP1, + _NL_CTYPE_TOLOWER, + _NL_CTYPE_GAP2, + _NL_CTYPE_CLASS32, + _NL_CTYPE_GAP3, + _NL_CTYPE_GAP4, + _NL_CTYPE_GAP5, + _NL_CTYPE_GAP6, + _NL_CTYPE_CLASS_NAMES, + _NL_CTYPE_MAP_NAMES, + _NL_CTYPE_WIDTH, + _NL_CTYPE_MB_CUR_MAX, + CODESET, + + // These values are defined only to make sure CRNCYSTR below gets the correct value. + __INT_CURR_SYMBOL = nl_item(LC_MONETARY), + __CURRENCY_SYMBOL, + __MON_DECIMAL_POINT, + __MON_THOUSANDS_SEP, + __MON_GROUPING, + __POSITIVE_SIGN, + __NEGATIVE_SIGN, + __INT_FRAC_DIGITS, + __FRAC_DIGITS, + __P_CS_PRECEDES, + __P_SEP_BY_SPACE, + __N_CS_PRECEDES, + __N_SEP_BY_SPACE, + __P_SIGN_POSN, + __N_SIGN_POSN, + CRNCYSTR, + + RADIXCHAR = nl_item(LC_NUMERIC), + THOUSEP, + + YESEXPR = nl_item(LC_MESSAGES), + NOEXPR, + } + +// NOTE: declared with `_t` so we can enumerate the real `nl_info`. + nl_item_t :: distinct c.int + + ABDAY_1 :: _langinfo_values.ABDAY_1 + ABDAY_2 :: _langinfo_values.ABDAY_2 + ABDAY_3 :: _langinfo_values.ABDAY_3 + ABDAY_4 :: _langinfo_values.ABDAY_4 + ABDAY_5 :: _langinfo_values.ABDAY_5 + ABDAY_6 :: _langinfo_values.ABDAY_6 + ABDAY_7 :: _langinfo_values.ABDAY_7 + + DAY_1 :: _langinfo_values.DAY_1 + DAY_2 :: _langinfo_values.DAY_2 + DAY_3 :: _langinfo_values.DAY_3 + DAY_4 :: _langinfo_values.DAY_4 + DAY_5 :: _langinfo_values.DAY_5 + DAY_6 :: _langinfo_values.DAY_6 + DAY_7 :: _langinfo_values.DAY_7 + + ABMON_1 :: _langinfo_values.ABMON_1 + ABMON_2 :: _langinfo_values.ABMON_2 + ABMON_3 :: _langinfo_values.ABMON_3 + ABMON_4 :: _langinfo_values.ABMON_4 + ABMON_5 :: _langinfo_values.ABMON_5 + ABMON_6 :: _langinfo_values.ABMON_6 + ABMON_7 :: _langinfo_values.ABMON_7 + ABMON_8 :: _langinfo_values.ABMON_8 + ABMON_9 :: _langinfo_values.ABMON_9 + ABMON_10 :: _langinfo_values.ABMON_10 + ABMON_11 :: _langinfo_values.ABMON_11 + ABMON_12 :: _langinfo_values.ABMON_12 + + MON_1 :: _langinfo_values.MON_1 + MON_2 :: _langinfo_values.MON_2 + MON_3 :: _langinfo_values.MON_3 + MON_4 :: _langinfo_values.MON_4 + MON_5 :: _langinfo_values.MON_5 + MON_6 :: _langinfo_values.MON_6 + MON_7 :: _langinfo_values.MON_7 + MON_8 :: _langinfo_values.MON_8 + MON_9 :: _langinfo_values.MON_9 + MON_10 :: _langinfo_values.MON_10 + MON_11 :: _langinfo_values.MON_11 + MON_12 :: _langinfo_values.MON_12 + + AM_STR :: _langinfo_values.AM_STR + PM_STR :: _langinfo_values.PM_STR + + D_T_FMT :: _langinfo_values.D_T_FMT + D_FMT :: _langinfo_values.D_FMT + T_FMT :: _langinfo_values.T_FMT + T_FMT_AMPM :: _langinfo_values.T_FMT_AMPM + + ERA :: _langinfo_values.ERA + ERA_D_FMT :: _langinfo_values.ERA_D_FMT + ALT_DIGITS :: _langinfo_values.ALT_DIGITS + ERA_D_T_FMT :: _langinfo_values.ERA_D_T_FMT + ERA_T_FMT :: _langinfo_values.ERA_T_FMT + + CODESET :: _langinfo_values.CODESET + + CRNCYSTR :: _langinfo_values.CRNCYSTR + + RADIXCHAR :: _langinfo_values.RADIXCHAR + THOUSEP :: _langinfo_values.THOUSEP + + YESEXP :: _langinfo_values.YESEXP + NOEXPR :: _langinfo_values.NOEXPR } else { #panic("posix is unimplemented for the current target") diff --git a/core/sys/posix/locale.odin b/core/sys/posix/locale.odin index 1f2a336b5..fae692bcb 100644 --- a/core/sys/posix/locale.odin +++ b/core/sys/posix/locale.odin @@ -88,6 +88,44 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS LC_NUMERIC :: 4 LC_TIME :: 5 +} else when ODIN_OS == .Linux { + + // NOTE: All of these fields are standard ([PSX]). + lconv :: struct { + decimal_point: cstring, + thousand_sep: cstring, + grouping: cstring, + int_curr_symbol: cstring, + currency_symbol: cstring, + mon_decimal_points: cstring, + mon_thousands_sep: cstring, + mon_grouping: cstring, + positive_sign: cstring, + negative_sign: cstring, + int_frac_digits: c.char, + frac_digits: c.char, + p_cs_precedes: c.char, + p_sep_by_space: c.char, + n_cs_precedes: c.char, + n_sep_by_space: c.char, + p_sign_posn: c.char, + n_sign_posn: c.char, + int_p_cs_precedes: c.char, + int_n_cs_precedes: c.char, + int_p_sep_by_space: c.char, + int_n_sep_by_space: c.char, + int_p_sign_posn: c.char, + int_n_sign_posn: c.char, + } + + LC_CTYPE :: 0 + LC_NUMERIC :: 1 + LC_TIME :: 2 + LC_COLLATE :: 3 + LC_MONETARY :: 4 + LC_MESSAGES :: 5 + LC_ALL :: 6 + } else { #panic("posix is unimplemented for the current target") } From 186565b0c18317c035c15b1525969ccab7ebfce5 Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Fri, 30 Aug 2024 20:34:12 -0600 Subject: [PATCH 13/33] Simplify the implementation of POSIX langinfo for Linux: No need for the enum runtime checks. Constant values were set manually and comments were added to help locate their origin. --- core/sys/posix/langinfo.odin | 231 +++++++++++------------------------ 1 file changed, 69 insertions(+), 162 deletions(-) diff --git a/core/sys/posix/langinfo.odin b/core/sys/posix/langinfo.odin index ffb83730c..7f521e3a4 100644 --- a/core/sys/posix/langinfo.odin +++ b/core/sys/posix/langinfo.odin @@ -282,180 +282,87 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD { } else when ODIN_OS == .Linux { - @(private="file") - nl_item :: proc(flag: int) -> int { - return flag << 16 - } - - @(private="file") - _langinfo_values :: enum { - ABDAY_1 = nl_item(LC_TIME), - ABDAY_2, - ABDAY_3, - ABDAY_4, - ABDAY_5, - ABDAY_6, - ABDAY_7, - - DAY_1, - DAY_2, - DAY_3, - DAY_4, - DAY_5, - DAY_6, - DAY_7, - - ABMON_1, - ABMON_2, - ABMON_3, - ABMON_4, - ABMON_5, - ABMON_6, - ABMON_7, - ABMON_8, - ABMON_9, - ABMON_10, - ABMON_11, - ABMON_12, - - MON_1, - MON_2, - MON_3, - MON_4, - MON_5, - MON_6, - MON_7, - MON_8, - MON_9, - MON_10, - MON_11, - MON_12, - - AM_STR, - PM_STR, - - D_T_FMT, - D_FMT, - T_FMT, - T_FMT_AMPM, - - ERA, - _, - ERA_D_FMT, - ALT_DIGITS, - ERA_D_T_FMT, - ERA_T_FMT, - - // These values are defined only to make sure CODESET below gets the correct value. - _NL_CTYPE_CLASS = nl_item(LC_CTYPE), - _NL_CTYPE_TOUPPER, - _NL_CTYPE_GAP1, - _NL_CTYPE_TOLOWER, - _NL_CTYPE_GAP2, - _NL_CTYPE_CLASS32, - _NL_CTYPE_GAP3, - _NL_CTYPE_GAP4, - _NL_CTYPE_GAP5, - _NL_CTYPE_GAP6, - _NL_CTYPE_CLASS_NAMES, - _NL_CTYPE_MAP_NAMES, - _NL_CTYPE_WIDTH, - _NL_CTYPE_MB_CUR_MAX, - CODESET, - - // These values are defined only to make sure CRNCYSTR below gets the correct value. - __INT_CURR_SYMBOL = nl_item(LC_MONETARY), - __CURRENCY_SYMBOL, - __MON_DECIMAL_POINT, - __MON_THOUSANDS_SEP, - __MON_GROUPING, - __POSITIVE_SIGN, - __NEGATIVE_SIGN, - __INT_FRAC_DIGITS, - __FRAC_DIGITS, - __P_CS_PRECEDES, - __P_SEP_BY_SPACE, - __N_CS_PRECEDES, - __N_SEP_BY_SPACE, - __P_SIGN_POSN, - __N_SIGN_POSN, - CRNCYSTR, - - RADIXCHAR = nl_item(LC_NUMERIC), - THOUSEP, - - YESEXPR = nl_item(LC_MESSAGES), - NOEXPR, - } - -// NOTE: declared with `_t` so we can enumerate the real `nl_info`. + // NOTE: declared with `_t` so we can enumerate the real `nl_info`. nl_item_t :: distinct c.int - ABDAY_1 :: _langinfo_values.ABDAY_1 - ABDAY_2 :: _langinfo_values.ABDAY_2 - ABDAY_3 :: _langinfo_values.ABDAY_3 - ABDAY_4 :: _langinfo_values.ABDAY_4 - ABDAY_5 :: _langinfo_values.ABDAY_5 - ABDAY_6 :: _langinfo_values.ABDAY_6 - ABDAY_7 :: _langinfo_values.ABDAY_7 + // NOTE: All these values are set in an enum on the Linux implementation. + // Some depend on locale.h contants (bits/locale.h to be precise). - DAY_1 :: _langinfo_values.DAY_1 - DAY_2 :: _langinfo_values.DAY_2 - DAY_3 :: _langinfo_values.DAY_3 - DAY_4 :: _langinfo_values.DAY_4 - DAY_5 :: _langinfo_values.DAY_5 - DAY_6 :: _langinfo_values.DAY_6 - DAY_7 :: _langinfo_values.DAY_7 + // NOTE: ABDAY_1 is set to LC_TIME << 16 (LC_TIME is 2) on the enum group of + // the Linux implementation. + ABDAY_1 :: 0x20_000 + ABDAY_2 :: 0x20_001 + ABDAY_3 :: 0x20_002 + ABDAY_4 :: 0x20_003 + ABDAY_5 :: 0x20_004 + ABDAY_6 :: 0x20_005 + ABDAY_7 :: 0x20_006 - ABMON_1 :: _langinfo_values.ABMON_1 - ABMON_2 :: _langinfo_values.ABMON_2 - ABMON_3 :: _langinfo_values.ABMON_3 - ABMON_4 :: _langinfo_values.ABMON_4 - ABMON_5 :: _langinfo_values.ABMON_5 - ABMON_6 :: _langinfo_values.ABMON_6 - ABMON_7 :: _langinfo_values.ABMON_7 - ABMON_8 :: _langinfo_values.ABMON_8 - ABMON_9 :: _langinfo_values.ABMON_9 - ABMON_10 :: _langinfo_values.ABMON_10 - ABMON_11 :: _langinfo_values.ABMON_11 - ABMON_12 :: _langinfo_values.ABMON_12 + DAY_1 :: 0x20_007 + DAY_2 :: 0x20_008 + DAY_3 :: 0x20_009 + DAY_4 :: 0x20_010 + DAY_5 :: 0x20_011 + DAY_6 :: 0x20_012 + DAY_7 :: 0x20_013 - MON_1 :: _langinfo_values.MON_1 - MON_2 :: _langinfo_values.MON_2 - MON_3 :: _langinfo_values.MON_3 - MON_4 :: _langinfo_values.MON_4 - MON_5 :: _langinfo_values.MON_5 - MON_6 :: _langinfo_values.MON_6 - MON_7 :: _langinfo_values.MON_7 - MON_8 :: _langinfo_values.MON_8 - MON_9 :: _langinfo_values.MON_9 - MON_10 :: _langinfo_values.MON_10 - MON_11 :: _langinfo_values.MON_11 - MON_12 :: _langinfo_values.MON_12 + ABMON_1 :: 0x20_014 + ABMON_2 :: 0x20_015 + ABMON_3 :: 0x20_016 + ABMON_4 :: 0x20_017 + ABMON_5 :: 0x20_018 + ABMON_6 :: 0x20_019 + ABMON_7 :: 0x20_020 + ABMON_8 :: 0x20_021 + ABMON_9 :: 0x20_022 + ABMON_10 :: 0x20_023 + ABMON_11 :: 0x20_024 + ABMON_12 :: 0x20_025 - AM_STR :: _langinfo_values.AM_STR - PM_STR :: _langinfo_values.PM_STR + MON_1 :: 0x20_026 + MON_2 :: 0x20_027 + MON_3 :: 0x20_028 + MON_4 :: 0x20_029 + MON_5 :: 0x20_030 + MON_6 :: 0x20_031 + MON_7 :: 0x20_032 + MON_8 :: 0x20_033 + MON_9 :: 0x20_034 + MON_10 :: 0x20_035 + MON_11 :: 0x20_036 + MON_12 :: 0x20_037 - D_T_FMT :: _langinfo_values.D_T_FMT - D_FMT :: _langinfo_values.D_FMT - T_FMT :: _langinfo_values.T_FMT - T_FMT_AMPM :: _langinfo_values.T_FMT_AMPM + AM_STR :: 0x20_038 + PM_STR :: 0x20_039 - ERA :: _langinfo_values.ERA - ERA_D_FMT :: _langinfo_values.ERA_D_FMT - ALT_DIGITS :: _langinfo_values.ALT_DIGITS - ERA_D_T_FMT :: _langinfo_values.ERA_D_T_FMT - ERA_T_FMT :: _langinfo_values.ERA_T_FMT + D_T_FMT :: 0x20_040 + D_FMT :: 0x20_041 + T_FMT :: 0x20_042 + T_FMT_AMPM :: 0x20_043 - CODESET :: _langinfo_values.CODESET + ERA :: 0x20_044 + ERA_D_FMT :: 0x20_045 + ALT_DIGITS :: 0x20_046 + ERA_D_T_FMT :: 0x20_047 + ERA_T_FMT :: 0x20_048 - CRNCYSTR :: _langinfo_values.CRNCYSTR + // NOTE: CODESET is the 16th member of the enum group starting with value + // LC_CTYPE << 16, LC_CTYPE is 0. + CODESET :: 0x15 - RADIXCHAR :: _langinfo_values.RADIXCHAR - THOUSEP :: _langinfo_values.THOUSEP + // NOTE: CRNCYSTR is the 16th member of the enum group starting with value + // LC_MONETARY << 16, LC_MONETARY is 4. + CRNCYSTR :: 0x40_000 - YESEXP :: _langinfo_values.YESEXP - NOEXPR :: _langinfo_values.NOEXPR + // NOTE: RADIXCHAR is the 1st member of the enum group starting with value + // LC_NUMERIC << 16, LC_NUMERIC is 1. + RADIXCHAR :: 0x10_000 + THOUSEP :: 0x10_001 + + // NOTE: YESEXPR is the 1st member of the enum group starting with value + // LC_MESSAGES << 16, LC_MESSAGES is 5. + YESEXPR :: 0x50_000 + NOEXPR :: 0x50_001 } else { #panic("posix is unimplemented for the current target") From a248d49f349479e3a74b7c2fe8f9a173b512efe1 Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Mon, 2 Sep 2024 14:04:05 -0600 Subject: [PATCH 14/33] Add Linux support for POSIX limits. --- core/sys/posix/limits.odin | 95 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/core/sys/posix/limits.odin b/core/sys/posix/limits.odin index 7bb561215..81ede3368 100644 --- a/core/sys/posix/limits.odin +++ b/core/sys/posix/limits.odin @@ -454,6 +454,101 @@ when ODIN_OS == .Darwin { NL_TEXTMAX :: 255 NZERO :: 20 +} else when ODIN_OS == .Linux { + + // A definition of one of the symbolic constants in the following list shall be omitted from + // on specific implementations where the corresponding value is equal to or greater + // than the stated minimum, but is unspecified. + // + // This indetermination might depend on the amount of available memory space on a specific + // instance of a specific implementation. The actual value supported by a specific instance shall + // be provided by the sysconf() function. + + // AIO_LISTIO_MAX :: sysconf(._AIO_LISTIO_MAX) + // AIO_MAX :: sysconf(._AIO_MAX) + AIO_PRIO_DELTA_MAX :: 20 + ARG_MAX :: 131_072 + // ATEXIT_MAX :: sysconf(._ATEXIT_MAX) + // CHILD_MAX :: sysconf(._POSIX_ARG_MAX) + DELAYTIMER_MAX :: 2_147_483_647 + HOST_NAME_MAX :: 64 + // IOV_MAX :: sysconf(._XOPEN_IOV_MAX) + LOGIN_NAME_MAX :: 256 + // MQ_OPEN_MAX :: sysconf(._MQ_OPEN_MAX) + // MQ_PRIO_MAX :: sysconf(._MQ_PRIO_MAX) + // PAGESIZE :: PAGE_SIZE + // PAGE_SIZE :: sysconf(._PAGE_SIZE) + PTHREAD_DESTRUCTOR_ITERATIONS :: 4 + PTHREAD_KEYS_MAX :: 1024 + PTHREAD_STACK_MIN :: 16_384 + RTSIG_MAX :: 32 + // SEM_NSEMS_MAX :: sysconf(._SEM_NSEMS_MAX) + SEM_VALUE_MAX :: 2_147_483_647 + // SIGQUEUE_MAX :: sysconf(._SIGQUEUE_MAX) + // SS_REPL_MAX :: sysconf(._SS_REPL_MAX) + // STREAM_MAX :: sysconf(._STREAM_MAX) + // SYMLOOP_MAX :: sysconf(._SYSLOOP_MAX) + // TIMER_MAX :: sysconf(._TIMER_MAX) + // TRACE_EVENT_NAME_MAX :: sysconf(._TRACE_EVENT_NAME_MAX) + // TRACE_NAME_MAX :: sysconf(._TRACE_NAME_MAX) + // TRACE_SYS_MAX :: sysconf(._TRACE_SYS_MAX) + // TRACE_USER_EVENT_MAX :: sysconf(._TRACE_USER_EVENT_MAX) + TTY_NAME_MAX :: 32 + // TZNAME_MAX :: sysconf(._TZNAME_MAX) + + // The values in the following list may be constants within an implementation or may vary from + // one pathname to another. + // For example, file systems or directories may have different characteristics. + // + // A definition of one of the symbolic constants in the following list shall be omitted from the + // header on specific implementations where the corresponding value is equal to or + // greater than the stated minimum, but where the value can vary depending on the file to which + // it is applied. + // The actual value supported for a specific pathname shall be provided by the pathconf() function. + + // FILESIZEBITS :: pathconf(".", ._FILESIZEBITS) + LINK_MAX :: 127 + MAX_CANON :: 255 + MAX_INPUT :: 255 + NAME_MAX :: 255 + PATH_MAX :: 4096 + PIPE_BUF :: 4096 + // POSIX_ALLOC_SIZE_MIN :: sysconf(._POSIX_ALLOC_SIZE_MIN) + // POSIX_REC_INCR_XFER_SIZE :: sysconf(._POSIX_REC_INCR_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_XFER_ALIGN :: sysconf(._POSIX_REC_XFER_ALIGN) + SYMLINK_MAX :: PATH_MAX + + + // The magnitude limitations in the following list shall be fixed by specific implementations. + // An application should assume that the value of the symbolic constant defined by + // in a specific implementation is the minimum that pertains whenever the application is run + // under that implementation. + // A specific instance of a specific implementation may increase the value relative to that + // supplied by for that implementation. + // The actual value supported by a specific instance shall be provided by the sysconf() function. + + BC_BASE_MAX :: 99 + BC_DIM_MAX :: 2048 + BC_SCALE_MAX :: 99 + BC_STRING_MAX :: 1000 + CHARCLASS_NAME_MAX :: 14 + COLL_WEIGHTS_MAX :: 2 + EXPR_NEST_MAX :: 32 + LINE_MAX :: 2048 + NGROUPS_MAX :: 65_536 + RE_DUP_MAX :: 255 + + // Other limits. + + NL_ARGMAX :: 9 + NL_LANGMAX :: 14 + NL_MSGMAX :: 32_767 + NL_SETMAX :: 255 + NL_TEXTMAX :: 255 + NZERO :: 20 + } else { #panic("posix is unimplemented for the current target") } From 35f961d80f11fca6c0d1f8c6cb7d8d149f3e71f2 Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Mon, 2 Sep 2024 14:25:32 -0600 Subject: [PATCH 15/33] Add POSIX Linux support for net_if and netdb. --- core/sys/posix/net_if.odin | 2 +- core/sys/posix/netdb.odin | 38 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/core/sys/posix/net_if.odin b/core/sys/posix/net_if.odin index aaeb5088a..75c1a863e 100644 --- a/core/sys/posix/net_if.odin +++ b/core/sys/posix/net_if.odin @@ -44,7 +44,7 @@ foreign lib { if_freenameindex :: proc(ptr: ^if_nameindex_t) --- } -when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD { +when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux { // NOTE: `_t` suffix added due to name conflict. diff --git a/core/sys/posix/netdb.odin b/core/sys/posix/netdb.odin index 7570f9a22..b8259b60c 100644 --- a/core/sys/posix/netdb.odin +++ b/core/sys/posix/netdb.odin @@ -318,7 +318,7 @@ Info_Errno :: enum c.int { OVERFLOW = EAI_OVERFLOW, } -when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD { +when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .OpenBSD { hostent :: struct { h_name: cstring, /* [PSX] official name of host */ @@ -412,9 +412,28 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS NI_NUMERICSERV :: 2 NI_NUMERICSCOPE :: 32 NI_DGRAM :: 16 + + } else when ODIN_OS == .Linux { + + AI_PASSIVE :: 0x001 + AI_CANONNAME :: 0x002 + AI_NUMERICHOST :: 0x004 + AI_NUMERICSERV :: 0x400 + AI_V4MAPPED :: 0x008 + AI_ALL :: 0x010 + AI_ADDRCONFIG :: 0x020 + + NI_NOFQDN :: 4 + NI_NUMERICHOST :: 1 + NI_NAMEREQD :: 8 + NI_NUMERICSERV :: 2 + NI_NUMERICSCOPE :: 0 // NOTE: not implemented + NI_DGRAM :: 16 + } when ODIN_OS == .OpenBSD { + EAI_AGAIN :: -3 EAI_BADFLAGS :: -1 EAI_FAIL :: -4 @@ -425,7 +444,22 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS EAI_SOCKTYPE :: -7 EAI_SYSTEM :: -11 EAI_OVERFLOW :: -14 + + } else when ODIN_OS == .Linux { + + EAI_AGAIN :: -3 + EAI_BADFLAGS :: -1 + EAI_FAIL :: -4 + EAI_FAMILY :: -6 + EAI_MEMORY :: -10 + EAI_NONAME :: -2 + EAI_SERVICE :: -8 + EAI_SOCKTYPE :: -7 + EAI_SYSTEM :: -11 + EAI_OVERFLOW :: -12 + } else { + EAI_AGAIN :: 2 EAI_BADFLAGS :: 3 EAI_FAIL :: 4 @@ -438,6 +472,6 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS EAI_OVERFLOW :: 14 } -}else { +} else { #panic("posix is unimplemented for the current target") } From f072136c04e4e8f43232fa46679059018f2f77c3 Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Mon, 2 Sep 2024 21:59:03 -0600 Subject: [PATCH 16/33] Implement POSIX linux support for poll and netinet_tcp. Incomplete support for netinet/in. --- core/sys/posix/netinet_in.odin | 168 ++++++++++++++++++++++++++++++++ core/sys/posix/netinet_tcp.odin | 2 +- core/sys/posix/poll.odin | 28 +++++- 3 files changed, 196 insertions(+), 2 deletions(-) diff --git a/core/sys/posix/netinet_in.odin b/core/sys/posix/netinet_in.odin index 3926c5288..70427e8af 100644 --- a/core/sys/posix/netinet_in.odin +++ b/core/sys/posix/netinet_in.odin @@ -194,6 +194,174 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS ) } +} else when ODIN_OS == .Linux { + + in_addr :: struct { + s_addr: in_addr_t, /* [PSX] big endian address */ + } + + in6_addr :: struct { + using _: struct #raw_union { + s6_addr: [16]c.uint8_t, /* [PSX] big endian address */ + __u6_addr16: [8]c.uint16_t, + __u6_addr32: [4]c.uint32_t, + }, + } + + sockaddr_in :: struct { + sin_family: sa_family_t, /* [PSX] AF_INET (but a smaller size) */ + sin_port: in_port_t, /* [PSX] port number */ + sin_addr: in_addr, /* [PSX] IP address */ + sin_zero: [size_of(sockaddr) - + u16 - + size_of(in_port_t) - + size_of(in_addr)]c.char, + } + + sockaddr_in6 :: struct { + sin6_family: sa_family_t, /* [PSX] AF_INET6 (but a smaller size) */ + sin6_port: in_port_t, /* [PSX] port number */ + sin6_flowinfo: u32be, /* [PSX] IPv6 traffic class and flow information */ + sin6_addr: in6_addr, /* [PSX] IPv6 address */ + sin6_scope_id: c.uint32_t, /* [PSX] set of interfaces for a scope */ + } + + ipv6_mreq :: struct { + ipv6mr_multiaddr: in6_addr, /* [PSX] IPv6 multicast address */ + ipv6mr_interface: c.int, /* [PSX] interface index */ + } + + IPPROTO_IP :: 0 + IPPROTO_ICMP :: 1 + IPPROTO_IPV6 :: 41 + IPPROTO_RAW :: 255 + IPPROTO_TCP :: 6 + IPPROTO_UDP :: 17 + + INADDR_ANY :: 0x00000000 + INADDR_BROADCAST :: 0xFFFFFFFF + + IPV6_MULTICAST_IF :: 17 + IPV6_UNICAST_HOPS :: 16 + IPV6_MULTICAST_HOPS :: 18 + IPV6_MULTICAST_LOOP :: 19 + IPV6_JOIN_GROUP :: 20 + IPV6_LEAVE_GROUP :: 21 + IPV6_V6ONLY :: 26 + + // TODO: (Isaac Andrade, 2024-09-02) Copied from the BSDs block above. Needs to be implemented for Linux. + // Get mentoring from a more senior C and Odin developer or leave this to one of them. + + //IN6_IS_ADDR_UNSPECIFIED :: #force_inline proc "contextless" (a: in6_addr) -> b32 { + // return a.s6_addr == 0 + //} + // + //IN6_IS_ADDR_LOOPBACK :: #force_inline proc "contextless" (a: in6_addr) -> b32 { + // a := a + // return ( + // (^c.uint32_t)(&a.s6_addr[0])^ == 0 && + // (^c.uint32_t)(&a.s6_addr[4])^ == 0 && + // (^c.uint32_t)(&a.s6_addr[8])^ == 0 && + // (^u32be)(&a.s6_addr[12])^ == 1 \ + // ) + //} + // + //IN6_IS_ADDR_MULTICAST :: #force_inline proc "contextless" (a: in6_addr) -> b32 { + // return a.s6_addr[0] == 0xff + //} + // + //IN6_IS_ADDR_LINKLOCAL :: #force_inline proc "contextless" (a: in6_addr) -> b32 { + // return a.s6_addr[0] == 0xfe && a.s6_addr[1] & 0xc0 == 0x80 + //} + // + //IN6_IS_ADDR_SITELOCAL :: #force_inline proc "contextless" (a: in6_addr) -> b32 { + // return a.s6_addr[0] == 0xfe && a.s6_addr[1] & 0xc0 == 0xc0 + //} + // + //IN6_IS_ADDR_V4MAPPED :: #force_inline proc "contextless" (a: in6_addr) -> b32 { + // a := a + // return ( + // (^c.uint32_t)(&a.s6_addr[0])^ == 0 && + // (^c.uint32_t)(&a.s6_addr[4])^ == 0 && + // (^u32be)(&a.s6_addr[8])^ == 0x0000ffff \ + // ) + //} + // + //IN6_IS_ADDR_V4COMPAT :: #force_inline proc "contextless" (a: in6_addr) -> b32 { + // a := a + // return ( + // (^c.uint32_t)(&a.s6_addr[0])^ == 0 && + // (^c.uint32_t)(&a.s6_addr[4])^ == 0 && + // (^c.uint32_t)(&a.s6_addr[8])^ == 0 && + // (^c.uint32_t)(&a.s6_addr[12])^ != 0 && + // (^u32be)(&a.s6_addr[12])^ != 1 \ + // ) + //} + // + //@(private) + //__IPV6_ADDR_SCOPE_NODELOCAL :: 0x01 + //@(private) + //__IPV6_ADDR_SCOPE_LINKLOCAL :: 0x02 + //@(private) + //__IPV6_ADDR_SCOPE_SITELOCAL :: 0x05 + //@(private) + //__IPV6_ADDR_SCOPE_ORGLOCAL :: 0x08 + //@(private) + //__IPV6_ADDR_SCOPE_GLOBAL :: 0x0e + // + //@(private) + //IPV6_ADDR_MC_FLAGS :: #force_inline proc "contextless" (a: in6_addr) -> c.uint8_t { + // return a.s6_addr[1] & 0xf0 + //} + // + //@(private) + //IPV6_ADDR_MC_FLAGS_TRANSIENT :: 0x10 + //@(private) + //IPV6_ADDR_MC_FLAGS_PREFIX :: 0x20 + //@(private) + //IPV6_ADDR_MC_FLAGS_UNICAST_BASED :: IPV6_ADDR_MC_FLAGS_TRANSIENT | IPV6_ADDR_MC_FLAGS_PREFIX + // + //@(private) + //__IPV6_ADDR_MC_SCOPE :: #force_inline proc "contextless" (a: in6_addr) -> c.uint8_t { + // return a.s6_addr[1] & 0x0f + //} + // + //IN6_IS_ADDR_MC_NODELOCAL :: #force_inline proc "contextless" (a: in6_addr) -> b32 { + // return ( + // IN6_IS_ADDR_MULTICAST(a) && + // (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_NODELOCAL) \ + // ) + //} + // + //IN6_IS_ADDR_MC_LINKLOCAL :: #force_inline proc "contextless" (a: in6_addr) -> b32 { + // return ( + // IN6_IS_ADDR_MULTICAST(a) && + // (IPV6_ADDR_MC_FLAGS(a) != IPV6_ADDR_MC_FLAGS_UNICAST_BASED) && + // (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_LINKLOCAL) \ + // ) + //} + // + //IN6_IS_ADDR_MC_SITELOCAL :: #force_inline proc "contextless" (a: in6_addr) -> b32 { + // return ( + // IN6_IS_ADDR_MULTICAST(a) && + // (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_SITELOCAL) \ + // ) + //} + // + //IN6_IS_ADDR_MC_ORGLOCAL :: #force_inline proc "contextless" (a: in6_addr) -> b32 { + // return ( + // IN6_IS_ADDR_MULTICAST(a) && + // (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_ORGLOCAL) \ + // ) + //} + // + //IN6_IS_ADDR_MC_GLOBAL :: #force_inline proc "contextless" (a: in6_addr) -> b32 { + // return ( + // IN6_IS_ADDR_MULTICAST(a) && + // (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_GLOBAL) \ + // ) + //} + } else { #panic("posix is unimplemented for the current target") } diff --git a/core/sys/posix/netinet_tcp.odin b/core/sys/posix/netinet_tcp.odin index ecd084b38..284351732 100644 --- a/core/sys/posix/netinet_tcp.odin +++ b/core/sys/posix/netinet_tcp.odin @@ -2,7 +2,7 @@ package posix // netinet/tcp.h - definitions for the Internet Transmission Control Protocol (TCP) -when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD { +when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux { TCP_NODELAY :: 0x01 diff --git a/core/sys/posix/poll.odin b/core/sys/posix/poll.odin index 3e825e009..7f23de267 100644 --- a/core/sys/posix/poll.odin +++ b/core/sys/posix/poll.odin @@ -21,11 +21,17 @@ foreign lib { [[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/poll.html ]] */ - poll :: proc(fds: [^]pollfd, nfds: nfds_t, timeout: c.int) -> c.int --- + poll :: proc(fds: [^]pollfd, nfds: nfds_t, timeout: c.int) -> Poll_Error --- } nfds_t :: c.uint +Poll_Error :: enum c.int { + EAGAIN = Errno.EAGAIN, + EINTR = Errno.EINTR, + EINVAL = Errno.EINVAL, +} + Poll_Event_Bits :: enum c.short { // Data other than high-priority data may be read without blocking. IN = log2(POLLIN), @@ -72,6 +78,26 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS POLLHUP :: 0x0010 POLLNVAL :: 0x0020 +} else when ODIN_OS == .Linux { + + pollfd :: struct { + fd: FD, /* [PSX] the following descriptor being polled */ + events: Poll_Event, /* [PSX] the input event flags */ + revents: Poll_Event, /* [PSX] the output event flags */ + } + + POLLIN :: 0x0001 + POLLRDNORM :: 0x0040 + POLLRDBAND :: 0x0080 + POLLPRI :: 0x0002 + POLLOUT :: 0x0004 + POLLWRNORM :: 0x0100 + POLLWRBAND :: 0x0200 + + POLLERR :: 0x0008 + POLLHUP :: 0x0010 + POLLNVAL :: 0x0020 + } else { #panic("posix is unimplemented for the current target") } From d93f55c5d475e84282e542750e657977fc2daae6 Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Mon, 2 Sep 2024 22:32:52 -0600 Subject: [PATCH 17/33] Reuse POSIX netinet_in constants for linux. --- core/sys/posix/netinet_in.odin | 251 ++++++++------------------------- 1 file changed, 57 insertions(+), 194 deletions(-) diff --git a/core/sys/posix/netinet_in.odin b/core/sys/posix/netinet_in.odin index 70427e8af..66027362f 100644 --- a/core/sys/posix/netinet_in.odin +++ b/core/sys/posix/netinet_in.odin @@ -44,26 +44,65 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS }, } - sockaddr_in :: struct { - sin_len: c.uint8_t, - sin_family: sa_family_t, /* [PSX] AF_INET (but a smaller size) */ - sin_port: in_port_t, /* [PSX] port number */ - sin_addr: in_addr, /* [PSX] IP address */ - sin_zero: [8]c.char, - } + when ODIN_OS == .Linux { + sockaddr_in :: struct { + sin_family: sa_family_t, /* [PSX] AF_INET (but a smaller size) */ + sin_port: in_port_t, /* [PSX] port number */ + sin_addr: in_addr, /* [PSX] IP address */ + sin_zero: [size_of(sockaddr) - + u16 - + size_of(in_port_t) - + size_of(in_addr)]c.char, + } - sockaddr_in6 :: struct { - sin6_len: c.uint8_t, - sin6_family: sa_family_t, /* [PSX] AF_INET6 (but a smaller size) */ - sin6_port: in_port_t, /* [PSX] port number */ - sin6_flowinfo: c.uint32_t, /* [PSX] IPv6 traffic class and flow information */ - sin6_addr: in6_addr, /* [PSX] IPv6 address */ - sin6_scope_id: c.uint32_t, /* [PSX] set of interfaces for a scope */ - } + sockaddr_in6 :: struct { + sin6_family: sa_family_t, /* [PSX] AF_INET6 (but a smaller size) */ + sin6_port: in_port_t, /* [PSX] port number */ + sin6_flowinfo: u32be, /* [PSX] IPv6 traffic class and flow information */ + sin6_addr: in6_addr, /* [PSX] IPv6 address */ + sin6_scope_id: c.uint32_t, /* [PSX] set of interfaces for a scope */ + } + + IPV6_MULTICAST_IF :: 17 + IPV6_UNICAST_HOPS :: 16 + IPV6_MULTICAST_HOPS :: 18 + IPV6_MULTICAST_LOOP :: 19 + IPV6_JOIN_GROUP :: 20 + IPV6_LEAVE_GROUP :: 21 + IPV6_V6ONLY :: 26 + + } else { + + sockaddr_in :: struct { + sin_len: c.uint8_t, + sin_family: sa_family_t, /* [PSX] AF_INET (but a smaller size) */ + sin_port: in_port_t, /* [PSX] port number */ + sin_addr: in_addr, /* [PSX] IP address */ + sin_zero: [8]c.char, + } + + sockaddr_in6 :: struct { + sin6_len: c.uint8_t, + sin6_family: sa_family_t, /* [PSX] AF_INET6 (but a smaller size) */ + sin6_port: in_port_t, /* [PSX] port number */ + sin6_flowinfo: c.uint32_t, /* [PSX] IPv6 traffic class and flow information */ + sin6_addr: in6_addr, /* [PSX] IPv6 address */ + sin6_scope_id: c.uint32_t, /* [PSX] set of interfaces for a scope */ + } + + ipv6_mreq :: struct { + ipv6mr_multiaddr: in6_addr, /* [PSX] IPv6 multicast address */ + ipv6mr_interface: c.uint, /* [PSX] interface index */ + } + + IPV6_JOIN_GROUP :: 12 + IPV6_LEAVE_GROUP :: 13 + IPV6_MULTICAST_HOPS :: 10 + IPV6_MULTICAST_IF :: 9 + IPV6_MULTICAST_LOOP :: 11 + IPV6_UNICAST_HOPS :: 4 + IPV6_V6ONLY :: 27 - ipv6_mreq :: struct { - ipv6mr_multiaddr: in6_addr, /* [PSX] IPv6 multicast address */ - ipv6mr_interface: c.uint, /* [PSX] interface index */ } IPPROTO_IP :: 0 @@ -76,14 +115,6 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS INADDR_ANY :: 0x00000000 INADDR_BROADCAST :: 0xFFFFFFFF - IPV6_JOIN_GROUP :: 12 - IPV6_LEAVE_GROUP :: 13 - IPV6_MULTICAST_HOPS :: 10 - IPV6_MULTICAST_IF :: 9 - IPV6_MULTICAST_LOOP :: 11 - IPV6_UNICAST_HOPS :: 4 - IPV6_V6ONLY :: 27 - IN6_IS_ADDR_UNSPECIFIED :: #force_inline proc "contextless" (a: in6_addr) -> b32 { return a.s6_addr == 0 } @@ -194,174 +225,6 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS ) } -} else when ODIN_OS == .Linux { - - in_addr :: struct { - s_addr: in_addr_t, /* [PSX] big endian address */ - } - - in6_addr :: struct { - using _: struct #raw_union { - s6_addr: [16]c.uint8_t, /* [PSX] big endian address */ - __u6_addr16: [8]c.uint16_t, - __u6_addr32: [4]c.uint32_t, - }, - } - - sockaddr_in :: struct { - sin_family: sa_family_t, /* [PSX] AF_INET (but a smaller size) */ - sin_port: in_port_t, /* [PSX] port number */ - sin_addr: in_addr, /* [PSX] IP address */ - sin_zero: [size_of(sockaddr) - - u16 - - size_of(in_port_t) - - size_of(in_addr)]c.char, - } - - sockaddr_in6 :: struct { - sin6_family: sa_family_t, /* [PSX] AF_INET6 (but a smaller size) */ - sin6_port: in_port_t, /* [PSX] port number */ - sin6_flowinfo: u32be, /* [PSX] IPv6 traffic class and flow information */ - sin6_addr: in6_addr, /* [PSX] IPv6 address */ - sin6_scope_id: c.uint32_t, /* [PSX] set of interfaces for a scope */ - } - - ipv6_mreq :: struct { - ipv6mr_multiaddr: in6_addr, /* [PSX] IPv6 multicast address */ - ipv6mr_interface: c.int, /* [PSX] interface index */ - } - - IPPROTO_IP :: 0 - IPPROTO_ICMP :: 1 - IPPROTO_IPV6 :: 41 - IPPROTO_RAW :: 255 - IPPROTO_TCP :: 6 - IPPROTO_UDP :: 17 - - INADDR_ANY :: 0x00000000 - INADDR_BROADCAST :: 0xFFFFFFFF - - IPV6_MULTICAST_IF :: 17 - IPV6_UNICAST_HOPS :: 16 - IPV6_MULTICAST_HOPS :: 18 - IPV6_MULTICAST_LOOP :: 19 - IPV6_JOIN_GROUP :: 20 - IPV6_LEAVE_GROUP :: 21 - IPV6_V6ONLY :: 26 - - // TODO: (Isaac Andrade, 2024-09-02) Copied from the BSDs block above. Needs to be implemented for Linux. - // Get mentoring from a more senior C and Odin developer or leave this to one of them. - - //IN6_IS_ADDR_UNSPECIFIED :: #force_inline proc "contextless" (a: in6_addr) -> b32 { - // return a.s6_addr == 0 - //} - // - //IN6_IS_ADDR_LOOPBACK :: #force_inline proc "contextless" (a: in6_addr) -> b32 { - // a := a - // return ( - // (^c.uint32_t)(&a.s6_addr[0])^ == 0 && - // (^c.uint32_t)(&a.s6_addr[4])^ == 0 && - // (^c.uint32_t)(&a.s6_addr[8])^ == 0 && - // (^u32be)(&a.s6_addr[12])^ == 1 \ - // ) - //} - // - //IN6_IS_ADDR_MULTICAST :: #force_inline proc "contextless" (a: in6_addr) -> b32 { - // return a.s6_addr[0] == 0xff - //} - // - //IN6_IS_ADDR_LINKLOCAL :: #force_inline proc "contextless" (a: in6_addr) -> b32 { - // return a.s6_addr[0] == 0xfe && a.s6_addr[1] & 0xc0 == 0x80 - //} - // - //IN6_IS_ADDR_SITELOCAL :: #force_inline proc "contextless" (a: in6_addr) -> b32 { - // return a.s6_addr[0] == 0xfe && a.s6_addr[1] & 0xc0 == 0xc0 - //} - // - //IN6_IS_ADDR_V4MAPPED :: #force_inline proc "contextless" (a: in6_addr) -> b32 { - // a := a - // return ( - // (^c.uint32_t)(&a.s6_addr[0])^ == 0 && - // (^c.uint32_t)(&a.s6_addr[4])^ == 0 && - // (^u32be)(&a.s6_addr[8])^ == 0x0000ffff \ - // ) - //} - // - //IN6_IS_ADDR_V4COMPAT :: #force_inline proc "contextless" (a: in6_addr) -> b32 { - // a := a - // return ( - // (^c.uint32_t)(&a.s6_addr[0])^ == 0 && - // (^c.uint32_t)(&a.s6_addr[4])^ == 0 && - // (^c.uint32_t)(&a.s6_addr[8])^ == 0 && - // (^c.uint32_t)(&a.s6_addr[12])^ != 0 && - // (^u32be)(&a.s6_addr[12])^ != 1 \ - // ) - //} - // - //@(private) - //__IPV6_ADDR_SCOPE_NODELOCAL :: 0x01 - //@(private) - //__IPV6_ADDR_SCOPE_LINKLOCAL :: 0x02 - //@(private) - //__IPV6_ADDR_SCOPE_SITELOCAL :: 0x05 - //@(private) - //__IPV6_ADDR_SCOPE_ORGLOCAL :: 0x08 - //@(private) - //__IPV6_ADDR_SCOPE_GLOBAL :: 0x0e - // - //@(private) - //IPV6_ADDR_MC_FLAGS :: #force_inline proc "contextless" (a: in6_addr) -> c.uint8_t { - // return a.s6_addr[1] & 0xf0 - //} - // - //@(private) - //IPV6_ADDR_MC_FLAGS_TRANSIENT :: 0x10 - //@(private) - //IPV6_ADDR_MC_FLAGS_PREFIX :: 0x20 - //@(private) - //IPV6_ADDR_MC_FLAGS_UNICAST_BASED :: IPV6_ADDR_MC_FLAGS_TRANSIENT | IPV6_ADDR_MC_FLAGS_PREFIX - // - //@(private) - //__IPV6_ADDR_MC_SCOPE :: #force_inline proc "contextless" (a: in6_addr) -> c.uint8_t { - // return a.s6_addr[1] & 0x0f - //} - // - //IN6_IS_ADDR_MC_NODELOCAL :: #force_inline proc "contextless" (a: in6_addr) -> b32 { - // return ( - // IN6_IS_ADDR_MULTICAST(a) && - // (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_NODELOCAL) \ - // ) - //} - // - //IN6_IS_ADDR_MC_LINKLOCAL :: #force_inline proc "contextless" (a: in6_addr) -> b32 { - // return ( - // IN6_IS_ADDR_MULTICAST(a) && - // (IPV6_ADDR_MC_FLAGS(a) != IPV6_ADDR_MC_FLAGS_UNICAST_BASED) && - // (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_LINKLOCAL) \ - // ) - //} - // - //IN6_IS_ADDR_MC_SITELOCAL :: #force_inline proc "contextless" (a: in6_addr) -> b32 { - // return ( - // IN6_IS_ADDR_MULTICAST(a) && - // (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_SITELOCAL) \ - // ) - //} - // - //IN6_IS_ADDR_MC_ORGLOCAL :: #force_inline proc "contextless" (a: in6_addr) -> b32 { - // return ( - // IN6_IS_ADDR_MULTICAST(a) && - // (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_ORGLOCAL) \ - // ) - //} - // - //IN6_IS_ADDR_MC_GLOBAL :: #force_inline proc "contextless" (a: in6_addr) -> b32 { - // return ( - // IN6_IS_ADDR_MULTICAST(a) && - // (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_GLOBAL) \ - // ) - //} - } else { #panic("posix is unimplemented for the current target") } From 9e4b45f0f00aa4238249ffd3914dd148e295958e Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Mon, 2 Sep 2024 22:58:54 -0600 Subject: [PATCH 18/33] Add linux to OS check. --- core/sys/posix/netdb.odin | 2 +- core/sys/posix/netinet_in.odin | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/sys/posix/netdb.odin b/core/sys/posix/netdb.odin index b8259b60c..cd965e2a4 100644 --- a/core/sys/posix/netdb.odin +++ b/core/sys/posix/netdb.odin @@ -318,7 +318,7 @@ Info_Errno :: enum c.int { OVERFLOW = EAI_OVERFLOW, } -when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .OpenBSD { +when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux { hostent :: struct { h_name: cstring, /* [PSX] official name of host */ diff --git a/core/sys/posix/netinet_in.odin b/core/sys/posix/netinet_in.odin index 66027362f..d5121606b 100644 --- a/core/sys/posix/netinet_in.odin +++ b/core/sys/posix/netinet_in.odin @@ -30,7 +30,7 @@ Protocol :: enum c.int { UDP = IPPROTO_UDP, } -when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD { +when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux { in_addr :: struct { s_addr: in_addr_t, /* [PSX] big endian address */ From 92ff04629e083e78c8d19d531b4ea6075c642130 Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Mon, 9 Sep 2024 22:17:42 -0600 Subject: [PATCH 19/33] Fix some compilation errors on POSIX linux. --- core/sys/posix/sys_times.odin | 2 +- core/sys/posix/sys_uio.odin | 2 +- core/sys/posix/sys_un.odin | 7 +++++++ core/sys/posix/ulimit.odin | 2 +- core/sys/posix/utime.odin | 2 +- 5 files changed, 11 insertions(+), 4 deletions(-) diff --git a/core/sys/posix/sys_times.odin b/core/sys/posix/sys_times.odin index 685ced515..d38f3efc4 100644 --- a/core/sys/posix/sys_times.odin +++ b/core/sys/posix/sys_times.odin @@ -24,7 +24,7 @@ when ODIN_OS == .NetBSD { @(private) LTIMES :: "times" } -when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD { +when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux { tms :: struct { tms_utime: clock_t, /* [PSX] user CPU time */ diff --git a/core/sys/posix/sys_uio.odin b/core/sys/posix/sys_uio.odin index 01664e576..6755fe2ae 100644 --- a/core/sys/posix/sys_uio.odin +++ b/core/sys/posix/sys_uio.odin @@ -30,7 +30,7 @@ foreign libc { writev :: proc(fildes: FD, iov: [^]iovec, iovcnt: c.int) -> c.ssize_t --- } -when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD { +when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux { iovec :: struct { iov_base: rawptr, /* [PSX] base address of I/O memory region */ diff --git a/core/sys/posix/sys_un.odin b/core/sys/posix/sys_un.odin index 146882051..15eb7b5fc 100644 --- a/core/sys/posix/sys_un.odin +++ b/core/sys/posix/sys_un.odin @@ -12,6 +12,13 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS sun_path: [104]c.char, /* [PSX] socket pathname */ } +} else when ODIN_OS == .Linux { + + sockaddr_un :: struct { + sun_family: sa_family_t, /* [PSX] address family */ + sun_path: [108]c.char, /* [PSX] socket pathname */ + } + } else { #panic("posix is unimplemented for the current target") } diff --git a/core/sys/posix/ulimit.odin b/core/sys/posix/ulimit.odin index 067b83271..782756f6e 100644 --- a/core/sys/posix/ulimit.odin +++ b/core/sys/posix/ulimit.odin @@ -31,7 +31,7 @@ Ulimit_Cmd :: enum c.int { SETFSIZE = UL_SETFSIZE, } -when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD { +when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux { UL_GETFSIZE :: 1 UL_SETFSIZE :: 2 diff --git a/core/sys/posix/utime.odin b/core/sys/posix/utime.odin index 591a6db06..1207cb402 100644 --- a/core/sys/posix/utime.odin +++ b/core/sys/posix/utime.odin @@ -24,7 +24,7 @@ when ODIN_OS == .NetBSD { @(private) LUTIME :: "utime" } -when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD { +when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux { utimbuf :: struct { actime: time_t, /* [PSX] access time (seconds since epoch) */ From ff82396e7c518378654436abbec01c16237bceb9 Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Tue, 10 Sep 2024 07:32:58 -0600 Subject: [PATCH 20/33] Add Linux support for POSIX sys ipc, mman, time, utsname. --- core/sys/posix/sys_ipc.odin | 2 +- core/sys/posix/sys_mman.odin | 11 ++++++++--- core/sys/posix/sys_time.odin | 2 +- core/sys/posix/sys_utsname.odin | 11 ++++++++--- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/core/sys/posix/sys_ipc.odin b/core/sys/posix/sys_ipc.odin index f8778ee15..0ba9d2d5d 100644 --- a/core/sys/posix/sys_ipc.odin +++ b/core/sys/posix/sys_ipc.odin @@ -36,7 +36,7 @@ IPC_Flag_Bits :: enum c.int { } IPC_Flags :: bit_set[IPC_Flag_Bits; c.int] -when ODIN_OS == .Darwin { +when ODIN_OS == .Darwin || ODIN_OS == .Linux { key_t :: distinct c.int32_t diff --git a/core/sys/posix/sys_mman.odin b/core/sys/posix/sys_mman.odin index 217d321ac..d71a92639 100644 --- a/core/sys/posix/sys_mman.odin +++ b/core/sys/posix/sys_mman.odin @@ -163,7 +163,7 @@ when ODIN_OS == .NetBSD { @(private) LMSYNC :: "msync" } -when ODIN_OS == .Darwin || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD { +when ODIN_OS == .Darwin || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux { PROT_EXEC :: 0x04 _PROT_NONE :: 0x00 @@ -174,7 +174,7 @@ when ODIN_OS == .Darwin || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD { MAP_PRIVATE :: 0x0002 MAP_SHARED :: 0x0001 - when ODIN_OS == .Darwin { + when ODIN_OS == .Darwin || ODIN_OS == .Linux { MS_INVALIDATE :: 0x0002 _MS_SYNC :: 0x0010 } else when ODIN_OS == .NetBSD { @@ -184,13 +184,18 @@ when ODIN_OS == .Darwin || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD { MS_INVALIDATE :: 0x0004 _MS_SYNC :: 0x0002 } + MS_ASYNC :: 0x0001 MS_SYNC :: Sync_Flags{Sync_Flags_Bits(log2(_MS_SYNC))} MCL_CURRENT :: 0x0001 MCL_FUTURE :: 0x0002 - MAP_FAILED :: rawptr(~uintptr(0)) + when ODIN_OS == .Linux { + MAP_FAILED :: rawptr(~uintptr(-1)) + } else { + MAP_FAILED :: rawptr(~uintptr(0)) + } POSIX_MADV_DONTNEED :: 4 POSIX_MADV_NORMAL :: 0 diff --git a/core/sys/posix/sys_time.odin b/core/sys/posix/sys_time.odin index 093fdd688..fd2e58121 100644 --- a/core/sys/posix/sys_time.odin +++ b/core/sys/posix/sys_time.odin @@ -66,7 +66,7 @@ when ODIN_OS == .NetBSD { @(private) LUTIMES :: "utimes" } -when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD { +when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux { itimerval :: struct { it_interval: timeval, /* [PSX] timer interval */ diff --git a/core/sys/posix/sys_utsname.odin b/core/sys/posix/sys_utsname.odin index 803f40ffd..4786eb4fd 100644 --- a/core/sys/posix/sys_utsname.odin +++ b/core/sys/posix/sys_utsname.odin @@ -37,10 +37,15 @@ foreign lib { uname :: proc(uname: ^utsname) -> c.int --- } -when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD { +when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux { - @(private) - _SYS_NAMELEN :: 256 + when ODIN_OS == .Linux { + @(private) + _SYS_NAMELEN :: 65 + } else { + @(private) + _SYS_NAMELEN :: 256 + } utsname :: struct { sysname: [_SYS_NAMELEN]c.char `fmt:"s,0"`, /* [PSX] name of OS */ From 1632f198265147dcfd9c3a7dc717e5a6647aeff4 Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Tue, 10 Sep 2024 18:43:09 -0600 Subject: [PATCH 21/33] In-progress support for POSIX on Linux for sys/socket. --- core/sys/posix/sys_socket.odin | 103 ++++++++++++++++++++++++--------- 1 file changed, 75 insertions(+), 28 deletions(-) diff --git a/core/sys/posix/sys_socket.odin b/core/sys/posix/sys_socket.odin index 36c3c1467..1f228c396 100644 --- a/core/sys/posix/sys_socket.odin +++ b/core/sys/posix/sys_socket.odin @@ -321,16 +321,27 @@ when ODIN_OS == .NetBSD { @(private) LSOCKET :: "socket" } -when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD { +when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux { - socklen_t :: distinct c.uint + when ODIN_OS == .Linux { + socklen_t :: distinct c.uint32_t + } else { + socklen_t :: distinct c.uint + } _sa_family_t :: distinct c.uint8_t - sockaddr :: struct { - sa_len: c.uint8_t, /* total length */ - sa_family: sa_family_t, /* [PSX] address family */ - sa_data: [14]c.char, /* [PSX] socket address */ + when ODIN_OS == .Linux { + sockaddr :: struct { + sa_family: sa_family_t, /* [PSX] address family */ + sa_data: [14]c.char, /* [PSX] socket address */ + } + } else { + sockaddr :: struct { + sa_len: c.uint8_t, /* total length */ + sa_family: sa_family_t, /* [PSX] address family */ + sa_data: [14]c.char, /* [PSX] socket address */ + } } @@ -339,6 +350,11 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS _SS_PAD1SIZE :: 6 @(private) _SS_PAD2SIZE :: 240 + } else when ODIN_OS == .Linux { + @(private) + _SS_SIZE :: 128 + @(private) + _SS_PADSIZE :: _SS_SIZE - size_of(c.uint16_t) - size_of(c.uint64_t) } else { @(private) _SS_MAXSIZE :: 128 @@ -350,23 +366,42 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS _SS_PAD2SIZE :: _SS_MAXSIZE - size_of(c.uint8_t) - size_of(sa_family_t) - _SS_PAD1SIZE - _SS_ALIGNSIZE } - sockaddr_storage :: struct { - ss_len: c.uint8_t, /* address length */ - ss_family: sa_family_t, /* [PSX] address family */ - __ss_pad1: [_SS_PAD1SIZE]c.char, - __ss_align: c.int64_t, /* force structure storage alignment */ - __ss_pad2: [_SS_PAD2SIZE]c.char, + when ODIN_OS == .Linux { + sockaddr_storage :: struct { + ss_family: sa_family_t, /* [PSX] address family */ + __ss_padding: [_SS_PADSIZE]c.char, + __ss_align: c.uint64_t, /* force structure storage alignment */ + } + + msghdr :: struct { + msg_name: rawptr, /* [PSX] optional address */ + msg_namelen: socklen_t, /* [PSX] size of address */ + msg_iov: [^]iovec, /* [PSX] scatter/gather array */ + msg_iovlen: c.size_t, /* [PSX] members in msg_iov */ + msg_control: rawptr, /* [PSX] ancillary data */ + msg_controllen: c.size_t, /* [PSX] ancillary data buffer length */ + msg_flags: Msg_Flags, /* [PSX] flags on received message */ + } + } else { + sockaddr_storage :: struct { + ss_len: c.uint8_t, /* address length */ + ss_family: sa_family_t, /* [PSX] address family */ + __ss_pad1: [_SS_PAD1SIZE]c.char, + __ss_align: c.int64_t, /* force structure storage alignment */ + __ss_pad2: [_SS_PAD2SIZE]c.char, + } + + msghdr :: struct { + msg_name: rawptr, /* [PSX] optional address */ + msg_namelen: socklen_t, /* [PSX] size of address */ + msg_iov: [^]iovec, /* [PSX] scatter/gather array */ + msg_iovlen: c.int, /* [PSX] members in msg_iov */ + msg_control: rawptr, /* [PSX] ancillary data */ + msg_controllen: socklen_t, /* [PSX] ancillary data buffer length */ + msg_flags: Msg_Flags, /* [PSX] flags on received message */ + } } - msghdr :: struct { - msg_name: rawptr, /* [PSX] optional address */ - msg_namelen: socklen_t, /* [PSX] size of address */ - msg_iov: [^]iovec, /* [PSX] scatter/gather array */ - msg_iovlen: c.int, /* [PSX] members in msg_iov */ - msg_control: rawptr, /* [PSX] ancillary data */ - msg_controllen: socklen_t, /* [PSX] ancillary data buffer length */ - msg_flags: Msg_Flags, /* [PSX] flags on received message */ - } cmsghdr :: struct { cmsg_len: socklen_t, /* [PSX] data byte count, including cmsghdr */ @@ -458,13 +493,23 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS // The maximum backlog queue length for listen(). SOMAXCONN :: 128 - MSG_CTRUNC :: 0x20 - MSG_DONTROUTE :: 0x4 - MSG_EOR :: 0x8 - MSG_OOB :: 0x1 - MSG_PEEK :: 0x2 - MSG_TRUNC :: 0x10 - MSG_WAITALL :: 0x40 + when ODIN_OS == .Linux { + MSG_CTRUNC :: 0x007 + MSG_DONTROUTE :: 0x004 + MSG_EOR :: 0x080 + MSG_OOB :: 0x001 + MSG_PEEK :: 0x002 + MSG_TRUNC :: 0x020 + MSG_WAITALL :: 0x100 + } else { + MSG_CTRUNC :: 0x20 + MSG_DONTROUTE :: 0x4 + MSG_EOR :: 0x8 + MSG_OOB :: 0x1 + MSG_PEEK :: 0x2 + MSG_TRUNC :: 0x10 + MSG_WAITALL :: 0x40 + } when ODIN_OS == .Darwin { MSG_NOSIGNAL :: 0x80000 @@ -472,6 +517,8 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS MSG_NOSIGNAL :: 0x00020000 } else when ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD { MSG_NOSIGNAL :: 0x0400 + } else when ODIN_OS == .Linux { + MSG_NOSIGNAL :: 0x4000 } AF_INET :: 2 From 55a9ba1fc00a68fb83ad0b24878db815e68b546a Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Wed, 11 Sep 2024 22:25:38 -0600 Subject: [PATCH 22/33] Finish sys/socket POSIX support for Linux. --- core/sys/posix/sys_socket.odin | 126 +++++++++++++++++++++------------ 1 file changed, 79 insertions(+), 47 deletions(-) diff --git a/core/sys/posix/sys_socket.odin b/core/sys/posix/sys_socket.odin index 1f228c396..185bb7722 100644 --- a/core/sys/posix/sys_socket.odin +++ b/core/sys/posix/sys_socket.odin @@ -382,6 +382,12 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS msg_controllen: c.size_t, /* [PSX] ancillary data buffer length */ msg_flags: Msg_Flags, /* [PSX] flags on received message */ } + + cmsghdr :: struct { + cmsg_len: c.size_t, /* [PSX] data byte count, including cmsghdr */ + cmsg_level: c.int, /* [PSX] originating protocol */ + cmsg_type: c.int, /* [PSX] protocol-specific type */ + } } else { sockaddr_storage :: struct { ss_len: c.uint8_t, /* address length */ @@ -400,13 +406,12 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS msg_controllen: socklen_t, /* [PSX] ancillary data buffer length */ msg_flags: Msg_Flags, /* [PSX] flags on received message */ } - } - - cmsghdr :: struct { - cmsg_len: socklen_t, /* [PSX] data byte count, including cmsghdr */ - cmsg_level: c.int, /* [PSX] originating protocol */ - cmsg_type: c.int, /* [PSX] protocol-specific type */ + cmsghdr :: struct { + cmsg_len: socklen_t, /* [PSX] data byte count, including cmsghdr */ + cmsg_level: c.int, /* [PSX] originating protocol */ + cmsg_type: c.int, /* [PSX] protocol-specific type */ + } } SCM_RIGHTS :: 0x01 @@ -456,51 +461,78 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS SOCK_STREAM :: 1 // Options to be accessed at socket level, not protocol level. - SOL_SOCKET :: 0xffff + when ODIN_OS == .Linux { + SOL_SOCKET :: 1 - SO_ACCEPTCONN :: 0x0002 - SO_BROADCAST :: 0x0020 - SO_DEBUG :: 0x0001 - SO_DONTROUTE :: 0x0010 - SO_ERROR :: 0x1007 - SO_KEEPALIVE :: 0x0008 - SO_OOBINLINE :: 0x0100 - SO_RCVBUF :: 0x1002 - SO_RCVLOWAT :: 0x1004 - SO_REUSEADDR :: 0x0004 - SO_SNDBUF :: 0x1001 - SO_SNDLOWAT :: 0x1003 - SO_TYPE :: 0x1008 + SO_ACCEPTCONN :: 30 + SO_BROADCAST :: 6 + SO_DEBUG :: 1 + SO_DONTROUTE :: 5 + SO_ERROR :: 4 + SO_KEEPALIVE :: 9 + SO_OOBINLINE :: 10 + SO_RCVBUF :: 8 + SO_RCVLOWAT :: 18 + SO_REUSEADDR :: 2 + SO_SNDBUF :: 7 + SO_SNDLOWAT :: 19 + SO_TYPE :: 3 + SO_LINGER :: 13 - when ODIN_OS == .Darwin { - SO_LINGER :: 0x1080 - SO_RCVTIMEO :: 0x1006 - SO_SNDTIMEO :: 0x1005 - } else when ODIN_OS == .FreeBSD { - SO_LINGER :: 0x0080 - SO_RCVTIMEO :: 0x1006 - SO_SNDTIMEO :: 0x1005 - } else when ODIN_OS == .NetBSD { - SO_LINGER :: 0x0080 - SO_RCVTIMEO :: 0x100c - SO_SNDTIMEO :: 0x100b - } else when ODIN_OS == .OpenBSD { - SO_LINGER :: 0x0080 - SO_RCVTIMEO :: 0x1006 - SO_SNDTIMEO :: 0x1005 + SO_RCVTIMEO :: 66 + SO_SNDTIMEO :: 67 + } else { + SOL_SOCKET :: 0xffff + + SO_ACCEPTCONN :: 0x0002 + SO_BROADCAST :: 0x0020 + SO_DEBUG :: 0x0001 + SO_DONTROUTE :: 0x0010 + SO_ERROR :: 0x1007 + SO_KEEPALIVE :: 0x0008 + SO_OOBINLINE :: 0x0100 + SO_RCVBUF :: 0x1002 + SO_RCVLOWAT :: 0x1004 + SO_REUSEADDR :: 0x0004 + SO_SNDBUF :: 0x1001 + SO_SNDLOWAT :: 0x1003 + SO_TYPE :: 0x1008 + + when ODIN_OS == .Darwin { + SO_LINGER :: 0x1080 + SO_RCVTIMEO :: 0x1006 + SO_SNDTIMEO :: 0x1005 + } else when ODIN_OS == .FreeBSD { + SO_LINGER :: 0x0080 + SO_RCVTIMEO :: 0x1006 + SO_SNDTIMEO :: 0x1005 + } else when ODIN_OS == .NetBSD { + SO_LINGER :: 0x0080 + SO_RCVTIMEO :: 0x100c + SO_SNDTIMEO :: 0x100b + } else when ODIN_OS == .OpenBSD { + SO_LINGER :: 0x0080 + SO_RCVTIMEO :: 0x1006 + SO_SNDTIMEO :: 0x1005 + } } // The maximum backlog queue length for listen(). - SOMAXCONN :: 128 + when ODIN_OS == .Linux { + SOMAXCONN :: 4096 + } else { + SOMAXCONN :: 128 + } when ODIN_OS == .Linux { - MSG_CTRUNC :: 0x007 + MSG_CTRUNC :: 0x008 MSG_DONTROUTE :: 0x004 MSG_EOR :: 0x080 MSG_OOB :: 0x001 MSG_PEEK :: 0x002 MSG_TRUNC :: 0x020 MSG_WAITALL :: 0x100 + MSG_NOSIGNAL :: 0x4000 } else { MSG_CTRUNC :: 0x20 MSG_DONTROUTE :: 0x4 @@ -509,16 +541,14 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS MSG_PEEK :: 0x2 MSG_TRUNC :: 0x10 MSG_WAITALL :: 0x40 - } - when ODIN_OS == .Darwin { - MSG_NOSIGNAL :: 0x80000 - } else when ODIN_OS == .FreeBSD { - MSG_NOSIGNAL :: 0x00020000 - } else when ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD { - MSG_NOSIGNAL :: 0x0400 - } else when ODIN_OS == .Linux { - MSG_NOSIGNAL :: 0x4000 + when ODIN_OS == .Darwin { + MSG_NOSIGNAL :: 0x80000 + } else when ODIN_OS == .FreeBSD { + MSG_NOSIGNAL :: 0x00020000 + } else when ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD { + MSG_NOSIGNAL :: 0x0400 + } } AF_INET :: 2 @@ -530,6 +560,8 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS AF_INET6 :: 28 } else when ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD { AF_INET6 :: 24 + } else when ODIN_OS == .Linux { + AF_INET6 :: 10 } SHUT_RD :: 0 From af94c4ab32c4a5efa68124804ce003a2ded0b8a4 Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Sat, 14 Sep 2024 10:06:25 -0600 Subject: [PATCH 23/33] Add initial POSIX support for Linux for wordexp. --- core/sys/posix/wordexp.odin | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/core/sys/posix/wordexp.odin b/core/sys/posix/wordexp.odin index d730db0f7..6bb362625 100644 --- a/core/sys/posix/wordexp.odin +++ b/core/sys/posix/wordexp.odin @@ -102,6 +102,27 @@ when ODIN_OS == .Darwin { WRDE_NOSPACE :: 4 WRDE_SYNTAX :: 6 +} else when ODIN_OS == .Linux { + + wordexp_t :: struct { + we_wordc: c.size_t, /* [PSX] count of words matched by words */ + we_wordv: [^]cstring, /* [PSX] pointer to list of expanded words */ + we_offs: c.size_t, /* [PSX] slots to reserve at the beginning of we_wordv */ + } + + WRDE_DOOFFS :: 1 << 0 /* Insert PWORDEXP->we_offs NULLs. */ + WRDE_APPEND :: 1 << 1 /* Append to results of a previous call. */ + WRDE_NOCMD :: 1 << 2 /* Don't do command substitution. */ + WRDE_REUSE :: 1 << 3 /* Reuse storage in PWORDEXP. */ + WRDE_SHOWERR :: 1 << 4 /* Don't redirect stderr to /dev/null. */ + WRDE_UNDEF :: 1 << 5 /* Error for expanding undefined variables. */ + + WRDE_NOSPACE :: 1 + WRDE_BADCHAR :: 2 + WRDE_BADVAL :: 3 + WRDE_CMDSUB :: 4 + WRDE_SYNTAX :: 5 + } else { #panic("posix is unimplemented for the current target") } From aa91479870251894b36e723d2c29d771e9af64ba Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Sat, 14 Sep 2024 17:01:15 -0600 Subject: [PATCH 24/33] Fix O_NOFOLLOW typo. Add Linux support for POSIX fcntl. --- core/sys/posix/fcntl.odin | 152 +++++++++++++++++++++++++++----------- 1 file changed, 109 insertions(+), 43 deletions(-) diff --git a/core/sys/posix/fcntl.odin b/core/sys/posix/fcntl.odin index ca030a9a5..bb2e6835b 100644 --- a/core/sys/posix/fcntl.odin +++ b/core/sys/posix/fcntl.odin @@ -107,11 +107,11 @@ O_Flag_Bits :: enum c.int { // 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_NOFOLOW), + 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_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, @@ -123,7 +123,7 @@ O_Flag_Bits :: enum c.int { 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 + // 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, @@ -135,7 +135,6 @@ O_Flag_Bits :: enum c.int { WRONLY = log2(O_WRONLY), // Reading only. // RDONLY = 0, // Default - } O_Flags :: bit_set[O_Flag_Bits; c.int] @@ -152,8 +151,8 @@ AT_Flags :: bit_set[AT_Flag_Bits; c.int] when ODIN_OS == .Darwin { - off_t :: distinct c.int64_t - pid_t :: distinct c.int32_t + off_t :: distinct c.int64_t + pid_t :: distinct c.int32_t F_DUPFD :: 0 F_DUPFD_CLOEXEC :: 67 @@ -178,7 +177,7 @@ when ODIN_OS == .Darwin { O_DIRECTORY :: 0x00100000 O_EXCL :: 0x00000800 O_NOCTTY :: 0x00020000 - O_NOFOLOW :: 0x00000100 + O_NOFOLLOW :: 0x00000100 O_TRUNC :: 0x00000400 _O_TTY_INIT :: 0 @@ -189,18 +188,18 @@ when ODIN_OS == .Darwin { O_NONBLOCK :: 0x00000004 O_SYNC :: 0x0080 - _O_RSYNC :: 0 - O_RSYNC :: O_Flags{} + _O_RSYNC :: 0 + O_RSYNC :: O_Flags{} - O_EXEC :: 0x40000000 - O_RDONLY :: 0 - O_RDWR :: 0x0002 - O_WRONLY :: 0x0001 + O_EXEC :: 0x40000000 + O_RDONLY :: 0 + O_RDWR :: 0x0002 + O_WRONLY :: 0x0001 _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_SYMLINK_NOFOLLOW :: 0x0020 @@ -217,8 +216,8 @@ when ODIN_OS == .Darwin { } else when ODIN_OS == .FreeBSD { - off_t :: distinct c.int64_t - pid_t :: distinct c.int32_t + off_t :: distinct c.int64_t + pid_t :: distinct c.int32_t F_DUPFD :: 0 F_DUPFD_CLOEXEC :: 17 @@ -243,7 +242,7 @@ when ODIN_OS == .Darwin { O_DIRECTORY :: 0x00020000 O_EXCL :: 0x0800 O_NOCTTY :: 0x8000 - O_NOFOLOW :: 0x0100 + O_NOFOLLOW :: 0x0100 O_TRUNC :: 0x0400 _O_TTY_INIT :: 0x00080000 @@ -256,15 +255,15 @@ when ODIN_OS == .Darwin { _O_RSYNC :: 0 O_RSYNC :: O_Flags{} // NOTE: not defined in headers - O_EXEC :: 0x00040000 - O_RDONLY :: 0 - O_RDWR :: 0x0002 - O_WRONLY :: 0x0001 + O_EXEC :: 0x00040000 + O_RDONLY :: 0 + O_RDWR :: 0x0002 + O_WRONLY :: 0x0001 _O_SEARCH :: O_EXEC O_SEARCH :: O_Flags{ .EXEC } - AT_FDCWD: FD: -100 + AT_FDCWD: FD : -100 AT_EACCESS :: 0x0100 AT_SYMLINK_NOFOLLOW :: 0x0200 @@ -282,8 +281,8 @@ when ODIN_OS == .Darwin { } else when ODIN_OS == .NetBSD { - off_t :: distinct c.int64_t - pid_t :: distinct c.int32_t + off_t :: distinct c.int64_t + pid_t :: distinct c.int32_t F_DUPFD :: 0 F_DUPFD_CLOEXEC :: 12 @@ -308,7 +307,7 @@ when ODIN_OS == .Darwin { O_DIRECTORY :: 0x0020000 O_EXCL :: 0x0800 O_NOCTTY :: 0x8000 - O_NOFOLOW :: 0x0100 + O_NOFOLLOW :: 0x0100 O_TRUNC :: 0x0400 _O_TTY_INIT :: 0 @@ -319,19 +318,19 @@ when ODIN_OS == .Darwin { O_NONBLOCK :: 0x0004 O_SYNC :: 0x0080 - _O_RSYNC :: 0x0002 - O_RSYNC :: O_Flags{O_Flag_Bits(log2(_O_RSYNC))} + _O_RSYNC :: 0x0002 + O_RSYNC :: O_Flags{O_Flag_Bits(log2(_O_RSYNC))} - O_EXEC :: 0x04000000 - O_RDONLY :: 0 - O_RDWR :: 0x0002 - O_WRONLY :: 0x0001 + O_EXEC :: 0x04000000 + O_RDONLY :: 0 + O_RDWR :: 0x0002 + O_WRONLY :: 0x0001 _O_SEARCH :: 0x00800000 O_SEARCH :: O_Flags{O_Flag_Bits(log2(_O_SEARCH))} - AT_FDCWD: FD: -100 + AT_FDCWD: FD : -100 AT_EACCESS :: 0x100 AT_SYMLINK_NOFOLLOW :: 0x200 @@ -347,8 +346,8 @@ when ODIN_OS == .Darwin { } } else when ODIN_OS == .OpenBSD { - off_t :: distinct c.int64_t - pid_t :: distinct c.int32_t + off_t :: distinct c.int64_t + pid_t :: distinct c.int32_t F_DUPFD :: 0 F_DUPFD_CLOEXEC :: 10 @@ -373,7 +372,7 @@ when ODIN_OS == .Darwin { O_DIRECTORY :: 0x20000 O_EXCL :: 0x0800 O_NOCTTY :: 0x8000 - O_NOFOLOW :: 0x0100 + O_NOFOLLOW :: 0x0100 O_TRUNC :: 0x0400 _O_TTY_INIT :: 0 @@ -384,18 +383,18 @@ when ODIN_OS == .Darwin { O_NONBLOCK :: 0x0004 O_SYNC :: 0x0080 - _O_RSYNC :: O_SYNC - O_RSYNC :: O_Flags{ .SYNC } + _O_RSYNC :: O_SYNC + O_RSYNC :: O_Flags{.SYNC} - O_EXEC :: 0x04000000 // NOTE: not defined in the headers - O_RDONLY :: 0 - O_RDWR :: 0x0002 - O_WRONLY :: 0x0001 + O_EXEC :: 0x04000000 // NOTE: not defined in the headers + O_RDONLY :: 0 + O_RDWR :: 0x0002 + O_WRONLY :: 0x0001 _O_SEARCH :: 0 O_SEARCH :: O_Flags{} // NOTE: not defined in the headers - AT_FDCWD: FD: -100 + AT_FDCWD: FD : -100 AT_EACCESS :: 0x01 AT_SYMLINK_NOFOLLOW :: 0x02 @@ -410,6 +409,73 @@ when ODIN_OS == .Darwin { l_whence: c.short, /* [PSX] flag (Whence) of starting offset */ } +} else when ODIN_OS == .Linux { + + off_t :: distinct c.int64_t + pid_t :: distinct c.int + + F_DUPFD :: 0 // Duplicate file descriptor. + F_GETFD :: 1 /* Get file descriptor flags. */ + F_SETFD :: 2 /* Set file descriptor flags. */ + F_GETFL :: 3 /* Get file status flags. */ + F_SETFL :: 4 /* Set file status flags. */ + F_GETLK :: 5 /* Get record locking info. */ + F_SETLK :: 6 /* Set record locking info (non-blocking). */ + F_SETLKW :: 7 /* Set record locking info (blocking). */ + F_SETOWN :: 8 /* Get owner (process receiving SIGIO). */ + F_GETOWN :: 9 /* Set owner (process receiving SIGIO). */ + F_RDLCK :: 0 /* Read lock. */ + F_UNLCK :: 2 /* Remove lock. */ + F_WRLCK :: 1 /* Write lock. */ + + F_DUPFD_CLOEXEC :: 1030 /* Duplicate file descriptor with close-on-exit set. */ + + FD_CLOEXEC :: 1 + + O_CREAT :: 0o0_000_100 + O_EXCL :: 0o0_000_200 + O_NOCTTY :: 0o0_000_400 + O_TRUNC :: 0o0_001_000 + O_DIRECTORY :: 0o0_200_000 + O_NOFOLLOW :: 0o0_400_000 + O_CLOEXEC :: 0o2_000_000 + + _O_TTY_INIT :: 0 + O_TTY_INIT :: O_Flags{} + + O_APPEND :: 0o0_002_000 + O_NONBLOCK :: 0o0_004_000 + O_DSYNC :: 0o0_010_000 + O_SYNC :: 0o4_010_000 + + _O_RSYNC :: 0 + O_RSYNC :: O_Flags{} + + // NOTE: Not implemented in Linux + O_EXEC :: 0 + + O_RDONLY :: 0 + O_WRONLY :: 0o1 + O_RDWR :: 0o2 + + _O_SEARCH :: 0 + O_SEARCH :: O_Flags{} + + AT_FDCWD: FD : -100 // Special value used to indicate the *at functions should use the current working directory. + + AT_EACCESS :: 0x200 // Test access permitted for effective IDs, not real IDs. + AT_SYMLINK_NOFOLLOW :: 0x100 // Do not follow symbolic links. + AT_SYMLINK_FOLLOW :: 0x400 // Follow symbolic links. + AT_REMOVEDIR :: 0x200 // Remove directory instead of unlinking file. + + flock :: struct { + l_start: off_t, // [PSX] relative offset in bytes. + 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_type: Lock_Type, // [PSX] type of lock. + l_whence: c.short, // [PSX] flag (Whence) of starting offset. + } + } else { #panic("posix is unimplemented for the current target") } From 8616842ec6694b14f3c3f534c92bda670304c4ed Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Sat, 14 Sep 2024 20:23:42 -0600 Subject: [PATCH 25/33] Implement Linux POSIX compliance for poll, sched, sys/select. Fix enum in fcntl. --- core/sys/posix/fcntl.odin | 10 +++++----- core/sys/posix/poll.odin | 6 +++--- core/sys/posix/sched.odin | 2 +- core/sys/posix/sys_select.odin | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/core/sys/posix/fcntl.odin b/core/sys/posix/fcntl.odin index bb2e6835b..d48e39d02 100644 --- a/core/sys/posix/fcntl.odin +++ b/core/sys/posix/fcntl.odin @@ -128,7 +128,7 @@ O_Flag_Bits :: enum c.int { // RSYNC = O_RSYNC, // Execute only. - EXEC = log2(O_EXEC), + EXEC = O_EXEC when ODIN_OS == .Linux else log2(O_EXEC), // Reading and writing. RDWR = log2(O_RDWR), // Writing only. @@ -177,7 +177,7 @@ when ODIN_OS == .Darwin { O_DIRECTORY :: 0x00100000 O_EXCL :: 0x00000800 O_NOCTTY :: 0x00020000 - O_NOFOLLOW :: 0x00000100 + O_NOFOLLOW :: 0x00000100 O_TRUNC :: 0x00000400 _O_TTY_INIT :: 0 @@ -242,7 +242,7 @@ when ODIN_OS == .Darwin { O_DIRECTORY :: 0x00020000 O_EXCL :: 0x0800 O_NOCTTY :: 0x8000 - O_NOFOLLOW :: 0x0100 + O_NOFOLLOW :: 0x0100 O_TRUNC :: 0x0400 _O_TTY_INIT :: 0x00080000 @@ -307,7 +307,7 @@ when ODIN_OS == .Darwin { O_DIRECTORY :: 0x0020000 O_EXCL :: 0x0800 O_NOCTTY :: 0x8000 - O_NOFOLLOW :: 0x0100 + O_NOFOLLOW :: 0x0100 O_TRUNC :: 0x0400 _O_TTY_INIT :: 0 @@ -372,7 +372,7 @@ when ODIN_OS == .Darwin { O_DIRECTORY :: 0x20000 O_EXCL :: 0x0800 O_NOCTTY :: 0x8000 - O_NOFOLLOW :: 0x0100 + O_NOFOLLOW :: 0x0100 O_TRUNC :: 0x0400 _O_TTY_INIT :: 0 diff --git a/core/sys/posix/poll.odin b/core/sys/posix/poll.odin index 7f23de267..3d403d625 100644 --- a/core/sys/posix/poll.odin +++ b/core/sys/posix/poll.odin @@ -27,9 +27,9 @@ foreign lib { nfds_t :: c.uint Poll_Error :: enum c.int { - EAGAIN = Errno.EAGAIN, - EINTR = Errno.EINTR, - EINVAL = Errno.EINVAL, + EAGAIN = cast(c.int)Errno.EAGAIN, + EINTR = cast(c.int)Errno.EINTR, + EINVAL = cast(c.int)Errno.EINVAL, } Poll_Event_Bits :: enum c.short { diff --git a/core/sys/posix/sched.odin b/core/sys/posix/sched.odin index 6623ba6e6..3923257aa 100644 --- a/core/sys/posix/sched.odin +++ b/core/sys/posix/sched.odin @@ -94,7 +94,7 @@ when ODIN_OS == .Darwin { SCHED_RR :: 3 SCHED_OTHER :: 2 -} else when ODIN_OS == .NetBSD { +} else when ODIN_OS == .NetBSD || ODIN_OS == .Linux { SCHED_OTHER :: 0 SCHED_FIFO :: 1 diff --git a/core/sys/posix/sys_select.odin b/core/sys/posix/sys_select.odin index 3392e02bc..c20636b21 100644 --- a/core/sys/posix/sys_select.odin +++ b/core/sys/posix/sys_select.odin @@ -55,7 +55,7 @@ when ODIN_OS == .NetBSD { LSELECT :: "select" } -when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD { +when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux { suseconds_t :: distinct (c.int32_t when ODIN_OS == .Darwin || ODIN_OS == .NetBSD else c.long) From 97e06cb98e890643d17f5ebca3b029f4dd21d6aa Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Sun, 15 Sep 2024 18:43:51 -0600 Subject: [PATCH 26/33] Fix bit flags on fcntl linux POSIX implemention. Add sys/sem linux implementation. --- core/sys/posix/fcntl.odin | 9 +++++++-- core/sys/posix/sys_sem.odin | 30 ++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/core/sys/posix/fcntl.odin b/core/sys/posix/fcntl.odin index d48e39d02..3350238e4 100644 --- a/core/sys/posix/fcntl.odin +++ b/core/sys/posix/fcntl.odin @@ -123,12 +123,16 @@ O_Flag_Bits :: enum c.int { 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 = O_EXEC when ODIN_OS == .Linux else log2(O_EXEC), + // 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. @@ -139,7 +143,8 @@ O_Flag_Bits :: enum c.int { O_Flags :: bit_set[O_Flag_Bits; c.int] // A mask of all the access mode bits. -O_ACCMODE :: O_Flags{ .EXEC, .RDWR, .WRONLY } +// NOTE: .EXEC and .RDONLY also belong here, but they are 0 on some platforms. +O_ACCMODE :: O_Flags{ .RDWR, .WRONLY } AT_Flag_Bits :: enum c.int { EACCESS = log2(AT_EACCESS), diff --git a/core/sys/posix/sys_sem.odin b/core/sys/posix/sys_sem.odin index 3fcde325b..9f45ab1fe 100644 --- a/core/sys/posix/sys_sem.odin +++ b/core/sys/posix/sys_sem.odin @@ -127,6 +127,36 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS sem_flg: c.short, /* [PSX] operation flags */ } +} else when ODIN_OS == .Linux { + + SEM_UNDO :: 0x1000 // undo the operation on exit + + // Commands for `semctl'. + GETPID :: 11 + GETVAL :: 12 + GETALL :: 13 + GETNCNT :: 14 + GETZCNT :: 15 + SETVAL :: 16 + SETALL :: 17 + + semid_ds :: struct { + sem_perm: ipc_perm, // [PSX] operation permission structure + sem_otime: time_t, // [PSX] last semop() + __sem_otime_high: c.ulong, + sem_ctime: time_t, // [PSX] last time changed by semctl() + __sem_ctime_high: c.ulong, + sem_nsems: c.ulong, // [PSX] number of semaphores in set + __glibc_reserved3: c.ulong, + __glibc_reserved4: c.ulong, + } + + sembuf :: struct { + sem_num: c.ushort, /* [PSX] semaphore number */ + sem_op: c.short, /* [PSX] semaphore operation */ + sem_flg: c.short, /* [PSX] operation flags */ + } + } else { #panic("posix is unimplemented for the current target") } From 10702f113476fc4094801e27f1f861a29a2ab632 Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Sat, 21 Sep 2024 20:44:33 -0600 Subject: [PATCH 27/33] Implement POSIX pthread, signal, sys/resource, unistd for Linux. --- core/sys/posix/pthread.odin | 39 ++++ core/sys/posix/signal.odin | 151 +++++++++++++++- core/sys/posix/sys_resource.odin | 12 +- core/sys/posix/unistd.odin | 300 +++++++++++++++++++++++++------ 4 files changed, 438 insertions(+), 64 deletions(-) diff --git a/core/sys/posix/pthread.odin b/core/sys/posix/pthread.odin index e264f6f6c..aa7b50a6f 100644 --- a/core/sys/posix/pthread.odin +++ b/core/sys/posix/pthread.odin @@ -513,6 +513,45 @@ when ODIN_OS == .Darwin { sched_priority: c.int, /* [PSX] process or thread execution scheduling priority */ } +} else when ODIN_OS == .Linux { + + PTHREAD_CANCEL_DEFERRED :: 0 + PTHREAD_CANCEL_ASYNCHRONOUS :: 1 + + PTHREAD_CANCEL_ENABLE :: 0 + PTHREAD_CANCEL_DISABLE :: 1 + + PTHREAD_CANCELED :: rawptr(uintptr(-1)) + + PTHREAD_CREATE_JOINABLE :: 0 + PTHREAD_CREATE_DETACHED :: 1 + + PTHREAD_INHERIT_SCHED :: 0 + PTHREAD_EXPLICIT_SCHED :: 1 + + PTHREAD_PRIO_NONE :: 0 + PTHREAD_PRIO_INHERIT :: 1 + PTHREAD_PRIO_PROTECT :: 2 + + PTHREAD_PROCESS_PRIVATE :: 0 + PTHREAD_PROCESS_SHARED :: 1 + + PTHREAD_SCOPE_SYSTEM :: 0 + PTHREAD_SCOPE_PROCESS :: 1 + + pthread_t :: distinct c.ulong + + pthread_attr_t :: struct #raw_union { + __size: [56]c.char, + __align: c.long, + } + + pthread_key_t :: distinct c.uint + + sched_param :: struct { + sched_priority: c.int, /* [PSX] process or thread execution scheduling priority */ + } + } else { #panic("posix is unimplemented for the current target") } diff --git a/core/sys/posix/signal.odin b/core/sys/posix/signal.odin index c35494185..7cb4f4c43 100644 --- a/core/sys/posix/signal.odin +++ b/core/sys/posix/signal.odin @@ -220,6 +220,16 @@ foreign lib { const struct timespec *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 { @@ -480,7 +490,7 @@ when ODIN_OS == .Darwin { uid_t :: distinct c.uint32_t sigset_t :: distinct c.uint32_t - // MOTE: unimplemented on darwin. + // NOTE: unimplemented on darwin. // // SIGRTMIN :: // SIGRTMAX :: @@ -625,7 +635,7 @@ when ODIN_OS == .Darwin { __bits: [4]c.uint32_t, } - // MOTE: unimplemented on darwin. + // NOTE: unimplemented on FreeBSD. // // SIGRTMIN :: 65 // SIGRTMAX :: 126 @@ -794,7 +804,7 @@ when ODIN_OS == .Darwin { __bits: [4]c.uint32_t, } - // MOTE: unimplemented on darwin. + // NOTE: unimplemented on NetBSD. // // SIGRTMIN :: 33 // SIGRTMAX :: 63 @@ -1126,6 +1136,141 @@ when ODIN_OS == .Darwin { SI_ASYNCIO :: -4 // NOTE: not implemented SI_MESGQ :: -5 // NOTE: not implemented +} else when ODIN_OS == .Linux { + + // Request that signal be held + SIG_HOLD :: rawptr(uintptr(2)) + + uid_t :: distinct c.uint32_t + sigset_t :: struct { + [1024/(8 * size_of(c.ulong))]val + } + + SIGRTMIN :: __libc_current_sigrtmin() + SIGRTMAX :: __libc_current_sigrtmax() + + SIGHUP :: 1 + SIGQUIT :: 3 + SIGTRAP :: 5 + SIGBUS :: 7 + SIGKILL :: 9 + SIGUSR1 :: 10 + SIGUSR2 :: 12 + SIGPIPE :: 13 + SIGALRM :: 14 + SIGCHLD :: 17 + SIGCONT :: 18 + SIGSTOP :: 19 + SIGTSTP :: 20 + SIGTTIN :: 21 + SIGTTOU :: 22 + SIGURG :: 23 + SIGXCPU :: 24 + SIGXFSZ :: 25 + SIGVTALRM :: 26 + SIGPROF :: 27 + SIGPOLL :: 29 + SIGSYS :: 31 + + sigaction :: struct { + sa_handler: proc "c" (Signal), + sa_flags: SA_Flags, + sa_mask: sigset_t, + } + + SIG_BLOCK :: 0 + SIG_UNBLOCK :: 1 + SIG_SETMASK :: 2 + + SA_NOCLDSTOP :: 1 + SA_NOCLDWAIT :: 2 + SA_SIGINFO :: 4 + SA_ONSTACK :: 0x08000000 + SA_RESTART :: 0x10000000 + SA_NODEFER :: 0x40000000 + SA_RESETHAND :: 0x80000000 + + SS_ONSTACK :: 1 + SS_DISABLE :: 2 + + MINSIGSTKSZ :: 2048 + SIGSTKSZ :: 8192 + + stack_t :: struct { + ss_sp: rawptr, /* [PSX] stack base or pointer */ + ss_flags: SS_Flags, /* [PSX] flags */ + ss_size: c.size_t, /* [PSX] stack size */ + } + + // WARNING: This implementaion might be completely wrong and need to be reviewed and corrected. + siginfo_t :: struct { + si_signo: Signal, /* [PSX] signal number */ + si_code: struct #raw_union { /* [PSX] specific more detailed codes per signal */ + ill: ILL_Code, + fpe: FPE_Code, + segv: SEGV_Code, + bus: BUS_Code, + trap: TRAP_Code, + chld: CLD_Code, + poll: POLL_Code, + any: Any_Code, + }, + si_errno: Errno, /* [PSX] errno value associated with this signal */ + si_pid: pid_t, /* [PSX] sending process ID */ + si_uid: uid_t, /* [PSX] real user ID of sending process */ + si_addr: rawptr, /* [PSX] address of faulting instruction */ + si_status: c.int, /* [PSX] exit value or signal */ + si_band: c.long, /* [PSX] band event for SIGPOLL */ + si_value: sigval, /* [PSX] signal value */ + } + + ILL_ILLOPC :: 1 + ILL_ILLOPN :: 2 + ILL_ILLADR :: 3 + ILL_ILLTRP :: 4 + ILL_PRVOPC :: 5 + ILL_PRVREG :: 6 + ILL_COPROC :: 7 + ILL_BADSTK :: 8 + + FPE_INTDIV :: 1 + FPE_INTOVF :: 2 + FPE_FLTDIV :: 3 + FPE_FLTOVF :: 4 + FPE_FLTUND :: 5 + FPE_FLTRES :: 6 + FPE_FLTINV :: 7 + FPE_FLTSUB :: 8 + + SEGV_MAPERR :: 1 + SEGV_ACCERR :: 2 + + BUS_ADRALN :: 1 + BUS_ADRERR :: 2 + BUS_OBJERR :: 3 + + TRAP_BRKPT :: 1 + TRAP_TRACE :: 2 + + CLD_EXITED :: 1 + CLD_KILLED :: 2 + CLD_DUMPED :: 3 + CLD_TRAPPED :: 4 + CLD_STOPPED :: 5 + CLD_CONTINUED :: 6 + + POLL_IN :: 1 + POLL_OUT :: 2 + POLL_MSG :: 3 + POLL_ERR :: 4 + POLL_PRI :: 5 + POLL_HUP :: 6 + + SI_USER :: 0 + SI_QUEUE :: -1 + SI_TIMER :: -2 + SI_MESGQ :: -3 + SI_ASYNCIO :: -4 } else { #panic("posix is unimplemented for the current target") } diff --git a/core/sys/posix/sys_resource.odin b/core/sys/posix/sys_resource.odin index 6716d60c3..ad944a7bb 100644 --- a/core/sys/posix/sys_resource.odin +++ b/core/sys/posix/sys_resource.odin @@ -95,7 +95,7 @@ when ODIN_OS == .NetBSD { @(private) LGETRUSAGE :: "getrusage" } -when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD { +when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux { PRIO_PROCESS :: 0 PRIO_PGRP :: 1 @@ -103,7 +103,7 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS rlim_t :: distinct c.uint64_t - RLIM_INFINITY :: (rlim_t(1) << 63) - 1 + RLIM_INFINITY :: max(rlim_t) - 1 when ODIN_OS == .Linux else (rlim_t(1) << 63) - 1 RLIM_SAVED_MAX :: RLIM_INFINITY RLIM_SAVED_CUR :: RLIM_INFINITY @@ -143,9 +143,13 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS RLIMIT_CPU :: 0 RLIMIT_DATA :: 2 RLIMIT_FSIZE :: 1 - RLIMIT_NOFILE :: 8 + RLIMIT_NOFILE :: 7 when ODIN_OS == .Linux else 8 RLIMIT_STACK :: 3 - RLIMIT_AS :: 5 when ODIN_OS == .Darwin || ODIN_OS == .OpenBSD else 10 + when ODIN_OS == .Linux { + RLIMIT_AS :: 9 + } else { + RLIMIT_AS :: 5 when ODIN_OS == .Darwin || ODIN_OS == .OpenBSD else 10 + } } else { #panic("posix is unimplemented for the current target") diff --git a/core/sys/posix/unistd.odin b/core/sys/posix/unistd.odin index 6ed9e5d11..08f4e4b69 100644 --- a/core/sys/posix/unistd.odin +++ b/core/sys/posix/unistd.odin @@ -1181,20 +1181,20 @@ when ODIN_OS == .Darwin { F_TLOCK :: 2 F_ULOCK :: 0 - _CS_PATH :: 1 - _CS_POSIX_V6_ILP32_OFF32_CFLAGS :: 2 - _CS_POSIX_V6_ILP32_OFF32_LDFLAGS :: 3 - _CS_POSIX_V6_ILP32_OFF32_LIBS :: 4 - _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS :: 5 - _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS :: 6 - _CS_POSIX_V6_ILP32_OFFBIG_LIBS :: 7 - _CS_POSIX_V6_LP64_OFF64_CFLAGS :: 8 - _CS_POSIX_V6_LP64_OFF64_LDFLAGS :: 9 - _CS_POSIX_V6_LP64_OFF64_LIBS :: 10 - _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS :: 11 - _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS :: 12 - _CS_POSIX_V6_LPBIG_OFFBIG_LIBS :: 13 - _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS :: 14 + _CS_PATH :: 1 + _CS_POSIX_V6_ILP32_OFF32_CFLAGS :: 2 + _CS_POSIX_V6_ILP32_OFF32_LDFLAGS :: 3 + _CS_POSIX_V6_ILP32_OFF32_LIBS :: 4 + _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS :: 5 + _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS :: 6 + _CS_POSIX_V6_ILP32_OFFBIG_LIBS :: 7 + _CS_POSIX_V6_LP64_OFF64_CFLAGS :: 8 + _CS_POSIX_V6_LP64_OFF64_LDFLAGS :: 9 + _CS_POSIX_V6_LP64_OFF64_LIBS :: 10 + _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS :: 11 + _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS :: 12 + _CS_POSIX_V6_LPBIG_OFFBIG_LIBS :: 13 + _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS :: 14 _PC_LINK_MAX :: 1 _PC_MAX_CANON :: 2 @@ -1362,20 +1362,20 @@ when ODIN_OS == .Darwin { F_TLOCK :: 2 F_ULOCK :: 0 - _CS_PATH :: 1 - _CS_POSIX_V6_ILP32_OFF32_CFLAGS :: 2 - _CS_POSIX_V6_ILP32_OFF32_LDFLAGS :: 3 - _CS_POSIX_V6_ILP32_OFF32_LIBS :: 4 - _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS :: 5 - _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS :: 6 - _CS_POSIX_V6_ILP32_OFFBIG_LIBS :: 7 - _CS_POSIX_V6_LP64_OFF64_CFLAGS :: 8 - _CS_POSIX_V6_LP64_OFF64_LDFLAGS :: 9 - _CS_POSIX_V6_LP64_OFF64_LIBS :: 10 - _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS :: 11 - _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS :: 12 - _CS_POSIX_V6_LPBIG_OFFBIG_LIBS :: 13 - _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS :: 14 + _CS_PATH :: 1 + _CS_POSIX_V6_ILP32_OFF32_CFLAGS :: 2 + _CS_POSIX_V6_ILP32_OFF32_LDFLAGS :: 3 + _CS_POSIX_V6_ILP32_OFF32_LIBS :: 4 + _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS :: 5 + _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS :: 6 + _CS_POSIX_V6_ILP32_OFFBIG_LIBS :: 7 + _CS_POSIX_V6_LP64_OFF64_CFLAGS :: 8 + _CS_POSIX_V6_LP64_OFF64_LDFLAGS :: 9 + _CS_POSIX_V6_LP64_OFF64_LIBS :: 10 + _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS :: 11 + _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS :: 12 + _CS_POSIX_V6_LPBIG_OFFBIG_LIBS :: 13 + _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS :: 14 _PC_LINK_MAX :: 1 _PC_MAX_CANON :: 2 @@ -1543,20 +1543,20 @@ when ODIN_OS == .Darwin { F_TLOCK :: 2 F_ULOCK :: 0 - _CS_PATH :: 1 - _CS_POSIX_V6_ILP32_OFF32_CFLAGS :: 2 - _CS_POSIX_V6_ILP32_OFF32_LDFLAGS :: 3 - _CS_POSIX_V6_ILP32_OFF32_LIBS :: 4 - _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS :: 5 - _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS :: 6 - _CS_POSIX_V6_ILP32_OFFBIG_LIBS :: 7 - _CS_POSIX_V6_LP64_OFF64_CFLAGS :: 8 - _CS_POSIX_V6_LP64_OFF64_LDFLAGS :: 9 - _CS_POSIX_V6_LP64_OFF64_LIBS :: 10 - _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS :: 11 - _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS :: 12 - _CS_POSIX_V6_LPBIG_OFFBIG_LIBS :: 13 - _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS :: 14 + _CS_PATH :: 1 + _CS_POSIX_V6_ILP32_OFF32_CFLAGS :: 2 + _CS_POSIX_V6_ILP32_OFF32_LDFLAGS :: 3 + _CS_POSIX_V6_ILP32_OFF32_LIBS :: 4 + _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS :: 5 + _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS :: 6 + _CS_POSIX_V6_ILP32_OFFBIG_LIBS :: 7 + _CS_POSIX_V6_LP64_OFF64_CFLAGS :: 8 + _CS_POSIX_V6_LP64_OFF64_LDFLAGS :: 9 + _CS_POSIX_V6_LP64_OFF64_LIBS :: 10 + _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS :: 11 + _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS :: 12 + _CS_POSIX_V6_LPBIG_OFFBIG_LIBS :: 13 + _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS :: 14 _PC_LINK_MAX :: 1 _PC_MAX_CANON :: 2 @@ -1655,7 +1655,6 @@ when ODIN_OS == .Darwin { _SC_TTY_NAME_MAX :: 68 _SC_HOST_NAME_MAX :: 69 - _SC_PASS_MAX :: 70 _SC_REGEXP :: 71 _SC_SHELL :: 72 _SC_SYMLOOP_MAX :: 73 @@ -1729,20 +1728,20 @@ when ODIN_OS == .Darwin { F_TLOCK :: 2 F_ULOCK :: 0 - _CS_PATH :: 1 - _CS_POSIX_V6_ILP32_OFF32_CFLAGS :: 2 - _CS_POSIX_V6_ILP32_OFF32_LDFLAGS :: 3 - _CS_POSIX_V6_ILP32_OFF32_LIBS :: 4 - _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS :: 5 - _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS :: 6 - _CS_POSIX_V6_ILP32_OFFBIG_LIBS :: 7 - _CS_POSIX_V6_LP64_OFF64_CFLAGS :: 8 - _CS_POSIX_V6_LP64_OFF64_LDFLAGS :: 9 - _CS_POSIX_V6_LP64_OFF64_LIBS :: 10 - _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS :: 11 - _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS :: 12 - _CS_POSIX_V6_LPBIG_OFFBIG_LIBS :: 13 - _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS :: 14 + _CS_PATH :: 1 + _CS_POSIX_V6_ILP32_OFF32_CFLAGS :: 2 + _CS_POSIX_V6_ILP32_OFF32_LDFLAGS :: 3 + _CS_POSIX_V6_ILP32_OFF32_LIBS :: 4 + _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS :: 5 + _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS :: 6 + _CS_POSIX_V6_ILP32_OFFBIG_LIBS :: 7 + _CS_POSIX_V6_LP64_OFF64_CFLAGS :: 8 + _CS_POSIX_V6_LP64_OFF64_LDFLAGS :: 9 + _CS_POSIX_V6_LP64_OFF64_LIBS :: 10 + _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS :: 11 + _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS :: 12 + _CS_POSIX_V6_LPBIG_OFFBIG_LIBS :: 13 + _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS :: 14 _PC_LINK_MAX :: 1 _PC_MAX_CANON :: 2 @@ -1911,6 +1910,193 @@ when ODIN_OS == .Darwin { _POSIX_VDISABLE :: '\377' +} else when ODIN_OS == .Linux { + + _F_OK :: 0 + X_OK :: 1 + W_OK :: 2 + R_OK :: 4 + + F_LOCK :: 1 + F_TEST :: 3 + F_TLOCK :: 2 + F_ULOCK :: 0 + + _CS_PATH :: 1 + _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS :: 2 + + _CS_POSIX_V6_ILP32_OFF32_CFLAGS :: 1116 + _CS_POSIX_V6_ILP32_OFF32_LDFLAGS :: 1117 + _CS_POSIX_V6_ILP32_OFF32_LIBS :: 1118 + _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS :: 1120 + _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS :: 1121 + _CS_POSIX_V6_ILP32_OFFBIG_LIBS :: 1122 + _CS_POSIX_V6_LP64_OFF64_CFLAGS :: 1124 + _CS_POSIX_V6_LP64_OFF64_LDFLAGS :: 1125 + _CS_POSIX_V6_LP64_OFF64_LIBS :: 1126 + _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS :: 1128 + _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS :: 1129 + _CS_POSIX_V6_LPBIG_OFFBIG_LIBS :: 1130 + + _PC_LINK_MAX :: 1 + _PC_MAX_CANON :: 2 + _PC_MAX_INPUT :: 3 + _PC_NAME_MAX :: 4 + _PC_PATH_MAX :: 5 + _PC_PIPE_BUF :: 6 + _PC_CHOWN_RESTRICTED :: 7 + _PC_NO_TRUNC :: 8 + _PC_VDISABLE :: 9 + _PC_SYNC_IO :: 10 + _PC_ASYNC_IO :: 11 + _PC_PRIO_IO :: 12 + _PC_FILESIZEBITS :: 14 + _PC_REC_INCR_XFER_SIZE :: 15 + _PC_REC_MAX_XFER_SIZE :: 16 + _PC_REC_MIN_XFER_SIZE :: 17 + _PC_REC_XFER_ALIGN :: 18 + _PC_ALLOC_SIZE_MIN :: 19 + _PC_SYMLINK_MAX :: 20 + _PC_2_SYMLINK :: 21 + + _SC_ARG_MAX :: 1 + _SC_CHILD_MAX :: 2 + _SC_CLK_TCK :: 3 + _SC_NGROUPS_MAX :: 4 + _SC_OPEN_MAX :: 5 + _SC_STREAM_MAX :: 6 + _SC_TZNAME_MAX :: 7 + _SC_JOB_CONTROL :: 8 + _SC_SAVED_IDS :: 9 + _SC_REALTIME_SIGNALS :: 10 + _SC_PRIORITY_SCHEDULING :: 11 + _SC_TIMERS :: 12 + _SC_ASYNCHRONOUS_IO :: 13 + _SC_PRIORITIZED_IO :: 14 + _SC_SYNCHRONIZED_IO :: 15 + _SC_FSYNC :: 16 + _SC_MAPPED_FILES :: 17 + _SC_MEMLOCK :: 18 + _SC_MEMLOCK_RANGE :: 19 + _SC_MEMORY_PROTECTION :: 20 + _SC_MESSAGE_PASSING :: 21 + _SC_SEMAPHORES :: 22 + _SC_SHARED_MEMORY_OBJECTS :: 23 + _SC_AIO_LISTIO_MAX :: 24 + _SC_AIO_MAX :: 25 + _SC_AIO_PRIO_DELTA_MAX :: 26 + _SC_DELAYTIMER_MAX :: 27 + _SC_MQ_OPEN_MAX :: 28 + _SC_MQ_PRIO_MAX :: 29 + _SC_VERSION :: 30 + _SC_PAGESIZE :: 31 + _SC_PAGE_SIZE :: _SC_PAGESIZE + _SC_RTSIG_MAX :: 32 + _SC_SEM_NSEMS_MAX :: 33 + _SC_SEM_VALUE_MAX :: 34 + _SC_SIGQUEUE_MAX :: 35 + _SC_TIMER_MAX :: 36 + _SC_BC_BASE_MAX :: 37 + _SC_BC_DIM_MAX :: 38 + _SC_BC_SCALE_MAX :: 39 + _SC_BC_STRING_MAX :: 40 + _SC_COLL_WEIGHTS_MAX :: 41 + _SC_EXPR_NEST_MAX :: 43 + _SC_LINE_MAX :: 44 + _SC_RE_DUP_MAX :: 45 + _SC_2_VERSION :: 47 + _SC_2_C_BIND :: 48 + _SC_2_C_DEV :: 49 + _SC_2_FORT_DEV :: 50 + _SC_2_FORT_RUN :: 51 + _SC_2_SW_DEV :: 52 + _SC_2_LOCALEDEF :: 53 + + _SC_IOV_MAX :: 62 + _SC_THREADS :: 69 + _SC_THREAD_SAFE_FUNCTIONS :: 70 + _SC_GETGR_R_SIZE_MAX :: 71 + _SC_GETPW_R_SIZE_MAX :: 72 + _SC_LOGIN_NAME_MAX :: 73 + _SC_TTY_NAME_MAX :: 74 + _SC_THREAD_DESTRUCTOR_ITERATIONS :: 75 + _SC_THREAD_KEYS_MAX :: 76 + _SC_THREAD_STACK_MIN :: 77 + _SC_THREAD_THREADS_MAX :: 78 + _SC_THREAD_ATTR_STACKADDR :: 79 + _SC_THREAD_ATTR_STACKSIZE :: 80 + _SC_THREAD_PRIORITY_SCHEDULING :: 81 + _SC_THREAD_PRIO_INHERIT :: 82 + _SC_THREAD_PRIO_PROTECT :: 83 + _SC_THREAD_PROCESS_SHARED :: 84 + _SC_NPROCESSORS_CONF :: 85 + _SC_NPROCESSORS_ONLN :: 86 + _SC_PHYS_PAGES :: 87 + _SC_AVPHYS_PAGES :: 88 + _SC_ATEXIT_MAX :: 89 + _SC_PASS_MAX :: 90 + _SC_XOPEN_VERSION :: 91 + _SC_XOPEN_UNIX :: 92 + _SC_XOPEN_CRYPT :: 93 + _SC_XOPEN_ENH_I18N :: 94 + _SC_XOPEN_SHM :: 95 + _SC_2_CHAR_TERM :: 96 + _SC_2_UPE :: 97 + + _SC_XOPEN_LEGACY :: 129 + _SC_XOPEN_REALTIME :: 130 + _SC_XOPEN_REALTIME_THREADS :: 131 + _SC_ADVISORY_INFO :: 132 + _SC_BARRIERS :: 133 + _SC_CLOCK_SELECTION :: 137 + _SC_CPUTIME :: 138 + _SC_THREAD_CPUTIME :: 139 + _SC_MONOTONIC_CLOCK :: 149 + _SC_READER_WRITER_LOCKS :: 153 + _SC_SPIN_LOCKS :: 154 + _SC_REGEXP :: 155 + _SC_SHELL :: 157 + _SC_SPAWN :: 159 + _SC_SPORADIC_SERVER :: 160 + _SC_THREAD_SPORADIC_SERVER :: 161 + _SC_TIMEOUTS :: 164 + _SC_TYPED_MEMORY_OBJECTS :: 165 + _SC_2_PBS :: 168 + _SC_2_PBS_ACCOUNTING :: 169 + _SC_2_PBS_MESSAGE :: 171 + _SC_2_PBS_TRACK :: 172 + _SC_SYMLOOP_MAX :: 173 + _SC_2_PBS_CHECKPOINT :: 174 + _SC_V6_ILP32_OFF32 :: 175 + _SC_V6_ILP32_OFFBIG :: 176 + _SC_V6_LP64_OFF64 :: 177 + _SC_V6_LPBIG_OFFBIG :: 178 + _SC_HOST_NAME_MAX :: 179 + _SC_TRACE :: 180 + _SC_TRACE_EVENT_FILTER :: 181 + _SC_TRACE_INHERIT :: 182 + _SC_TRACE_LOG :: 183 + + _SC_IPV6 :: 234 + _SC_RAW_SOCKETS :: 235 + _SC_V7_ILP32_OFF32 :: 236 + _SC_V7_ILP32_OFFBIG :: 237 + _SC_V7_LP64_OFF64 :: 238 + _SC_V7_LPBIG_OFFBIG :: 239 + _SC_SS_REPL_MAX :: 240 + _SC_TRACE_EVENT_NAME_MAX :: 241 + _SC_TRACE_NAME_MAX :: 242 + _SC_TRACE_SYS_MAX :: 243 + _SC_TRACE_USER_EVENT_MAX :: 244 + _SC_XOPEN_STREAMS :: 245 + _SC_THREAD_ROBUST_PRIO_INHERIT :: 246 + _SC_THREAD_ROBUST_PRIO_PROTECT :: 247 + + // NOTE: Not implemented. + _SC_XOPEN_UUCP :: 0 + // NOTE: Not implemented. + _POSIX_VDISABLE :: 0 + } else { #panic("posix is unimplemented for the current target") } From 5162c6c506be74fcd8f7e09e7bb51106e03b24a3 Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Sat, 21 Sep 2024 20:56:52 -0600 Subject: [PATCH 28/33] Rename sigaction duplicate type to sigaction_t on linux, following other platforms. --- core/sys/posix/signal.odin | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/sys/posix/signal.odin b/core/sys/posix/signal.odin index 7cb4f4c43..8edaad5ba 100644 --- a/core/sys/posix/signal.odin +++ b/core/sys/posix/signal.odin @@ -1172,7 +1172,9 @@ when ODIN_OS == .Darwin { SIGPOLL :: 29 SIGSYS :: 31 - sigaction :: struct { + // NOTE: this is actually defined as `sigaction`, but due to the function with the same name + // `_t` has been added. + sigaction_t :: struct { sa_handler: proc "c" (Signal), sa_flags: SA_Flags, sa_mask: sigset_t, From c68d847fb38d11416b09a7bae2b33167d0bf6191 Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Sat, 21 Sep 2024 20:59:54 -0600 Subject: [PATCH 29/33] Satisfy the compiler. --- core/sys/posix/signal.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/sys/posix/signal.odin b/core/sys/posix/signal.odin index 8edaad5ba..6748c162f 100644 --- a/core/sys/posix/signal.odin +++ b/core/sys/posix/signal.odin @@ -1143,7 +1143,7 @@ when ODIN_OS == .Darwin { uid_t :: distinct c.uint32_t sigset_t :: struct { - [1024/(8 * size_of(c.ulong))]val + [1024/(8 * size_of(c.ulong))]val, } SIGRTMIN :: __libc_current_sigrtmin() From 04c08c2e2dbbacddae2a596a62fca5f904e3fa2c Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Sat, 21 Sep 2024 21:24:18 -0600 Subject: [PATCH 30/33] Resolve bit set differences between linux and other platforms in posix/fcntl --- core/sys/posix/fcntl.odin | 142 +++++++++++++++++++++++++++----------- 1 file changed, 101 insertions(+), 41 deletions(-) diff --git a/core/sys/posix/fcntl.odin b/core/sys/posix/fcntl.odin index 3350238e4..499fe757b 100644 --- a/core/sys/posix/fcntl.odin +++ b/core/sys/posix/fcntl.odin @@ -95,56 +95,116 @@ Lock_Type :: enum c.short { // Assertions made to unify this bit set. #assert(O_RDONLY == 0) -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), +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 { + // 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), - // 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_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, - // 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, + // 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), - // 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 + // 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, - // Reading and writing. - RDWR = log2(O_RDWR), - // Writing only. - WRONLY = log2(O_WRONLY), - // Reading only. - // RDONLY = 0, // Default + // 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 + } + +} 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. + // 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] // A mask of all the access mode bits. -// NOTE: .EXEC and .RDONLY also belong here, but they are 0 on some platforms. -O_ACCMODE :: O_Flags{ .RDWR, .WRONLY } +when ODIN_OS == .Linux { + + // NOTE: .EXEC and .RDONLY also belong here, but they are 0 on some platforms. + 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 { EACCESS = log2(AT_EACCESS), From cc60725eda4d3a9d63bf64a8d92a19526bde75f0 Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Sat, 21 Sep 2024 21:28:18 -0600 Subject: [PATCH 31/33] Move bit set creation to compiler guard. Fix indentation on posix/sys_sem. --- core/sys/posix/fcntl.odin | 5 ++++- core/sys/posix/sys_sem.odin | 8 ++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/core/sys/posix/fcntl.odin b/core/sys/posix/fcntl.odin index 499fe757b..32c124168 100644 --- a/core/sys/posix/fcntl.odin +++ b/core/sys/posix/fcntl.odin @@ -143,6 +143,8 @@ when ODIN_OS == .Linux { // RDONLY = 0, // Default } + O_Flags :: bit_set[O_Flag_Bits; c.int] + } else { O_Flag_Bits :: enum c.int { @@ -190,8 +192,9 @@ when ODIN_OS == .Linux { // Reading only. // RDONLY = 0, // Default } + + O_Flags :: bit_set[O_Flag_Bits; c.int] } -O_Flags :: bit_set[O_Flag_Bits; c.int] // A mask of all the access mode bits. when ODIN_OS == .Linux { diff --git a/core/sys/posix/sys_sem.odin b/core/sys/posix/sys_sem.odin index 9f45ab1fe..a496ecb4a 100644 --- a/core/sys/posix/sys_sem.odin +++ b/core/sys/posix/sys_sem.odin @@ -143,12 +143,12 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS semid_ds :: struct { sem_perm: ipc_perm, // [PSX] operation permission structure sem_otime: time_t, // [PSX] last semop() - __sem_otime_high: c.ulong, + __sem_otime_high: c.ulong, sem_ctime: time_t, // [PSX] last time changed by semctl() - __sem_ctime_high: c.ulong, + __sem_ctime_high: c.ulong, sem_nsems: c.ulong, // [PSX] number of semaphores in set - __glibc_reserved3: c.ulong, - __glibc_reserved4: c.ulong, + __glibc_reserved3: c.ulong, + __glibc_reserved4: c.ulong, } sembuf :: struct { From c1a67f37e62d5f928f47eb480c33f533d3160041 Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Sat, 21 Sep 2024 21:37:41 -0600 Subject: [PATCH 32/33] Fix O_Flag_Bits.EXEC for non Linux platforms on posix/fcntl. --- core/sys/posix/fcntl.odin | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/core/sys/posix/fcntl.odin b/core/sys/posix/fcntl.odin index 32c124168..be33739e4 100644 --- a/core/sys/posix/fcntl.odin +++ b/core/sys/posix/fcntl.odin @@ -181,9 +181,7 @@ when ODIN_OS == .Linux { // 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, + EXEC = log2(O_EXEC), // Reading and writing. RDWR = log2(O_RDWR), From 5cd1784d4186e2c2f562c815a7929b52b48e69c5 Mon Sep 17 00:00:00 2001 From: Laytan Date: Mon, 30 Sep 2024 16:00:46 +0200 Subject: [PATCH 33/33] review/correct/cleanup posix linux PR --- core/sys/linux/bits.odin | 95 ++++++-------- core/sys/posix/fcntl.odin | 205 ++++++++++--------------------- core/sys/posix/glob.odin | 5 +- core/sys/posix/langinfo.odin | 82 ++++++------- core/sys/posix/limits.odin | 30 ++--- core/sys/posix/netdb.odin | 2 +- core/sys/posix/netinet_in.odin | 8 +- core/sys/posix/poll.odin | 8 +- core/sys/posix/posix.odin | 4 +- core/sys/posix/pthread.odin | 9 +- core/sys/posix/signal.odin | 96 ++++++++------- core/sys/posix/sys_ipc.odin | 28 ++++- core/sys/posix/sys_mman.odin | 6 +- core/sys/posix/sys_resource.odin | 7 +- core/sys/posix/sys_socket.odin | 12 +- 15 files changed, 265 insertions(+), 332 deletions(-) diff --git a/core/sys/linux/bits.odin b/core/sys/linux/bits.odin index f78891bc8..12b10e806 100644 --- a/core/sys/linux/bits.odin +++ b/core/sys/linux/bits.odin @@ -152,66 +152,43 @@ Errno :: enum i32 { RDONLY flag is not present, because it has the value of 0, i.e. it is the default, unless WRONLY or RDWR is specified. */ -when ODIN_ARCH != .arm64 && ODIN_ARCH != .arm32 { - Open_Flags_Bits :: enum { - WRONLY = 0, - RDWR = 1, - CREAT = 6, - EXCL = 7, - NOCTTY = 8, - TRUNC = 9, - APPEND = 10, - NONBLOCK = 11, - DSYNC = 12, - ASYNC = 13, - DIRECT = 14, - LARGEFILE = 15, - DIRECTORY = 16, - NOFOLLOW = 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) - -} 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, - } +Open_Flags_Bits :: enum { + WRONLY = 0, + RDWR = 1, + CREAT = 6, + EXCL = 7, + NOCTTY = 8, + TRUNC = 9, + APPEND = 10, + NONBLOCK = 11, + DSYNC = 12, + ASYNC = 13, + DIRECT = 14, + LARGEFILE = 15, + DIRECTORY = 16, + NOFOLLOW = 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 diff --git a/core/sys/posix/fcntl.odin b/core/sys/posix/fcntl.odin index be33739e4..1ccc07c54 100644 --- a/core/sys/posix/fcntl.odin +++ b/core/sys/posix/fcntl.odin @@ -92,120 +92,52 @@ Lock_Type :: enum c.short { WRLCK = F_WRLCK, } -// Assertions made to unify this bit set. -#assert(O_RDONLY == 0) +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), -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 { - // 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), + // 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_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, + // 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, - // 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. - // 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] + // Execute only. + EXEC = log2(O_EXEC), + // Reading and writing. + RDWR = log2(O_RDWR), + // Writing only. + WRONLY = log2(O_WRONLY), + // Reading only. + // RDONLY = 0, // Default } -// A mask of all the access mode bits. -when ODIN_OS == .Linux { +O_Flags :: bit_set[O_Flag_Bits; c.int] - // NOTE: .EXEC and .RDONLY also belong here, but they are 0 on some platforms. - 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 } - -} +O_ACCMODE :: O_Flags{ .EXEC, .RDWR, .WRONLY } AT_Flag_Bits :: enum c.int { EACCESS = log2(AT_EACCESS), @@ -265,7 +197,7 @@ when ODIN_OS == .Darwin { _O_SEARCH :: O_EXEC | O_DIRECTORY O_SEARCH :: O_Flags{.EXEC, .DIRECTORY} - AT_FDCWD: FD : -2 + AT_FDCWD: FD: -2 AT_EACCESS :: 0x0010 AT_SYMLINK_NOFOLLOW :: 0x0020 @@ -329,7 +261,7 @@ when ODIN_OS == .Darwin { _O_SEARCH :: O_EXEC O_SEARCH :: O_Flags{ .EXEC } - AT_FDCWD: FD : -100 + AT_FDCWD: FD: -100 AT_EACCESS :: 0x0100 AT_SYMLINK_NOFOLLOW :: 0x0200 @@ -396,7 +328,7 @@ when ODIN_OS == .Darwin { _O_SEARCH :: 0x00800000 O_SEARCH :: O_Flags{O_Flag_Bits(log2(_O_SEARCH))} - AT_FDCWD: FD : -100 + AT_FDCWD: FD: -100 AT_EACCESS :: 0x100 AT_SYMLINK_NOFOLLOW :: 0x200 @@ -460,7 +392,7 @@ when ODIN_OS == .Darwin { _O_SEARCH :: 0 O_SEARCH :: O_Flags{} // NOTE: not defined in the headers - AT_FDCWD: FD : -100 + AT_FDCWD: FD: -100 AT_EACCESS :: 0x01 AT_SYMLINK_NOFOLLOW :: 0x02 @@ -480,21 +412,21 @@ when ODIN_OS == .Darwin { off_t :: distinct c.int64_t pid_t :: distinct c.int - F_DUPFD :: 0 // Duplicate file descriptor. - F_GETFD :: 1 /* Get file descriptor flags. */ - F_SETFD :: 2 /* Set file descriptor flags. */ - F_GETFL :: 3 /* Get file status flags. */ - F_SETFL :: 4 /* Set file status flags. */ - F_GETLK :: 5 /* Get record locking info. */ - F_SETLK :: 6 /* Set record locking info (non-blocking). */ - F_SETLKW :: 7 /* Set record locking info (blocking). */ - F_SETOWN :: 8 /* Get owner (process receiving SIGIO). */ - F_GETOWN :: 9 /* Set owner (process receiving SIGIO). */ - F_RDLCK :: 0 /* Read lock. */ - F_UNLCK :: 2 /* Remove lock. */ - F_WRLCK :: 1 /* Write lock. */ + F_DUPFD :: 0 + F_GETFD :: 1 + F_SETFD :: 2 + F_GETFL :: 3 + F_SETFL :: 4 + F_GETLK :: 5 + F_SETLK :: 6 + F_SETLKW :: 7 + F_SETOWN :: 8 + F_GETOWN :: 9 + F_RDLCK :: 0 + F_UNLCK :: 2 + F_WRLCK :: 1 - F_DUPFD_CLOEXEC :: 1030 /* Duplicate file descriptor with close-on-exit set. */ + F_DUPFD_CLOEXEC :: 1030 FD_CLOEXEC :: 1 @@ -517,8 +449,7 @@ when ODIN_OS == .Darwin { _O_RSYNC :: 0 O_RSYNC :: O_Flags{} - // NOTE: Not implemented in Linux - O_EXEC :: 0 + O_EXEC :: 0x04000000 // NOTE: not defined in the headers O_RDONLY :: 0 O_WRONLY :: 0o1 @@ -527,19 +458,19 @@ when ODIN_OS == .Darwin { _O_SEARCH :: 0 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_SYMLINK_NOFOLLOW :: 0x100 // Do not follow symbolic links. - AT_SYMLINK_FOLLOW :: 0x400 // Follow symbolic links. - AT_REMOVEDIR :: 0x200 // Remove directory instead of unlinking file. + AT_EACCESS :: 0x200 + AT_SYMLINK_NOFOLLOW :: 0x100 + AT_SYMLINK_FOLLOW :: 0x400 + AT_REMOVEDIR :: 0x200 flock :: struct { - l_start: off_t, // [PSX] relative offset in bytes. - 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_type: Lock_Type, // [PSX] type of lock. - l_whence: c.short, // [PSX] flag (Whence) of starting offset. + l_start: off_t, /* [PSX] relative offset in bytes. */ + 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_type: Lock_Type, /* [PSX] type of lock. */ + l_whence: c.short, /* [PSX] flag (Whence) of starting offset. */ } } else { diff --git a/core/sys/posix/glob.odin b/core/sys/posix/glob.odin index b09104900..c17f8b2c3 100644 --- a/core/sys/posix/glob.odin +++ b/core/sys/posix/glob.odin @@ -178,15 +178,12 @@ when ODIN_OS == .Darwin { glob_t :: struct { 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_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: - gl_errfunc: proc "c" (cstring, c.int) -> c.int, - gl_closedir: proc "c" (dirp: DIR), gl_readdir: proc "c" (dirp: DIR) -> ^dirent, gl_opendir: proc "c" (path: cstring) -> DIR, diff --git a/core/sys/posix/langinfo.odin b/core/sys/posix/langinfo.odin index 7f521e3a4..04b46921c 100644 --- a/core/sys/posix/langinfo.odin +++ b/core/sys/posix/langinfo.odin @@ -301,58 +301,58 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD { DAY_1 :: 0x20_007 DAY_2 :: 0x20_008 DAY_3 :: 0x20_009 - DAY_4 :: 0x20_010 - DAY_5 :: 0x20_011 - DAY_6 :: 0x20_012 - DAY_7 :: 0x20_013 + DAY_4 :: 0x20_00A + DAY_5 :: 0x20_00B + DAY_6 :: 0x20_00C + DAY_7 :: 0x20_00D - ABMON_1 :: 0x20_014 - ABMON_2 :: 0x20_015 - ABMON_3 :: 0x20_016 - ABMON_4 :: 0x20_017 - ABMON_5 :: 0x20_018 - ABMON_6 :: 0x20_019 - ABMON_7 :: 0x20_020 - ABMON_8 :: 0x20_021 - ABMON_9 :: 0x20_022 - ABMON_10 :: 0x20_023 - ABMON_11 :: 0x20_024 - ABMON_12 :: 0x20_025 + ABMON_1 :: 0x20_00E + ABMON_2 :: 0x20_010 + ABMON_3 :: 0x20_011 + ABMON_4 :: 0x20_012 + ABMON_5 :: 0x20_013 + ABMON_6 :: 0x20_014 + ABMON_7 :: 0x20_015 + ABMON_8 :: 0x20_016 + ABMON_9 :: 0x20_017 + ABMON_10 :: 0x20_018 + ABMON_11 :: 0x20_019 + ABMON_12 :: 0x20_01A - MON_1 :: 0x20_026 - MON_2 :: 0x20_027 - MON_3 :: 0x20_028 - MON_4 :: 0x20_029 - MON_5 :: 0x20_030 - MON_6 :: 0x20_031 - MON_7 :: 0x20_032 - MON_8 :: 0x20_033 - MON_9 :: 0x20_034 - MON_10 :: 0x20_035 - MON_11 :: 0x20_036 - MON_12 :: 0x20_037 + MON_1 :: 0x20_01B + MON_2 :: 0x20_01C + MON_3 :: 0x20_01D + MON_4 :: 0x20_01E + MON_5 :: 0x20_020 + MON_6 :: 0x20_021 + MON_7 :: 0x20_022 + MON_8 :: 0x20_023 + MON_9 :: 0x20_024 + MON_10 :: 0x20_025 + MON_11 :: 0x20_026 + MON_12 :: 0x20_027 - AM_STR :: 0x20_038 - PM_STR :: 0x20_039 + AM_STR :: 0x20_028 + PM_STR :: 0x20_029 - D_T_FMT :: 0x20_040 - D_FMT :: 0x20_041 - T_FMT :: 0x20_042 - T_FMT_AMPM :: 0x20_043 + D_T_FMT :: 0x20_02A + D_FMT :: 0x20_02B + T_FMT :: 0x20_02C + T_FMT_AMPM :: 0x20_02D - ERA :: 0x20_044 - ERA_D_FMT :: 0x20_045 - ALT_DIGITS :: 0x20_046 - ERA_D_T_FMT :: 0x20_047 - ERA_T_FMT :: 0x20_048 + ERA :: 0x20_02E + ERA_D_FMT :: 0x20_030 + ALT_DIGITS :: 0x20_031 + ERA_D_T_FMT :: 0x20_032 + ERA_T_FMT :: 0x20_033 // NOTE: CODESET is the 16th member of the enum group starting with value // LC_CTYPE << 16, LC_CTYPE is 0. - CODESET :: 0x15 + CODESET :: 0x0F // NOTE: CRNCYSTR is the 16th member of the enum group starting with value // 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 // LC_NUMERIC << 16, LC_NUMERIC is 1. diff --git a/core/sys/posix/limits.odin b/core/sys/posix/limits.odin index 81ede3368..58adce0a1 100644 --- a/core/sys/posix/limits.odin +++ b/core/sys/posix/limits.odin @@ -466,24 +466,24 @@ when ODIN_OS == .Darwin { // AIO_LISTIO_MAX :: sysconf(._AIO_LISTIO_MAX) // AIO_MAX :: sysconf(._AIO_MAX) - AIO_PRIO_DELTA_MAX :: 20 + // AIO_PRIO_DELTA_MAX :: sysconf(._AIO_PRIO_DELTA_MAX) ARG_MAX :: 131_072 // ATEXIT_MAX :: sysconf(._ATEXIT_MAX) // CHILD_MAX :: sysconf(._POSIX_ARG_MAX) - DELAYTIMER_MAX :: 2_147_483_647 - HOST_NAME_MAX :: 64 + // DELAYTIMER_MAX :: sysconf(._DELAYTIMER_MAX) + // HOST_NAME_MAX :: sysconf(._HOST_NAME_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_PRIO_MAX :: sysconf(._MQ_PRIO_MAX) // PAGESIZE :: PAGE_SIZE // PAGE_SIZE :: sysconf(._PAGE_SIZE) PTHREAD_DESTRUCTOR_ITERATIONS :: 4 - PTHREAD_KEYS_MAX :: 1024 - PTHREAD_STACK_MIN :: 16_384 - RTSIG_MAX :: 32 + // PTHREAD_KEYS_MAX :: sysconf(._PTHREAD_KEYS_MAX) + // PTHREAD_STACK_MIN :: sysconf(._PTHREAD_STACK_MIN) + // RTSIG_MAX :: sysconf(._RTSIG_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) // SS_REPL_MAX :: sysconf(._SS_REPL_MAX) // STREAM_MAX :: sysconf(._STREAM_MAX) @@ -493,7 +493,7 @@ when ODIN_OS == .Darwin { // TRACE_NAME_MAX :: sysconf(._TRACE_NAME_MAX) // TRACE_SYS_MAX :: sysconf(._TRACE_SYS_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) // 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_MIN_XFER_SIZE :: sysconf(._POSIX_REC_MIN_XFER_SIZE) // 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. @@ -536,17 +536,17 @@ when ODIN_OS == .Darwin { CHARCLASS_NAME_MAX :: 14 COLL_WEIGHTS_MAX :: 2 EXPR_NEST_MAX :: 32 - LINE_MAX :: 2048 - NGROUPS_MAX :: 65_536 + // LINE_MAX :: sysconf(._LINE_MAX) + // NGROUPS_MAX :: sysconf(._NGROUPS_MAX) RE_DUP_MAX :: 255 // Other limits. - + NL_ARGMAX :: 9 - NL_LANGMAX :: 14 + NL_LANGMAX :: 32 // 14 on glibc, 32 on musl NL_MSGMAX :: 32_767 NL_SETMAX :: 255 - NL_TEXTMAX :: 255 + NL_TEXTMAX :: 2048 // 255 on glibc, 2048 on musl NZERO :: 20 } else { diff --git a/core/sys/posix/netdb.odin b/core/sys/posix/netdb.odin index cd965e2a4..f31de2c2b 100644 --- a/core/sys/posix/netdb.odin +++ b/core/sys/posix/netdb.odin @@ -427,7 +427,7 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS NI_NUMERICHOST :: 1 NI_NAMEREQD :: 8 NI_NUMERICSERV :: 2 - NI_NUMERICSCOPE :: 0 // NOTE: not implemented + NI_NUMERICSCOPE :: 0x100 NI_DGRAM :: 16 } diff --git a/core/sys/posix/netinet_in.odin b/core/sys/posix/netinet_in.odin index d5121606b..22bfde9bc 100644 --- a/core/sys/posix/netinet_in.odin +++ b/core/sys/posix/netinet_in.odin @@ -45,20 +45,18 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS } when ODIN_OS == .Linux { + sockaddr_in :: struct { sin_family: sa_family_t, /* [PSX] AF_INET (but a smaller size) */ sin_port: in_port_t, /* [PSX] port number */ sin_addr: in_addr, /* [PSX] IP address */ - sin_zero: [size_of(sockaddr) - - u16 - - size_of(in_port_t) - - size_of(in_addr)]c.char, + sin_zero: [8]c.char, } sockaddr_in6 :: struct { sin6_family: sa_family_t, /* [PSX] AF_INET6 (but a smaller size) */ 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_scope_id: c.uint32_t, /* [PSX] set of interfaces for a scope */ } diff --git a/core/sys/posix/poll.odin b/core/sys/posix/poll.odin index 3d403d625..9e38afe12 100644 --- a/core/sys/posix/poll.odin +++ b/core/sys/posix/poll.odin @@ -21,17 +21,11 @@ foreign lib { [[ 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 -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 { // Data other than high-priority data may be read without blocking. IN = log2(POLLIN), diff --git a/core/sys/posix/posix.odin b/core/sys/posix/posix.odin index 5cb4122a6..44486e424 100644 --- a/core/sys/posix/posix.odin +++ b/core/sys/posix/posix.odin @@ -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, being fully replaced (and better) by other Odin packages, diff --git a/core/sys/posix/pthread.odin b/core/sys/posix/pthread.odin index aa7b50a6f..76acb1a3d 100644 --- a/core/sys/posix/pthread.odin +++ b/core/sys/posix/pthread.odin @@ -521,7 +521,7 @@ when ODIN_OS == .Darwin { PTHREAD_CANCEL_ENABLE :: 0 PTHREAD_CANCEL_DISABLE :: 1 - PTHREAD_CANCELED :: rawptr(uintptr(-1)) + PTHREAD_CANCELED :: rawptr(~uintptr(0)) PTHREAD_CREATE_JOINABLE :: 0 PTHREAD_CREATE_DETACHED :: 1 @@ -542,7 +542,7 @@ when ODIN_OS == .Darwin { pthread_t :: distinct c.ulong 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, } @@ -550,6 +550,11 @@ when ODIN_OS == .Darwin { sched_param :: struct { 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 { diff --git a/core/sys/posix/signal.odin b/core/sys/posix/signal.odin index 6748c162f..1e3f05104 100644 --- a/core/sys/posix/signal.odin +++ b/core/sys/posix/signal.odin @@ -220,16 +220,6 @@ foreign lib { const struct timespec *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 { @@ -490,11 +480,6 @@ when ODIN_OS == .Darwin { uid_t :: distinct c.uint32_t sigset_t :: distinct c.uint32_t - // NOTE: unimplemented on darwin. - // - // SIGRTMIN :: - // SIGRTMAX :: - SIGHUP :: 1 SIGQUIT :: 3 SIGTRAP :: 5 @@ -635,11 +620,6 @@ when ODIN_OS == .Darwin { __bits: [4]c.uint32_t, } - // NOTE: unimplemented on FreeBSD. - // - // SIGRTMIN :: 65 - // SIGRTMAX :: 126 - SIGHUP :: 1 SIGQUIT :: 3 SIGTRAP :: 5 @@ -804,11 +784,6 @@ when ODIN_OS == .Darwin { __bits: [4]c.uint32_t, } - // NOTE: unimplemented on NetBSD. - // - // SIGRTMIN :: 33 - // SIGRTMAX :: 63 - SIGHUP :: 1 SIGQUIT :: 3 SIGTRAP :: 5 @@ -1146,9 +1121,6 @@ when ODIN_OS == .Darwin { [1024/(8 * size_of(c.ulong))]val, } - SIGRTMIN :: __libc_current_sigrtmin() - SIGRTMAX :: __libc_current_sigrtmax() - SIGHUP :: 1 SIGQUIT :: 3 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 // `_t` has been added. + sigaction_t :: struct { - sa_handler: proc "c" (Signal), - sa_flags: SA_Flags, - sa_mask: sigset_t, + using _: struct #raw_union { + sa_handler: proc "c" (Signal), /* [PSX] signal-catching function or one of the SIG_IGN or SIG_DFL */ + 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 @@ -1195,8 +1172,13 @@ when ODIN_OS == .Darwin { SS_ONSTACK :: 1 SS_DISABLE :: 2 - MINSIGSTKSZ :: 2048 - SIGSTKSZ :: 8192 + when ODIN_ARCH == .arm64 { + MINSIGSTKSZ :: 6144 + SIGSTKSZ :: 12288 + } else { + MINSIGSTKSZ :: 2048 + SIGSTKSZ :: 8192 + } stack_t :: struct { ss_sp: rawptr, /* [PSX] stack base or pointer */ @@ -1204,9 +1186,27 @@ when ODIN_OS == .Darwin { ss_size: c.size_t, /* [PSX] stack size */ } - // WARNING: This implementaion might be completely wrong and need to be reviewed and corrected. - siginfo_t :: struct { + @(private) + __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_errno: Errno, /* [PSX] errno value associated with this signal */ si_code: struct #raw_union { /* [PSX] specific more detailed codes per signal */ ill: ILL_Code, fpe: FPE_Code, @@ -1217,13 +1217,25 @@ when ODIN_OS == .Darwin { poll: POLL_Code, any: Any_Code, }, - si_errno: Errno, /* [PSX] errno value associated with this signal */ - si_pid: pid_t, /* [PSX] sending process ID */ - si_uid: uid_t, /* [PSX] real user ID of sending process */ - si_addr: rawptr, /* [PSX] address of faulting instruction */ - si_status: c.int, /* [PSX] exit value or signal */ - si_band: c.long, /* [PSX] band event for SIGPOLL */ - si_value: sigval, /* [PSX] signal value */ + __pad0: _pad0, + using _sifields: struct #raw_union { + _pad: [__SI_PAD_SIZE]c.int, + + using _: struct { + si_pid: pid_t, /* [PSX] sending process ID */ + 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 diff --git a/core/sys/posix/sys_ipc.odin b/core/sys/posix/sys_ipc.odin index 0ba9d2d5d..33f8fa259 100644 --- a/core/sys/posix/sys_ipc.odin +++ b/core/sys/posix/sys_ipc.odin @@ -36,7 +36,7 @@ IPC_Flag_Bits :: enum 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 @@ -84,6 +84,32 @@ when ODIN_OS == .Darwin || ODIN_OS == .Linux { IPC_SET :: 1 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 { #panic("posix is unimplemented for the current target") } diff --git a/core/sys/posix/sys_mman.odin b/core/sys/posix/sys_mman.odin index d71a92639..2f4eb566b 100644 --- a/core/sys/posix/sys_mman.odin +++ b/core/sys/posix/sys_mman.odin @@ -191,11 +191,7 @@ when ODIN_OS == .Darwin || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS MCL_CURRENT :: 0x0001 MCL_FUTURE :: 0x0002 - when ODIN_OS == .Linux { - MAP_FAILED :: rawptr(~uintptr(-1)) - } else { - MAP_FAILED :: rawptr(~uintptr(0)) - } + MAP_FAILED :: rawptr(~uintptr(0)) POSIX_MADV_DONTNEED :: 4 POSIX_MADV_NORMAL :: 0 diff --git a/core/sys/posix/sys_resource.odin b/core/sys/posix/sys_resource.odin index ad944a7bb..55789ee95 100644 --- a/core/sys/posix/sys_resource.odin +++ b/core/sys/posix/sys_resource.odin @@ -103,7 +103,7 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS 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_CUR :: RLIM_INFINITY @@ -145,10 +145,13 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS RLIMIT_FSIZE :: 1 RLIMIT_NOFILE :: 7 when ODIN_OS == .Linux else 8 RLIMIT_STACK :: 3 + when ODIN_OS == .Linux { RLIMIT_AS :: 9 + } else when ODIN_OS == .Darwin || ODIN_OS == .OpenBSD { + RLIMIT_AS :: 5 } else { - RLIMIT_AS :: 5 when ODIN_OS == .Darwin || ODIN_OS == .OpenBSD else 10 + RLIMIT_AS :: 10 } } else { diff --git a/core/sys/posix/sys_socket.odin b/core/sys/posix/sys_socket.odin index 185bb7722..e613f0a10 100644 --- a/core/sys/posix/sys_socket.odin +++ b/core/sys/posix/sys_socket.odin @@ -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 == .Linux { - socklen_t :: distinct c.uint32_t - } else { - socklen_t :: distinct c.uint - } + socklen_t :: distinct c.uint _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(). - when ODIN_OS == .Linux { - SOMAXCONN :: 4096 - } else { - SOMAXCONN :: 128 - } + SOMAXCONN :: 128 when ODIN_OS == .Linux { MSG_CTRUNC :: 0x008