aboutsummaryrefslogtreecommitdiff
path: root/core/sys/linux
diff options
context:
space:
mode:
Diffstat (limited to 'core/sys/linux')
-rw-r--r--core/sys/linux/bits.odin44
-rw-r--r--core/sys/linux/constants.odin19
-rw-r--r--core/sys/linux/sys.odin3
-rw-r--r--core/sys/linux/types.odin6
-rw-r--r--core/sys/linux/wrappers.odin70
5 files changed, 102 insertions, 40 deletions
diff --git a/core/sys/linux/bits.odin b/core/sys/linux/bits.odin
index 4493ea767..d4edf354b 100644
--- a/core/sys/linux/bits.odin
+++ b/core/sys/linux/bits.odin
@@ -1,5 +1,10 @@
package linux
+import "base:intrinsics"
+
+@(private)
+log2 :: intrinsics.constant_log2
+
/*
Represents an error returned by most of syscalls
@@ -574,7 +579,7 @@ Inotify_Event_Bits :: enum u32 {
/*
Bits for Mem_Protection bitfield
*/
-Mem_Protection_Bits :: enum{
+Mem_Protection_Bits :: enum {
READ = 0,
WRITE = 1,
EXEC = 2,
@@ -589,11 +594,13 @@ Mem_Protection_Bits :: enum{
/*
Bits for Map_Flags
+
+ See `constants.odin` for `MAP_SHARED_VALIDATE` and `MAP_HUGE_16KB`, et al.
*/
Map_Flags_Bits :: enum {
SHARED = 0,
PRIVATE = 1,
- SHARED_VALIDATE = 2,
+ DROPPABLE = 3,
FIXED = 4,
ANONYMOUS = 5,
// platform-dependent section start
@@ -1839,22 +1846,23 @@ EPoll_Flags_Bits :: enum {
}
EPoll_Event_Kind :: enum u32 {
- IN = 0x001,
- PRI = 0x002,
- OUT = 0x004,
- RDNORM = 0x040,
- RDBAND = 0x080,
- WRNORM = 0x100,
- WRBAND = 0x200,
- MSG = 0x400,
- ERR = 0x008,
- HUP = 0x010,
- RDHUP = 0x2000,
- EXCLUSIVE = 1<<28,
- WAKEUP = 1<<29,
- ONESHOT = 1<<30,
- ET = 1<<31,
-}
+ IN = log2(0x001),
+ PRI = log2(0x002),
+ OUT = log2(0x004),
+ RDNORM = log2(0x040),
+ RDBAND = log2(0x080),
+ WRNORM = log2(0x100),
+ WRBAND = log2(0x200),
+ MSG = log2(0x400),
+ ERR = log2(0x008),
+ HUP = log2(0x010),
+ RDHUP = log2(0x2000),
+ EXCLUSIVE = log2(1<<28),
+ WAKEUP = log2(1<<29),
+ ONESHOT = log2(1<<30),
+ ET = log2(1<<31),
+}
+EPoll_Event_Set :: bit_set[EPoll_Event_Kind; u32]
EPoll_Ctl_Opcode :: enum i32 {
ADD = 1,
diff --git a/core/sys/linux/constants.odin b/core/sys/linux/constants.odin
index 3fba74b4c..ceab17f6d 100644
--- a/core/sys/linux/constants.odin
+++ b/core/sys/linux/constants.odin
@@ -374,5 +374,24 @@ PTRACE_SECCOMP_GET_METADATA :: PTrace_Seccomp_Get_Metadata_Type(.SECCOMP_GET_M
PTRACE_GET_SYSCALL_INFO :: PTrace_Get_Syscall_Info_Type(.GET_SYSCALL_INFO)
PTRACE_GET_RSEQ_CONFIGURATION :: PTrace_Get_RSeq_Configuration_Type(.GET_RSEQ_CONFIGURATION)
+MAP_SHARED_VALIDATE :: Map_Flags{.SHARED, .PRIVATE}
+
+MAP_HUGE_SHIFT :: 26
+MAP_HUGE_MASK :: 63
+
+MAP_HUGE_16KB :: transmute(Map_Flags)(u32(14) << MAP_HUGE_SHIFT)
+MAP_HUGE_64KB :: transmute(Map_Flags)(u32(16) << MAP_HUGE_SHIFT)
+MAP_HUGE_512KB :: transmute(Map_Flags)(u32(19) << MAP_HUGE_SHIFT)
+MAP_HUGE_1MB :: transmute(Map_Flags)(u32(20) << MAP_HUGE_SHIFT)
+MAP_HUGE_2MB :: transmute(Map_Flags)(u32(21) << MAP_HUGE_SHIFT)
+MAP_HUGE_8MB :: transmute(Map_Flags)(u32(23) << MAP_HUGE_SHIFT)
+MAP_HUGE_16MB :: transmute(Map_Flags)(u32(24) << MAP_HUGE_SHIFT)
+MAP_HUGE_32MB :: transmute(Map_Flags)(u32(25) << MAP_HUGE_SHIFT)
+MAP_HUGE_256MB :: transmute(Map_Flags)(u32(28) << MAP_HUGE_SHIFT)
+MAP_HUGE_512MB :: transmute(Map_Flags)(u32(29) << MAP_HUGE_SHIFT)
+MAP_HUGE_1GB :: transmute(Map_Flags)(u32(30) << MAP_HUGE_SHIFT)
+MAP_HUGE_2GB :: transmute(Map_Flags)(u32(31) << MAP_HUGE_SHIFT)
+MAP_HUGE_16GB :: transmute(Map_Flags)(u32(34) << MAP_HUGE_SHIFT)
+
/* Get window size */
TIOCGWINSZ :: 0x5413
diff --git a/core/sys/linux/sys.odin b/core/sys/linux/sys.odin
index 5fc4a0efa..deb22726f 100644
--- a/core/sys/linux/sys.odin
+++ b/core/sys/linux/sys.odin
@@ -1,3 +1,4 @@
+#+build linux
#+no-instrumentation
package linux
@@ -1412,7 +1413,7 @@ umask :: proc "contextless" (mask: Mode) -> Mode {
Available since Linux 1.0.
*/
gettimeofday :: proc "contextless" (tv: ^Time_Val) -> (Errno) {
- ret := syscall(SYS_gettimeofday, tv)
+ ret := syscall(SYS_gettimeofday, tv, rawptr(nil))
return Errno(-ret)
}
diff --git a/core/sys/linux/types.odin b/core/sys/linux/types.odin
index dcc72f72b..08e0026d3 100644
--- a/core/sys/linux/types.odin
+++ b/core/sys/linux/types.odin
@@ -288,7 +288,7 @@ Rename_Flags :: bit_set[Rename_Flags_Bits; u32]
/*
Directory entry record.
- Recommended iterate these with `dirent_iterator()`,
+ Recommended to iterate these with `dirent_iterate_buf()`,
and obtain the name via `dirent_name()`.
*/
Dirent :: struct {
@@ -368,6 +368,8 @@ Mem_Protection :: bit_set[Mem_Protection_Bits; i32]
/*
Flags for mmap.
+
+ See `constants.odin` for `MAP_SHARED_VALIDATE` and `MAP_HUGE_16KB`, et al.
*/
Map_Flags :: bit_set[Map_Flags_Bits; i32]
@@ -1450,7 +1452,7 @@ EPoll_Data :: struct #raw_union {
}
EPoll_Event :: struct #packed {
- events: EPoll_Event_Kind,
+ events: EPoll_Event_Set,
data: EPoll_Data,
}
diff --git a/core/sys/linux/wrappers.odin b/core/sys/linux/wrappers.odin
index ab1992a57..53eb80f86 100644
--- a/core/sys/linux/wrappers.odin
+++ b/core/sys/linux/wrappers.odin
@@ -54,22 +54,45 @@ WCOREDUMP :: #force_inline proc "contextless" (s: u32) -> bool {
// TODO: sigaddset etc
-/// Iterate the results of getdents
-/// Only iterates as much data as loaded in the buffer
-/// In case you need to iterate *all* files in a directory
-/// consider using dirent_get_iterate
-///
-/// Example of using dirent_iterate_buf
-/// // Get dirents into a buffer
-/// buf: [128]u8
-/// sys.getdents(dirfd, buf[:])
-/// // Print the names of the files
-/// for dir in sys.dirent_iterate_buf(buf[:], &offs) {
-/// name := sys.dirent_name(dir)
-/// fmt.println(name)
-/// }
-/// This function doesn't automatically make a request
-/// for the buffer to be refilled
+/*
+Iterate the results of `getdents()`.
+
+This procedure extracts a directory entry from `buf` at the offset `offs`.
+`offs` will be modified to store an offset to the possible next directory entry
+in `buf`. The procedure only iterates as much data as loaded in the buffer and
+does not automatically make a request for the buffer to be refilled.
+
+Inputs:
+- buf: A byte buffer with data from `getdents()`
+- offs: An offset to the next possible directory entry in `buf`
+
+Returns:
+- A pointer to a directory entry in `buf`, or `nil`
+- A bool value denoting if a valid directory entry is returned
+
+Example:
+
+ import "core:fmt"
+ import "core:sys/linux"
+
+ print_names :: proc(dirfd: linux.Fd) {
+ // Get dirents into a buffer.
+ buf: [128]u8
+ // Loop until there are no more entries.
+ for {
+ written, err := linux.getdents(dirfd, buf[:])
+ if err != .NONE || written == 0 {
+ break
+ }
+ // Print the names of the files.
+ offset : int
+ for dir in linux.dirent_iterate_buf(buf[:written], &offset) {
+ name := linux.dirent_name(dir)
+ fmt.println(name)
+ }
+ }
+ }
+*/
dirent_iterate_buf :: proc "contextless" (buf: []u8, offs: ^int) -> (d: ^Dirent, cont: bool) {
// Stopped iterating when there's no space left
if offs^ >= len(buf) {
@@ -82,8 +105,17 @@ dirent_iterate_buf :: proc "contextless" (buf: []u8, offs: ^int) -> (d: ^Dirent,
return dirent, true
}
-/// Obtain the name of dirent as a string
-/// The lifetime of the string is bound to the lifetime of the provided dirent structure
+/*
+Obtain the name of dirent as a string.
+
+The lifetime of the returned string is bound to the lifetime of the provided dirent structure.
+
+Inputs:
+- dirent: A directory entry
+
+Returns:
+- A name of the entry
+*/
dirent_name :: proc "contextless" (dirent: ^Dirent) -> string #no_bounds_check {
str := ([^]u8)(&dirent.name)
// Dirents are aligned to 8 bytes, so there is guaranteed to be a null
@@ -93,10 +125,10 @@ dirent_name :: proc "contextless" (dirent: ^Dirent) -> string #no_bounds_check {
trunc := min(str_size, 8)
str_size -= trunc
for _ in 0..<trunc {
- str_size += 1
if str[str_size] == 0 {
break
}
+ str_size += 1
}
return string(str[:str_size])
}