aboutsummaryrefslogtreecommitdiff
path: root/core/sys/linux
diff options
context:
space:
mode:
authorjason <jkercher43@gmail.com>2024-06-27 16:29:47 -0400
committerjason <jkercher43@gmail.com>2024-06-27 16:29:47 -0400
commitf22754fc9036cf3c0bb5707e000c5055607ba374 (patch)
tree7bcf66dc6cc15b8c777ec4b6185275b9f109aaed /core/sys/linux
parentaa27cd4b0b7876d028f66fdc92a4636eb9c1dc90 (diff)
sys/linux: fix some syscalls and types; add more to Sig_Action and Sig_Info; Pid int->i32
Diffstat (limited to 'core/sys/linux')
-rw-r--r--core/sys/linux/bits.odin115
-rw-r--r--core/sys/linux/sys.odin47
-rw-r--r--core/sys/linux/types.odin96
3 files changed, 182 insertions, 76 deletions
diff --git a/core/sys/linux/bits.odin b/core/sys/linux/bits.odin
index cfae06013..bf7ab4fae 100644
--- a/core/sys/linux/bits.odin
+++ b/core/sys/linux/bits.odin
@@ -150,44 +150,66 @@ 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.
*/
-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)
+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,
+ }
+}
/*
Bits for FD_Flags bitset
@@ -867,7 +889,7 @@ Wait_Option :: enum {
WSTOPPED = 1,
WEXITED = 2,
WCONTINUED = 3,
- WNOWAIT = 24,
+ WNOWAIT = 24,
// // For processes created using clone
__WNOTHREAD = 29,
__WALL = 30,
@@ -946,9 +968,22 @@ Sig_Stack_Flag :: enum i32 {
AUTODISARM = 31,
}
+Sig_Action_Flag :: enum u32 {
+ NOCLDSTOP = 0,
+ NOCLDWAIT = 1,
+ SIGINFO = 2,
+ UNSUPPORTED = 10,
+ EXPOSE_TAGBITS = 11,
+ RESTORER = 26,
+ ONSTACK = 27,
+ RESTART = 28,
+ NODEFER = 30,
+ RESETHAND = 31,
+}
+
/*
Type of socket to create
- - For TCP you want to use SOCK_STREAM
+ - For TCP you want to use SOCK_STREAM
- For UDP you want to use SOCK_DGRAM
Also see `Protocol`
*/
diff --git a/core/sys/linux/sys.odin b/core/sys/linux/sys.odin
index 171829cde..ed40719bf 100644
--- a/core/sys/linux/sys.odin
+++ b/core/sys/linux/sys.odin
@@ -69,7 +69,7 @@ close :: proc "contextless" (fd: Fd) -> (Errno) {
stat :: proc "contextless" (filename: cstring, stat: ^Stat) -> (Errno) {
when size_of(int) == 8 {
when ODIN_ARCH == .arm64 {
- ret := syscall(SYS_fstatat, AT_FDCWD, cast(rawptr) filename, stat)
+ ret := syscall(SYS_fstatat, AT_FDCWD, cast(rawptr) filename, stat, 0)
return Errno(-ret)
} else {
ret := syscall(SYS_stat, cast(rawptr) filename, stat)
@@ -201,9 +201,24 @@ brk :: proc "contextless" (addr: uintptr) -> (Errno) {
}
/*
+ Returns from signal handlers on some archs.
+*/
+rt_sigreturn :: proc "c" () -> ! {
+ intrinsics.syscall(uintptr(SYS_rt_sigreturn))
+ unreachable()
+}
+
+/*
Alter an action taken by a process.
*/
-rt_sigaction :: proc "contextless" (sig: Signal, sigaction: ^Sig_Action, old_sigaction: ^Sig_Action) -> Errno {
+rt_sigaction :: proc "contextless" (sig: Signal, sigaction: ^Sig_Action($T), old_sigaction: ^Sig_Action) -> Errno {
+ // NOTE(jason): It appears that the restorer is required for i386 and amd64
+ when ODIN_ARCH == .i386 || ODIN_ARCH == .amd64 {
+ sigaction.flags += {.RESTORER}
+ }
+ if sigaction != nil && sigaction.restorer == nil && .RESTORER in sigaction.flags {
+ sigaction.restorer = rt_sigreturn
+ }
ret := syscall(SYS_rt_sigaction, sig, sigaction, old_sigaction, size_of(Sig_Set))
return Errno(-ret)
}
@@ -1123,7 +1138,7 @@ ftruncate :: proc "contextless" (fd: Fd, length: i64) -> (Errno) {
ret := syscall(SYS_ftruncate64, fd, compat64_arg_pair(length))
return Errno(-ret)
} else {
- ret := syscall(SYS_truncate, fd, compat64_arg_pair(length))
+ ret := syscall(SYS_ftruncate, fd, compat64_arg_pair(length))
return Errno(-ret)
}
}
@@ -1231,7 +1246,7 @@ creat :: proc "contextless" (name: cstring, mode: Mode) -> (Fd, Errno) {
*/
link :: proc "contextless" (target: cstring, linkpath: cstring) -> (Errno) {
when ODIN_ARCH == .arm64 {
- ret := syscall(SYS_linkat, AT_FDCWD, cast(rawptr) target, AT_FDCWD, cast(rawptr) linkpath)
+ ret := syscall(SYS_linkat, AT_FDCWD, cast(rawptr) target, AT_FDCWD, cast(rawptr) linkpath, 0)
return Errno(-ret)
} else {
ret := syscall(SYS_link, cast(rawptr) target, cast(rawptr) linkpath)
@@ -1261,7 +1276,7 @@ unlink :: proc "contextless" (name: cstring) -> (Errno) {
*/
symlink :: proc "contextless" (target: cstring, linkpath: cstring) -> (Errno) {
when ODIN_ARCH == .arm64 {
- ret := syscall(SYS_symlinkat, AT_FDCWD, cast(rawptr) target, cast(rawptr) linkpath)
+ ret := syscall(SYS_symlinkat, cast(rawptr) target, AT_FDCWD, cast(rawptr) linkpath)
return Errno(-ret)
} else {
ret := syscall(SYS_symlink, cast(rawptr) target, cast(rawptr) linkpath)
@@ -1291,7 +1306,7 @@ readlink :: proc "contextless" (name: cstring, buf: []u8) -> (int, Errno) {
*/
chmod :: proc "contextless" (name: cstring, mode: Mode) -> (Errno) {
when ODIN_ARCH == .arm64 {
- ret := syscall(SYS_fchmodat, cast(rawptr) name, transmute(u32) mode, 0)
+ ret := syscall(SYS_fchmodat, AT_FDCWD, cast(rawptr) name, transmute(u32) mode)
return Errno(-ret)
} else {
ret := syscall(SYS_chmod, cast(rawptr) name, transmute(u32) mode)
@@ -2476,8 +2491,8 @@ tgkill :: proc "contextless" (tgid, tid: Pid, sig: Signal) -> (Errno) {
Wait on process, process group or pid file descriptor.
Available since Linux 2.6.10.
*/
-waitid :: proc "contextless" (id_type: Id_Type, id: Id, sig_info: ^Sig_Info, options: Wait_Options) -> (Errno) {
- ret := syscall(SYS_waitid, id_type, id, sig_info, transmute(i32) options)
+waitid :: proc "contextless" (id_type: Id_Type, id: Id, sig_info: ^Sig_Info, options: Wait_Options, rusage: ^RUsage) -> (Errno) {
+ ret := syscall(SYS_waitid, id_type, id, sig_info, transmute(i32) options, rusage)
return Errno(-ret)
}
@@ -2504,7 +2519,7 @@ waitid :: proc "contextless" (id_type: Id_Type, id: Id, sig_info: ^Sig_Info, opt
Available since Linux 2.6.16.
*/
openat :: proc "contextless" (fd: Fd, name: cstring, flags: Open_Flags, mode: Mode = {}) -> (Fd, Errno) {
- ret := syscall(SYS_openat, fd, AT_FDCWD, transmute(uintptr) name, transmute(u32) mode)
+ ret := syscall(SYS_openat, fd, transmute(uintptr) name, transmute(u32) flags, transmute(u32) mode)
return errno_unwrap(ret, Fd)
}
@@ -2583,8 +2598,8 @@ linkat :: proc "contextless" (target_dirfd: Fd, oldpath: cstring, link_dirfd: Fd
Create a symbolic link at specified dirfd.
Available since Linux 2.6.16.
*/
-symlinkat :: proc "contextless" (dirfd: Fd, target: cstring, linkpath: cstring) -> (Errno) {
- ret := syscall(SYS_symlinkat, dirfd, cast(rawptr) target, cast(rawptr) linkpath)
+symlinkat :: proc "contextless" (target: cstring, dirfd: Fd, linkpath: cstring) -> (Errno) {
+ ret := syscall(SYS_symlinkat, cast(rawptr) target, dirfd, cast(rawptr) linkpath)
return Errno(-ret)
}
@@ -2619,13 +2634,13 @@ faccessat :: proc "contextless" (dirfd: Fd, name: cstring, mode: Mode = F_OK) ->
Wait for events on a file descriptor.
Available since Linux 2.6.16.
*/
-ppoll :: proc "contextless" (fds: []Poll_Fd, timeout: ^Time_Spec, sigmask: ^Sig_Set) -> (Errno) {
+ppoll :: proc "contextless" (fds: []Poll_Fd, timeout: ^Time_Spec, sigmask: ^Sig_Set) -> (i32, Errno) {
when size_of(int) == 8 {
ret := syscall(SYS_ppoll, raw_data(fds), len(fds), timeout, sigmask, size_of(Sig_Set))
- return Errno(-ret)
+ return errno_unwrap(ret, i32)
} else {
ret := syscall(SYS_ppoll_time64, raw_data(fds), len(fds), timeout, sigmask, size_of(Sig_Set))
- return Errno(-ret)
+ return errno_unwrap(ret, i32)
}
}
@@ -2808,8 +2823,8 @@ getrandom :: proc "contextless" (buf: []u8, flags: Get_Random_Flags) -> (int, Er
Execute program relative to a directory file descriptor.
Available since Linux 3.19.
*/
-execveat :: proc "contextless" (dirfd: Fd, name: cstring, argv: [^]cstring, envp: [^]cstring) -> (Errno) {
- ret := syscall(SYS_execveat, dirfd, cast(rawptr) name, cast(rawptr) argv, cast(rawptr) envp)
+execveat :: proc "contextless" (dirfd: Fd, name: cstring, argv: [^]cstring, envp: [^]cstring, flags: FD_Flags = {}) -> (Errno) {
+ ret := syscall(SYS_execveat, dirfd, cast(rawptr) name, cast(rawptr) argv, cast(rawptr) envp, transmute(i32) flags)
return Errno(-ret)
}
diff --git a/core/sys/linux/types.odin b/core/sys/linux/types.odin
index 5053e1e1c..e3fe67a9b 100644
--- a/core/sys/linux/types.odin
+++ b/core/sys/linux/types.odin
@@ -18,7 +18,7 @@ Gid :: distinct u32
/*
Type for Process IDs, Thread IDs, Thread group ID.
*/
-Pid :: distinct int
+Pid :: distinct i32
/*
Type for any of: pid, pidfd, pgid.
@@ -89,11 +89,11 @@ FD_Flags :: bit_set[FD_Flags_Bits; i32]
Represents file's permission and status bits
**Example:**
When you're passing a value of this type the recommended usage is:
-
+
```
linux.Mode{.S_IXOTH, .S_IROTH} | linux.S_IRWXU | linux.S_IRWXG
```
-
+
This would generate a mode that has full permissions for the
file's owner and group, and only "read" and "execute" bits
for others.
@@ -151,9 +151,9 @@ when ODIN_ARCH == .amd64 {
size: i64,
blksize: uint,
blocks: u64,
- atim: Time_Spec,
- mtim: Time_Spec,
- ctim: Time_Spec,
+ atime: Time_Spec,
+ mtime: Time_Spec,
+ ctime: Time_Spec,
ino: Inode,
}
}
@@ -495,16 +495,15 @@ Pid_FD_Flags :: bit_set[Pid_FD_Flags_Bits; i32]
// 1. Odin's bitfields start from 0, whereas signals start from 1
// 2. It's unclear how bitfields act in terms of ABI (are they an array of ints or an array of longs?).
// it makes a difference because ARM is big endian.
-@private _SIGSET_NWORDS :: (1024 / (8 * size_of(uint)))
+@private _SIGSET_NWORDS :: (8 / size_of(uint))
Sig_Set :: [_SIGSET_NWORDS]uint
@private SI_MAX_SIZE :: 128
-@private SI_ARCH_PREAMBLE :: 3 * size_of(i32)
-@private SI_PAD_SIZE :: (SI_MAX_SIZE - SI_ARCH_PREAMBLE) / size_of(i32)
-@private SI_TIMER_PAD_SIZE :: size_of(Uid) - size_of(i32)
+@private SI_ARCH_PREAMBLE :: 4 * size_of(i32)
+@private SI_PAD_SIZE :: SI_MAX_SIZE - SI_ARCH_PREAMBLE
Sig_Handler_Fn :: #type proc "c" (sig: Signal)
-Sig_Restore_Fn :: #type proc "c" ()
+Sig_Restore_Fn :: #type proc "c" () -> !
Sig_Info :: struct #packed {
signo: Signal,
@@ -518,8 +517,9 @@ Sig_Info :: struct #packed {
uid: Uid, /* sender's uid */
},
using _timer: struct {
- timerid: i32, /* timer id */
+ timerid: i32, /* timer id */
overrun: i32, /* overrun count */
+ value: Sig_Val, /* timer value */
},
/* POSIX.1b signals */
using _rt: struct {
@@ -528,8 +528,8 @@ Sig_Info :: struct #packed {
},
/* SIGCHLD */
using _sigchld: struct {
- _pid1: Pid, /* which child */
- _uid1: Uid, /* sender's uid */
+ _pid1: Pid, /* which child */
+ _uid1: Uid, /* sender's uid */
status: i32, /* exit code */
utime: uint,
stime: uint, //clock_t
@@ -537,7 +537,24 @@ Sig_Info :: struct #packed {
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
using _sigfault: struct {
addr: rawptr, /* faulting insn/memory ref. */
- addr_lsb: i16, /* LSB of the reported address */
+ using _: struct #raw_union {
+ trapno: i32, /* Trap number that caused signal */
+ addr_lsb: i16, /* LSB of the reported address */
+ using _addr_bnd: struct {
+ _pad2: u64,
+ lower: rawptr, /* lower bound during fault */
+ upper: rawptr, /* upper bound during fault */
+ },
+ using _addr_pkey: struct {
+ _pad3: u64,
+ pkey: u32, /* protection key on PTE that faulted */
+ },
+ using _perf: struct {
+ perf_data: u64,
+ perf_type: u32,
+ perf_flags: u32,
+ },
+ },
},
/* SIGPOLL */
using _sigpoll: struct {
@@ -547,12 +564,43 @@ Sig_Info :: struct #packed {
/* SIGSYS */
using _sigsys: struct {
call_addr: rawptr, /* calling user insn */
- syscall: i32, /* triggering system call number */
- arch: u32, /* AUDIT_ARCH_* of syscall */
+ syscall: i32, /* triggering system call number */
+ arch: u32, /* AUDIT_ARCH_* of syscall */
},
},
}
+#assert(size_of(Sig_Info) == 128)
+when ODIN_ARCH == .amd64 || ODIN_ARCH == .arm64 {
+ #assert(offset_of(Sig_Info, signo) == 0x00)
+ #assert(offset_of(Sig_Info, errno) == 0x04)
+ #assert(offset_of(Sig_Info, code) == 0x08)
+ #assert(offset_of(Sig_Info, pid) == 0x10)
+ #assert(offset_of(Sig_Info, uid) == 0x14)
+ #assert(offset_of(Sig_Info, timerid) == 0x10)
+ #assert(offset_of(Sig_Info, overrun) == 0x14)
+ #assert(offset_of(Sig_Info, value) == 0x18)
+ #assert(offset_of(Sig_Info, status) == 0x18)
+ #assert(offset_of(Sig_Info, utime) == 0x20)
+ #assert(offset_of(Sig_Info, stime) == 0x28)
+ #assert(offset_of(Sig_Info, addr) == 0x10)
+ #assert(offset_of(Sig_Info, addr_lsb) == 0x18)
+ #assert(offset_of(Sig_Info, trapno) == 0x18)
+ #assert(offset_of(Sig_Info, lower) == 0x20)
+ #assert(offset_of(Sig_Info, upper) == 0x28)
+ #assert(offset_of(Sig_Info, pkey) == 0x20)
+ #assert(offset_of(Sig_Info, perf_data) == 0x18)
+ #assert(offset_of(Sig_Info, perf_type) == 0x20)
+ #assert(offset_of(Sig_Info, perf_flags) == 0x24)
+ #assert(offset_of(Sig_Info, band) == 0x10)
+ #assert(offset_of(Sig_Info, fd) == 0x18)
+ #assert(offset_of(Sig_Info, call_addr) == 0x10)
+ #assert(offset_of(Sig_Info, syscall) == 0x18)
+ #assert(offset_of(Sig_Info, arch) == 0x1C)
+} else {
+ // TODO
+}
+
SIGEV_MAX_SIZE :: 64
SIGEV_PAD_SIZE :: ((SIGEV_MAX_SIZE-size_of(i32)*2+size_of(Sig_Val))/size_of(i32))
@@ -583,12 +631,20 @@ Sig_Stack :: struct {
size: uintptr,
}
+Sig_Action_Special :: enum uint {
+ SIG_DFL = 0,
+ SIG_IGN = 1,
+ SIG_ERR = ~uint(0),
+}
+
+Sig_Action_Flags :: bit_set[Sig_Action_Flag; uint]
Sig_Action :: struct($T: typeid) {
using _u: struct #raw_union {
handler: Sig_Handler_Fn,
sigaction: #type proc "c" (sig: Signal, si: ^Sig_Info, ctx: ^T),
+ special: Sig_Action_Special,
},
- flags: uint,
+ flags: Sig_Action_Flags,
restorer: Sig_Restore_Fn,
mask: Sig_Set,
}
@@ -733,7 +789,7 @@ RLimit :: struct {
/*
Structure representing how much of each resource got used.
-*/
+*/
RUsage :: struct {
utime: Time_Val,
stime: Time_Val,
@@ -813,7 +869,7 @@ when size_of(int) == 8 || ODIN_ARCH == .i386 {
cpid: Pid,
lpid: Pid,
nattach: uint,
- _: [2]uint,
+ _: [2]uint,
}
}