mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 15:18:49 +00:00
Merge pull request #4427 from laytan/posix-additions
Finish sys/posix with Linux and partial Windows support & clean up other packages as a result
This commit is contained in:
@@ -14,7 +14,7 @@ The following is a mostly-complete projection of the C11 standard library as def
|
|||||||
| `<inttypes.h>` | Fully projected |
|
| `<inttypes.h>` | Fully projected |
|
||||||
| `<iso646.h>` | Not applicable, use Odin's operators |
|
| `<iso646.h>` | Not applicable, use Odin's operators |
|
||||||
| `<limits.h>` | Not projected |
|
| `<limits.h>` | Not projected |
|
||||||
| `<locale.h>` | Not projected |
|
| `<locale.h>` | Fully projected |
|
||||||
| `<math.h>` | Mostly projected, see [limitations](#Limitations) |
|
| `<math.h>` | Mostly projected, see [limitations](#Limitations) |
|
||||||
| `<setjmp.h>` | Fully projected |
|
| `<setjmp.h>` | Fully projected |
|
||||||
| `<signal.h>` | Fully projected |
|
| `<signal.h>` | Fully projected |
|
||||||
@@ -70,4 +70,4 @@ with the following copyright.
|
|||||||
|
|
||||||
```
|
```
|
||||||
Copyright 2021 Dale Weiler <weilercdale@gmail.com>.
|
Copyright 2021 Dale Weiler <weilercdale@gmail.com>.
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -0,0 +1,133 @@
|
|||||||
|
package libc
|
||||||
|
|
||||||
|
import "core:c"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import libc "system:libucrt.lib"
|
||||||
|
} else when ODIN_OS == .Darwin {
|
||||||
|
foreign import libc "system:System.framework"
|
||||||
|
} else {
|
||||||
|
foreign import libc "system:c"
|
||||||
|
}
|
||||||
|
|
||||||
|
// locale.h - category macros
|
||||||
|
|
||||||
|
foreign libc {
|
||||||
|
/*
|
||||||
|
Sets the components of an object with the type lconv with the values appropriate for the
|
||||||
|
formatting of numeric quantities (monetary and otherwise) according to the rules of the current
|
||||||
|
locale.
|
||||||
|
|
||||||
|
Returns: a pointer to the lconv structure, might be invalidated by subsequent calls to localeconv() and setlocale()
|
||||||
|
|
||||||
|
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/localeconv.html ]]
|
||||||
|
*/
|
||||||
|
localeconv :: proc() -> ^lconv ---
|
||||||
|
|
||||||
|
/*
|
||||||
|
Selects the appropriate piece of the global locale, as specified by the category and locale arguments,
|
||||||
|
and can be used to change or query the entire global locale or portions thereof.
|
||||||
|
|
||||||
|
Returns: the current locale if `locale` is `nil`, the set locale otherwise
|
||||||
|
|
||||||
|
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/setlocale.html ]]
|
||||||
|
*/
|
||||||
|
@(link_name=LSETLOCALE)
|
||||||
|
setlocale :: proc(category: Locale_Category, locale: cstring) -> cstring ---
|
||||||
|
}
|
||||||
|
|
||||||
|
Locale_Category :: enum c.int {
|
||||||
|
ALL = LC_ALL,
|
||||||
|
COLLATE = LC_COLLATE,
|
||||||
|
CTYPE = LC_CTYPE,
|
||||||
|
MESSAGES = LC_MESSAGES,
|
||||||
|
MONETARY = LC_MONETARY,
|
||||||
|
NUMERIC = LC_NUMERIC,
|
||||||
|
TIME = LC_TIME,
|
||||||
|
}
|
||||||
|
|
||||||
|
when ODIN_OS == .NetBSD {
|
||||||
|
@(private) LSETLOCALE :: "__setlocale50"
|
||||||
|
} else {
|
||||||
|
@(private) LSETLOCALE :: "setlocale"
|
||||||
|
}
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
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,
|
||||||
|
_W_decimal_point: [^]u16 `fmt:"s,0"`,
|
||||||
|
_W_thousands_sep: [^]u16 `fmt:"s,0"`,
|
||||||
|
_W_int_curr_symbol: [^]u16 `fmt:"s,0"`,
|
||||||
|
_W_currency_symbol: [^]u16 `fmt:"s,0"`,
|
||||||
|
_W_mon_decimal_point: [^]u16 `fmt:"s,0"`,
|
||||||
|
_W_mon_thousands_sep: [^]u16 `fmt:"s,0"`,
|
||||||
|
_W_positive_sign: [^]u16 `fmt:"s,0"`,
|
||||||
|
_W_negative_sign: [^]u16 `fmt:"s,0"`,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Windows {
|
||||||
|
|
||||||
|
LC_ALL :: 0
|
||||||
|
LC_COLLATE :: 1
|
||||||
|
LC_CTYPE :: 2
|
||||||
|
LC_MESSAGES :: 6
|
||||||
|
LC_MONETARY :: 3
|
||||||
|
LC_NUMERIC :: 4
|
||||||
|
LC_TIME :: 5
|
||||||
|
|
||||||
|
} else when ODIN_OS == .Linux {
|
||||||
|
|
||||||
|
LC_CTYPE :: 0
|
||||||
|
LC_NUMERIC :: 1
|
||||||
|
LC_TIME :: 2
|
||||||
|
LC_COLLATE :: 3
|
||||||
|
LC_MONETARY :: 4
|
||||||
|
LC_MESSAGES :: 5
|
||||||
|
LC_ALL :: 6
|
||||||
|
|
||||||
|
}
|
||||||
@@ -37,8 +37,8 @@ Example:
|
|||||||
fmt.println("The library %q was successfully loaded", LIBRARY_PATH)
|
fmt.println("The library %q was successfully loaded", LIBRARY_PATH)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
load_library :: proc(path: string, global_symbols := false) -> (library: Library, did_load: bool) {
|
load_library :: proc(path: string, global_symbols := false, allocator := context.temp_allocator) -> (library: Library, did_load: bool) {
|
||||||
return _load_library(path, global_symbols)
|
return _load_library(path, global_symbols, allocator)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -98,8 +98,8 @@ Example:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
symbol_address :: proc(library: Library, symbol: string) -> (ptr: rawptr, found: bool) #optional_ok {
|
symbol_address :: proc(library: Library, symbol: string, allocator := context.temp_allocator) -> (ptr: rawptr, found: bool) #optional_ok {
|
||||||
return _symbol_address(library, symbol)
|
return _symbol_address(library, symbol, allocator)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -174,4 +174,4 @@ initialize_symbols :: proc(
|
|||||||
// Returns an error message for the last failed procedure call.
|
// Returns an error message for the last failed procedure call.
|
||||||
last_error :: proc() -> string {
|
last_error :: proc() -> string {
|
||||||
return _last_error()
|
return _last_error()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
#+private
|
#+private
|
||||||
package dynlib
|
package dynlib
|
||||||
|
|
||||||
_load_library :: proc(path: string, global_symbols := false) -> (Library, bool) {
|
import "base:runtime"
|
||||||
|
|
||||||
|
_load_library :: proc(path: string, global_symbols: bool, allocator: runtime.Allocator) -> (Library, bool) {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -10,10 +12,10 @@ _unload_library :: proc(library: Library) -> bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
_symbol_address :: proc(library: Library, symbol: string) -> (ptr: rawptr, found: bool) {
|
_symbol_address :: proc(library: Library, symbol: string, allocator: runtime.Allocator) -> (ptr: rawptr, found: bool) {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
_last_error :: proc() -> string {
|
_last_error :: proc() -> string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-10
@@ -2,28 +2,38 @@
|
|||||||
#+private
|
#+private
|
||||||
package dynlib
|
package dynlib
|
||||||
|
|
||||||
import "core:os"
|
import "base:runtime"
|
||||||
|
|
||||||
_load_library :: proc(path: string, global_symbols := false) -> (Library, bool) {
|
import "core:strings"
|
||||||
flags := os.RTLD_NOW
|
import "core:sys/posix"
|
||||||
|
|
||||||
|
_load_library :: proc(path: string, global_symbols: bool, allocator: runtime.Allocator) -> (Library, bool) {
|
||||||
|
flags := posix.RTLD_Flags{.NOW}
|
||||||
if global_symbols {
|
if global_symbols {
|
||||||
flags |= os.RTLD_GLOBAL
|
flags += {.GLOBAL}
|
||||||
}
|
}
|
||||||
lib := os.dlopen(path, flags)
|
|
||||||
|
cpath := strings.clone_to_cstring(path, allocator)
|
||||||
|
defer delete(cpath, allocator)
|
||||||
|
|
||||||
|
lib := posix.dlopen(cpath, flags)
|
||||||
return Library(lib), lib != nil
|
return Library(lib), lib != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
_unload_library :: proc(library: Library) -> bool {
|
_unload_library :: proc(library: Library) -> bool {
|
||||||
return os.dlclose(rawptr(library))
|
return posix.dlclose(posix.Symbol_Table(library)) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
_symbol_address :: proc(library: Library, symbol: string) -> (ptr: rawptr, found: bool) {
|
_symbol_address :: proc(library: Library, symbol: string, allocator: runtime.Allocator) -> (ptr: rawptr, found: bool) {
|
||||||
ptr = os.dlsym(rawptr(library), symbol)
|
csymbol := strings.clone_to_cstring(symbol, allocator)
|
||||||
|
defer delete(csymbol, allocator)
|
||||||
|
|
||||||
|
ptr = posix.dlsym(posix.Symbol_Table(library), csymbol)
|
||||||
found = ptr != nil
|
found = ptr != nil
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_last_error :: proc() -> string {
|
_last_error :: proc() -> string {
|
||||||
err := os.dlerror()
|
err := string(posix.dlerror())
|
||||||
return "unknown" if err == "" else err
|
return "unknown" if err == "" else err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,13 @@
|
|||||||
#+private
|
#+private
|
||||||
package dynlib
|
package dynlib
|
||||||
|
|
||||||
|
import "base:runtime"
|
||||||
|
|
||||||
import win32 "core:sys/windows"
|
import win32 "core:sys/windows"
|
||||||
import "core:strings"
|
import "core:strings"
|
||||||
import "core:reflect"
|
import "core:reflect"
|
||||||
|
|
||||||
_load_library :: proc(path: string, global_symbols := false, allocator := context.temp_allocator) -> (Library, bool) {
|
_load_library :: proc(path: string, global_symbols: bool, allocator: runtime.Allocator) -> (Library, bool) {
|
||||||
// NOTE(bill): 'global_symbols' is here only for consistency with POSIX which has RTLD_GLOBAL
|
// NOTE(bill): 'global_symbols' is here only for consistency with POSIX which has RTLD_GLOBAL
|
||||||
wide_path := win32.utf8_to_wstring(path, allocator)
|
wide_path := win32.utf8_to_wstring(path, allocator)
|
||||||
defer free(wide_path, allocator)
|
defer free(wide_path, allocator)
|
||||||
@@ -19,7 +21,7 @@ _unload_library :: proc(library: Library) -> bool {
|
|||||||
return bool(ok)
|
return bool(ok)
|
||||||
}
|
}
|
||||||
|
|
||||||
_symbol_address :: proc(library: Library, symbol: string, allocator := context.temp_allocator) -> (ptr: rawptr, found: bool) {
|
_symbol_address :: proc(library: Library, symbol: string, allocator: runtime.Allocator) -> (ptr: rawptr, found: bool) {
|
||||||
c_str := strings.clone_to_cstring(symbol, allocator)
|
c_str := strings.clone_to_cstring(symbol, allocator)
|
||||||
defer delete(c_str, allocator)
|
defer delete(c_str, allocator)
|
||||||
ptr = win32.GetProcAddress(cast(win32.HMODULE)library, c_str)
|
ptr = win32.GetProcAddress(cast(win32.HMODULE)library, c_str)
|
||||||
@@ -31,4 +33,4 @@ _last_error :: proc() -> string {
|
|||||||
err := win32.System_Error(win32.GetLastError())
|
err := win32.System_Error(win32.GetLastError())
|
||||||
err_msg := reflect.enum_string(err)
|
err_msg := reflect.enum_string(err)
|
||||||
return "unknown" if err_msg == "" else err_msg
|
return "unknown" if err_msg == "" else err_msg
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -490,7 +490,7 @@ foreign libc {
|
|||||||
@(link_name="free") _unix_free :: proc(ptr: rawptr) ---
|
@(link_name="free") _unix_free :: proc(ptr: rawptr) ---
|
||||||
@(link_name="realloc") _unix_realloc :: proc(ptr: rawptr, size: c.size_t) -> rawptr ---
|
@(link_name="realloc") _unix_realloc :: proc(ptr: rawptr, size: c.size_t) -> rawptr ---
|
||||||
|
|
||||||
@(link_name="execvp") _unix_execvp :: proc(path: cstring, argv: [^]cstring) -> int ---
|
@(link_name="execvp") _unix_execvp :: proc(path: cstring, argv: [^]cstring) -> c.int ---
|
||||||
@(link_name="getenv") _unix_getenv :: proc(cstring) -> cstring ---
|
@(link_name="getenv") _unix_getenv :: proc(cstring) -> cstring ---
|
||||||
@(link_name="putenv") _unix_putenv :: proc(cstring) -> c.int ---
|
@(link_name="putenv") _unix_putenv :: proc(cstring) -> c.int ---
|
||||||
@(link_name="setenv") _unix_setenv :: proc(key: cstring, value: cstring, overwrite: c.int) -> c.int ---
|
@(link_name="setenv") _unix_setenv :: proc(key: cstring, value: cstring, overwrite: c.int) -> c.int ---
|
||||||
|
|||||||
@@ -1,14 +1,10 @@
|
|||||||
#+build linux, darwin, freebsd, openbsd, netbsd
|
#+build linux, darwin, freebsd, openbsd, netbsd
|
||||||
package filepath
|
package filepath
|
||||||
|
|
||||||
when ODIN_OS == .Darwin {
|
|
||||||
foreign import libc "system:System.framework"
|
|
||||||
} else {
|
|
||||||
foreign import libc "system:c"
|
|
||||||
}
|
|
||||||
|
|
||||||
import "base:runtime"
|
import "base:runtime"
|
||||||
|
|
||||||
import "core:strings"
|
import "core:strings"
|
||||||
|
import "core:sys/posix"
|
||||||
|
|
||||||
SEPARATOR :: '/'
|
SEPARATOR :: '/'
|
||||||
SEPARATOR_STRING :: `/`
|
SEPARATOR_STRING :: `/`
|
||||||
@@ -28,11 +24,11 @@ abs :: proc(path: string, allocator := context.allocator) -> (string, bool) {
|
|||||||
rel = "."
|
rel = "."
|
||||||
}
|
}
|
||||||
rel_cstr := strings.clone_to_cstring(rel, context.temp_allocator)
|
rel_cstr := strings.clone_to_cstring(rel, context.temp_allocator)
|
||||||
path_ptr := realpath(rel_cstr, nil)
|
path_ptr := posix.realpath(rel_cstr, nil)
|
||||||
if path_ptr == nil {
|
if path_ptr == nil {
|
||||||
return "", __error()^ == 0
|
return "", posix.errno() == nil
|
||||||
}
|
}
|
||||||
defer _unix_free(rawptr(path_ptr))
|
defer posix.free(path_ptr)
|
||||||
|
|
||||||
path_str := strings.clone(string(path_ptr), allocator)
|
path_str := strings.clone(string(path_ptr), allocator)
|
||||||
return path_str, true
|
return path_str, true
|
||||||
@@ -48,26 +44,3 @@ join :: proc(elems: []string, allocator := context.allocator) -> (joined: string
|
|||||||
}
|
}
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@(private)
|
|
||||||
foreign libc {
|
|
||||||
realpath :: proc(path: cstring, resolved_path: [^]byte = nil) -> cstring ---
|
|
||||||
@(link_name="free") _unix_free :: proc(ptr: rawptr) ---
|
|
||||||
|
|
||||||
}
|
|
||||||
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD {
|
|
||||||
@(private)
|
|
||||||
foreign libc {
|
|
||||||
@(link_name="__error") __error :: proc() -> ^i32 ---
|
|
||||||
}
|
|
||||||
} else when ODIN_OS == .OpenBSD || ODIN_OS == .NetBSD {
|
|
||||||
@(private)
|
|
||||||
foreign libc {
|
|
||||||
@(link_name="__errno") __error :: proc() -> ^i32 ---
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
@(private)
|
|
||||||
foreign libc {
|
|
||||||
@(link_name="__errno_location") __error :: proc() -> ^i32 ---
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build darwin, linux, freebsd, openbsd, netbsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build darwin, linux, freebsd, openbsd, netbsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -210,6 +211,4 @@ when ODIN_OS == .Darwin {
|
|||||||
d_name: [256]c.char `fmt:"s,0"`, /* [PSX] entry name */
|
d_name: [256]c.char `fmt:"s,0"`, /* [PSX] entry name */
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build darwin, linux, freebsd, openbsd, netbsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -120,7 +121,5 @@ when ODIN_OS == .Darwin {
|
|||||||
_RTLD_LOCAL :: 0
|
_RTLD_LOCAL :: 0
|
||||||
RTLD_LOCAL :: RTLD_Flags{}
|
RTLD_LOCAL :: RTLD_Flags{}
|
||||||
|
|
||||||
} else {
|
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build windows, darwin, linux, freebsd, openbsd, netbsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -456,7 +457,84 @@ when ODIN_OS == .Darwin {
|
|||||||
|
|
||||||
EOWNERDEAD :: 130
|
EOWNERDEAD :: 130
|
||||||
ENOTRECOVERABLE :: 131
|
ENOTRECOVERABLE :: 131
|
||||||
} else {
|
} else when ODIN_OS == .Windows {
|
||||||
#panic("posix is unimplemented for the current target")
|
E2BIG :: 7
|
||||||
|
EACCES :: 13
|
||||||
|
EADDRINUSE :: 100
|
||||||
|
EADDRNOTAVAIL :: 101
|
||||||
|
EAFNOSUPPORT :: 102
|
||||||
|
EAGAIN :: 11
|
||||||
|
EALREADY :: 103
|
||||||
|
EBADF :: 9
|
||||||
|
EBADMSG :: 104
|
||||||
|
EBUSY :: 16
|
||||||
|
ECANCELED :: 105
|
||||||
|
ECHILD :: 10
|
||||||
|
ECONNABORTED :: 106
|
||||||
|
ECONNREFUSED :: 107
|
||||||
|
ECONNRESET :: 108
|
||||||
|
EDEADLK :: 36
|
||||||
|
EDESTADDRREQ :: 109
|
||||||
|
EDQUOT :: -1 // NOTE: not defined
|
||||||
|
EEXIST :: 17
|
||||||
|
EFAULT :: 14
|
||||||
|
EFBIG :: 27
|
||||||
|
EHOSTUNREACH :: 110
|
||||||
|
EIDRM :: 111
|
||||||
|
EINPROGRESS :: 112
|
||||||
|
EINTR :: 4
|
||||||
|
EINVAL :: 22
|
||||||
|
EIO :: 5
|
||||||
|
EISCONN :: 113
|
||||||
|
EISDIR :: 21
|
||||||
|
ELOOP :: 114
|
||||||
|
EMFILE :: 24
|
||||||
|
EMLINK :: 31
|
||||||
|
EMSGSIZE :: 115
|
||||||
|
EMULTIHOP :: -1 // NOTE: not defined
|
||||||
|
ENAMETOOLONG :: 38
|
||||||
|
ENETDOWN :: 116
|
||||||
|
ENETRESET :: 117
|
||||||
|
ENETUNREACH :: 118
|
||||||
|
ENFILE :: 23
|
||||||
|
ENOBUFS :: 119
|
||||||
|
ENODATA :: 120
|
||||||
|
ENODEV :: 19
|
||||||
|
ENOENT :: 2
|
||||||
|
ENOEXEC :: 8
|
||||||
|
ENOLCK :: 39
|
||||||
|
ENOLINK :: 121
|
||||||
|
ENOMEM :: 12
|
||||||
|
ENOMSG :: 122
|
||||||
|
ENOPROTOOPT :: 123
|
||||||
|
ENOSPC :: 28
|
||||||
|
ENOSR :: 124
|
||||||
|
ENOSTR :: 125
|
||||||
|
ENOSYS :: 40
|
||||||
|
ENOTCONN :: 126
|
||||||
|
ENOTDIR :: 20
|
||||||
|
ENOTEMPTY :: 41
|
||||||
|
ENOTRECOVERABLE :: 127
|
||||||
|
ENOTSOCK :: 128
|
||||||
|
ENOTSUP :: 129
|
||||||
|
ENOTTY :: 25
|
||||||
|
ENXIO :: 6
|
||||||
|
EOPNOTSUPP :: 130
|
||||||
|
EOVERFLOW :: 132
|
||||||
|
EOWNERDEAD :: 133
|
||||||
|
EPERM :: 1
|
||||||
|
EPIPE :: 32
|
||||||
|
EPROTO :: 134
|
||||||
|
EPROTONOSUPPORT :: 135
|
||||||
|
EPROTOTYPE :: 136
|
||||||
|
EROFS :: 30
|
||||||
|
ESPIPE :: 29
|
||||||
|
ESRCH :: 3
|
||||||
|
ESTALE :: -1 // NOTE: not defined
|
||||||
|
ETIME :: 137
|
||||||
|
ETIMEDOUT :: 138
|
||||||
|
ETXTBSY :: 139
|
||||||
|
EWOULDBLOCK :: 140
|
||||||
|
EXDEV :: 18
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, openbsd, freebsd, netbsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -466,13 +467,11 @@ when ODIN_OS == .Darwin {
|
|||||||
AT_REMOVEDIR :: 0x200
|
AT_REMOVEDIR :: 0x200
|
||||||
|
|
||||||
flock :: struct {
|
flock :: struct {
|
||||||
|
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_start: off_t, /* [PSX] relative offset in bytes. */
|
||||||
l_len: off_t, /* [PSX] size; if 0 then until EOF. */
|
l_len: off_t, /* [PSX] size; if 0 then until EOF. */
|
||||||
l_pid: pid_t, /* [PSX] process ID of the process holding the lock. */
|
l_pid: pid_t, /* [PSX] process ID of the process holding the lock. */
|
||||||
l_type: Lock_Type, /* [PSX] type of lock. */
|
|
||||||
l_whence: c.short, /* [PSX] flag (Whence) of starting offset. */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build darwin, linux, openbsd, freebsd, netbsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -61,6 +62,4 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
FNM_NOESCAPE :: 0x02
|
FNM_NOESCAPE :: 0x02
|
||||||
FNM_PERIOD :: 0x04
|
FNM_PERIOD :: 0x04
|
||||||
|
|
||||||
} else {
|
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -203,6 +204,4 @@ when ODIN_OS == .Darwin {
|
|||||||
GLOB_ABORTED :: 2
|
GLOB_ABORTED :: 2
|
||||||
GLOB_NOMATCH :: 3
|
GLOB_NOMATCH :: 3
|
||||||
|
|
||||||
} else {
|
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -125,6 +126,4 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
gr_mem: [^]cstring, /* [PSX] group members */
|
gr_mem: [^]cstring, /* [PSX] group members */
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
when ODIN_OS == .Darwin {
|
when ODIN_OS == .Darwin {
|
||||||
@@ -56,6 +57,7 @@ foreign lib {
|
|||||||
|
|
||||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/basename.html ]]
|
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/basename.html ]]
|
||||||
*/
|
*/
|
||||||
|
@(link_name=LBASENAME)
|
||||||
basename :: proc(path: cstring) -> cstring ---
|
basename :: proc(path: cstring) -> cstring ---
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -72,3 +74,9 @@ foreign lib {
|
|||||||
*/
|
*/
|
||||||
dirname :: proc(path: cstring) -> cstring ---
|
dirname :: proc(path: cstring) -> cstring ---
|
||||||
}
|
}
|
||||||
|
|
||||||
|
when ODIN_OS == .Linux {
|
||||||
|
@(private) LBASENAME :: "__xpg_basename"
|
||||||
|
} else {
|
||||||
|
@(private) LBASENAME :: "basename"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
// limits.h - implementation-defined constants
|
// limits.h - implementation-defined constants
|
||||||
@@ -549,6 +550,4 @@ when ODIN_OS == .Darwin {
|
|||||||
NL_TEXTMAX :: 2048 // 255 on glibc, 2048 on musl
|
NL_TEXTMAX :: 2048 // 255 on glibc, 2048 on musl
|
||||||
NZERO :: 20
|
NZERO :: 20
|
||||||
|
|
||||||
} else {
|
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-126
@@ -1,131 +1,11 @@
|
|||||||
|
#+build windows, linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c/libc"
|
||||||
|
|
||||||
when ODIN_OS == .Darwin {
|
localeconv :: libc.localeconv
|
||||||
foreign import lib "system:System.framework"
|
setlocale :: libc.setlocale
|
||||||
} else {
|
|
||||||
foreign import lib "system:c"
|
|
||||||
}
|
|
||||||
|
|
||||||
// locale.h - category macros
|
lconv :: libc.lconv
|
||||||
|
|
||||||
foreign lib {
|
Locale_Category :: libc.Locale_Category
|
||||||
/*
|
|
||||||
Sets the components of an object with the type lconv with the values appropriate for the
|
|
||||||
formatting of numeric quantities (monetary and otherwise) according to the rules of the current
|
|
||||||
locale.
|
|
||||||
|
|
||||||
Returns: a pointer to the lconv structure, might be invalidated by subsequent calls to localeconv() and setlocale()
|
|
||||||
|
|
||||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/localeconv.html ]]
|
|
||||||
*/
|
|
||||||
localeconv :: proc() -> ^lconv ---
|
|
||||||
|
|
||||||
/*
|
|
||||||
Selects the appropriate piece of the global locale, as specified by the category and locale arguments,
|
|
||||||
and can be used to change or query the entire global locale or portions thereof.
|
|
||||||
|
|
||||||
Returns: the current locale if `locale` is `nil`, the set locale otherwise
|
|
||||||
|
|
||||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/setlocale.html ]]
|
|
||||||
*/
|
|
||||||
@(link_name=LSETLOCALE)
|
|
||||||
setlocale :: proc(category: Locale_Category, locale: cstring) -> cstring ---
|
|
||||||
}
|
|
||||||
|
|
||||||
Locale_Category :: enum c.int {
|
|
||||||
ALL = LC_ALL,
|
|
||||||
COLLATE = LC_COLLATE,
|
|
||||||
CTYPE = LC_CTYPE,
|
|
||||||
MESSAGES = LC_MESSAGES,
|
|
||||||
MONETARY = LC_MONETARY,
|
|
||||||
NUMERIC = LC_NUMERIC,
|
|
||||||
TIME = LC_TIME,
|
|
||||||
}
|
|
||||||
|
|
||||||
when ODIN_OS == .NetBSD {
|
|
||||||
@(private) LSETLOCALE :: "__setlocale50"
|
|
||||||
} else {
|
|
||||||
@(private) LSETLOCALE :: "setlocale"
|
|
||||||
}
|
|
||||||
|
|
||||||
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD {
|
|
||||||
|
|
||||||
// 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_ALL :: 0
|
|
||||||
LC_COLLATE :: 1
|
|
||||||
LC_CTYPE :: 2
|
|
||||||
LC_MESSAGES :: 6
|
|
||||||
LC_MONETARY :: 3
|
|
||||||
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")
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -55,6 +56,4 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
|
|
||||||
IF_NAMESIZE :: 16
|
IF_NAMESIZE :: 16
|
||||||
|
|
||||||
} else {
|
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -472,6 +473,4 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
EAI_OVERFLOW :: 14
|
EAI_OVERFLOW :: 14
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -61,6 +62,11 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
sin6_scope_id: c.uint32_t, /* [PSX] set of interfaces for a scope */
|
sin6_scope_id: c.uint32_t, /* [PSX] set of interfaces for a scope */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ipv6_mreq :: struct {
|
||||||
|
ipv6mr_multiaddr: in6_addr, /* [PSX] IPv6 multicast address */
|
||||||
|
ipv6mr_interface: c.uint, /* [PSX] interface index */
|
||||||
|
}
|
||||||
|
|
||||||
IPV6_MULTICAST_IF :: 17
|
IPV6_MULTICAST_IF :: 17
|
||||||
IPV6_UNICAST_HOPS :: 16
|
IPV6_UNICAST_HOPS :: 16
|
||||||
IPV6_MULTICAST_HOPS :: 18
|
IPV6_MULTICAST_HOPS :: 18
|
||||||
@@ -223,6 +229,4 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
// netinet/tcp.h - definitions for the Internet Transmission Control Protocol (TCP)
|
// netinet/tcp.h - definitions for the Internet Transmission Control Protocol (TCP)
|
||||||
@@ -6,6 +7,4 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
|
|
||||||
TCP_NODELAY :: 0x01
|
TCP_NODELAY :: 0x01
|
||||||
|
|
||||||
} else {
|
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "base:intrinsics"
|
import "base:intrinsics"
|
||||||
@@ -92,7 +93,4 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
POLLHUP :: 0x0010
|
POLLHUP :: 0x0010
|
||||||
POLLNVAL :: 0x0020
|
POLLNVAL :: 0x0020
|
||||||
|
|
||||||
} else {
|
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ The struct fields that are cross-platform are documented with `[PSX]`.
|
|||||||
Accessing these fields on one target should be the same on others.
|
Accessing these fields on one target should be the same on others.
|
||||||
Other fields are implementation specific.
|
Other fields are implementation specific.
|
||||||
|
|
||||||
|
The parts of POSIX that Windows implements are also supported here, but
|
||||||
|
other symbols are undefined on Windows targets.
|
||||||
|
|
||||||
Most macros have been reimplemented in Odin with inlined functions.
|
Most macros have been reimplemented in Odin with inlined functions.
|
||||||
|
|
||||||
Unimplemented headers:
|
Unimplemented headers:
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|
||||||
when ODIN_OS == .Darwin {
|
when ODIN_OS == .Darwin {
|
||||||
foreign import lib "system:System.framework"
|
foreign import lib "system:System.framework"
|
||||||
} else when ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD {
|
} else when ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .Linux {
|
||||||
foreign import lib "system:pthread"
|
foreign import lib "system:pthread"
|
||||||
} else {
|
} else {
|
||||||
foreign import lib "system:c"
|
foreign import lib "system:c"
|
||||||
@@ -398,6 +399,16 @@ when ODIN_OS == .Darwin {
|
|||||||
|
|
||||||
pthread_key_t :: distinct c.ulong
|
pthread_key_t :: distinct c.ulong
|
||||||
|
|
||||||
|
pthread_mutex_t :: struct {
|
||||||
|
__sig: c.long,
|
||||||
|
__opaque: [56]c.char,
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_cond_t :: struct {
|
||||||
|
__sig: c.long,
|
||||||
|
__opaque: [40]c.char,
|
||||||
|
}
|
||||||
|
|
||||||
sched_param :: struct {
|
sched_param :: struct {
|
||||||
sched_priority: c.int, /* [PSX] process or thread execution scheduling priority */
|
sched_priority: c.int, /* [PSX] process or thread execution scheduling priority */
|
||||||
_: [4]c.char,
|
_: [4]c.char,
|
||||||
@@ -431,10 +442,20 @@ when ODIN_OS == .Darwin {
|
|||||||
|
|
||||||
pthread_t :: distinct u64
|
pthread_t :: distinct u64
|
||||||
|
|
||||||
pthread_attr_t :: distinct rawptr
|
pthread_attr_t :: struct #align(8) {
|
||||||
|
_: [8]byte,
|
||||||
|
}
|
||||||
|
|
||||||
pthread_key_t :: distinct c.int
|
pthread_key_t :: distinct c.int
|
||||||
|
|
||||||
|
pthread_mutex_t :: struct #align(8) {
|
||||||
|
_: [8]byte,
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_cond_t :: struct #align(8) {
|
||||||
|
_: [8]byte,
|
||||||
|
}
|
||||||
|
|
||||||
sched_param :: struct {
|
sched_param :: struct {
|
||||||
sched_priority: c.int, /* [PSX] process or thread execution scheduling priority */
|
sched_priority: c.int, /* [PSX] process or thread execution scheduling priority */
|
||||||
}
|
}
|
||||||
@@ -475,6 +496,14 @@ when ODIN_OS == .Darwin {
|
|||||||
|
|
||||||
pthread_key_t :: distinct c.int
|
pthread_key_t :: distinct c.int
|
||||||
|
|
||||||
|
pthread_cond_t :: struct #align(8) {
|
||||||
|
_: [40]byte,
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_t :: struct #align(8) {
|
||||||
|
_: [48]byte,
|
||||||
|
}
|
||||||
|
|
||||||
sched_param :: struct {
|
sched_param :: struct {
|
||||||
sched_priority: c.int, /* [PSX] process or thread execution scheduling priority */
|
sched_priority: c.int, /* [PSX] process or thread execution scheduling priority */
|
||||||
}
|
}
|
||||||
@@ -505,9 +534,11 @@ when ODIN_OS == .Darwin {
|
|||||||
PTHREAD_SCOPE_PROCESS :: 0
|
PTHREAD_SCOPE_PROCESS :: 0
|
||||||
PTHREAD_SCOPE_SYSTEM :: 0x2
|
PTHREAD_SCOPE_SYSTEM :: 0x2
|
||||||
|
|
||||||
pthread_t :: distinct rawptr
|
pthread_t :: distinct rawptr
|
||||||
pthread_attr_t :: distinct rawptr
|
pthread_attr_t :: distinct rawptr
|
||||||
pthread_key_t :: distinct c.int
|
pthread_key_t :: distinct c.int
|
||||||
|
pthread_mutex_t :: distinct rawptr
|
||||||
|
pthread_cond_t :: distinct rawptr
|
||||||
|
|
||||||
sched_param :: struct {
|
sched_param :: struct {
|
||||||
sched_priority: c.int, /* [PSX] process or thread execution scheduling priority */
|
sched_priority: c.int, /* [PSX] process or thread execution scheduling priority */
|
||||||
@@ -548,6 +579,16 @@ when ODIN_OS == .Darwin {
|
|||||||
|
|
||||||
pthread_key_t :: distinct c.uint
|
pthread_key_t :: distinct c.uint
|
||||||
|
|
||||||
|
pthread_cond_t :: struct {
|
||||||
|
__size: [40]c.char, // NOTE: may be smaller depending on libc or arch, but never larger.
|
||||||
|
__align: c.long,
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_t :: struct {
|
||||||
|
__size: [32]c.char, // NOTE: may be smaller depending on libc or arch, but never larger.
|
||||||
|
__align: c.long,
|
||||||
|
}
|
||||||
|
|
||||||
sched_param :: struct {
|
sched_param :: struct {
|
||||||
sched_priority: c.int, /* [PSX] process or thread execution scheduling priority */
|
sched_priority: c.int, /* [PSX] process or thread execution scheduling priority */
|
||||||
|
|
||||||
@@ -557,6 +598,4 @@ when ODIN_OS == .Darwin {
|
|||||||
__reserved3: c.int,
|
__reserved3: c.int,
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-2
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -163,6 +164,16 @@ when ODIN_OS == .Darwin || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD {
|
|||||||
pw_fields: c.int,
|
pw_fields: c.int,
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else when ODIN_OS == .Linux {
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
|
passwd :: struct {
|
||||||
|
pw_name: cstring, /* [PSX] user name */
|
||||||
|
pw_passwd: cstring, /* encrypted password */
|
||||||
|
pw_uid: uid_t, /* [PSX] user uid */
|
||||||
|
pw_gid: gid_t, /* [PSX] user gid */
|
||||||
|
pw_gecos: cstring, /* Real name. */
|
||||||
|
pw_dir: cstring, /* Home directory. */
|
||||||
|
pw_shell: cstring, /* Shell program. */
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -100,6 +101,4 @@ when ODIN_OS == .Darwin {
|
|||||||
SCHED_FIFO :: 1
|
SCHED_FIFO :: 1
|
||||||
SCHED_RR :: 2
|
SCHED_RR :: 2
|
||||||
|
|
||||||
} else {
|
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
import "core:c/libc"
|
|
||||||
|
|
||||||
when ODIN_OS == .Darwin {
|
when ODIN_OS == .Darwin {
|
||||||
foreign import lib "system:System.framework"
|
foreign import lib "system:System.framework"
|
||||||
@@ -43,12 +43,8 @@ foreign lib {
|
|||||||
sigsetjmp :: proc(env: ^sigjmp_buf, savemask: b32) -> c.int ---
|
sigsetjmp :: proc(env: ^sigjmp_buf, savemask: b32) -> c.int ---
|
||||||
}
|
}
|
||||||
|
|
||||||
jmp_buf :: libc.jmp_buf
|
|
||||||
sigjmp_buf :: distinct jmp_buf
|
sigjmp_buf :: distinct jmp_buf
|
||||||
|
|
||||||
longjmp :: libc.longjmp
|
|
||||||
setjmp :: libc.setjmp
|
|
||||||
|
|
||||||
when ODIN_OS == .NetBSD {
|
when ODIN_OS == .NetBSD {
|
||||||
@(private) LSIGSETJMP :: "__sigsetjmp14"
|
@(private) LSIGSETJMP :: "__sigsetjmp14"
|
||||||
@(private) LSIGLONGJMP :: "__siglongjmp14"
|
@(private) LSIGLONGJMP :: "__siglongjmp14"
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#+build windows, linux, darwin, netbsd, openbsd, freebsd
|
||||||
|
package posix
|
||||||
|
|
||||||
|
import "core:c/libc"
|
||||||
|
|
||||||
|
// setjmp.h - stack environment declarations
|
||||||
|
|
||||||
|
jmp_buf :: libc.jmp_buf
|
||||||
|
|
||||||
|
longjmp :: libc.longjmp
|
||||||
|
setjmp :: libc.setjmp
|
||||||
+2
-109
@@ -1,9 +1,9 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "base:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
import "core:c/libc"
|
|
||||||
|
|
||||||
when ODIN_OS == .Darwin {
|
when ODIN_OS == .Darwin {
|
||||||
foreign import lib "system:System.framework"
|
foreign import lib "system:System.framework"
|
||||||
@@ -14,31 +14,6 @@ when ODIN_OS == .Darwin {
|
|||||||
// signal.h - signals
|
// signal.h - signals
|
||||||
|
|
||||||
foreign lib {
|
foreign lib {
|
||||||
// LIBC:
|
|
||||||
|
|
||||||
/*
|
|
||||||
Set a signal handler.
|
|
||||||
|
|
||||||
func can either be:
|
|
||||||
- `auto_cast posix.SIG_DFL` setting the default handler for that specific signal
|
|
||||||
- `auto_cast posix.SIG_IGN` causing the specific signal to be ignored
|
|
||||||
- a custom signal handler
|
|
||||||
|
|
||||||
Returns: SIG_ERR (setting errno), the last value of func on success
|
|
||||||
|
|
||||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/signal.html ]]
|
|
||||||
*/
|
|
||||||
signal :: proc(sig: Signal, func: proc "c" (Signal)) -> proc "c" (Signal) ---
|
|
||||||
|
|
||||||
/*
|
|
||||||
Raises a signal, calling its handler and then returning.
|
|
||||||
|
|
||||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/raise.html ]]
|
|
||||||
*/
|
|
||||||
raise :: proc(sig: Signal) -> result ---
|
|
||||||
|
|
||||||
// POSIX:
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Raise a signal to the process/group specified by pid.
|
Raise a signal to the process/group specified by pid.
|
||||||
|
|
||||||
@@ -227,72 +202,6 @@ sigval :: struct #raw_union {
|
|||||||
sigval_ptr: rawptr, /* [PSX] pointer signal value */
|
sigval_ptr: rawptr, /* [PSX] pointer signal value */
|
||||||
}
|
}
|
||||||
|
|
||||||
Signal :: enum c.int {
|
|
||||||
NONE,
|
|
||||||
|
|
||||||
// LIBC:
|
|
||||||
|
|
||||||
// Process abort signal.
|
|
||||||
SIGABRT = SIGABRT,
|
|
||||||
// Erronous arithemtic operation.
|
|
||||||
SIGFPE = SIGFPE,
|
|
||||||
// Illegal instruction.
|
|
||||||
SIGILL = SIGILL,
|
|
||||||
// Terminal interrupt signal.
|
|
||||||
SIGINT = SIGINT,
|
|
||||||
// Invalid memory reference.
|
|
||||||
SIGSEGV = SIGSEGV,
|
|
||||||
// Termination signal.
|
|
||||||
SIGTERM = SIGTERM,
|
|
||||||
|
|
||||||
// POSIX:
|
|
||||||
|
|
||||||
// Process abort signal.
|
|
||||||
SIGALRM = SIGALRM,
|
|
||||||
// Access to an undefined portion of a memory object.
|
|
||||||
SIGBUS = SIGBUS,
|
|
||||||
// Child process terminated, stopped, or continued.
|
|
||||||
SIGCHLD = SIGCHLD,
|
|
||||||
// Continue execution, if stopped.
|
|
||||||
SIGCONT = SIGCONT,
|
|
||||||
// Hangup.
|
|
||||||
SIGHUP = SIGHUP,
|
|
||||||
// Kill (cannot be caught or ignored).
|
|
||||||
SIGKILL = SIGKILL,
|
|
||||||
// Write on a pipe with no one to read it.
|
|
||||||
SIGPIPE = SIGPIPE,
|
|
||||||
// Terminal quit signal.
|
|
||||||
SIGQUIT = SIGQUIT,
|
|
||||||
// Stop executing (cannot be caught or ignored).
|
|
||||||
SIGSTOP = SIGSTOP,
|
|
||||||
// Terminal stop process.
|
|
||||||
SIGTSTP = SIGTSTP,
|
|
||||||
// Background process attempting read.
|
|
||||||
SIGTTIN = SIGTTIN,
|
|
||||||
// Background process attempting write.
|
|
||||||
SIGTTOU = SIGTTOU,
|
|
||||||
// User-defined signal 1.
|
|
||||||
SIGUSR1 = SIGUSR1,
|
|
||||||
// User-defined signal 2.
|
|
||||||
SIGUSR2 = SIGUSR2,
|
|
||||||
// Pollable event.
|
|
||||||
SIGPOLL = SIGPOLL,
|
|
||||||
// Profiling timer expired.
|
|
||||||
SIGPROF = SIGPROF,
|
|
||||||
// Bad system call.
|
|
||||||
SIGSYS = SIGSYS,
|
|
||||||
// Trace/breakpoint trap.
|
|
||||||
SIGTRAP = SIGTRAP,
|
|
||||||
// High bandwidth data is available at a socket.
|
|
||||||
SIGURG = SIGURG,
|
|
||||||
// Virtual timer expired.
|
|
||||||
SIGVTALRM = SIGVTALRM,
|
|
||||||
// CPU time limit exceeded.
|
|
||||||
SIGXCPU = SIGXCPU,
|
|
||||||
// File size limit exceeded.
|
|
||||||
SIGXFSZ = SIGXFSZ,
|
|
||||||
}
|
|
||||||
|
|
||||||
ILL_Code :: enum c.int {
|
ILL_Code :: enum c.int {
|
||||||
// Illegal opcode.
|
// Illegal opcode.
|
||||||
ILLOPC = ILL_ILLOPC,
|
ILLOPC = ILL_ILLOPC,
|
||||||
@@ -434,20 +343,6 @@ Sig :: enum c.int {
|
|||||||
SETMASK = SIG_SETMASK,
|
SETMASK = SIG_SETMASK,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request for default signal handling.
|
|
||||||
SIG_DFL :: libc.SIG_DFL
|
|
||||||
// Return value from signal() in case of error.
|
|
||||||
SIG_ERR :: libc.SIG_ERR
|
|
||||||
// Request that signal be ignored.
|
|
||||||
SIG_IGN :: libc.SIG_IGN
|
|
||||||
|
|
||||||
SIGABRT :: libc.SIGABRT
|
|
||||||
SIGFPE :: libc.SIGFPE
|
|
||||||
SIGILL :: libc.SIGILL
|
|
||||||
SIGINT :: libc.SIGINT
|
|
||||||
SIGSEGV :: libc.SIGSEGV
|
|
||||||
SIGTERM :: libc.SIGTERM
|
|
||||||
|
|
||||||
when ODIN_OS == .NetBSD {
|
when ODIN_OS == .NetBSD {
|
||||||
@(private) LSIGPROCMASK :: "__sigprocmask14"
|
@(private) LSIGPROCMASK :: "__sigprocmask14"
|
||||||
@(private) LSIGACTION :: "__sigaction_siginfo"
|
@(private) LSIGACTION :: "__sigaction_siginfo"
|
||||||
@@ -1118,7 +1013,7 @@ when ODIN_OS == .Darwin {
|
|||||||
|
|
||||||
uid_t :: distinct c.uint32_t
|
uid_t :: distinct c.uint32_t
|
||||||
sigset_t :: struct {
|
sigset_t :: struct {
|
||||||
[1024/(8 * size_of(c.ulong))]val,
|
__val: [1024/(8 * size_of(c.ulong))]c.ulong,
|
||||||
}
|
}
|
||||||
|
|
||||||
SIGHUP :: 1
|
SIGHUP :: 1
|
||||||
@@ -1285,6 +1180,4 @@ when ODIN_OS == .Darwin {
|
|||||||
SI_TIMER :: -2
|
SI_TIMER :: -2
|
||||||
SI_MESGQ :: -3
|
SI_MESGQ :: -3
|
||||||
SI_ASYNCIO :: -4
|
SI_ASYNCIO :: -4
|
||||||
} else {
|
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,145 @@
|
|||||||
|
#+build linux, windows, darwin, netbsd, openbsd, freebsd
|
||||||
|
package posix
|
||||||
|
|
||||||
|
import "base:intrinsics"
|
||||||
|
|
||||||
|
import "core:c"
|
||||||
|
import "core:c/libc"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib "system:libucrt.lib"
|
||||||
|
} else when ODIN_OS == .Darwin {
|
||||||
|
foreign import lib "system:System.framework"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:c"
|
||||||
|
}
|
||||||
|
|
||||||
|
// signal.h - signals
|
||||||
|
|
||||||
|
foreign lib {
|
||||||
|
/*
|
||||||
|
Set a signal handler.
|
||||||
|
|
||||||
|
func can either be:
|
||||||
|
- `auto_cast posix.SIG_DFL` setting the default handler for that specific signal
|
||||||
|
- `auto_cast posix.SIG_IGN` causing the specific signal to be ignored
|
||||||
|
- a custom signal handler
|
||||||
|
|
||||||
|
Returns: SIG_ERR (setting errno), the last value of func on success
|
||||||
|
|
||||||
|
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/signal.html ]]
|
||||||
|
*/
|
||||||
|
signal :: proc(sig: Signal, func: proc "c" (Signal)) -> proc "c" (Signal) ---
|
||||||
|
|
||||||
|
/*
|
||||||
|
Raises a signal, calling its handler and then returning.
|
||||||
|
|
||||||
|
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/raise.html ]]
|
||||||
|
*/
|
||||||
|
raise :: proc(sig: Signal) -> result ---
|
||||||
|
}
|
||||||
|
|
||||||
|
Signal :: enum c.int {
|
||||||
|
NONE,
|
||||||
|
|
||||||
|
// LIBC:
|
||||||
|
|
||||||
|
// Process abort signal.
|
||||||
|
SIGABRT = SIGABRT,
|
||||||
|
// Erronous arithemtic operation.
|
||||||
|
SIGFPE = SIGFPE,
|
||||||
|
// Illegal instruction.
|
||||||
|
SIGILL = SIGILL,
|
||||||
|
// Terminal interrupt signal.
|
||||||
|
SIGINT = SIGINT,
|
||||||
|
// Invalid memory reference.
|
||||||
|
SIGSEGV = SIGSEGV,
|
||||||
|
// Termination signal.
|
||||||
|
SIGTERM = SIGTERM,
|
||||||
|
|
||||||
|
// POSIX:
|
||||||
|
|
||||||
|
// Process abort signal.
|
||||||
|
SIGALRM = SIGALRM,
|
||||||
|
// Access to an undefined portion of a memory object.
|
||||||
|
SIGBUS = SIGBUS,
|
||||||
|
// Child process terminated, stopped, or continued.
|
||||||
|
SIGCHLD = SIGCHLD,
|
||||||
|
// Continue execution, if stopped.
|
||||||
|
SIGCONT = SIGCONT,
|
||||||
|
// Hangup.
|
||||||
|
SIGHUP = SIGHUP,
|
||||||
|
// Kill (cannot be caught or ignored).
|
||||||
|
SIGKILL = SIGKILL,
|
||||||
|
// Write on a pipe with no one to read it.
|
||||||
|
SIGPIPE = SIGPIPE,
|
||||||
|
// Terminal quit signal.
|
||||||
|
SIGQUIT = SIGQUIT,
|
||||||
|
// Stop executing (cannot be caught or ignored).
|
||||||
|
SIGSTOP = SIGSTOP,
|
||||||
|
// Terminal stop process.
|
||||||
|
SIGTSTP = SIGTSTP,
|
||||||
|
// Background process attempting read.
|
||||||
|
SIGTTIN = SIGTTIN,
|
||||||
|
// Background process attempting write.
|
||||||
|
SIGTTOU = SIGTTOU,
|
||||||
|
// User-defined signal 1.
|
||||||
|
SIGUSR1 = SIGUSR1,
|
||||||
|
// User-defined signal 2.
|
||||||
|
SIGUSR2 = SIGUSR2,
|
||||||
|
// Pollable event.
|
||||||
|
SIGPOLL = SIGPOLL,
|
||||||
|
// Profiling timer expired.
|
||||||
|
SIGPROF = SIGPROF,
|
||||||
|
// Bad system call.
|
||||||
|
SIGSYS = SIGSYS,
|
||||||
|
// Trace/breakpoint trap.
|
||||||
|
SIGTRAP = SIGTRAP,
|
||||||
|
// High bandwidth data is available at a socket.
|
||||||
|
SIGURG = SIGURG,
|
||||||
|
// Virtual timer expired.
|
||||||
|
SIGVTALRM = SIGVTALRM,
|
||||||
|
// CPU time limit exceeded.
|
||||||
|
SIGXCPU = SIGXCPU,
|
||||||
|
// File size limit exceeded.
|
||||||
|
SIGXFSZ = SIGXFSZ,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request for default signal handling.
|
||||||
|
SIG_DFL :: libc.SIG_DFL
|
||||||
|
// Return value from signal() in case of error.
|
||||||
|
SIG_ERR :: libc.SIG_ERR
|
||||||
|
// Request that signal be ignored.
|
||||||
|
SIG_IGN :: libc.SIG_IGN
|
||||||
|
|
||||||
|
SIGABRT :: libc.SIGABRT
|
||||||
|
SIGFPE :: libc.SIGFPE
|
||||||
|
SIGILL :: libc.SIGILL
|
||||||
|
SIGINT :: libc.SIGINT
|
||||||
|
SIGSEGV :: libc.SIGSEGV
|
||||||
|
SIGTERM :: libc.SIGTERM
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
SIGALRM :: -1
|
||||||
|
SIGBUS :: -1
|
||||||
|
SIGCHLD :: -1
|
||||||
|
SIGCONT :: -1
|
||||||
|
SIGHUP :: -1
|
||||||
|
SIGKILL :: -1
|
||||||
|
SIGPIPE :: -1
|
||||||
|
SIGQUIT :: -1
|
||||||
|
SIGSTOP :: -1
|
||||||
|
SIGTSTP :: -1
|
||||||
|
SIGTTIN :: -1
|
||||||
|
SIGTTOU :: -1
|
||||||
|
SIGUSR1 :: -1
|
||||||
|
SIGUSR2 :: -1
|
||||||
|
SIGPOLL :: -1
|
||||||
|
SIGPROF :: -1
|
||||||
|
SIGSYS :: -1
|
||||||
|
SIGTRAP :: -1
|
||||||
|
SIGURG :: -1
|
||||||
|
SIGVTALRM :: -1
|
||||||
|
SIGXCPU :: -1
|
||||||
|
SIGXFSZ :: -1
|
||||||
|
}
|
||||||
+8
-165
@@ -1,7 +1,7 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
import "core:c/libc"
|
|
||||||
|
|
||||||
when ODIN_OS == .Darwin {
|
when ODIN_OS == .Darwin {
|
||||||
foreign import lib "system:System.framework"
|
foreign import lib "system:System.framework"
|
||||||
@@ -32,16 +32,6 @@ foreign lib {
|
|||||||
*/
|
*/
|
||||||
dprintf :: proc(fildse: FD, format: cstring, #c_vararg args: ..any) -> c.int ---
|
dprintf :: proc(fildse: FD, format: cstring, #c_vararg args: ..any) -> c.int ---
|
||||||
|
|
||||||
/*
|
|
||||||
Equivalent to fprintf but output is written to s, it is the user's responsibility to
|
|
||||||
ensure there is enough space.
|
|
||||||
|
|
||||||
Return: number of bytes written, negative (setting errno) on failure
|
|
||||||
|
|
||||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/dprintf.html ]]
|
|
||||||
*/
|
|
||||||
sprintf :: proc(s: [^]byte, format: cstring, #c_vararg args: ..any) -> c.int ---
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Associate a stream with a file descriptor.
|
Associate a stream with a file descriptor.
|
||||||
|
|
||||||
@@ -115,34 +105,6 @@ foreign lib {
|
|||||||
*/
|
*/
|
||||||
open_memstream :: proc(bufp: ^[^]byte, sizep: ^c.size_t) -> ^FILE ---
|
open_memstream :: proc(bufp: ^[^]byte, sizep: ^c.size_t) -> ^FILE ---
|
||||||
|
|
||||||
/*
|
|
||||||
Equivalent to getc but unaffected by locks.
|
|
||||||
|
|
||||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getc_unlocked.html ]]
|
|
||||||
*/
|
|
||||||
getc_unlocked :: proc(stream: ^FILE) -> c.int ---
|
|
||||||
|
|
||||||
/*
|
|
||||||
Equivalent to getchar but unaffected by locks.
|
|
||||||
|
|
||||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getc_unlocked.html ]]
|
|
||||||
*/
|
|
||||||
getchar_unlocked :: proc() -> c.int ---
|
|
||||||
|
|
||||||
/*
|
|
||||||
Equivalent to putc but unaffected by locks.
|
|
||||||
|
|
||||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getc_unlocked.html ]]
|
|
||||||
*/
|
|
||||||
putc_unlocked :: proc(ch: c.int, stream: ^FILE) -> c.int ---
|
|
||||||
|
|
||||||
/*
|
|
||||||
Equivalent to putchar but unaffected by locks.
|
|
||||||
|
|
||||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getc_unlocked.html ]]
|
|
||||||
*/
|
|
||||||
putchar_unlocked :: proc(ch: c.int) -> c.int ---
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Read a delimited record from the stream.
|
Read a delimited record from the stream.
|
||||||
|
|
||||||
@@ -181,60 +143,6 @@ foreign lib {
|
|||||||
*/
|
*/
|
||||||
getline :: proc(lineptr: ^cstring, n: ^c.size_t, stream: ^FILE) -> c.ssize_t ---
|
getline :: proc(lineptr: ^cstring, n: ^c.size_t, stream: ^FILE) -> c.ssize_t ---
|
||||||
|
|
||||||
/*
|
|
||||||
Get a string from the stdin stream.
|
|
||||||
|
|
||||||
It is up to the user to make sure s is big enough.
|
|
||||||
|
|
||||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/gets.html ]]
|
|
||||||
*/
|
|
||||||
gets :: proc(s: [^]byte) -> cstring ---
|
|
||||||
|
|
||||||
/*
|
|
||||||
Create a name for a temporary file.
|
|
||||||
|
|
||||||
Returns: an allocated cstring that needs to be freed, nil on failure
|
|
||||||
|
|
||||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/tempnam.html ]]
|
|
||||||
*/
|
|
||||||
tempnam :: proc(dir: cstring, pfx: cstring) -> cstring ---
|
|
||||||
|
|
||||||
/*
|
|
||||||
Executes the command specified, creating a pipe and returning a pointer to a stream that can
|
|
||||||
read or write from/to the pipe.
|
|
||||||
|
|
||||||
Returns: nil (setting errno) on failure or a pointer to the stream
|
|
||||||
|
|
||||||
Example:
|
|
||||||
fp := posix.popen("ls *", "r")
|
|
||||||
if fp == nil {
|
|
||||||
/* Handle error */
|
|
||||||
}
|
|
||||||
|
|
||||||
path: [1024]byte
|
|
||||||
for posix.fgets(raw_data(path[:]), len(path), fp) != nil {
|
|
||||||
posix.printf("%s", &path)
|
|
||||||
}
|
|
||||||
|
|
||||||
status := posix.pclose(fp)
|
|
||||||
if status == -1 {
|
|
||||||
/* Error reported by pclose() */
|
|
||||||
} else {
|
|
||||||
/* Use functions described under wait() to inspect `status` in order
|
|
||||||
to determine success/failure of the command executed by popen() */
|
|
||||||
}
|
|
||||||
|
|
||||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/popen.html ]]
|
|
||||||
*/
|
|
||||||
popen :: proc(command: cstring, mode: cstring) -> ^FILE ---
|
|
||||||
|
|
||||||
/*
|
|
||||||
Closes a pipe stream to or from a process.
|
|
||||||
|
|
||||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pclose.html ]]
|
|
||||||
*/
|
|
||||||
pclose :: proc(stream: ^FILE) -> c.int ---
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Equivalent to rename but relative directories are resolved from their respective fds.
|
Equivalent to rename but relative directories are resolved from their respective fds.
|
||||||
|
|
||||||
@@ -243,76 +151,6 @@ foreign lib {
|
|||||||
renameat :: proc(oldfd: FD, old: cstring, newfd: FD, new: cstring) -> result ---
|
renameat :: proc(oldfd: FD, old: cstring, newfd: FD, new: cstring) -> result ---
|
||||||
}
|
}
|
||||||
|
|
||||||
clearerr :: libc.clearerr
|
|
||||||
fclose :: libc.fclose
|
|
||||||
feof :: libc.feof
|
|
||||||
ferror :: libc.ferror
|
|
||||||
fflush :: libc.fflush
|
|
||||||
fgetc :: libc.fgetc
|
|
||||||
fgetpos :: libc.fgetpos
|
|
||||||
fgets :: libc.fgets
|
|
||||||
fopen :: libc.fopen
|
|
||||||
fprintf :: libc.fprintf
|
|
||||||
fputc :: libc.fputc
|
|
||||||
fread :: libc.fread
|
|
||||||
freopen :: libc.freopen
|
|
||||||
fscanf :: libc.fscanf
|
|
||||||
fseek :: libc.fseek
|
|
||||||
fsetpos :: libc.fsetpos
|
|
||||||
ftell :: libc.ftell
|
|
||||||
fwrite :: libc.fwrite
|
|
||||||
getc :: libc.getc
|
|
||||||
getchar :: libc.getchar
|
|
||||||
perror :: libc.perror
|
|
||||||
printf :: libc.printf
|
|
||||||
putc :: libc.puts
|
|
||||||
putchar :: libc.putchar
|
|
||||||
puts :: libc.puts
|
|
||||||
remove :: libc.remove
|
|
||||||
rename :: libc.rename
|
|
||||||
rewind :: libc.rewind
|
|
||||||
scanf :: libc.scanf
|
|
||||||
setbuf :: libc.setbuf
|
|
||||||
setvbuf :: libc.setvbuf
|
|
||||||
snprintf :: libc.snprintf
|
|
||||||
sscanf :: libc.sscanf
|
|
||||||
tmpfile :: libc.tmpfile
|
|
||||||
tmpnam :: libc.tmpnam
|
|
||||||
vfprintf :: libc.vfprintf
|
|
||||||
vfscanf :: libc.vfscanf
|
|
||||||
vprintf :: libc.vprintf
|
|
||||||
vscanf :: libc.vscanf
|
|
||||||
vsnprintf :: libc.vsnprintf
|
|
||||||
vsprintf :: libc.vsprintf
|
|
||||||
vsscanf :: libc.vsscanf
|
|
||||||
ungetc :: libc.ungetc
|
|
||||||
|
|
||||||
to_stream :: libc.to_stream
|
|
||||||
|
|
||||||
Whence :: libc.Whence
|
|
||||||
FILE :: libc.FILE
|
|
||||||
fpos_t :: libc.fpos_t
|
|
||||||
|
|
||||||
BUFSIZ :: libc.BUFSIZ
|
|
||||||
|
|
||||||
_IOFBF :: libc._IOFBF
|
|
||||||
_IOLBF :: libc._IOLBF
|
|
||||||
_IONBF :: libc._IONBF
|
|
||||||
|
|
||||||
SEEK_CUR :: libc.SEEK_CUR
|
|
||||||
SEEK_END :: libc.SEEK_END
|
|
||||||
SEEK_SET :: libc.SEEK_SET
|
|
||||||
|
|
||||||
FILENAME_MAX :: libc.FILENAME_MAX
|
|
||||||
FOPEN_MAX :: libc.FOPEN_MAX
|
|
||||||
TMP_MAX :: libc.TMP_MAX
|
|
||||||
|
|
||||||
EOF :: libc.EOF
|
|
||||||
|
|
||||||
stderr := libc.stderr
|
|
||||||
stdin := libc.stdin
|
|
||||||
stdout := libc.stdout
|
|
||||||
|
|
||||||
when ODIN_OS == .Darwin {
|
when ODIN_OS == .Darwin {
|
||||||
|
|
||||||
L_ctermid :: 1024
|
L_ctermid :: 1024
|
||||||
@@ -327,6 +165,11 @@ when ODIN_OS == .Darwin {
|
|||||||
|
|
||||||
P_tmpdir :: "/tmp/"
|
P_tmpdir :: "/tmp/"
|
||||||
|
|
||||||
} else {
|
} else when ODIN_OS == .Linux {
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
|
L_ctermid :: 20 // 20 on musl, 9 on glibc
|
||||||
|
L_tmpnam :: 20
|
||||||
|
|
||||||
|
P_tmpdir :: "/tmp/"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,207 @@
|
|||||||
|
#+build linux, windows, linux, darwin, netbsd, openbsd, freebsd
|
||||||
|
package posix
|
||||||
|
|
||||||
|
import "core:c"
|
||||||
|
import "core:c/libc"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib {
|
||||||
|
"system:libucrt.lib",
|
||||||
|
"system:legacy_stdio_definitions.lib",
|
||||||
|
}
|
||||||
|
} else when ODIN_OS == .Darwin {
|
||||||
|
foreign import lib "system:System.framework"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:c"
|
||||||
|
}
|
||||||
|
|
||||||
|
// stdio.h - standard buffered input/output
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
@(private) LGETC_UNLOCKED :: "_getc_nolock"
|
||||||
|
@(private) LGETCHAR_UNLOCKED :: "_getchar_nolock"
|
||||||
|
@(private) LPUTC_UNLOCKED :: "_putc_nolock"
|
||||||
|
@(private) LPUTCHAR_UNLOCKED :: "_putchar_nolock"
|
||||||
|
@(private) LTEMPNAM :: "_tempnam"
|
||||||
|
@(private) LPOPEN :: "_popen"
|
||||||
|
@(private) LPCLOSE :: "_pclose"
|
||||||
|
} else {
|
||||||
|
@(private) LGETC_UNLOCKED :: "getc_unlocked"
|
||||||
|
@(private) LGETCHAR_UNLOCKED :: "getchar_unlocked"
|
||||||
|
@(private) LPUTC_UNLOCKED :: "putc_unlocked"
|
||||||
|
@(private) LPUTCHAR_UNLOCKED :: "putchar_unlocked"
|
||||||
|
@(private) LTEMPNAM :: "tempnam"
|
||||||
|
@(private) LPOPEN :: "popen"
|
||||||
|
@(private) LPCLOSE :: "pclose"
|
||||||
|
}
|
||||||
|
|
||||||
|
foreign lib {
|
||||||
|
/*
|
||||||
|
Equivalent to fprintf but output is written to s, it is the user's responsibility to
|
||||||
|
ensure there is enough space.
|
||||||
|
|
||||||
|
Return: number of bytes written, negative (setting errno) on failure
|
||||||
|
|
||||||
|
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/dprintf.html ]]
|
||||||
|
*/
|
||||||
|
sprintf :: proc(s: [^]byte, format: cstring, #c_vararg args: ..any) -> c.int ---
|
||||||
|
|
||||||
|
/*
|
||||||
|
Equivalent to getc but unaffected by locks.
|
||||||
|
|
||||||
|
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getc_unlocked.html ]]
|
||||||
|
*/
|
||||||
|
@(link_name=LGETC_UNLOCKED)
|
||||||
|
getc_unlocked :: proc(stream: ^FILE) -> c.int ---
|
||||||
|
|
||||||
|
/*
|
||||||
|
Equivalent to getchar but unaffected by locks.
|
||||||
|
|
||||||
|
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getc_unlocked.html ]]
|
||||||
|
*/
|
||||||
|
@(link_name=LGETCHAR_UNLOCKED)
|
||||||
|
getchar_unlocked :: proc() -> c.int ---
|
||||||
|
|
||||||
|
/*
|
||||||
|
Equivalent to putc but unaffected by locks.
|
||||||
|
|
||||||
|
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getc_unlocked.html ]]
|
||||||
|
*/
|
||||||
|
@(link_name=LPUTC_UNLOCKED)
|
||||||
|
putc_unlocked :: proc(ch: c.int, stream: ^FILE) -> c.int ---
|
||||||
|
|
||||||
|
/*
|
||||||
|
Equivalent to putchar but unaffected by locks.
|
||||||
|
|
||||||
|
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getc_unlocked.html ]]
|
||||||
|
*/
|
||||||
|
@(link_name=LPUTCHAR_UNLOCKED)
|
||||||
|
putchar_unlocked :: proc(ch: c.int) -> c.int ---
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get a string from the stdin stream.
|
||||||
|
|
||||||
|
It is up to the user to make sure s is big enough.
|
||||||
|
|
||||||
|
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/gets.html ]]
|
||||||
|
*/
|
||||||
|
gets :: proc(s: [^]byte) -> cstring ---
|
||||||
|
|
||||||
|
/*
|
||||||
|
Create a name for a temporary file.
|
||||||
|
|
||||||
|
Returns: an allocated cstring that needs to be freed, nil on failure
|
||||||
|
|
||||||
|
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/tempnam.html ]]
|
||||||
|
*/
|
||||||
|
@(link_name=LTEMPNAM)
|
||||||
|
tempnam :: proc(dir: cstring, pfx: cstring) -> cstring ---
|
||||||
|
|
||||||
|
/*
|
||||||
|
Executes the command specified, creating a pipe and returning a pointer to a stream that can
|
||||||
|
read or write from/to the pipe.
|
||||||
|
|
||||||
|
Returns: nil (setting errno) on failure or a pointer to the stream
|
||||||
|
|
||||||
|
Example:
|
||||||
|
fp := posix.popen("ls *", "r")
|
||||||
|
if fp == nil {
|
||||||
|
/* Handle error */
|
||||||
|
}
|
||||||
|
|
||||||
|
path: [1024]byte
|
||||||
|
for posix.fgets(raw_data(path[:]), len(path), fp) != nil {
|
||||||
|
posix.printf("%s", &path)
|
||||||
|
}
|
||||||
|
|
||||||
|
status := posix.pclose(fp)
|
||||||
|
if status == -1 {
|
||||||
|
/* Error reported by pclose() */
|
||||||
|
} else {
|
||||||
|
/* Use functions described under wait() to inspect `status` in order
|
||||||
|
to determine success/failure of the command executed by popen() */
|
||||||
|
}
|
||||||
|
|
||||||
|
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/popen.html ]]
|
||||||
|
*/
|
||||||
|
@(link_name=LPOPEN)
|
||||||
|
popen :: proc(command: cstring, mode: cstring) -> ^FILE ---
|
||||||
|
|
||||||
|
/*
|
||||||
|
Closes a pipe stream to or from a process.
|
||||||
|
|
||||||
|
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/pclose.html ]]
|
||||||
|
*/
|
||||||
|
@(link_name=LPCLOSE)
|
||||||
|
pclose :: proc(stream: ^FILE) -> c.int ---
|
||||||
|
}
|
||||||
|
|
||||||
|
clearerr :: libc.clearerr
|
||||||
|
fclose :: libc.fclose
|
||||||
|
feof :: libc.feof
|
||||||
|
ferror :: libc.ferror
|
||||||
|
fflush :: libc.fflush
|
||||||
|
fgetc :: libc.fgetc
|
||||||
|
fgetpos :: libc.fgetpos
|
||||||
|
fgets :: libc.fgets
|
||||||
|
fopen :: libc.fopen
|
||||||
|
fprintf :: libc.fprintf
|
||||||
|
fputc :: libc.fputc
|
||||||
|
fread :: libc.fread
|
||||||
|
freopen :: libc.freopen
|
||||||
|
fscanf :: libc.fscanf
|
||||||
|
fseek :: libc.fseek
|
||||||
|
fsetpos :: libc.fsetpos
|
||||||
|
ftell :: libc.ftell
|
||||||
|
fwrite :: libc.fwrite
|
||||||
|
getc :: libc.getc
|
||||||
|
getchar :: libc.getchar
|
||||||
|
perror :: libc.perror
|
||||||
|
printf :: libc.printf
|
||||||
|
putc :: libc.puts
|
||||||
|
putchar :: libc.putchar
|
||||||
|
puts :: libc.puts
|
||||||
|
remove :: libc.remove
|
||||||
|
rename :: libc.rename
|
||||||
|
rewind :: libc.rewind
|
||||||
|
scanf :: libc.scanf
|
||||||
|
setbuf :: libc.setbuf
|
||||||
|
setvbuf :: libc.setvbuf
|
||||||
|
snprintf :: libc.snprintf
|
||||||
|
sscanf :: libc.sscanf
|
||||||
|
tmpfile :: libc.tmpfile
|
||||||
|
tmpnam :: libc.tmpnam
|
||||||
|
vfprintf :: libc.vfprintf
|
||||||
|
vfscanf :: libc.vfscanf
|
||||||
|
vprintf :: libc.vprintf
|
||||||
|
vscanf :: libc.vscanf
|
||||||
|
vsnprintf :: libc.vsnprintf
|
||||||
|
vsprintf :: libc.vsprintf
|
||||||
|
vsscanf :: libc.vsscanf
|
||||||
|
ungetc :: libc.ungetc
|
||||||
|
|
||||||
|
to_stream :: libc.to_stream
|
||||||
|
|
||||||
|
Whence :: libc.Whence
|
||||||
|
FILE :: libc.FILE
|
||||||
|
fpos_t :: libc.fpos_t
|
||||||
|
|
||||||
|
BUFSIZ :: libc.BUFSIZ
|
||||||
|
|
||||||
|
_IOFBF :: libc._IOFBF
|
||||||
|
_IOLBF :: libc._IOLBF
|
||||||
|
_IONBF :: libc._IONBF
|
||||||
|
|
||||||
|
SEEK_CUR :: libc.SEEK_CUR
|
||||||
|
SEEK_END :: libc.SEEK_END
|
||||||
|
SEEK_SET :: libc.SEEK_SET
|
||||||
|
|
||||||
|
FILENAME_MAX :: libc.FILENAME_MAX
|
||||||
|
FOPEN_MAX :: libc.FOPEN_MAX
|
||||||
|
TMP_MAX :: libc.TMP_MAX
|
||||||
|
|
||||||
|
EOF :: libc.EOF
|
||||||
|
|
||||||
|
stderr := libc.stderr
|
||||||
|
stdin := libc.stdin
|
||||||
|
stdout := libc.stdout
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "base:intrinsics"
|
import "base:intrinsics"
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
import "core:c/libc"
|
|
||||||
|
|
||||||
when ODIN_OS == .Darwin {
|
when ODIN_OS == .Darwin {
|
||||||
foreign import lib "system:System.framework"
|
foreign import lib "system:System.framework"
|
||||||
@@ -11,56 +11,6 @@ when ODIN_OS == .Darwin {
|
|||||||
foreign import lib "system:c"
|
foreign import lib "system:c"
|
||||||
}
|
}
|
||||||
|
|
||||||
// stdlib.h - standard library definitions
|
|
||||||
|
|
||||||
atof :: libc.atof
|
|
||||||
atoi :: libc.atoi
|
|
||||||
atol :: libc.atol
|
|
||||||
atoll :: libc.atoll
|
|
||||||
strtod :: libc.strtod
|
|
||||||
strtof :: libc.strtof
|
|
||||||
strtol :: libc.strtol
|
|
||||||
strtoll :: libc.strtoll
|
|
||||||
strtoul :: libc.strtoul
|
|
||||||
strtoull :: libc.strtoull
|
|
||||||
|
|
||||||
rand :: libc.rand
|
|
||||||
srand :: libc.srand
|
|
||||||
|
|
||||||
calloc :: libc.calloc
|
|
||||||
malloc :: libc.malloc
|
|
||||||
realloc :: libc.realloc
|
|
||||||
|
|
||||||
abort :: libc.abort
|
|
||||||
atexit :: libc.atexit
|
|
||||||
at_quick_exit :: libc.at_quick_exit
|
|
||||||
exit :: libc.exit
|
|
||||||
_Exit :: libc._Exit
|
|
||||||
getenv :: libc.getenv
|
|
||||||
quick_exit :: libc.quick_exit
|
|
||||||
system :: libc.system
|
|
||||||
|
|
||||||
bsearch :: libc.bsearch
|
|
||||||
qsort :: libc.qsort
|
|
||||||
|
|
||||||
abs :: libc.abs
|
|
||||||
labs :: libc.labs
|
|
||||||
llabs :: libc.llabs
|
|
||||||
div :: libc.div
|
|
||||||
ldiv :: libc.ldiv
|
|
||||||
lldiv :: libc.lldiv
|
|
||||||
|
|
||||||
mblen :: libc.mblen
|
|
||||||
mbtowc :: libc.mbtowc
|
|
||||||
wctomb :: libc.wctomb
|
|
||||||
|
|
||||||
mbstowcs :: libc.mbstowcs
|
|
||||||
wcstombs :: libc.wcstombs
|
|
||||||
|
|
||||||
free :: #force_inline proc(ptr: $T) where intrinsics.type_is_pointer(T) || intrinsics.type_is_multi_pointer(T) || T == cstring {
|
|
||||||
libc.free(rawptr(ptr))
|
|
||||||
}
|
|
||||||
|
|
||||||
foreign lib {
|
foreign lib {
|
||||||
/*
|
/*
|
||||||
Takes a pointer to a radix-64 representation, in which the first digit is the least significant,
|
Takes a pointer to a radix-64 representation, in which the first digit is the least significant,
|
||||||
@@ -342,21 +292,6 @@ foreign lib {
|
|||||||
*/
|
*/
|
||||||
unlockpt :: proc(fildes: FD) -> result ---
|
unlockpt :: proc(fildes: FD) -> result ---
|
||||||
|
|
||||||
/*
|
|
||||||
Uses the string argument to set environment variable values.
|
|
||||||
|
|
||||||
Returns: 0 on success, non-zero (setting errno) on failure
|
|
||||||
|
|
||||||
Example:
|
|
||||||
if posix.putenv("HOME=/usr/home") != 0 {
|
|
||||||
fmt.panicf("putenv failure: %v", posix.strerror(posix.errno()))
|
|
||||||
}
|
|
||||||
|
|
||||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/putenv.html ]]
|
|
||||||
*/
|
|
||||||
@(link_name=LPUTENV)
|
|
||||||
putenv :: proc(string: cstring) -> c.int ---
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Updates or add a variable in the environment of the calling process.
|
Updates or add a variable in the environment of the calling process.
|
||||||
|
|
||||||
@@ -427,23 +362,11 @@ foreign lib {
|
|||||||
setkey :: proc(key: [^]byte) ---
|
setkey :: proc(key: [^]byte) ---
|
||||||
}
|
}
|
||||||
|
|
||||||
EXIT_FAILURE :: libc.EXIT_FAILURE
|
|
||||||
EXIT_SUCCESS :: libc.EXIT_SUCCESS
|
|
||||||
|
|
||||||
RAND_MAX :: libc.RAND_MAX
|
|
||||||
MB_CUR_MAX :: libc.MB_CUR_MAX
|
|
||||||
|
|
||||||
div_t :: libc.div_t
|
|
||||||
ldiv_t :: libc.ldiv_t
|
|
||||||
lldiv_t :: libc.lldiv_t
|
|
||||||
|
|
||||||
when ODIN_OS == .NetBSD {
|
when ODIN_OS == .NetBSD {
|
||||||
@(private) LPUTENV :: "__putenv50"
|
|
||||||
@(private) LINITSTATE :: "__initstate60"
|
@(private) LINITSTATE :: "__initstate60"
|
||||||
@(private) LSRANDOM :: "__srandom60"
|
@(private) LSRANDOM :: "__srandom60"
|
||||||
@(private) LUNSETENV :: "__unsetenv13"
|
@(private) LUNSETENV :: "__unsetenv13"
|
||||||
} else {
|
} else {
|
||||||
@(private) LPUTENV :: "putenv"
|
|
||||||
@(private) LINITSTATE :: "initstate"
|
@(private) LINITSTATE :: "initstate"
|
||||||
@(private) LSRANDOM :: "srandom"
|
@(private) LSRANDOM :: "srandom"
|
||||||
@(private) LUNSETENV :: "unsetenv"
|
@(private) LUNSETENV :: "unsetenv"
|
||||||
|
|||||||
@@ -0,0 +1,101 @@
|
|||||||
|
#+build linux, windows, darwin, netbsd, openbsd, freebsd
|
||||||
|
package posix
|
||||||
|
|
||||||
|
import "base:intrinsics"
|
||||||
|
|
||||||
|
import "core:c"
|
||||||
|
import "core:c/libc"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib "system:libucrt.lib"
|
||||||
|
} else when ODIN_OS == .Darwin {
|
||||||
|
foreign import lib "system:System.framework"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:c"
|
||||||
|
}
|
||||||
|
|
||||||
|
// stdlib.h - standard library definitions
|
||||||
|
|
||||||
|
atof :: libc.atof
|
||||||
|
atoi :: libc.atoi
|
||||||
|
atol :: libc.atol
|
||||||
|
atoll :: libc.atoll
|
||||||
|
strtod :: libc.strtod
|
||||||
|
strtof :: libc.strtof
|
||||||
|
strtol :: libc.strtol
|
||||||
|
strtoll :: libc.strtoll
|
||||||
|
strtoul :: libc.strtoul
|
||||||
|
strtoull :: libc.strtoull
|
||||||
|
|
||||||
|
rand :: libc.rand
|
||||||
|
srand :: libc.srand
|
||||||
|
|
||||||
|
calloc :: libc.calloc
|
||||||
|
malloc :: libc.malloc
|
||||||
|
realloc :: libc.realloc
|
||||||
|
|
||||||
|
abort :: libc.abort
|
||||||
|
atexit :: libc.atexit
|
||||||
|
at_quick_exit :: libc.at_quick_exit
|
||||||
|
exit :: libc.exit
|
||||||
|
_Exit :: libc._Exit
|
||||||
|
getenv :: libc.getenv
|
||||||
|
quick_exit :: libc.quick_exit
|
||||||
|
system :: libc.system
|
||||||
|
|
||||||
|
bsearch :: libc.bsearch
|
||||||
|
qsort :: libc.qsort
|
||||||
|
|
||||||
|
abs :: libc.abs
|
||||||
|
labs :: libc.labs
|
||||||
|
llabs :: libc.llabs
|
||||||
|
div :: libc.div
|
||||||
|
ldiv :: libc.ldiv
|
||||||
|
lldiv :: libc.lldiv
|
||||||
|
|
||||||
|
mblen :: libc.mblen
|
||||||
|
mbtowc :: libc.mbtowc
|
||||||
|
wctomb :: libc.wctomb
|
||||||
|
|
||||||
|
mbstowcs :: libc.mbstowcs
|
||||||
|
wcstombs :: libc.wcstombs
|
||||||
|
|
||||||
|
free :: #force_inline proc(ptr: $T) where intrinsics.type_is_pointer(T) || intrinsics.type_is_multi_pointer(T) || T == cstring {
|
||||||
|
libc.free(rawptr(ptr))
|
||||||
|
}
|
||||||
|
|
||||||
|
foreign lib {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Uses the string argument to set environment variable values.
|
||||||
|
|
||||||
|
Returns: 0 on success, non-zero (setting errno) on failure
|
||||||
|
|
||||||
|
Example:
|
||||||
|
if posix.putenv("HOME=/usr/home") != 0 {
|
||||||
|
fmt.panicf("putenv failure: %v", posix.strerror(posix.errno()))
|
||||||
|
}
|
||||||
|
|
||||||
|
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/putenv.html ]]
|
||||||
|
*/
|
||||||
|
@(link_name=LPUTENV)
|
||||||
|
putenv :: proc(string: cstring) -> c.int ---
|
||||||
|
}
|
||||||
|
|
||||||
|
EXIT_FAILURE :: libc.EXIT_FAILURE
|
||||||
|
EXIT_SUCCESS :: libc.EXIT_SUCCESS
|
||||||
|
|
||||||
|
RAND_MAX :: libc.RAND_MAX
|
||||||
|
MB_CUR_MAX :: libc.MB_CUR_MAX
|
||||||
|
|
||||||
|
div_t :: libc.div_t
|
||||||
|
ldiv_t :: libc.ldiv_t
|
||||||
|
lldiv_t :: libc.lldiv_t
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
@(private) LPUTENV :: "_putenv"
|
||||||
|
} else when ODIN_OS == .NetBSD {
|
||||||
|
@(private) LPUTENV :: "__putenv50"
|
||||||
|
} else {
|
||||||
|
@(private) LPUTENV :: "putenv"
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -13,16 +14,6 @@ when ODIN_OS == .Darwin {
|
|||||||
// NOTE: most of the symbols in this header are not useful in Odin and have been left out.
|
// NOTE: most of the symbols in this header are not useful in Odin and have been left out.
|
||||||
|
|
||||||
foreign lib {
|
foreign lib {
|
||||||
/*
|
|
||||||
Map the error number to a locale-dependent error message string.
|
|
||||||
|
|
||||||
Returns: a string that may be invalidated by subsequent calls
|
|
||||||
|
|
||||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/strerror.html ]]
|
|
||||||
*/
|
|
||||||
@(link_name="strerror")
|
|
||||||
_strerror :: proc(errnum: Errno) -> cstring ---
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Map the error number to a locale-dependent error message string and put it in the buffer.
|
Map the error number to a locale-dependent error message string and put it in the buffer.
|
||||||
|
|
||||||
@@ -41,7 +32,3 @@ foreign lib {
|
|||||||
*/
|
*/
|
||||||
strsignal :: proc(sig: Signal) -> cstring ---
|
strsignal :: proc(sig: Signal) -> cstring ---
|
||||||
}
|
}
|
||||||
|
|
||||||
strerror :: #force_inline proc "contextless" (errnum: Maybe(Errno) = nil) -> cstring {
|
|
||||||
return _strerror(errnum.? or_else errno())
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
#+build linux, windows, darwin, netbsd, openbsd, freebsd
|
||||||
|
package posix
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib "system:libucrt.lib"
|
||||||
|
} else when ODIN_OS == .Darwin {
|
||||||
|
foreign import lib "system:System.framework"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:c"
|
||||||
|
}
|
||||||
|
|
||||||
|
// string.h - string operations
|
||||||
|
|
||||||
|
// NOTE: most of the symbols in this header are not useful in Odin and have been left out.
|
||||||
|
|
||||||
|
foreign lib {
|
||||||
|
/*
|
||||||
|
Map the error number to a locale-dependent error message string.
|
||||||
|
|
||||||
|
Returns: a string that may be invalidated by subsequent calls
|
||||||
|
|
||||||
|
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/strerror.html ]]
|
||||||
|
*/
|
||||||
|
@(link_name="strerror")
|
||||||
|
_strerror :: proc(errnum: Errno) -> cstring ---
|
||||||
|
}
|
||||||
|
|
||||||
|
strerror :: #force_inline proc "contextless" (errnum: Maybe(Errno) = nil) -> cstring {
|
||||||
|
return _strerror(errnum.? or_else errno())
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -110,6 +111,4 @@ when ODIN_OS == .Darwin {
|
|||||||
IPC_SET :: 1
|
IPC_SET :: 1
|
||||||
IPC_STAT :: 2
|
IPC_STAT :: 2
|
||||||
|
|
||||||
} else {
|
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -225,6 +226,4 @@ when ODIN_OS == .Darwin || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS
|
|||||||
POSIX_MADV_SEQUENTIAL :: 2
|
POSIX_MADV_SEQUENTIAL :: 2
|
||||||
POSIX_MADV_WILLNEED :: 3
|
POSIX_MADV_WILLNEED :: 3
|
||||||
|
|
||||||
} else {
|
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -150,6 +151,24 @@ when ODIN_OS == .Darwin {
|
|||||||
msg_pad4: [4]c.long,
|
msg_pad4: [4]c.long,
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else when ODIN_OS == .Linux {
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
|
msgqnum_t :: distinct c.ulong
|
||||||
|
msglen_t :: distinct c.ulong
|
||||||
|
|
||||||
|
MSG_NOERROR :: 0o10000
|
||||||
|
|
||||||
|
msqid_ds :: struct {
|
||||||
|
msg_perm: ipc_perm, /* [PSX] operation permission structure */
|
||||||
|
msg_stime: time_t, /* [PSX] time of last msgsnd() */
|
||||||
|
msg_rtime: time_t, /* [PSX] time of last msgrcv() */
|
||||||
|
msg_ctime: time_t, /* [PSX] time of last change */
|
||||||
|
msg_cbytes: c.ulong,
|
||||||
|
msg_qnum: msgqnum_t, /* [PSX] number of messages currently on queue */
|
||||||
|
msg_qbytes: msglen_t, /* [PSX] maximum number of bytes allowed on queue */
|
||||||
|
msg_lspid: pid_t, /* [PSX] process ID of last msgsnd() */
|
||||||
|
msg_lrpid: pid_t, /* [PSX] process ID of last msgrcv() */
|
||||||
|
__unused: [2]c.ulong,
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -154,6 +155,4 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
RLIMIT_AS :: 10
|
RLIMIT_AS :: 10
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "base:intrinsics"
|
import "base:intrinsics"
|
||||||
@@ -72,7 +73,7 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
|
|
||||||
// NOTE: this seems correct for FreeBSD but they do use a set backed by the long type themselves (thus the align change).
|
// NOTE: this seems correct for FreeBSD but they do use a set backed by the long type themselves (thus the align change).
|
||||||
@(private)
|
@(private)
|
||||||
ALIGN :: align_of(c.long) when ODIN_OS == .FreeBSD else align_of(c.int32_t)
|
ALIGN :: align_of(c.long) when ODIN_OS == .FreeBSD || ODIN_OS == .Linux else align_of(c.int32_t)
|
||||||
|
|
||||||
fd_set :: struct #align(ALIGN) {
|
fd_set :: struct #align(ALIGN) {
|
||||||
fds_bits: [(FD_SETSIZE / __NFDBITS) when (FD_SETSIZE % __NFDBITS) == 0 else (FD_SETSIZE / __NFDBITS) + 1]c.int32_t,
|
fds_bits: [(FD_SETSIZE / __NFDBITS) when (FD_SETSIZE % __NFDBITS) == 0 else (FD_SETSIZE / __NFDBITS) + 1]c.int32_t,
|
||||||
@@ -115,6 +116,4 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
intrinsics.mem_zero(_p, size_of(fd_set))
|
intrinsics.mem_zero(_p, size_of(fd_set))
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -153,6 +154,4 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
sem_flg: c.short, /* [PSX] operation flags */
|
sem_flg: c.short, /* [PSX] operation flags */
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -137,6 +138,24 @@ when ODIN_OS == .Darwin {
|
|||||||
_shm_internal: rawptr,
|
_shm_internal: rawptr,
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else when ODIN_OS == .Linux {
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
|
SHM_RDONLY :: 0o10000
|
||||||
|
SHM_RND :: 0o20000
|
||||||
|
|
||||||
|
SHMLBA :: 4096
|
||||||
|
|
||||||
|
shmatt_t :: distinct c.ulong
|
||||||
|
|
||||||
|
shmid_ds :: struct {
|
||||||
|
shm_perm: ipc_perm, /* [PSX] operation permission structure */
|
||||||
|
shm_segsz: c.size_t, /* [PSX] size of segment in bytes */
|
||||||
|
shm_atime: time_t, /* [PSX] time of last shmat() */
|
||||||
|
shm_dtime: time_t, /* [PSX] time of last shmdt() */
|
||||||
|
shm_ctime: time_t, /* [PSX] time of last change by shmctl() */
|
||||||
|
shm_cpid: pid_t, /* [PSX] process ID of creator */
|
||||||
|
shm_lpid: pid_t, /* [PSX] process ID of last shared memory operation */
|
||||||
|
shm_nattch: shmatt_t, /* [PSX] number of current attaches */
|
||||||
|
_: [2]c.ulong,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -325,14 +326,16 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
|
|
||||||
socklen_t :: distinct c.uint
|
socklen_t :: distinct c.uint
|
||||||
|
|
||||||
_sa_family_t :: distinct c.uint8_t
|
|
||||||
|
|
||||||
when ODIN_OS == .Linux {
|
when ODIN_OS == .Linux {
|
||||||
|
_sa_family_t :: distinct c.ushort
|
||||||
|
|
||||||
sockaddr :: struct {
|
sockaddr :: struct {
|
||||||
sa_family: sa_family_t, /* [PSX] address family */
|
sa_family: sa_family_t, /* [PSX] address family */
|
||||||
sa_data: [14]c.char, /* [PSX] socket address */
|
sa_data: [14]c.char, /* [PSX] socket address */
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
_sa_family_t :: distinct c.uint8_t
|
||||||
|
|
||||||
sockaddr :: struct {
|
sockaddr :: struct {
|
||||||
sa_len: c.uint8_t, /* total length */
|
sa_len: c.uint8_t, /* total length */
|
||||||
sa_family: sa_family_t, /* [PSX] address family */
|
sa_family: sa_family_t, /* [PSX] address family */
|
||||||
@@ -560,7 +563,4 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
SHUT_RDWR :: 2
|
SHUT_RDWR :: 2
|
||||||
SHUT_WR :: 1
|
SHUT_WR :: 1
|
||||||
|
|
||||||
} else {
|
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+120
-67
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -280,20 +281,20 @@ when ODIN_OS == .Darwin {
|
|||||||
ino_t :: distinct c.uint64_t
|
ino_t :: distinct c.uint64_t
|
||||||
|
|
||||||
stat_t :: struct {
|
stat_t :: struct {
|
||||||
st_dev: dev_t, /* [XSI] ID of device containing file */
|
st_dev: dev_t, /* [PSX] ID of device containing file */
|
||||||
st_mode: mode_t, /* [XSI] mode of file */
|
st_mode: mode_t, /* [PSX] mode of file */
|
||||||
st_nlink: nlink_t, /* [XSI] number of hard links */
|
st_nlink: nlink_t, /* [PSX] number of hard links */
|
||||||
st_ino: ino_t, /* [XSI] file serial number */
|
st_ino: ino_t, /* [PSX] file serial number */
|
||||||
st_uid: uid_t, /* [XSI] user ID of the file */
|
st_uid: uid_t, /* [PSX] user ID of the file */
|
||||||
st_gid: gid_t, /* [XSI] group ID of the file */
|
st_gid: gid_t, /* [PSX] group ID of the file */
|
||||||
st_rdev: dev_t, /* [XSI] device ID */
|
st_rdev: dev_t, /* [PSX] device ID */
|
||||||
st_atim: timespec, /* [XSI] time of last access */
|
st_atim: timespec, /* [PSX] time of last access */
|
||||||
st_mtim: timespec, /* [XSI] time of last data modification */
|
st_mtim: timespec, /* [PSX] time of last data modification */
|
||||||
st_ctim: timespec, /* [XSI] time of last status change */
|
st_ctim: timespec, /* [PSX] time of last status change */
|
||||||
st_birthtimespec: timespec, /* time of file creation(birth) */
|
st_birthtimespec: timespec, /* time of file creation(birth) */
|
||||||
st_size: off_t, /* [XSI] file size, in bytes */
|
st_size: off_t, /* [PSX] file size, in bytes */
|
||||||
st_blocks: blkcnt_t, /* [XSI] blocks allocated for file */
|
st_blocks: blkcnt_t, /* [PSX] blocks allocated for file */
|
||||||
st_blksize: blksize_t, /* [XSI] optimal blocksize for I/O */
|
st_blksize: blksize_t, /* [PSX] optimal blocksize for I/O */
|
||||||
st_flags: c.uint32_t, /* user defined flags for file */
|
st_flags: c.uint32_t, /* user defined flags for file */
|
||||||
st_gen: c.uint32_t, /* file generation number */
|
st_gen: c.uint32_t, /* file generation number */
|
||||||
st_lspare: c.int32_t, /* RESERVED */
|
st_lspare: c.int32_t, /* RESERVED */
|
||||||
@@ -314,47 +315,47 @@ when ODIN_OS == .Darwin {
|
|||||||
|
|
||||||
when ODIN_ARCH == .i386 {
|
when ODIN_ARCH == .i386 {
|
||||||
stat_t :: struct {
|
stat_t :: struct {
|
||||||
st_dev: dev_t, /* [XSI] ID of device containing file */
|
st_dev: dev_t, /* [PSX] ID of device containing file */
|
||||||
st_ino: ino_t, /* [XSI] file serial number */
|
st_ino: ino_t, /* [PSX] file serial number */
|
||||||
st_nlink: nlink_t, /* [XSI] number of hard links */
|
st_nlink: nlink_t, /* [PSX] number of hard links */
|
||||||
st_mode: mode_t, /* [XSI] mode of file */
|
st_mode: mode_t, /* [PSX] mode of file */
|
||||||
st_padding0: c.int16_t,
|
st_padding0: c.int16_t,
|
||||||
st_uid: uid_t, /* [XSI] user ID of the file */
|
st_uid: uid_t, /* [PSX] user ID of the file */
|
||||||
st_gid: gid_t, /* [XSI] group ID of the file */
|
st_gid: gid_t, /* [PSX] group ID of the file */
|
||||||
st_padding1: c.int32_t,
|
st_padding1: c.int32_t,
|
||||||
st_rdev: dev_t, /* [XSI] device ID */
|
st_rdev: dev_t, /* [PSX] device ID */
|
||||||
st_atim_ext: c.int32_t,
|
st_atim_ext: c.int32_t,
|
||||||
st_atim: timespec, /* [XSI] time of last access */
|
st_atim: timespec, /* [PSX] time of last access */
|
||||||
st_mtim_ext: c.int32_t,
|
st_mtim_ext: c.int32_t,
|
||||||
st_mtim: timespec, /* [XSI] time of last data modification */
|
st_mtim: timespec, /* [PSX] time of last data modification */
|
||||||
st_ctim_ext: c.int32_t,
|
st_ctim_ext: c.int32_t,
|
||||||
st_ctim: timespec, /* [XSI] time of last status change */
|
st_ctim: timespec, /* [PSX] time of last status change */
|
||||||
st_birthtimespec: timespec, /* time of file creation(birth) */
|
st_birthtimespec: timespec, /* time of file creation(birth) */
|
||||||
st_size: off_t, /* [XSI] file size, in bytes */
|
st_size: off_t, /* [PSX] file size, in bytes */
|
||||||
st_blocks: blkcnt_t, /* [XSI] blocks allocated for file */
|
st_blocks: blkcnt_t, /* [PSX] blocks allocated for file */
|
||||||
st_blksize: blksize_t, /* [XSI] optimal blocksize for I/O */
|
st_blksize: blksize_t, /* [PSX] optimal blocksize for I/O */
|
||||||
st_flags: c.uint32_t, /* user defined flags for file */
|
st_flags: c.uint32_t, /* user defined flags for file */
|
||||||
st_gen: c.uint64_t,
|
st_gen: c.uint64_t,
|
||||||
st_spare: [10]c.uint64_t,
|
st_spare: [10]c.uint64_t,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
stat_t :: struct {
|
stat_t :: struct {
|
||||||
st_dev: dev_t, /* [XSI] ID of device containing file */
|
st_dev: dev_t, /* [PSX] ID of device containing file */
|
||||||
st_ino: ino_t, /* [XSI] file serial number */
|
st_ino: ino_t, /* [PSX] file serial number */
|
||||||
st_nlink: nlink_t, /* [XSI] number of hard links */
|
st_nlink: nlink_t, /* [PSX] number of hard links */
|
||||||
st_mode: mode_t, /* [XSI] mode of file */
|
st_mode: mode_t, /* [PSX] mode of file */
|
||||||
st_padding0: c.int16_t,
|
st_padding0: c.int16_t,
|
||||||
st_uid: uid_t, /* [XSI] user ID of the file */
|
st_uid: uid_t, /* [PSX] user ID of the file */
|
||||||
st_gid: gid_t, /* [XSI] group ID of the file */
|
st_gid: gid_t, /* [PSX] group ID of the file */
|
||||||
st_padding1: c.int32_t,
|
st_padding1: c.int32_t,
|
||||||
st_rdev: dev_t, /* [XSI] device ID */
|
st_rdev: dev_t, /* [PSX] device ID */
|
||||||
st_atim: timespec, /* [XSI] time of last access */
|
st_atim: timespec, /* [PSX] time of last access */
|
||||||
st_mtim: timespec, /* [XSI] time of last data modification */
|
st_mtim: timespec, /* [PSX] time of last data modification */
|
||||||
st_ctim: timespec, /* [XSI] time of last status change */
|
st_ctim: timespec, /* [PSX] time of last status change */
|
||||||
st_birthtimespec: timespec, /* time of file creation(birth) */
|
st_birthtimespec: timespec, /* time of file creation(birth) */
|
||||||
st_size: off_t, /* [XSI] file size, in bytes */
|
st_size: off_t, /* [PSX] file size, in bytes */
|
||||||
st_blocks: blkcnt_t, /* [XSI] blocks allocated for file */
|
st_blocks: blkcnt_t, /* [PSX] blocks allocated for file */
|
||||||
st_blksize: blksize_t, /* [XSI] optimal blocksize for I/O */
|
st_blksize: blksize_t, /* [PSX] optimal blocksize for I/O */
|
||||||
st_flags: c.uint32_t, /* user defined flags for file */
|
st_flags: c.uint32_t, /* user defined flags for file */
|
||||||
st_gen: c.uint64_t,
|
st_gen: c.uint64_t,
|
||||||
st_spare: [10]c.uint64_t,
|
st_spare: [10]c.uint64_t,
|
||||||
@@ -374,20 +375,20 @@ when ODIN_OS == .Darwin {
|
|||||||
ino_t :: distinct c.uint64_t
|
ino_t :: distinct c.uint64_t
|
||||||
|
|
||||||
stat_t :: struct {
|
stat_t :: struct {
|
||||||
st_dev: dev_t, /* [XSI] ID of device containing file */
|
st_dev: dev_t, /* [PSX] ID of device containing file */
|
||||||
st_mode: mode_t, /* [XSI] mode of file */
|
st_mode: mode_t, /* [PSX] mode of file */
|
||||||
st_ino: ino_t, /* [XSI] file serial number */
|
st_ino: ino_t, /* [PSX] file serial number */
|
||||||
st_nlink: nlink_t, /* [XSI] number of hard links */
|
st_nlink: nlink_t, /* [PSX] number of hard links */
|
||||||
st_uid: uid_t, /* [XSI] user ID of the file */
|
st_uid: uid_t, /* [PSX] user ID of the file */
|
||||||
st_gid: gid_t, /* [XSI] group ID of the file */
|
st_gid: gid_t, /* [PSX] group ID of the file */
|
||||||
st_rdev: dev_t, /* [XSI] device ID */
|
st_rdev: dev_t, /* [PSX] device ID */
|
||||||
st_atim: timespec, /* [XSI] time of last access */
|
st_atim: timespec, /* [PSX] time of last access */
|
||||||
st_mtim: timespec, /* [XSI] time of last data modification */
|
st_mtim: timespec, /* [PSX] time of last data modification */
|
||||||
st_ctim: timespec, /* [XSI] time of last status change */
|
st_ctim: timespec, /* [PSX] time of last status change */
|
||||||
st_birthtimespec: timespec, /* time of file creation(birth) */
|
st_birthtimespec: timespec, /* time of file creation(birth) */
|
||||||
st_size: off_t, /* [XSI] file size, in bytes */
|
st_size: off_t, /* [PSX] file size, in bytes */
|
||||||
st_blocks: blkcnt_t, /* [XSI] blocks allocated for file */
|
st_blocks: blkcnt_t, /* [PSX] blocks allocated for file */
|
||||||
st_blksize: blksize_t, /* [XSI] optimal blocksize for I/O */
|
st_blksize: blksize_t, /* [PSX] optimal blocksize for I/O */
|
||||||
st_flags: c.uint32_t, /* user defined flags for file */
|
st_flags: c.uint32_t, /* user defined flags for file */
|
||||||
st_gen: c.uint64_t,
|
st_gen: c.uint64_t,
|
||||||
st_spare: [2]c.uint32_t,
|
st_spare: [2]c.uint32_t,
|
||||||
@@ -406,19 +407,19 @@ when ODIN_OS == .Darwin {
|
|||||||
ino_t :: distinct c.uint64_t
|
ino_t :: distinct c.uint64_t
|
||||||
|
|
||||||
stat_t :: struct {
|
stat_t :: struct {
|
||||||
st_mode: mode_t, /* [XSI] mode of file */
|
st_mode: mode_t, /* [PSX] mode of file */
|
||||||
st_dev: dev_t, /* [XSI] ID of device containing file */
|
st_dev: dev_t, /* [PSX] ID of device containing file */
|
||||||
st_ino: ino_t, /* [XSI] file serial number */
|
st_ino: ino_t, /* [PSX] file serial number */
|
||||||
st_nlink: nlink_t, /* [XSI] number of hard links */
|
st_nlink: nlink_t, /* [PSX] number of hard links */
|
||||||
st_uid: uid_t, /* [XSI] user ID of the file */
|
st_uid: uid_t, /* [PSX] user ID of the file */
|
||||||
st_gid: gid_t, /* [XSI] group ID of the file */
|
st_gid: gid_t, /* [PSX] group ID of the file */
|
||||||
st_rdev: dev_t, /* [XSI] device ID */
|
st_rdev: dev_t, /* [PSX] device ID */
|
||||||
st_atim: timespec, /* [XSI] time of last access */
|
st_atim: timespec, /* [PSX] time of last access */
|
||||||
st_mtim: timespec, /* [XSI] time of last data modification */
|
st_mtim: timespec, /* [PSX] time of last data modification */
|
||||||
st_ctim: timespec, /* [XSI] time of last status change */
|
st_ctim: timespec, /* [PSX] time of last status change */
|
||||||
st_size: off_t, /* [XSI] file size, in bytes */
|
st_size: off_t, /* [PSX] file size, in bytes */
|
||||||
st_blocks: blkcnt_t, /* [XSI] blocks allocated for file */
|
st_blocks: blkcnt_t, /* [PSX] blocks allocated for file */
|
||||||
st_blksize: blksize_t, /* [XSI] optimal blocksize for I/O */
|
st_blksize: blksize_t, /* [PSX] optimal blocksize for I/O */
|
||||||
st_flags: c.uint32_t, /* user defined flags for file */
|
st_flags: c.uint32_t, /* user defined flags for file */
|
||||||
st_gen: c.int32_t,
|
st_gen: c.int32_t,
|
||||||
st_birthtimespec: timespec,
|
st_birthtimespec: timespec,
|
||||||
@@ -427,6 +428,58 @@ when ODIN_OS == .Darwin {
|
|||||||
UTIME_NOW :: -2
|
UTIME_NOW :: -2
|
||||||
UTIME_OMIT :: -1
|
UTIME_OMIT :: -1
|
||||||
|
|
||||||
} else {
|
} else when ODIN_OS == .Linux {
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
|
dev_t :: distinct u64
|
||||||
|
_mode_t :: distinct c.uint
|
||||||
|
blkcnt_t :: distinct i64
|
||||||
|
|
||||||
|
when ODIN_ARCH == .arm64 || ODIN_ARCH == .riscv64 {
|
||||||
|
nlink_t :: distinct c.uint
|
||||||
|
blksize_t :: distinct c.int
|
||||||
|
} else {
|
||||||
|
nlink_t :: distinct c.size_t
|
||||||
|
blksize_t :: distinct c.long
|
||||||
|
}
|
||||||
|
|
||||||
|
ino_t :: distinct u64
|
||||||
|
|
||||||
|
when ODIN_ARCH == .amd64 {
|
||||||
|
stat_t :: struct {
|
||||||
|
st_dev: dev_t, /* [PSX] ID of device containing file */
|
||||||
|
st_ino: ino_t, /* [PSX] file serial number */
|
||||||
|
st_nlink: nlink_t, /* [PSX] number of hard links */
|
||||||
|
st_mode: mode_t, /* [PSX] mode of file */
|
||||||
|
st_uid: uid_t, /* [PSX] user ID of the file */
|
||||||
|
st_gid: gid_t, /* [PSX] group ID of the file */
|
||||||
|
_pad0: c.uint,
|
||||||
|
st_rdev: dev_t, /* [PSX] device ID */
|
||||||
|
st_size: off_t, /* [PSX] file size, in bytes */
|
||||||
|
st_blksize: blksize_t, /* [PSX] optimal blocksize for I/O */
|
||||||
|
st_blocks: blkcnt_t, /* [PSX] blocks allocated for file */
|
||||||
|
st_atim: timespec, /* [PSX] time of last access */
|
||||||
|
st_mtim: timespec, /* [PSX] time of last data modification */
|
||||||
|
st_ctim: timespec, /* [PSX] time of last status change */
|
||||||
|
__unused: [3]c.long,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
stat_t :: struct {
|
||||||
|
st_dev: dev_t, /* [PSX] ID of device containing file */
|
||||||
|
st_ino: ino_t, /* [PSX] file serial number */
|
||||||
|
st_mode: mode_t, /* [PSX] mode of file */
|
||||||
|
st_nlink: nlink_t, /* [PSX] number of hard links */
|
||||||
|
st_uid: uid_t, /* [PSX] user ID of the file */
|
||||||
|
st_gid: gid_t, /* [PSX] group ID of the file */
|
||||||
|
st_rdev: dev_t, /* [PSX] device ID */
|
||||||
|
__pad: c.ulonglong,
|
||||||
|
st_size: off_t, /* [PSX] file size, in bytes */
|
||||||
|
st_blksize: blksize_t, /* [PSX] optimal blocksize for I/O */
|
||||||
|
__pad2: c.int,
|
||||||
|
st_blocks: blkcnt_t, /* [PSX] blocks allocated for file */
|
||||||
|
st_atim: timespec, /* [PSX] time of last access */
|
||||||
|
st_mtim: timespec, /* [PSX] time of last data modification */
|
||||||
|
st_ctim: timespec, /* [PSX] time of last status change */
|
||||||
|
__unused: [2]c.uint,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -130,6 +131,27 @@ when ODIN_OS == .Darwin || ODIN_OS == .OpenBSD {
|
|||||||
ST_RDONLY :: 0x00000001
|
ST_RDONLY :: 0x00000001
|
||||||
ST_NOSUID :: 0x00000008
|
ST_NOSUID :: 0x00000008
|
||||||
|
|
||||||
} else {
|
} else when ODIN_OS == .Linux {
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
|
fsblkcnt_t :: distinct c.uint64_t
|
||||||
|
|
||||||
|
statvfs_t :: struct {
|
||||||
|
f_bsize: c.ulong, /* [PSX] file system block size */
|
||||||
|
f_frsize: c.ulong, /* [PSX] fundamental file system block size */
|
||||||
|
f_blocks: fsblkcnt_t, /* [PSX] total number of blocks on file system in units of f_frsize */
|
||||||
|
f_bfree: fsblkcnt_t, /* [PSX] total number of free blocks */
|
||||||
|
f_bavail: fsblkcnt_t, /* [PSX] number of free blocks available to non-privileged process */
|
||||||
|
f_files: fsblkcnt_t, /* [PSX] total number of file serial numbers */
|
||||||
|
f_ffree: fsblkcnt_t, /* [PSX] total number of free file serial numbers */
|
||||||
|
f_favail: fsblkcnt_t, /* [PSX] number of file serial numbers available to non-privileged process */
|
||||||
|
f_fsid: c.ulong, /* [PSX] file system ID */
|
||||||
|
_: [2*size_of(c.int)-size_of(c.long)]byte,
|
||||||
|
f_flag: VFS_Flags, /* [PSX] bit mask of f_flag values */
|
||||||
|
f_namemax: c.ulong, /* [PSX] maximum filename length */
|
||||||
|
f_type: c.uint,
|
||||||
|
__reserved: [5]c.int,
|
||||||
|
}
|
||||||
|
|
||||||
|
ST_RDONLY :: 0x00000001
|
||||||
|
ST_NOSUID :: 0x00000002
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -77,6 +78,4 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
ITIMER_VIRTUAL :: 1
|
ITIMER_VIRTUAL :: 1
|
||||||
ITIMER_PROF :: 2
|
ITIMER_PROF :: 2
|
||||||
|
|
||||||
} else {
|
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
when ODIN_OS == .Darwin {
|
when ODIN_OS == .Darwin {
|
||||||
@@ -33,6 +34,4 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
tms_cstime: clock_t, /* [PSX] terminated children system CPU time */
|
tms_cstime: clock_t, /* [PSX] terminated children system CPU time */
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -37,6 +38,4 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
iov_len: c.size_t, /* [PSX] size of the region iov_base points to */
|
iov_len: c.size_t, /* [PSX] size of the region iov_base points to */
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -19,6 +20,4 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
sun_path: [108]c.char, /* [PSX] socket pathname */
|
sun_path: [108]c.char, /* [PSX] socket pathname */
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -37,15 +38,10 @@ foreign lib {
|
|||||||
uname :: proc(uname: ^utsname) -> c.int ---
|
uname :: proc(uname: ^utsname) -> c.int ---
|
||||||
}
|
}
|
||||||
|
|
||||||
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux {
|
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD {
|
||||||
|
|
||||||
when ODIN_OS == .Linux {
|
@(private)
|
||||||
@(private)
|
_SYS_NAMELEN :: 256
|
||||||
_SYS_NAMELEN :: 65
|
|
||||||
} else {
|
|
||||||
@(private)
|
|
||||||
_SYS_NAMELEN :: 256
|
|
||||||
}
|
|
||||||
|
|
||||||
utsname :: struct {
|
utsname :: struct {
|
||||||
sysname: [_SYS_NAMELEN]c.char `fmt:"s,0"`, /* [PSX] name of OS */
|
sysname: [_SYS_NAMELEN]c.char `fmt:"s,0"`, /* [PSX] name of OS */
|
||||||
@@ -55,6 +51,17 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
machine: [_SYS_NAMELEN]c.char `fmt:"s,0"`, /* [PSX] hardware type */
|
machine: [_SYS_NAMELEN]c.char `fmt:"s,0"`, /* [PSX] hardware type */
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else when ODIN_OS == .Linux {
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
|
@(private)
|
||||||
|
_SYS_NAMELEN :: 65
|
||||||
|
|
||||||
|
utsname :: struct {
|
||||||
|
sysname: [_SYS_NAMELEN]c.char `fmt:"s,0"`, /* [PSX] name of OS */
|
||||||
|
nodename: [_SYS_NAMELEN]c.char `fmt:"s,0"`, /* [PSX] name of this network node */
|
||||||
|
release: [_SYS_NAMELEN]c.char `fmt:"s,0"`, /* [PSX] release level */
|
||||||
|
version: [_SYS_NAMELEN]c.char `fmt:"s,0"`, /* [PSX] version level */
|
||||||
|
machine: [_SYS_NAMELEN]c.char `fmt:"s,0"`, /* [PSX] hardware type */
|
||||||
|
__domainname: [_SYS_NAMELEN]c.char `fmt:"s,0"`,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -391,6 +392,54 @@ when ODIN_OS == .Darwin {
|
|||||||
return (x & _WCONTINUED) == _WCONTINUED
|
return (x & _WCONTINUED) == _WCONTINUED
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else when ODIN_OS == .Linux {
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
|
id_t :: distinct c.uint
|
||||||
|
|
||||||
|
WCONTINUED :: 8
|
||||||
|
WNOHANG :: 1
|
||||||
|
WUNTRACED :: 2
|
||||||
|
|
||||||
|
WEXITED :: 4
|
||||||
|
WNOWAIT :: 0x1000000
|
||||||
|
WSTOPPED :: 2
|
||||||
|
|
||||||
|
_P_ALL :: 0
|
||||||
|
_P_PID :: 1
|
||||||
|
_P_PGID :: 2
|
||||||
|
|
||||||
|
@(private)
|
||||||
|
_WIFEXITED :: #force_inline proc "contextless" (x: c.int) -> bool {
|
||||||
|
return _WTERMSIG(x) == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
@(private)
|
||||||
|
_WEXITSTATUS :: #force_inline proc "contextless" (x: c.int) -> c.int {
|
||||||
|
return (x & 0xff00) >> 8
|
||||||
|
}
|
||||||
|
|
||||||
|
@(private)
|
||||||
|
_WIFSIGNALED :: #force_inline proc "contextless" (x: c.int) -> bool {
|
||||||
|
return (x & 0xffff) - 1 < 0xff
|
||||||
|
}
|
||||||
|
|
||||||
|
@(private)
|
||||||
|
_WTERMSIG :: #force_inline proc "contextless" (x: c.int) -> Signal {
|
||||||
|
return Signal(x & 0x7f)
|
||||||
|
}
|
||||||
|
|
||||||
|
@(private)
|
||||||
|
_WIFSTOPPED :: #force_inline proc "contextless" (x: c.int) -> bool {
|
||||||
|
return ((x & 0xffff) * 0x10001) >> 8 > 0x7f00
|
||||||
|
}
|
||||||
|
|
||||||
|
@(private)
|
||||||
|
_WSTOPSIG :: #force_inline proc "contextless" (x: c.int) -> Signal {
|
||||||
|
return Signal(_WEXITSTATUS(x))
|
||||||
|
}
|
||||||
|
|
||||||
|
@(private)
|
||||||
|
_WIFCONTINUED :: #force_inline proc "contextless" (x: c.int) -> bool {
|
||||||
|
return x == 0xffff
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -152,7 +153,7 @@ CControl_Flag_Bits :: enum tcflag_t {
|
|||||||
CControl_Flags :: bit_set[CControl_Flag_Bits; tcflag_t]
|
CControl_Flags :: bit_set[CControl_Flag_Bits; tcflag_t]
|
||||||
|
|
||||||
// character size mask
|
// character size mask
|
||||||
CSIZE :: CControl_Flags{ .CS6, .CS7, .CS8 }
|
CSIZE :: transmute(CControl_Flags)tcflag_t(_CSIZE)
|
||||||
|
|
||||||
COutput_Flag_Bits :: enum tcflag_t {
|
COutput_Flag_Bits :: enum tcflag_t {
|
||||||
OPOST = log2(OPOST), /* enable following output processing */
|
OPOST = log2(OPOST), /* enable following output processing */
|
||||||
@@ -181,17 +182,17 @@ COutput_Flag_Bits :: enum tcflag_t {
|
|||||||
COutput_Flags :: bit_set[COutput_Flag_Bits; tcflag_t]
|
COutput_Flags :: bit_set[COutput_Flag_Bits; tcflag_t]
|
||||||
|
|
||||||
// \n delay mask
|
// \n delay mask
|
||||||
NLDLY :: COutput_Flags{ .NL1, COutput_Flag_Bits(9) }
|
NLDLY :: transmute(COutput_Flags)tcflag_t(_NLDLY)
|
||||||
// \r delay mask
|
// \r delay mask
|
||||||
CRDLY :: COutput_Flags{ .CR1, .CR2, .CR3 }
|
CRDLY :: transmute(COutput_Flags)tcflag_t(_CRDLY)
|
||||||
// horizontal tab delay mask
|
// horizontal tab delay mask
|
||||||
TABDLY :: COutput_Flags{ .TAB1, .TAB3, COutput_Flag_Bits(2) }
|
TABDLY :: transmute(COutput_Flags)tcflag_t(_TABDLY)
|
||||||
// \b delay mask
|
// \b delay mask
|
||||||
BSDLY :: COutput_Flags{ .BS1 }
|
BSDLY :: transmute(COutput_Flags)tcflag_t(_BSDLY)
|
||||||
// vertical tab delay mask
|
// vertical tab delay mask
|
||||||
VTDLY :: COutput_Flags{ .VT1 }
|
VTDLY :: transmute(COutput_Flags)tcflag_t(_VTDLY)
|
||||||
// form feed delay mask
|
// form feed delay mask
|
||||||
FFDLY :: COutput_Flags{ .FF1 }
|
FFDLY :: transmute(COutput_Flags)tcflag_t(_FFDLY)
|
||||||
|
|
||||||
speed_t :: enum _speed_t {
|
speed_t :: enum _speed_t {
|
||||||
B0 = B0,
|
B0 = B0,
|
||||||
@@ -596,6 +597,4 @@ when ODIN_OS == .Darwin {
|
|||||||
TCOOFF :: 0
|
TCOOFF :: 0
|
||||||
TCOON :: 1
|
TCOON :: 1
|
||||||
|
|
||||||
} else {
|
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -229,6 +230,16 @@ when ODIN_OS == .Darwin {
|
|||||||
|
|
||||||
getdate_err: Errno = .ENOSYS // NOTE: looks like it's not a thing on OpenBSD.
|
getdate_err: Errno = .ENOSYS // NOTE: looks like it's not a thing on OpenBSD.
|
||||||
|
|
||||||
} else {
|
} else when ODIN_OS == .Linux {
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
|
clockid_t :: distinct c.int
|
||||||
|
|
||||||
|
CLOCK_MONOTONIC :: 1
|
||||||
|
CLOCK_PROCESS_CPUTIME_ID :: 2
|
||||||
|
CLOCK_REALTIME :: 0
|
||||||
|
CLOCK_THREAD_CPUTIME_ID :: 3
|
||||||
|
|
||||||
|
foreign lib {
|
||||||
|
getdate_err: Errno
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -38,6 +39,4 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
|
|
||||||
// NOTE: I don't think OpenBSD implements this API.
|
// NOTE: I don't think OpenBSD implements this API.
|
||||||
|
|
||||||
} else {
|
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-110
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -11,19 +12,6 @@ when ODIN_OS == .Darwin {
|
|||||||
// unistd.h - standard symbolic constants and types
|
// unistd.h - standard symbolic constants and types
|
||||||
|
|
||||||
foreign lib {
|
foreign lib {
|
||||||
/*
|
|
||||||
Checks the file named by the pathname pointed to by the path argument for
|
|
||||||
accessibility according to the bit pattern contained in amode.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
if (posix.access("/tmp/myfile", posix.F_OK) != .OK) {
|
|
||||||
fmt.printfln("/tmp/myfile access check failed: %v", posix.strerror(posix.errno()))
|
|
||||||
}
|
|
||||||
|
|
||||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/access.html ]]
|
|
||||||
*/
|
|
||||||
access :: proc(path: cstring, amode: Mode_Flags = F_OK) -> result ---
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Equivalent to `access` but relative paths are resolved based on `fd`.
|
Equivalent to `access` but relative paths are resolved based on `fd`.
|
||||||
|
|
||||||
@@ -42,18 +30,6 @@ foreign lib {
|
|||||||
*/
|
*/
|
||||||
alarm :: proc(seconds: c.uint) -> c.uint ---
|
alarm :: proc(seconds: c.uint) -> c.uint ---
|
||||||
|
|
||||||
/*
|
|
||||||
Causes the directory named by path to become the current working directory.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
if (posix.chdir("/tmp") == .OK) {
|
|
||||||
fmt.println("changed current directory to /tmp")
|
|
||||||
}
|
|
||||||
|
|
||||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/chdir.html ]]
|
|
||||||
*/
|
|
||||||
chdir :: proc(path: cstring) -> result ---
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Equivalent to chdir but instead of a path the fildes is resolved to a directory.
|
Equivalent to chdir but instead of a path the fildes is resolved to a directory.
|
||||||
|
|
||||||
@@ -204,15 +180,6 @@ foreign lib {
|
|||||||
*/
|
*/
|
||||||
dup2 :: proc(fildes, fildes2: FD) -> FD ---
|
dup2 :: proc(fildes, fildes2: FD) -> FD ---
|
||||||
|
|
||||||
/*
|
|
||||||
Exits but, shall not call functions registered with atexit() nor any registered signal handlers.
|
|
||||||
Open streams shall not be flushed.
|
|
||||||
Whether open streams are closed (without flushing) is implementation-defined. Finally, the calling process shall be terminated with the consequences described below.
|
|
||||||
|
|
||||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/_exit.html ]]
|
|
||||||
*/
|
|
||||||
_exit :: proc(status: c.int) -> ! ---
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The exec family of functions shall replace the current process image with a new process image.
|
The exec family of functions shall replace the current process image with a new process image.
|
||||||
The new image shall be constructed from a regular, executable file called the new process image file.
|
The new image shall be constructed from a regular, executable file called the new process image file.
|
||||||
@@ -392,44 +359,6 @@ foreign lib {
|
|||||||
*/
|
*/
|
||||||
ftruncate :: proc(fildes: FD, length: off_t) -> result ---
|
ftruncate :: proc(fildes: FD, length: off_t) -> result ---
|
||||||
|
|
||||||
/*
|
|
||||||
Places an absolute pathname of the current working directory into buf.
|
|
||||||
|
|
||||||
Returns: buf as a cstring on success, nil (setting errno) on failure
|
|
||||||
|
|
||||||
Example:
|
|
||||||
size: int
|
|
||||||
path_max := posix.pathconf(".", ._PATH_MAX)
|
|
||||||
if path_max == -1 {
|
|
||||||
size = 1024
|
|
||||||
} else if path_max > 10240 {
|
|
||||||
size = 10240
|
|
||||||
} else {
|
|
||||||
size = int(path_max)
|
|
||||||
}
|
|
||||||
|
|
||||||
buf: [dynamic]byte
|
|
||||||
cwd: cstring
|
|
||||||
for ; cwd == nil; size *= 2 {
|
|
||||||
if err := resize(&buf, size); err != nil {
|
|
||||||
fmt.panicf("allocation failure: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cwd = posix.getcwd(raw_data(buf), len(buf))
|
|
||||||
if cwd == nil {
|
|
||||||
errno := posix.errno()
|
|
||||||
if errno != .ERANGE {
|
|
||||||
fmt.panicf("getcwd failure: %v", posix.strerror(errno))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.println(path_max, cwd)
|
|
||||||
|
|
||||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getcwd.html ]]
|
|
||||||
*/
|
|
||||||
getcwd :: proc(buf: [^]c.char, size: c.size_t) -> cstring ---
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Returns the effective group ID of the calling process.
|
Returns the effective group ID of the calling process.
|
||||||
|
|
||||||
@@ -829,13 +758,6 @@ foreign lib {
|
|||||||
*/
|
*/
|
||||||
readlinkat :: proc(fd: FD, path: cstring, buf: [^]byte, bufsize: c.size_t) -> c.ssize_t ---
|
readlinkat :: proc(fd: FD, path: cstring, buf: [^]byte, bufsize: c.size_t) -> c.ssize_t ---
|
||||||
|
|
||||||
/*
|
|
||||||
Remove an (empty) directory.
|
|
||||||
|
|
||||||
]] More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/rmdir.html ]]
|
|
||||||
*/
|
|
||||||
rmdir :: proc(path: cstring) -> result ---
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Set the effective group ID.
|
Set the effective group ID.
|
||||||
|
|
||||||
@@ -912,13 +834,6 @@ foreign lib {
|
|||||||
*/
|
*/
|
||||||
sleep :: proc(seconds: c.uint) -> c.uint ---
|
sleep :: proc(seconds: c.uint) -> c.uint ---
|
||||||
|
|
||||||
/*
|
|
||||||
Copy nbyte bytes, from src, to dest, exchanging adjecent bytes.
|
|
||||||
|
|
||||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/swab.html ]]
|
|
||||||
*/
|
|
||||||
swab :: proc(src: [^]byte, dest: [^]byte, nbytes: c.ssize_t) ---
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Schedule file system updates.
|
Schedule file system updates.
|
||||||
|
|
||||||
@@ -958,13 +873,6 @@ foreign lib {
|
|||||||
*/
|
*/
|
||||||
ttyname_r :: proc(fildes: FD, name: [^]byte, namesize: c.size_t) -> Errno ---
|
ttyname_r :: proc(fildes: FD, name: [^]byte, namesize: c.size_t) -> Errno ---
|
||||||
|
|
||||||
/*
|
|
||||||
Remove a directory entry.
|
|
||||||
|
|
||||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/unlink.html ]]
|
|
||||||
*/
|
|
||||||
unlink :: proc(path: cstring) -> result ---
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Equivalent to unlink or rmdir (if flag is .REMOVEDIR) but relative paths are relative to the dir fd.
|
Equivalent to unlink or rmdir (if flag is .REMOVEDIR) but relative paths are relative to the dir fd.
|
||||||
|
|
||||||
@@ -973,20 +881,6 @@ foreign lib {
|
|||||||
unlinkat :: proc(fd: FD, path: cstring, flag: AT_Flags) -> result ---
|
unlinkat :: proc(fd: FD, path: cstring, flag: AT_Flags) -> result ---
|
||||||
}
|
}
|
||||||
|
|
||||||
STDERR_FILENO :: 2
|
|
||||||
STDIN_FILENO :: 0
|
|
||||||
STDOUT_FILENO :: 1
|
|
||||||
|
|
||||||
Mode_Flag_Bits :: enum c.int {
|
|
||||||
X_OK = log2(X_OK),
|
|
||||||
W_OK = log2(W_OK),
|
|
||||||
R_OK = log2(R_OK),
|
|
||||||
}
|
|
||||||
Mode_Flags :: bit_set[Mode_Flag_Bits; c.int]
|
|
||||||
|
|
||||||
#assert(_F_OK == 0)
|
|
||||||
F_OK :: Mode_Flags{}
|
|
||||||
|
|
||||||
CS :: enum c.int {
|
CS :: enum c.int {
|
||||||
_PATH = _CS_PATH,
|
_PATH = _CS_PATH,
|
||||||
_POSIX_V6_ILP32_OFF32_CFLAGS = _CS_POSIX_V6_ILP32_OFF32_CFLAGS,
|
_POSIX_V6_ILP32_OFF32_CFLAGS = _CS_POSIX_V6_ILP32_OFF32_CFLAGS,
|
||||||
@@ -2063,6 +1957,7 @@ when ODIN_OS == .Darwin {
|
|||||||
_SC_TYPED_MEMORY_OBJECTS :: 165
|
_SC_TYPED_MEMORY_OBJECTS :: 165
|
||||||
_SC_2_PBS :: 168
|
_SC_2_PBS :: 168
|
||||||
_SC_2_PBS_ACCOUNTING :: 169
|
_SC_2_PBS_ACCOUNTING :: 169
|
||||||
|
_SC_2_PBS_LOCATE :: 170
|
||||||
_SC_2_PBS_MESSAGE :: 171
|
_SC_2_PBS_MESSAGE :: 171
|
||||||
_SC_2_PBS_TRACK :: 172
|
_SC_2_PBS_TRACK :: 172
|
||||||
_SC_SYMLOOP_MAX :: 173
|
_SC_SYMLOOP_MAX :: 173
|
||||||
@@ -2097,7 +1992,4 @@ when ODIN_OS == .Darwin {
|
|||||||
// NOTE: Not implemented.
|
// NOTE: Not implemented.
|
||||||
_POSIX_VDISABLE :: 0
|
_POSIX_VDISABLE :: 0
|
||||||
|
|
||||||
} else {
|
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,153 @@
|
|||||||
|
#+build linux, windows, darwin, netbsd, openbsd, freebsd
|
||||||
|
package posix
|
||||||
|
|
||||||
|
import "core:c"
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
foreign import lib "system:libucrt.lib"
|
||||||
|
} else when ODIN_OS == .Darwin {
|
||||||
|
foreign import lib "system:System.framework"
|
||||||
|
} else {
|
||||||
|
foreign import lib "system:c"
|
||||||
|
}
|
||||||
|
|
||||||
|
// unistd.h - standard symbolic constants and types
|
||||||
|
|
||||||
|
foreign lib {
|
||||||
|
/*
|
||||||
|
Checks the file named by the pathname pointed to by the path argument for
|
||||||
|
accessibility according to the bit pattern contained in amode.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
if (posix.access("/tmp/myfile", posix.F_OK) != .OK) {
|
||||||
|
fmt.printfln("/tmp/myfile access check failed: %v", posix.strerror(posix.errno()))
|
||||||
|
}
|
||||||
|
|
||||||
|
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/access.html ]]
|
||||||
|
*/
|
||||||
|
@(link_name=LACCESS)
|
||||||
|
access :: proc(path: cstring, amode: Mode_Flags = F_OK) -> result ---
|
||||||
|
|
||||||
|
/*
|
||||||
|
Causes the directory named by path to become the current working directory.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
if (posix.chdir("/tmp") == .OK) {
|
||||||
|
fmt.println("changed current directory to /tmp")
|
||||||
|
}
|
||||||
|
|
||||||
|
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/chdir.html ]]
|
||||||
|
*/
|
||||||
|
@(link_name=LCHDIR)
|
||||||
|
chdir :: proc(path: cstring) -> result ---
|
||||||
|
|
||||||
|
/*
|
||||||
|
Exits but, shall not call functions registered with atexit() nor any registered signal handlers.
|
||||||
|
Open streams shall not be flushed.
|
||||||
|
Whether open streams are closed (without flushing) is implementation-defined. Finally, the calling process shall be terminated with the consequences described below.
|
||||||
|
|
||||||
|
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/_exit.html ]]
|
||||||
|
*/
|
||||||
|
_exit :: proc(status: c.int) -> ! ---
|
||||||
|
|
||||||
|
/*
|
||||||
|
Places an absolute pathname of the current working directory into buf.
|
||||||
|
|
||||||
|
Returns: buf as a cstring on success, nil (setting errno) on failure
|
||||||
|
|
||||||
|
Example:
|
||||||
|
size: int
|
||||||
|
path_max := posix.pathconf(".", ._PATH_MAX)
|
||||||
|
if path_max == -1 {
|
||||||
|
size = 1024
|
||||||
|
} else if path_max > 10240 {
|
||||||
|
size = 10240
|
||||||
|
} else {
|
||||||
|
size = int(path_max)
|
||||||
|
}
|
||||||
|
|
||||||
|
buf: [dynamic]byte
|
||||||
|
cwd: cstring
|
||||||
|
for ; cwd == nil; size *= 2 {
|
||||||
|
if err := resize(&buf, size); err != nil {
|
||||||
|
fmt.panicf("allocation failure: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cwd = posix.getcwd(raw_data(buf), len(buf))
|
||||||
|
if cwd == nil {
|
||||||
|
errno := posix.errno()
|
||||||
|
if errno != .ERANGE {
|
||||||
|
fmt.panicf("getcwd failure: %v", posix.strerror(errno))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.println(path_max, cwd)
|
||||||
|
|
||||||
|
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getcwd.html ]]
|
||||||
|
*/
|
||||||
|
@(link_name=LGETCWD)
|
||||||
|
getcwd :: proc(buf: [^]c.char, size: c.size_t) -> cstring ---
|
||||||
|
|
||||||
|
/*
|
||||||
|
Remove an (empty) directory.
|
||||||
|
|
||||||
|
]] More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/rmdir.html ]]
|
||||||
|
*/
|
||||||
|
@(link_name=LRMDIR)
|
||||||
|
rmdir :: proc(path: cstring) -> result ---
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copy nbyte bytes, from src, to dest, exchanging adjecent bytes.
|
||||||
|
|
||||||
|
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/swab.html ]]
|
||||||
|
*/
|
||||||
|
@(link_name=LSWAB)
|
||||||
|
swab :: proc(src: [^]byte, dest: [^]byte, nbytes: c.ssize_t) ---
|
||||||
|
|
||||||
|
/*
|
||||||
|
Remove a directory entry.
|
||||||
|
|
||||||
|
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/unlink.html ]]
|
||||||
|
*/
|
||||||
|
@(link_name=LUNLINK)
|
||||||
|
unlink :: proc(path: cstring) -> result ---
|
||||||
|
}
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
@(private) LACCESS :: "_access"
|
||||||
|
@(private) LCHDIR :: "_chdir"
|
||||||
|
@(private) LGETCWD :: "_getcwd"
|
||||||
|
@(private) LRMDIR :: "_rmdir"
|
||||||
|
@(private) LSWAB :: "_swab"
|
||||||
|
@(private) LUNLINK :: "_unlink"
|
||||||
|
} else {
|
||||||
|
@(private) LACCESS :: "access"
|
||||||
|
@(private) LCHDIR :: "chdir"
|
||||||
|
@(private) LGETCWD :: "getcwd"
|
||||||
|
@(private) LRMDIR :: "rmdir"
|
||||||
|
@(private) LSWAB :: "swab"
|
||||||
|
@(private) LUNLINK :: "unlink"
|
||||||
|
}
|
||||||
|
|
||||||
|
STDERR_FILENO :: 2
|
||||||
|
STDIN_FILENO :: 0
|
||||||
|
STDOUT_FILENO :: 1
|
||||||
|
|
||||||
|
Mode_Flag_Bits :: enum c.int {
|
||||||
|
X_OK = log2(X_OK),
|
||||||
|
W_OK = log2(W_OK),
|
||||||
|
R_OK = log2(R_OK),
|
||||||
|
}
|
||||||
|
Mode_Flags :: bit_set[Mode_Flag_Bits; c.int]
|
||||||
|
|
||||||
|
#assert(_F_OK == 0)
|
||||||
|
F_OK :: Mode_Flags{}
|
||||||
|
|
||||||
|
when ODIN_OS == .Windows {
|
||||||
|
_F_OK :: 0
|
||||||
|
X_OK :: 1
|
||||||
|
W_OK :: 2
|
||||||
|
R_OK :: 4
|
||||||
|
#assert(W_OK|R_OK == 6)
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
when ODIN_OS == .Darwin {
|
when ODIN_OS == .Darwin {
|
||||||
@@ -31,6 +32,4 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS
|
|||||||
modtime: time_t, /* [PSX] modification time (seconds since epoch) */
|
modtime: time_t, /* [PSX] modification time (seconds since epoch) */
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#+build linux, darwin, netbsd, openbsd, freebsd
|
||||||
package posix
|
package posix
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
@@ -123,6 +124,4 @@ when ODIN_OS == .Darwin {
|
|||||||
WRDE_CMDSUB :: 4
|
WRDE_CMDSUB :: 4
|
||||||
WRDE_SYNTAX :: 5
|
WRDE_SYNTAX :: 5
|
||||||
|
|
||||||
} else {
|
|
||||||
#panic("posix is unimplemented for the current target")
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,96 +0,0 @@
|
|||||||
#+build darwin
|
|
||||||
package unix
|
|
||||||
|
|
||||||
import "core:c"
|
|
||||||
|
|
||||||
// NOTE(tetra): No 32-bit Macs.
|
|
||||||
// Source: _pthread_types.h on my Mac.
|
|
||||||
PTHREAD_SIZE :: 8176
|
|
||||||
PTHREAD_ATTR_SIZE :: 56
|
|
||||||
PTHREAD_MUTEXATTR_SIZE :: 8
|
|
||||||
PTHREAD_MUTEX_SIZE :: 56
|
|
||||||
PTHREAD_CONDATTR_SIZE :: 8
|
|
||||||
PTHREAD_COND_SIZE :: 40
|
|
||||||
PTHREAD_ONCE_SIZE :: 8
|
|
||||||
PTHREAD_RWLOCK_SIZE :: 192
|
|
||||||
PTHREAD_RWLOCKATTR_SIZE :: 16
|
|
||||||
|
|
||||||
pthread_t :: distinct u64
|
|
||||||
|
|
||||||
pthread_attr_t :: struct {
|
|
||||||
sig: c.long,
|
|
||||||
_: [PTHREAD_ATTR_SIZE] c.char,
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_cond_t :: struct {
|
|
||||||
sig: c.long,
|
|
||||||
_: [PTHREAD_COND_SIZE] c.char,
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_condattr_t :: struct {
|
|
||||||
sig: c.long,
|
|
||||||
_: [PTHREAD_CONDATTR_SIZE] c.char,
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_t :: struct {
|
|
||||||
sig: c.long,
|
|
||||||
_: [PTHREAD_MUTEX_SIZE] c.char,
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutexattr_t :: struct {
|
|
||||||
sig: c.long,
|
|
||||||
_: [PTHREAD_MUTEXATTR_SIZE] c.char,
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_once_t :: struct {
|
|
||||||
sig: c.long,
|
|
||||||
_: [PTHREAD_ONCE_SIZE] c.char,
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_rwlock_t :: struct {
|
|
||||||
sig: c.long,
|
|
||||||
_: [PTHREAD_RWLOCK_SIZE] c.char,
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_rwlockattr_t :: struct {
|
|
||||||
sig: c.long,
|
|
||||||
_: [PTHREAD_RWLOCKATTR_SIZE] c.char,
|
|
||||||
}
|
|
||||||
|
|
||||||
SCHED_OTHER :: 1 // Avoid if you are writing portable software.
|
|
||||||
SCHED_FIFO :: 4
|
|
||||||
SCHED_RR :: 2 // Round robin.
|
|
||||||
|
|
||||||
SCHED_PARAM_SIZE :: 4
|
|
||||||
|
|
||||||
sched_param :: struct {
|
|
||||||
sched_priority: c.int,
|
|
||||||
_: [SCHED_PARAM_SIZE] c.char,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Source: https://github.com/apple/darwin-libpthread/blob/03c4628c8940cca6fd6a82957f683af804f62e7f/pthread/pthread.h#L138
|
|
||||||
PTHREAD_CREATE_JOINABLE :: 1
|
|
||||||
PTHREAD_CREATE_DETACHED :: 2
|
|
||||||
PTHREAD_INHERIT_SCHED :: 1
|
|
||||||
PTHREAD_EXPLICIT_SCHED :: 2
|
|
||||||
PTHREAD_PROCESS_SHARED :: 1
|
|
||||||
PTHREAD_PROCESS_PRIVATE :: 2
|
|
||||||
|
|
||||||
|
|
||||||
PTHREAD_MUTEX_NORMAL :: 0
|
|
||||||
PTHREAD_MUTEX_RECURSIVE :: 1
|
|
||||||
PTHREAD_MUTEX_ERRORCHECK :: 2
|
|
||||||
|
|
||||||
PTHREAD_CANCEL_ENABLE :: 0
|
|
||||||
PTHREAD_CANCEL_DISABLE :: 1
|
|
||||||
PTHREAD_CANCEL_DEFERRED :: 0
|
|
||||||
PTHREAD_CANCEL_ASYNCHRONOUS :: 1
|
|
||||||
|
|
||||||
foreign import pthread "system:System.framework"
|
|
||||||
|
|
||||||
@(default_calling_convention="c")
|
|
||||||
foreign pthread {
|
|
||||||
pthread_setcancelstate :: proc (state: c.int, old_state: ^c.int) -> c.int ---
|
|
||||||
pthread_setcanceltype :: proc (type: c.int, old_type: ^c.int) -> c.int ---
|
|
||||||
pthread_cancel :: proc (thread: pthread_t) -> c.int ---
|
|
||||||
}
|
|
||||||
@@ -1,122 +0,0 @@
|
|||||||
#+build freebsd
|
|
||||||
package unix
|
|
||||||
|
|
||||||
import "core:c"
|
|
||||||
|
|
||||||
pthread_t :: distinct u64
|
|
||||||
// pthread_t :: struct #align(16) { x: u64 }
|
|
||||||
|
|
||||||
PTHREAD_COND_T_SIZE :: 8
|
|
||||||
|
|
||||||
PTHREAD_MUTEXATTR_T_SIZE :: 8
|
|
||||||
PTHREAD_CONDATTR_T_SIZE :: 8
|
|
||||||
PTHREAD_RWLOCKATTR_T_SIZE :: 8
|
|
||||||
PTHREAD_BARRIERATTR_T_SIZE :: 8
|
|
||||||
|
|
||||||
// WARNING: The sizes of these things are different yet again
|
|
||||||
// on non-X86!
|
|
||||||
when size_of(int) == 8 {
|
|
||||||
PTHREAD_ATTR_T_SIZE :: 8
|
|
||||||
PTHREAD_MUTEX_T_SIZE :: 8
|
|
||||||
PTHREAD_RWLOCK_T_SIZE :: 8
|
|
||||||
PTHREAD_BARRIER_T_SIZE :: 8
|
|
||||||
} else when size_of(int) == 4 { // TODO
|
|
||||||
PTHREAD_ATTR_T_SIZE :: 32
|
|
||||||
PTHREAD_MUTEX_T_SIZE :: 32
|
|
||||||
PTHREAD_RWLOCK_T_SIZE :: 44
|
|
||||||
PTHREAD_BARRIER_T_SIZE :: 20
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_cond_t :: struct #align(16) {
|
|
||||||
_: [PTHREAD_COND_T_SIZE] c.char,
|
|
||||||
}
|
|
||||||
pthread_mutex_t :: struct #align(16) {
|
|
||||||
_: [PTHREAD_MUTEX_T_SIZE] c.char,
|
|
||||||
}
|
|
||||||
pthread_rwlock_t :: struct #align(16) {
|
|
||||||
_: [PTHREAD_RWLOCK_T_SIZE] c.char,
|
|
||||||
}
|
|
||||||
pthread_barrier_t :: struct #align(16) {
|
|
||||||
_: [PTHREAD_BARRIER_T_SIZE] c.char,
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_attr_t :: struct #align(16) {
|
|
||||||
_: [PTHREAD_ATTR_T_SIZE] c.char,
|
|
||||||
}
|
|
||||||
pthread_condattr_t :: struct #align(16) {
|
|
||||||
_: [PTHREAD_CONDATTR_T_SIZE] c.char,
|
|
||||||
}
|
|
||||||
pthread_mutexattr_t :: struct #align(16) {
|
|
||||||
_: [PTHREAD_MUTEXATTR_T_SIZE] c.char,
|
|
||||||
}
|
|
||||||
pthread_rwlockattr_t :: struct #align(16) {
|
|
||||||
_: [PTHREAD_RWLOCKATTR_T_SIZE] c.char,
|
|
||||||
}
|
|
||||||
pthread_barrierattr_t :: struct #align(16) {
|
|
||||||
_: [PTHREAD_BARRIERATTR_T_SIZE] c.char,
|
|
||||||
}
|
|
||||||
|
|
||||||
PTHREAD_MUTEX_ERRORCHECK :: 1
|
|
||||||
PTHREAD_MUTEX_RECURSIVE :: 2
|
|
||||||
PTHREAD_MUTEX_NORMAL :: 3
|
|
||||||
|
|
||||||
|
|
||||||
PTHREAD_CREATE_JOINABLE :: 0
|
|
||||||
PTHREAD_CREATE_DETACHED :: 1
|
|
||||||
PTHREAD_INHERIT_SCHED :: 4
|
|
||||||
PTHREAD_EXPLICIT_SCHED :: 0
|
|
||||||
PTHREAD_PROCESS_PRIVATE :: 0
|
|
||||||
PTHREAD_PROCESS_SHARED :: 1
|
|
||||||
|
|
||||||
SCHED_FIFO :: 1
|
|
||||||
SCHED_OTHER :: 2
|
|
||||||
SCHED_RR :: 3 // Round robin.
|
|
||||||
|
|
||||||
|
|
||||||
sched_param :: struct {
|
|
||||||
sched_priority: c.int,
|
|
||||||
}
|
|
||||||
|
|
||||||
_usem :: struct {
|
|
||||||
_has_waiters: u32,
|
|
||||||
_count: u32,
|
|
||||||
_flags: u32,
|
|
||||||
}
|
|
||||||
_usem2 :: struct {
|
|
||||||
_count: u32,
|
|
||||||
_flags: u32,
|
|
||||||
}
|
|
||||||
sem_t :: struct {
|
|
||||||
_magic: u32,
|
|
||||||
_kern: _usem2,
|
|
||||||
_padding: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
PTHREAD_CANCEL_ENABLE :: 0
|
|
||||||
PTHREAD_CANCEL_DISABLE :: 1
|
|
||||||
PTHREAD_CANCEL_DEFERRED :: 0
|
|
||||||
PTHREAD_CANCEL_ASYNCHRONOUS :: 2
|
|
||||||
|
|
||||||
foreign import "system:pthread"
|
|
||||||
|
|
||||||
@(default_calling_convention="c")
|
|
||||||
foreign pthread {
|
|
||||||
// create named semaphore.
|
|
||||||
// used in process-shared semaphores.
|
|
||||||
sem_open :: proc(name: cstring, flags: c.int) -> ^sem_t ---
|
|
||||||
|
|
||||||
sem_init :: proc(sem: ^sem_t, pshared: c.int, initial_value: c.uint) -> c.int ---
|
|
||||||
sem_destroy :: proc(sem: ^sem_t) -> c.int ---
|
|
||||||
sem_post :: proc(sem: ^sem_t) -> c.int ---
|
|
||||||
sem_wait :: proc(sem: ^sem_t) -> c.int ---
|
|
||||||
sem_trywait :: proc(sem: ^sem_t) -> c.int ---
|
|
||||||
// sem_timedwait :: proc(sem: ^sem_t, timeout: time.TimeSpec) -> c.int ---
|
|
||||||
|
|
||||||
// NOTE: unclear whether pthread_yield is well-supported on Linux systems,
|
|
||||||
// see https://linux.die.net/man/3/pthread_yield
|
|
||||||
pthread_yield :: proc() ---
|
|
||||||
|
|
||||||
pthread_setcancelstate :: proc (state: c.int, old_state: ^c.int) -> c.int ---
|
|
||||||
pthread_setcanceltype :: proc (type: c.int, old_type: ^c.int) -> c.int ---
|
|
||||||
pthread_cancel :: proc (thread: pthread_t) -> c.int ---
|
|
||||||
}
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
package unix
|
|
||||||
|
|
||||||
import "core:c"
|
|
||||||
|
|
||||||
pthread_t :: distinct rawptr
|
|
||||||
pthread_attr_t :: distinct rawptr
|
|
||||||
pthread_mutex_t :: distinct rawptr
|
|
||||||
pthread_mutexattr_t :: distinct rawptr
|
|
||||||
pthread_cond_t :: distinct rawptr
|
|
||||||
pthread_condattr_t :: distinct rawptr
|
|
||||||
pthread_rwlock_t :: distinct rawptr
|
|
||||||
pthread_rwlockattr_t :: distinct rawptr
|
|
||||||
pthread_barrier_t :: distinct rawptr
|
|
||||||
pthread_barrierattr_t :: distinct rawptr
|
|
||||||
pthread_spinlock_t :: distinct rawptr
|
|
||||||
|
|
||||||
pthread_key_t :: distinct c.int
|
|
||||||
pthread_once_t :: struct {
|
|
||||||
state: c.int,
|
|
||||||
mutex: pthread_mutex_t,
|
|
||||||
}
|
|
||||||
|
|
||||||
PTHREAD_MUTEX_DEFAULT :: 0
|
|
||||||
PTHREAD_MUTEX_NORMAL :: 1
|
|
||||||
PTHREAD_MUTEX_ERRORCHECK :: 2
|
|
||||||
PTHREAD_MUTEX_RECURSIVE :: 3
|
|
||||||
|
|
||||||
PTHREAD_DETACHED :: 0x1
|
|
||||||
PTHREAD_SCOPE_SYSTEM :: 0x2
|
|
||||||
PTHREAD_INHERIT_SCHED :: 0x4
|
|
||||||
PTHREAD_NOFLOAT :: 0x8
|
|
||||||
|
|
||||||
PTHREAD_CREATE_DETACHED :: PTHREAD_DETACHED
|
|
||||||
PTHREAD_CREATE_JOINABLE :: 0
|
|
||||||
PTHREAD_SCOPE_PROCESS :: 0
|
|
||||||
PTHREAD_EXPLICIT_SCHED :: 0
|
|
||||||
|
|
||||||
SCHED_FIFO :: 1
|
|
||||||
SCHED_RR :: 2
|
|
||||||
SCHED_SPORADIC :: 3
|
|
||||||
SCHED_OTHER :: 4
|
|
||||||
|
|
||||||
sched_param :: struct {
|
|
||||||
sched_priority: c.int,
|
|
||||||
}
|
|
||||||
|
|
||||||
sem_t :: distinct rawptr
|
|
||||||
|
|
||||||
PTHREAD_CANCEL_ENABLE :: 0
|
|
||||||
PTHREAD_CANCEL_DISABLE :: 1
|
|
||||||
PTHREAD_CANCEL_DEFERRED :: 0
|
|
||||||
PTHREAD_CANCEL_ASYNCHRONOUS :: 2
|
|
||||||
|
|
||||||
foreign import libc "system:c"
|
|
||||||
|
|
||||||
@(default_calling_convention="c")
|
|
||||||
foreign libc {
|
|
||||||
sem_open :: proc(name: cstring, flags: c.int) -> ^sem_t ---
|
|
||||||
|
|
||||||
sem_init :: proc(sem: ^sem_t, pshared: c.int, initial_value: c.uint) -> c.int ---
|
|
||||||
sem_destroy :: proc(sem: ^sem_t) -> c.int ---
|
|
||||||
sem_post :: proc(sem: ^sem_t) -> c.int ---
|
|
||||||
sem_wait :: proc(sem: ^sem_t) -> c.int ---
|
|
||||||
sem_trywait :: proc(sem: ^sem_t) -> c.int ---
|
|
||||||
|
|
||||||
pthread_yield :: proc() ---
|
|
||||||
|
|
||||||
pthread_setcancelstate :: proc (state: c.int, old_state: ^c.int) -> c.int ---
|
|
||||||
pthread_setcanceltype :: proc (type: c.int, old_type: ^c.int) -> c.int ---
|
|
||||||
pthread_cancel :: proc (thread: pthread_t) -> c.int ---
|
|
||||||
}
|
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
#+build linux
|
|
||||||
package unix
|
|
||||||
|
|
||||||
import "core:c"
|
|
||||||
|
|
||||||
// TODO(tetra): For robustness, I'd like to mark this with align 16.
|
|
||||||
// I cannot currently do this.
|
|
||||||
// And at the time of writing there is a bug with putting it
|
|
||||||
// as the only field in a struct.
|
|
||||||
pthread_t :: distinct u64
|
|
||||||
// pthread_t :: struct #align(16) { x: u64 };
|
|
||||||
|
|
||||||
// NOTE(tetra): Got all the size constants from pthreadtypes-arch.h on my
|
|
||||||
// Linux machine.
|
|
||||||
|
|
||||||
PTHREAD_COND_T_SIZE :: 48
|
|
||||||
|
|
||||||
PTHREAD_MUTEXATTR_T_SIZE :: 4
|
|
||||||
PTHREAD_CONDATTR_T_SIZE :: 4
|
|
||||||
PTHREAD_RWLOCKATTR_T_SIZE :: 8
|
|
||||||
PTHREAD_BARRIERATTR_T_SIZE :: 4
|
|
||||||
|
|
||||||
// WARNING: The sizes of these things are different yet again
|
|
||||||
// on non-X86!
|
|
||||||
when size_of(int) == 8 {
|
|
||||||
PTHREAD_ATTR_T_SIZE :: 56
|
|
||||||
PTHREAD_MUTEX_T_SIZE :: 40
|
|
||||||
PTHREAD_RWLOCK_T_SIZE :: 56
|
|
||||||
PTHREAD_BARRIER_T_SIZE :: 32
|
|
||||||
} else when size_of(int) == 4 {
|
|
||||||
PTHREAD_ATTR_T_SIZE :: 32
|
|
||||||
PTHREAD_MUTEX_T_SIZE :: 32
|
|
||||||
PTHREAD_RWLOCK_T_SIZE :: 44
|
|
||||||
PTHREAD_BARRIER_T_SIZE :: 20
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_cond_t :: struct #align(16) {
|
|
||||||
_: [PTHREAD_COND_T_SIZE] c.char,
|
|
||||||
}
|
|
||||||
pthread_mutex_t :: struct #align(16) {
|
|
||||||
_: [PTHREAD_MUTEX_T_SIZE] c.char,
|
|
||||||
}
|
|
||||||
pthread_rwlock_t :: struct #align(16) {
|
|
||||||
_: [PTHREAD_RWLOCK_T_SIZE] c.char,
|
|
||||||
}
|
|
||||||
pthread_barrier_t :: struct #align(16) {
|
|
||||||
_: [PTHREAD_BARRIER_T_SIZE] c.char,
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_attr_t :: struct #align(16) {
|
|
||||||
_: [PTHREAD_ATTR_T_SIZE] c.char,
|
|
||||||
}
|
|
||||||
pthread_condattr_t :: struct #align(16) {
|
|
||||||
_: [PTHREAD_CONDATTR_T_SIZE] c.char,
|
|
||||||
}
|
|
||||||
pthread_mutexattr_t :: struct #align(16) {
|
|
||||||
_: [PTHREAD_MUTEXATTR_T_SIZE] c.char,
|
|
||||||
}
|
|
||||||
pthread_rwlockattr_t :: struct #align(16) {
|
|
||||||
_: [PTHREAD_RWLOCKATTR_T_SIZE] c.char,
|
|
||||||
}
|
|
||||||
pthread_barrierattr_t :: struct #align(16) {
|
|
||||||
_: [PTHREAD_BARRIERATTR_T_SIZE] c.char,
|
|
||||||
}
|
|
||||||
|
|
||||||
PTHREAD_MUTEX_NORMAL :: 0
|
|
||||||
PTHREAD_MUTEX_RECURSIVE :: 1
|
|
||||||
PTHREAD_MUTEX_ERRORCHECK :: 2
|
|
||||||
|
|
||||||
|
|
||||||
// TODO(tetra, 2019-11-01): Maybe make `enum c.int`s for these?
|
|
||||||
PTHREAD_CREATE_JOINABLE :: 0
|
|
||||||
PTHREAD_CREATE_DETACHED :: 1
|
|
||||||
PTHREAD_INHERIT_SCHED :: 0
|
|
||||||
PTHREAD_EXPLICIT_SCHED :: 1
|
|
||||||
PTHREAD_PROCESS_PRIVATE :: 0
|
|
||||||
PTHREAD_PROCESS_SHARED :: 1
|
|
||||||
|
|
||||||
SCHED_OTHER :: 0
|
|
||||||
SCHED_FIFO :: 1
|
|
||||||
SCHED_RR :: 2 // Round robin.
|
|
||||||
|
|
||||||
sched_param :: struct {
|
|
||||||
sched_priority: c.int,
|
|
||||||
}
|
|
||||||
|
|
||||||
sem_t :: struct #align(16) {
|
|
||||||
_: [SEM_T_SIZE] c.char,
|
|
||||||
}
|
|
||||||
|
|
||||||
when size_of(int) == 8 {
|
|
||||||
SEM_T_SIZE :: 32
|
|
||||||
} else when size_of(int) == 4 {
|
|
||||||
SEM_T_SIZE :: 16
|
|
||||||
}
|
|
||||||
|
|
||||||
PTHREAD_CANCEL_ENABLE :: 0
|
|
||||||
PTHREAD_CANCEL_DISABLE :: 1
|
|
||||||
PTHREAD_CANCEL_DEFERRED :: 0
|
|
||||||
PTHREAD_CANCEL_ASYNCHRONOUS :: 1
|
|
||||||
|
|
||||||
foreign import "system:pthread"
|
|
||||||
|
|
||||||
@(default_calling_convention="c")
|
|
||||||
foreign pthread {
|
|
||||||
// create named semaphore.
|
|
||||||
// used in process-shared semaphores.
|
|
||||||
sem_open :: proc(name: cstring, flags: c.int) -> ^sem_t ---
|
|
||||||
|
|
||||||
sem_init :: proc(sem: ^sem_t, pshared: c.int, initial_value: c.uint) -> c.int ---
|
|
||||||
sem_destroy :: proc(sem: ^sem_t) -> c.int ---
|
|
||||||
sem_post :: proc(sem: ^sem_t) -> c.int ---
|
|
||||||
sem_wait :: proc(sem: ^sem_t) -> c.int ---
|
|
||||||
sem_trywait :: proc(sem: ^sem_t) -> c.int ---
|
|
||||||
// sem_timedwait :: proc(sem: ^sem_t, timeout: time.TimeSpec) -> c.int ---;
|
|
||||||
|
|
||||||
// NOTE: unclear whether pthread_yield is well-supported on Linux systems,
|
|
||||||
// see https://linux.die.net/man/3/pthread_yield
|
|
||||||
pthread_yield :: proc() -> c.int ---
|
|
||||||
|
|
||||||
pthread_setcancelstate :: proc (state: c.int, old_state: ^c.int) -> c.int ---
|
|
||||||
pthread_setcanceltype :: proc (type: c.int, old_type: ^c.int) -> c.int ---
|
|
||||||
pthread_cancel :: proc (thread: pthread_t) -> c.int ---
|
|
||||||
}
|
|
||||||
@@ -1,102 +0,0 @@
|
|||||||
package unix
|
|
||||||
|
|
||||||
import "core:c"
|
|
||||||
|
|
||||||
pthread_t :: distinct rawptr
|
|
||||||
|
|
||||||
SEM_T_SIZE :: 8
|
|
||||||
|
|
||||||
PTHREAD_CONDATTR_T_SIZE :: 16
|
|
||||||
PTHREAD_MUTEXATTR_T_SIZE :: 16
|
|
||||||
PTHREAD_RWLOCKATTR_T_SIZE :: 16
|
|
||||||
PTHREAD_BARRIERATTR_T_SIZE :: 16
|
|
||||||
|
|
||||||
PTHREAD_COND_T_SIZE :: 40
|
|
||||||
PTHREAD_MUTEX_T_SIZE :: 48
|
|
||||||
PTHREAD_RWLOCK_T_SIZE :: 64
|
|
||||||
PTHREAD_BARRIER_T_SIZE :: 48
|
|
||||||
PTHREAD_ATTR_T_SIZE :: 16
|
|
||||||
|
|
||||||
pthread_cond_t :: struct #align(8) {
|
|
||||||
_: [PTHREAD_COND_T_SIZE] c.char,
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_t :: struct #align(8) {
|
|
||||||
_: [PTHREAD_MUTEX_T_SIZE] c.char,
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_rwlock_t :: struct #align(8) {
|
|
||||||
_: [PTHREAD_RWLOCK_T_SIZE] c.char,
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_barrier_t :: struct #align(8) {
|
|
||||||
_: [PTHREAD_BARRIER_T_SIZE] c.char,
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_attr_t :: struct #align(8) {
|
|
||||||
_: [PTHREAD_ATTR_T_SIZE] c.char,
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_condattr_t :: struct #align(8) {
|
|
||||||
_: [PTHREAD_CONDATTR_T_SIZE] c.char,
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutexattr_t :: struct #align(8) {
|
|
||||||
_: [PTHREAD_MUTEXATTR_T_SIZE] c.char,
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_rwlockattr_t :: struct #align(8) {
|
|
||||||
_: [PTHREAD_RWLOCKATTR_T_SIZE] c.char,
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_barrierattr_t :: struct #align(8) {
|
|
||||||
_: [PTHREAD_BARRIERATTR_T_SIZE] c.char,
|
|
||||||
}
|
|
||||||
|
|
||||||
PTHREAD_MUTEX_NORMAL :: 0
|
|
||||||
PTHREAD_MUTEX_ERRORCHECK :: 1
|
|
||||||
PTHREAD_MUTEX_RECURSIVE :: 2
|
|
||||||
|
|
||||||
PTHREAD_CREATE_JOINABLE :: 0
|
|
||||||
PTHREAD_CREATE_DETACHED :: 1
|
|
||||||
PTHREAD_INHERIT_SCHED :: 0
|
|
||||||
PTHREAD_EXPLICIT_SCHED :: 1
|
|
||||||
PTHREAD_PROCESS_PRIVATE :: 0
|
|
||||||
PTHREAD_PROCESS_SHARED :: 1
|
|
||||||
|
|
||||||
SCHED_NONE :: -1
|
|
||||||
SCHED_OTHER :: 0
|
|
||||||
SCHED_FIFO :: 1
|
|
||||||
SCHED_RR :: 3
|
|
||||||
|
|
||||||
sched_param :: struct {
|
|
||||||
sched_priority: c.int,
|
|
||||||
}
|
|
||||||
|
|
||||||
sem_t :: struct #align(16) {
|
|
||||||
_: [SEM_T_SIZE] c.char,
|
|
||||||
}
|
|
||||||
|
|
||||||
PTHREAD_CANCEL_ENABLE :: 0
|
|
||||||
PTHREAD_CANCEL_DISABLE :: 1
|
|
||||||
PTHREAD_CANCEL_DEFERRED :: 0
|
|
||||||
PTHREAD_CANCEL_ASYNCHRONOUS :: 1
|
|
||||||
|
|
||||||
foreign import "system:pthread"
|
|
||||||
|
|
||||||
@(default_calling_convention="c")
|
|
||||||
foreign pthread {
|
|
||||||
sem_open :: proc(name: cstring, flags: c.int) -> ^sem_t ---
|
|
||||||
|
|
||||||
sem_init :: proc(sem: ^sem_t, pshared: c.int, initial_value: c.uint) -> c.int ---
|
|
||||||
sem_destroy :: proc(sem: ^sem_t) -> c.int ---
|
|
||||||
sem_post :: proc(sem: ^sem_t) -> c.int ---
|
|
||||||
sem_wait :: proc(sem: ^sem_t) -> c.int ---
|
|
||||||
sem_trywait :: proc(sem: ^sem_t) -> c.int ---
|
|
||||||
|
|
||||||
pthread_yield :: proc() ---
|
|
||||||
|
|
||||||
pthread_setcancelstate :: proc (state: c.int, old_state: ^c.int) -> c.int ---
|
|
||||||
pthread_setcanceltype :: proc (type: c.int, old_type: ^c.int) -> c.int ---
|
|
||||||
pthread_cancel :: proc (thread: pthread_t) -> c.int ---
|
|
||||||
}
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
#+build openbsd
|
|
||||||
package unix
|
|
||||||
|
|
||||||
import "core:c"
|
|
||||||
|
|
||||||
pthread_t :: distinct rawptr
|
|
||||||
pthread_attr_t :: distinct rawptr
|
|
||||||
pthread_mutex_t :: distinct rawptr
|
|
||||||
pthread_mutexattr_t :: distinct rawptr
|
|
||||||
pthread_cond_t :: distinct rawptr
|
|
||||||
pthread_condattr_t :: distinct rawptr
|
|
||||||
pthread_rwlock_t :: distinct rawptr
|
|
||||||
pthread_rwlockattr_t :: distinct rawptr
|
|
||||||
pthread_barrier_t :: distinct rawptr
|
|
||||||
pthread_barrierattr_t :: distinct rawptr
|
|
||||||
pthread_spinlock_t :: distinct rawptr
|
|
||||||
|
|
||||||
pthread_key_t :: distinct c.int
|
|
||||||
pthread_once_t :: struct {
|
|
||||||
state: c.int,
|
|
||||||
mutex: pthread_mutex_t,
|
|
||||||
}
|
|
||||||
|
|
||||||
PTHREAD_MUTEX_ERRORCHECK :: 1
|
|
||||||
PTHREAD_MUTEX_RECURSIVE :: 2
|
|
||||||
PTHREAD_MUTEX_NORMAL :: 3
|
|
||||||
PTHREAD_MUTEX_STRICT_NP :: 4
|
|
||||||
|
|
||||||
PTHREAD_DETACHED :: 0x1
|
|
||||||
PTHREAD_SCOPE_SYSTEM :: 0x2
|
|
||||||
PTHREAD_INHERIT_SCHED :: 0x4
|
|
||||||
PTHREAD_NOFLOAT :: 0x8
|
|
||||||
|
|
||||||
PTHREAD_CREATE_DETACHED :: PTHREAD_DETACHED
|
|
||||||
PTHREAD_CREATE_JOINABLE :: 0
|
|
||||||
PTHREAD_SCOPE_PROCESS :: 0
|
|
||||||
PTHREAD_EXPLICIT_SCHED :: 0
|
|
||||||
|
|
||||||
SCHED_FIFO :: 1
|
|
||||||
SCHED_OTHER :: 2
|
|
||||||
SCHED_RR :: 3
|
|
||||||
|
|
||||||
sched_param :: struct {
|
|
||||||
sched_priority: c.int,
|
|
||||||
}
|
|
||||||
|
|
||||||
sem_t :: distinct rawptr
|
|
||||||
|
|
||||||
PTHREAD_CANCEL_ENABLE :: 0
|
|
||||||
PTHREAD_CANCEL_DISABLE :: 1
|
|
||||||
PTHREAD_CANCEL_DEFERRED :: 0
|
|
||||||
PTHREAD_CANCEL_ASYNCHRONOUS :: 2
|
|
||||||
|
|
||||||
foreign import libc "system:c"
|
|
||||||
|
|
||||||
@(default_calling_convention="c")
|
|
||||||
foreign libc {
|
|
||||||
sem_open :: proc(name: cstring, flags: c.int) -> ^sem_t ---
|
|
||||||
|
|
||||||
sem_init :: proc(sem: ^sem_t, pshared: c.int, initial_value: c.uint) -> c.int ---
|
|
||||||
sem_destroy :: proc(sem: ^sem_t) -> c.int ---
|
|
||||||
sem_post :: proc(sem: ^sem_t) -> c.int ---
|
|
||||||
sem_wait :: proc(sem: ^sem_t) -> c.int ---
|
|
||||||
sem_trywait :: proc(sem: ^sem_t) -> c.int ---
|
|
||||||
//sem_timedwait :: proc(sem: ^sem_t, timeout: time.TimeSpec) -> c.int ---
|
|
||||||
|
|
||||||
// NOTE: unclear whether pthread_yield is well-supported on Linux systems,
|
|
||||||
// see https://linux.die.net/man/3/pthread_yield
|
|
||||||
pthread_yield :: proc() ---
|
|
||||||
|
|
||||||
pthread_setcancelstate :: proc (state: c.int, old_state: ^c.int) -> c.int ---
|
|
||||||
pthread_setcanceltype :: proc (type: c.int, old_type: ^c.int) -> c.int ---
|
|
||||||
pthread_cancel :: proc (thread: pthread_t) -> c.int ---
|
|
||||||
}
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
#+build linux, darwin, freebsd, openbsd, netbsd, haiku
|
|
||||||
package unix
|
|
||||||
|
|
||||||
foreign import "system:pthread"
|
|
||||||
|
|
||||||
import "core:c"
|
|
||||||
|
|
||||||
timespec :: struct {
|
|
||||||
tv_sec: i64,
|
|
||||||
tv_nsec: i64,
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// On success, these functions return 0.
|
|
||||||
//
|
|
||||||
|
|
||||||
@(default_calling_convention="c")
|
|
||||||
foreign pthread {
|
|
||||||
pthread_create :: proc(t: ^pthread_t, attrs: ^pthread_attr_t, routine: proc(data: rawptr) -> rawptr, arg: rawptr) -> c.int ---
|
|
||||||
|
|
||||||
// retval is a pointer to a location to put the return value of the thread proc.
|
|
||||||
pthread_join :: proc(t: pthread_t, retval: ^rawptr) -> c.int ---
|
|
||||||
|
|
||||||
pthread_kill :: proc(t: pthread_t, sig: c.int) -> c.int ---
|
|
||||||
|
|
||||||
pthread_self :: proc() -> pthread_t ---
|
|
||||||
|
|
||||||
pthread_equal :: proc(a, b: pthread_t) -> b32 ---
|
|
||||||
|
|
||||||
pthread_detach :: proc(t: pthread_t) -> c.int ---
|
|
||||||
|
|
||||||
sched_get_priority_min :: proc(policy: c.int) -> c.int ---
|
|
||||||
sched_get_priority_max :: proc(policy: c.int) -> c.int ---
|
|
||||||
|
|
||||||
// NOTE: POSIX says this can fail with OOM.
|
|
||||||
pthread_attr_init :: proc(attrs: ^pthread_attr_t) -> c.int ---
|
|
||||||
|
|
||||||
pthread_attr_destroy :: proc(attrs: ^pthread_attr_t) -> c.int ---
|
|
||||||
|
|
||||||
pthread_attr_getschedparam :: proc(attrs: ^pthread_attr_t, param: ^sched_param) -> c.int ---
|
|
||||||
pthread_attr_setschedparam :: proc(attrs: ^pthread_attr_t, param: ^sched_param) -> c.int ---
|
|
||||||
|
|
||||||
// states: PTHREAD_CREATE_DETACHED, PTHREAD_CREATE_JOINABLE
|
|
||||||
pthread_attr_setdetachstate :: proc(attrs: ^pthread_attr_t, detach_state: c.int) -> c.int ---
|
|
||||||
|
|
||||||
// NOTE(tetra, 2019-11-06): WARNING: Different systems have different alignment requirements.
|
|
||||||
// For maximum usefulness, use the OS's page size.
|
|
||||||
// ALSO VERY MAJOR WARNING: `stack_ptr` must be the LAST byte of the stack on systems
|
|
||||||
// where the stack grows downwards, which is the common case, so far as I know.
|
|
||||||
// On systems where it grows upwards, give the FIRST byte instead.
|
|
||||||
// ALSO SLIGHTLY LESS MAJOR WARNING: Using this procedure DISABLES automatically-provided
|
|
||||||
// guard pages. If you are using this procedure, YOU must set them up manually.
|
|
||||||
// If you forget to do this, you WILL get stack corruption bugs if you do not EXTREMELY
|
|
||||||
// know what you are doing!
|
|
||||||
pthread_attr_setstack :: proc(attrs: ^pthread_attr_t, stack_ptr: rawptr, stack_size: u64) -> c.int ---
|
|
||||||
pthread_attr_getstack :: proc(attrs: ^pthread_attr_t, stack_ptr: ^rawptr, stack_size: ^u64) -> c.int ---
|
|
||||||
|
|
||||||
pthread_sigmask :: proc(how: c.int, set: rawptr, oldset: rawptr) -> c.int ---
|
|
||||||
|
|
||||||
sched_yield :: proc() -> c.int ---
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: Unimplemented in Haiku.
|
|
||||||
when ODIN_OS != .Haiku {
|
|
||||||
foreign pthread {
|
|
||||||
// scheds: PTHREAD_INHERIT_SCHED, PTHREAD_EXPLICIT_SCHED
|
|
||||||
pthread_attr_setinheritsched :: proc(attrs: ^pthread_attr_t, sched: c.int) -> c.int ---
|
|
||||||
|
|
||||||
pthread_attr_getschedpolicy :: proc(t: ^pthread_attr_t, policy: ^c.int) -> c.int ---
|
|
||||||
pthread_attr_setschedpolicy :: proc(t: ^pthread_attr_t, policy: c.int) -> c.int ---
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@(default_calling_convention="c")
|
|
||||||
foreign pthread {
|
|
||||||
// NOTE: POSIX says this can fail with OOM.
|
|
||||||
pthread_cond_init :: proc(cond: ^pthread_cond_t, attrs: ^pthread_condattr_t) -> c.int ---
|
|
||||||
|
|
||||||
pthread_cond_destroy :: proc(cond: ^pthread_cond_t) -> c.int ---
|
|
||||||
|
|
||||||
pthread_cond_signal :: proc(cond: ^pthread_cond_t) -> c.int ---
|
|
||||||
|
|
||||||
// same as signal, but wakes up _all_ threads that are waiting
|
|
||||||
pthread_cond_broadcast :: proc(cond: ^pthread_cond_t) -> c.int ---
|
|
||||||
|
|
||||||
|
|
||||||
// assumes the mutex is pre-locked
|
|
||||||
pthread_cond_wait :: proc(cond: ^pthread_cond_t, mutex: ^pthread_mutex_t) -> c.int ---
|
|
||||||
pthread_cond_timedwait :: proc(cond: ^pthread_cond_t, mutex: ^pthread_mutex_t, timeout: ^timespec) -> c.int ---
|
|
||||||
|
|
||||||
pthread_condattr_init :: proc(attrs: ^pthread_condattr_t) -> c.int ---
|
|
||||||
pthread_condattr_destroy :: proc(attrs: ^pthread_condattr_t) -> c.int ---
|
|
||||||
|
|
||||||
// p-shared = "process-shared" - i.e: is this condition shared among multiple processes?
|
|
||||||
// values: PTHREAD_PROCESS_PRIVATE, PTHREAD_PROCESS_SHARED
|
|
||||||
pthread_condattr_setpshared :: proc(attrs: ^pthread_condattr_t, value: c.int) -> c.int ---
|
|
||||||
pthread_condattr_getpshared :: proc(attrs: ^pthread_condattr_t, result: ^c.int) -> c.int ---
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@(default_calling_convention="c")
|
|
||||||
foreign pthread {
|
|
||||||
// NOTE: POSIX says this can fail with OOM.
|
|
||||||
pthread_mutex_init :: proc(mutex: ^pthread_mutex_t, attrs: ^pthread_mutexattr_t) -> c.int ---
|
|
||||||
|
|
||||||
pthread_mutex_destroy :: proc(mutex: ^pthread_mutex_t) -> c.int ---
|
|
||||||
|
|
||||||
pthread_mutex_trylock :: proc(mutex: ^pthread_mutex_t) -> c.int ---
|
|
||||||
|
|
||||||
pthread_mutex_lock :: proc(mutex: ^pthread_mutex_t) -> c.int ---
|
|
||||||
|
|
||||||
pthread_mutex_timedlock :: proc(mutex: ^pthread_mutex_t, timeout: ^timespec) -> c.int ---
|
|
||||||
|
|
||||||
pthread_mutex_unlock :: proc(mutex: ^pthread_mutex_t) -> c.int ---
|
|
||||||
|
|
||||||
|
|
||||||
pthread_mutexattr_init :: proc(attrs: ^pthread_mutexattr_t) -> c.int ---
|
|
||||||
pthread_mutexattr_destroy :: proc(attrs: ^pthread_mutexattr_t) -> c.int ---
|
|
||||||
pthread_mutexattr_settype :: proc(attrs: ^pthread_mutexattr_t, type: c.int) -> c.int ---
|
|
||||||
|
|
||||||
// p-shared = "process-shared" - i.e: is this mutex shared among multiple processes?
|
|
||||||
// values: PTHREAD_PROCESS_PRIVATE, PTHREAD_PROCESS_SHARED
|
|
||||||
pthread_mutexattr_setpshared :: proc(attrs: ^pthread_mutexattr_t, value: c.int) -> c.int ---
|
|
||||||
pthread_mutexattr_getpshared :: proc(attrs: ^pthread_mutexattr_t, result: ^c.int) -> c.int ---
|
|
||||||
|
|
||||||
pthread_testcancel :: proc () ---
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package unix
|
||||||
|
|
||||||
|
import "core:c"
|
||||||
|
|
||||||
|
timespec :: struct {
|
||||||
|
secs: i64,
|
||||||
|
nsecs: c.long,
|
||||||
|
}
|
||||||
@@ -15,7 +15,7 @@ import "core:c/libc"
|
|||||||
import "core:encoding/ansi"
|
import "core:encoding/ansi"
|
||||||
import "core:sync"
|
import "core:sync"
|
||||||
import "core:os"
|
import "core:os"
|
||||||
@require import "core:sys/unix"
|
@require import "core:sys/posix"
|
||||||
|
|
||||||
@(private="file") stop_runner_flag: libc.sig_atomic_t
|
@(private="file") stop_runner_flag: libc.sig_atomic_t
|
||||||
|
|
||||||
@@ -114,8 +114,8 @@ This is a dire bug and should be reported to the Odin developers.
|
|||||||
// properly set to PTHREAD_CANCEL_ASYNCHRONOUS.
|
// properly set to PTHREAD_CANCEL_ASYNCHRONOUS.
|
||||||
//
|
//
|
||||||
// The runner would stall after returning from `pthread_cancel`.
|
// The runner would stall after returning from `pthread_cancel`.
|
||||||
|
|
||||||
unix.pthread_testcancel()
|
posix.pthread_testcancel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,14 +4,14 @@ package thread
|
|||||||
|
|
||||||
import "base:runtime"
|
import "base:runtime"
|
||||||
import "core:sync"
|
import "core:sync"
|
||||||
import "core:sys/unix"
|
import "core:sys/posix"
|
||||||
|
|
||||||
_IS_SUPPORTED :: true
|
_IS_SUPPORTED :: true
|
||||||
|
|
||||||
// NOTE(tetra): Aligned here because of core/unix/pthread_linux.odin/pthread_t.
|
// NOTE(tetra): Aligned here because of core/unix/pthread_linux.odin/pthread_t.
|
||||||
// Also see core/sys/darwin/mach_darwin.odin/semaphore_t.
|
// Also see core/sys/darwin/mach_darwin.odin/semaphore_t.
|
||||||
Thread_Os_Specific :: struct #align(16) {
|
Thread_Os_Specific :: struct #align(16) {
|
||||||
unix_thread: unix.pthread_t, // NOTE: very large on Darwin, small on Linux.
|
unix_thread: posix.pthread_t, // NOTE: very large on Darwin, small on Linux.
|
||||||
start_ok: sync.Sema,
|
start_ok: sync.Sema,
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
@@ -23,7 +23,7 @@ _create :: proc(procedure: Thread_Proc, priority: Thread_Priority) -> ^Thread {
|
|||||||
t := (^Thread)(t)
|
t := (^Thread)(t)
|
||||||
|
|
||||||
// We need to give the thread a moment to start up before we enable cancellation.
|
// We need to give the thread a moment to start up before we enable cancellation.
|
||||||
can_set_thread_cancel_state := unix.pthread_setcancelstate(unix.PTHREAD_CANCEL_ENABLE, nil) == 0
|
can_set_thread_cancel_state := posix.pthread_setcancelstate(.ENABLE, nil) == nil
|
||||||
|
|
||||||
t.id = sync.current_thread_id()
|
t.id = sync.current_thread_id()
|
||||||
|
|
||||||
@@ -37,8 +37,8 @@ _create :: proc(procedure: Thread_Proc, priority: Thread_Priority) -> ^Thread {
|
|||||||
|
|
||||||
// Enable thread's cancelability.
|
// Enable thread's cancelability.
|
||||||
if can_set_thread_cancel_state {
|
if can_set_thread_cancel_state {
|
||||||
unix.pthread_setcanceltype (unix.PTHREAD_CANCEL_ASYNCHRONOUS, nil)
|
posix.pthread_setcanceltype (.ASYNCHRONOUS, nil)
|
||||||
unix.pthread_setcancelstate(unix.PTHREAD_CANCEL_ENABLE, nil)
|
posix.pthread_setcancelstate(.ENABLE, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -59,8 +59,8 @@ _create :: proc(procedure: Thread_Proc, priority: Thread_Priority) -> ^Thread {
|
|||||||
sync.atomic_or(&t.flags, { .Done })
|
sync.atomic_or(&t.flags, { .Done })
|
||||||
|
|
||||||
if .Self_Cleanup in sync.atomic_load(&t.flags) {
|
if .Self_Cleanup in sync.atomic_load(&t.flags) {
|
||||||
res := unix.pthread_detach(t.unix_thread)
|
res := posix.pthread_detach(t.unix_thread)
|
||||||
assert_contextless(res == 0)
|
assert_contextless(res == nil)
|
||||||
|
|
||||||
t.unix_thread = {}
|
t.unix_thread = {}
|
||||||
// NOTE(ftphikari): It doesn't matter which context 'free' received, right?
|
// NOTE(ftphikari): It doesn't matter which context 'free' received, right?
|
||||||
@@ -71,19 +71,19 @@ _create :: proc(procedure: Thread_Proc, priority: Thread_Priority) -> ^Thread {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
attrs: unix.pthread_attr_t
|
attrs: posix.pthread_attr_t
|
||||||
if unix.pthread_attr_init(&attrs) != 0 {
|
if posix.pthread_attr_init(&attrs) != nil {
|
||||||
return nil // NOTE(tetra, 2019-11-01): POSIX OOM.
|
return nil // NOTE(tetra, 2019-11-01): POSIX OOM.
|
||||||
}
|
}
|
||||||
defer unix.pthread_attr_destroy(&attrs)
|
defer posix.pthread_attr_destroy(&attrs)
|
||||||
|
|
||||||
// NOTE(tetra, 2019-11-01): These only fail if their argument is invalid.
|
// NOTE(tetra, 2019-11-01): These only fail if their argument is invalid.
|
||||||
res: i32
|
res: posix.Errno
|
||||||
res = unix.pthread_attr_setdetachstate(&attrs, unix.PTHREAD_CREATE_JOINABLE)
|
res = posix.pthread_attr_setdetachstate(&attrs, .CREATE_JOINABLE)
|
||||||
assert(res == 0)
|
assert(res == nil)
|
||||||
when ODIN_OS != .Haiku && ODIN_OS != .NetBSD {
|
when ODIN_OS != .Haiku && ODIN_OS != .NetBSD {
|
||||||
res = unix.pthread_attr_setinheritsched(&attrs, unix.PTHREAD_EXPLICIT_SCHED)
|
res = posix.pthread_attr_setinheritsched(&attrs, .EXPLICIT_SCHED)
|
||||||
assert(res == 0)
|
assert(res == nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
thread := new(Thread)
|
thread := new(Thread)
|
||||||
@@ -93,26 +93,26 @@ _create :: proc(procedure: Thread_Proc, priority: Thread_Priority) -> ^Thread {
|
|||||||
thread.creation_allocator = context.allocator
|
thread.creation_allocator = context.allocator
|
||||||
|
|
||||||
// Set thread priority.
|
// Set thread priority.
|
||||||
policy: i32
|
policy: posix.Sched_Policy
|
||||||
when ODIN_OS != .Haiku && ODIN_OS != .NetBSD {
|
when ODIN_OS != .Haiku && ODIN_OS != .NetBSD {
|
||||||
res = unix.pthread_attr_getschedpolicy(&attrs, &policy)
|
res = posix.pthread_attr_getschedpolicy(&attrs, &policy)
|
||||||
assert(res == 0)
|
assert(res == nil)
|
||||||
}
|
}
|
||||||
params: unix.sched_param
|
params: posix.sched_param
|
||||||
res = unix.pthread_attr_getschedparam(&attrs, ¶ms)
|
res = posix.pthread_attr_getschedparam(&attrs, ¶ms)
|
||||||
assert(res == 0)
|
assert(res == nil)
|
||||||
low := unix.sched_get_priority_min(policy)
|
low := posix.sched_get_priority_min(policy)
|
||||||
high := unix.sched_get_priority_max(policy)
|
high := posix.sched_get_priority_max(policy)
|
||||||
switch priority {
|
switch priority {
|
||||||
case .Normal: // Okay
|
case .Normal: // Okay
|
||||||
case .Low: params.sched_priority = low + 1
|
case .Low: params.sched_priority = low + 1
|
||||||
case .High: params.sched_priority = high
|
case .High: params.sched_priority = high
|
||||||
}
|
}
|
||||||
res = unix.pthread_attr_setschedparam(&attrs, ¶ms)
|
res = posix.pthread_attr_setschedparam(&attrs, ¶ms)
|
||||||
assert(res == 0)
|
assert(res == nil)
|
||||||
|
|
||||||
thread.procedure = procedure
|
thread.procedure = procedure
|
||||||
if unix.pthread_create(&thread.unix_thread, &attrs, __unix_thread_entry_proc, thread) != 0 {
|
if posix.pthread_create(&thread.unix_thread, &attrs, __unix_thread_entry_proc, thread) != nil {
|
||||||
free(thread, thread.creation_allocator)
|
free(thread, thread.creation_allocator)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -130,7 +130,7 @@ _is_done :: proc(t: ^Thread) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_join :: proc(t: ^Thread) {
|
_join :: proc(t: ^Thread) {
|
||||||
if unix.pthread_equal(unix.pthread_self(), t.unix_thread) {
|
if posix.pthread_equal(posix.pthread_self(), t.unix_thread) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@ _join :: proc(t: ^Thread) {
|
|||||||
if .Started not_in sync.atomic_load(&t.flags) {
|
if .Started not_in sync.atomic_load(&t.flags) {
|
||||||
_start(t)
|
_start(t)
|
||||||
}
|
}
|
||||||
unix.pthread_join(t.unix_thread, nil)
|
posix.pthread_join(t.unix_thread, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
_join_multiple :: proc(threads: ..^Thread) {
|
_join_multiple :: proc(threads: ..^Thread) {
|
||||||
@@ -170,9 +170,9 @@ _terminate :: proc(t: ^Thread, exit_code: int) {
|
|||||||
//
|
//
|
||||||
// This is in contrast to behavior I have seen on Linux where the thread is
|
// This is in contrast to behavior I have seen on Linux where the thread is
|
||||||
// just terminated.
|
// just terminated.
|
||||||
unix.pthread_cancel(t.unix_thread)
|
posix.pthread_cancel(t.unix_thread)
|
||||||
}
|
}
|
||||||
|
|
||||||
_yield :: proc() {
|
_yield :: proc() {
|
||||||
unix.sched_yield()
|
posix.sched_yield()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1533,6 +1533,10 @@ gb_internal LoadDirectiveResult check_load_directory_directive(CheckerContext *c
|
|||||||
|
|
||||||
for (FileInfo fi : list) {
|
for (FileInfo fi : list) {
|
||||||
LoadFileCache *cache = nullptr;
|
LoadFileCache *cache = nullptr;
|
||||||
|
if (fi.is_dir) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (cache_load_file_directive(c, call, fi.fullpath, err_on_not_found, &cache, LoadFileTier_Contents, /*use_mutex*/false)) {
|
if (cache_load_file_directive(c, call, fi.fullpath, err_on_not_found, &cache, LoadFileTier_Contents, /*use_mutex*/false)) {
|
||||||
array_add(&file_caches, cache);
|
array_add(&file_caches, cache);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build darwin, freebsd, openbsd, netbsd
|
#+build linux, darwin, freebsd, openbsd, netbsd
|
||||||
package tests_core_posix
|
package tests_core_posix
|
||||||
|
|
||||||
import "core:log"
|
import "core:log"
|
||||||
@@ -144,7 +144,6 @@ test_libgen :: proc(t: ^testing.T) {
|
|||||||
{ "usr/", ".", "usr" },
|
{ "usr/", ".", "usr" },
|
||||||
{ "", ".", "." },
|
{ "", ".", "." },
|
||||||
{ "/", "/", "/" },
|
{ "/", "/", "/" },
|
||||||
{ "//", "/", "/" },
|
|
||||||
{ "///", "/", "/" },
|
{ "///", "/", "/" },
|
||||||
{ "/usr/", "/", "usr" },
|
{ "/usr/", "/", "usr" },
|
||||||
{ "/usr/lib", "/usr", "lib" },
|
{ "/usr/lib", "/usr", "lib" },
|
||||||
@@ -203,18 +202,6 @@ test_stat :: proc(t: ^testing.T) {
|
|||||||
testing.expect_value(t, stat.st_size, posix.off_t(len(CONTENT)))
|
testing.expect_value(t, stat.st_size, posix.off_t(len(CONTENT)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@(test)
|
|
||||||
test_termios :: proc(t: ^testing.T) {
|
|
||||||
testing.expect_value(t, transmute(posix.CControl_Flags)posix.tcflag_t(posix._CSIZE), posix.CSIZE)
|
|
||||||
|
|
||||||
testing.expect_value(t, transmute(posix.COutput_Flags)posix.tcflag_t(posix._NLDLY), posix.NLDLY)
|
|
||||||
testing.expect_value(t, transmute(posix.COutput_Flags)posix.tcflag_t(posix._CRDLY), posix.CRDLY)
|
|
||||||
testing.expect_value(t, transmute(posix.COutput_Flags)posix.tcflag_t(posix._TABDLY), posix.TABDLY)
|
|
||||||
testing.expect_value(t, transmute(posix.COutput_Flags)posix.tcflag_t(posix._BSDLY), posix.BSDLY)
|
|
||||||
testing.expect_value(t, transmute(posix.COutput_Flags)posix.tcflag_t(posix._VTDLY), posix.VTDLY)
|
|
||||||
testing.expect_value(t, transmute(posix.COutput_Flags)posix.tcflag_t(posix._FFDLY), posix.FFDLY)
|
|
||||||
}
|
|
||||||
|
|
||||||
@(test)
|
@(test)
|
||||||
test_pthreads :: proc(t: ^testing.T) {
|
test_pthreads :: proc(t: ^testing.T) {
|
||||||
testing.set_fail_timeout(t, time.Second)
|
testing.set_fail_timeout(t, time.Second)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#+build darwin, freebsd, openbsd, netbsd
|
#+build linux, darwin, freebsd, openbsd, netbsd
|
||||||
package tests_core_posix
|
package tests_core_posix
|
||||||
|
|
||||||
import "core:log"
|
import "core:log"
|
||||||
|
|||||||
@@ -40,7 +40,9 @@ int main(int argc, char *argv[])
|
|||||||
printf("pthread_attr_t %zu %zu\n", sizeof(pthread_attr_t), _Alignof(pthread_attr_t));
|
printf("pthread_attr_t %zu %zu\n", sizeof(pthread_attr_t), _Alignof(pthread_attr_t));
|
||||||
printf("pthread_key_t %zu %zu\n", sizeof(pthread_key_t), _Alignof(pthread_key_t));
|
printf("pthread_key_t %zu %zu\n", sizeof(pthread_key_t), _Alignof(pthread_key_t));
|
||||||
|
|
||||||
|
#ifndef __linux__
|
||||||
printf("sched_param %zu %zu\n", sizeof(struct sched_param), _Alignof(struct sched_param));
|
printf("sched_param %zu %zu\n", sizeof(struct sched_param), _Alignof(struct sched_param));
|
||||||
|
#endif
|
||||||
|
|
||||||
printf("termios %zu %zu\n", sizeof(struct termios), _Alignof(struct termios));
|
printf("termios %zu %zu\n", sizeof(struct termios), _Alignof(struct termios));
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,11 @@ main :: proc() {
|
|||||||
fmt.println("pthread_attr_t", size_of(posix.pthread_attr_t), align_of(posix.pthread_attr_t))
|
fmt.println("pthread_attr_t", size_of(posix.pthread_attr_t), align_of(posix.pthread_attr_t))
|
||||||
fmt.println("pthread_key_t", size_of(posix.pthread_key_t), align_of(posix.pthread_key_t))
|
fmt.println("pthread_key_t", size_of(posix.pthread_key_t), align_of(posix.pthread_key_t))
|
||||||
|
|
||||||
fmt.println("sched_param", size_of(posix.sched_param), align_of(posix.sched_param))
|
// NOTE: On Linux, differences between libc may mean the Odin side is larger than the other side,
|
||||||
|
// this is fine in practice.
|
||||||
|
when ODIN_OS != .Linux {
|
||||||
|
fmt.println("sched_param", size_of(posix.sched_param), align_of(posix.sched_param))
|
||||||
|
}
|
||||||
|
|
||||||
fmt.println("termios", size_of(posix.termios), align_of(posix.termios))
|
fmt.println("termios", size_of(posix.termios), align_of(posix.termios))
|
||||||
|
|
||||||
|
|||||||
Vendored
+7
-7
@@ -1,18 +1,18 @@
|
|||||||
#+build !windows
|
#+build !windows
|
||||||
package miniaudio
|
package miniaudio
|
||||||
|
|
||||||
import "core:sys/unix"
|
import "core:sys/posix"
|
||||||
import "core:c"
|
import "core:c"
|
||||||
|
|
||||||
thread :: unix.pthread_t
|
thread :: posix.pthread_t
|
||||||
mutex :: unix.pthread_mutex_t
|
mutex :: posix.pthread_mutex_t
|
||||||
event :: struct {
|
event :: struct {
|
||||||
value: u32,
|
value: u32,
|
||||||
lock: unix.pthread_mutex_t,
|
lock: posix.pthread_mutex_t,
|
||||||
cond: unix.pthread_cond_t,
|
cond: posix.pthread_cond_t,
|
||||||
}
|
}
|
||||||
semaphore :: struct {
|
semaphore :: struct {
|
||||||
value: c.int,
|
value: c.int,
|
||||||
lock: unix.pthread_mutex_t,
|
lock: posix.pthread_mutex_t,
|
||||||
cond: unix.pthread_cond_t,
|
cond: posix.pthread_cond_t,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user