mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-11 22:01:25 -07:00
Merge branch 'master' into tiocgwinsz_time
This commit is contained in:
+25
-17
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
|
||||
@@ -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])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user