mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-04 14:48:47 +00:00
posix: add package
This commit is contained in:
@@ -0,0 +1,450 @@
|
||||
package posix
|
||||
|
||||
import "base:intrinsics"
|
||||
|
||||
import "core:c"
|
||||
import "core:c/libc"
|
||||
|
||||
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 {
|
||||
/*
|
||||
Takes a pointer to a radix-64 representation, in which the first digit is the least significant,
|
||||
and return the corresponding long value.
|
||||
|
||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/a64l.html ]]
|
||||
*/
|
||||
a64l :: proc(s: cstring) -> c.long ---
|
||||
|
||||
/*
|
||||
The l64a() function shall take a long argument and return a pointer to the corresponding
|
||||
radix-64 representation.
|
||||
|
||||
Returns: a string that may be invalidated by subsequent calls
|
||||
|
||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/a64l.html ]]
|
||||
*/
|
||||
l64a :: proc(value: c.long) -> cstring ---
|
||||
|
||||
/*
|
||||
This family of functions shall generate pseudo-random numbers using a linear congruential algorithm and 48-bit integer arithmetic.
|
||||
|
||||
Returns: non-negative, double-precision, floating-point values, uniformly distributed over the interval [0.0,1.0)
|
||||
|
||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/drand48.html ]]
|
||||
*/
|
||||
drand48 :: proc() -> c.double ---
|
||||
|
||||
/*
|
||||
This family of functions shall generate pseudo-random numbers using a linear congruential algorithm and 48-bit integer arithmetic.
|
||||
|
||||
Returns: non-negative, double-precision, floating-point values, uniformly distributed over the interval [0.0,1.0)
|
||||
|
||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/drand48.html ]]
|
||||
*/
|
||||
erand48 :: proc(xsubi: ^[3]c.ushort) -> c.double ---
|
||||
|
||||
/*
|
||||
This family of functions shall generate pseudo-random numbers using a linear congruential algorithm and 48-bit integer arithmetic.
|
||||
|
||||
Returns: return signed long integers uniformly distributed over the interval [-231,231)
|
||||
|
||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/drand48.html ]]
|
||||
*/
|
||||
mrand48 :: proc() -> c.long ---
|
||||
|
||||
/*
|
||||
This family of functions shall generate pseudo-random numbers using a linear congruential algorithm and 48-bit integer arithmetic.
|
||||
|
||||
Returns: return signed long integers uniformly distributed over the interval [-231,231)
|
||||
|
||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/drand48.html ]]
|
||||
*/
|
||||
jrand48 :: proc(xsubi: ^[3]c.ushort) -> c.long ---
|
||||
|
||||
/*
|
||||
This family of functions shall generate pseudo-random numbers using a linear congruential algorithm and 48-bit integer arithmetic.
|
||||
|
||||
Returns: non-negative, long integers, uniformly distributed over the interval [0,231)
|
||||
|
||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/drand48.html ]]
|
||||
*/
|
||||
lrand48 :: proc() -> c.long ---
|
||||
|
||||
/*
|
||||
This family of functions shall generate pseudo-random numbers using a linear congruential algorithm and 48-bit integer arithmetic.
|
||||
|
||||
Returns: non-negative, long integers, uniformly distributed over the interval [0,231)
|
||||
|
||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/drand48.html ]]
|
||||
*/
|
||||
nrand48 :: proc(xsubi: ^[3]c.ushort) -> c.long ---
|
||||
|
||||
/*
|
||||
This family of functions shall generate pseudo-random numbers using a linear congruential algorithm and 48-bit integer arithmetic.
|
||||
|
||||
The srand48(), seed48(), and lcong48() functions are initialization entry points, one of which should be invoked before either drand48(), lrand48(), or mrand48() is called.
|
||||
|
||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/drand48.html ]]
|
||||
*/
|
||||
srand48 :: proc(seedval: c.long) ---
|
||||
|
||||
/*
|
||||
This family of functions shall generate pseudo-random numbers using a linear congruential algorithm and 48-bit integer arithmetic.
|
||||
|
||||
The srand48(), seed48(), and lcong48() functions are initialization entry points, one of which should be invoked before either drand48(), lrand48(), or mrand48() is called.
|
||||
|
||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/drand48.html ]]
|
||||
*/
|
||||
lcong48 :: proc(param: ^[7]c.ushort) ---
|
||||
|
||||
/*
|
||||
This family of functions shall generate pseudo-random numbers using a linear congruential algorithm and 48-bit integer arithmetic.
|
||||
|
||||
The srand48(), seed48(), and lcong48() functions are initialization entry points, one of which should be invoked before either drand48(), lrand48(), or mrand48() is called.
|
||||
|
||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/drand48.html ]]
|
||||
*/
|
||||
seed48 :: proc(seed16v: ^[3]c.ushort) -> ^[3]c.ushort ---
|
||||
|
||||
/*
|
||||
Parses suboption arguments in a flag argument.
|
||||
|
||||
Returns: the index of the matched token string, or -1 if no token strings were matched
|
||||
|
||||
Example:
|
||||
args := runtime.args__
|
||||
|
||||
Opt :: enum {
|
||||
RO,
|
||||
RW,
|
||||
NAME,
|
||||
NIL,
|
||||
}
|
||||
token := [Opt]cstring{
|
||||
.RO = "ro",
|
||||
.RW = "rw",
|
||||
.NAME = "name",
|
||||
.NIL = nil,
|
||||
}
|
||||
|
||||
Options :: struct {
|
||||
readonly, readwrite: bool,
|
||||
name: cstring,
|
||||
|
||||
}
|
||||
opts: Options
|
||||
|
||||
errfnd: bool
|
||||
for {
|
||||
opt := posix.getopt(i32(len(args)), raw_data(args), "o:")
|
||||
if opt == -1 {
|
||||
break
|
||||
}
|
||||
|
||||
switch opt {
|
||||
case 'o':
|
||||
subopt := posix.optarg
|
||||
value: cstring
|
||||
for subopt != "" && !errfnd {
|
||||
o := posix.getsubopt(&subopt, &token[.RO], &value)
|
||||
switch Opt(o) {
|
||||
case .RO: opts.readonly = true
|
||||
case .RW: opts.readwrite = true
|
||||
case .NAME:
|
||||
if value == nil {
|
||||
fmt.eprintfln("missing value for suboption %s", token[.NAME])
|
||||
errfnd = true
|
||||
continue
|
||||
}
|
||||
|
||||
opts.name = value
|
||||
case .NIL:
|
||||
fallthrough
|
||||
case:
|
||||
fmt.eprintfln("no match found for token: %s", value)
|
||||
errfnd = true
|
||||
}
|
||||
}
|
||||
if opts.readwrite && opts.readonly {
|
||||
fmt.eprintfln("Only one of %s and %s can be specified", token[.RO], token[.RW])
|
||||
errfnd = true
|
||||
}
|
||||
case:
|
||||
errfnd = true
|
||||
}
|
||||
}
|
||||
|
||||
if errfnd || len(args) == 1 {
|
||||
fmt.eprintfln("\nUsage: %s -o <suboptstring>", args[0])
|
||||
fmt.eprintfln("suboptions are 'ro', 'rw', and 'name=<value>'")
|
||||
posix.exit(1)
|
||||
}
|
||||
|
||||
fmt.println(opts)
|
||||
|
||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsubopt.html ]]
|
||||
*/
|
||||
getsubopt :: proc(optionp: ^cstring, keylistp: [^]cstring, valuep: ^cstring) -> c.int ---
|
||||
|
||||
/*
|
||||
Changes the mode and ownership of the slave pseudo-terminal device associated with its master pseudo-terminal counterpart.
|
||||
|
||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/grantpt.html ]]
|
||||
*/
|
||||
grantpt :: proc(fildes: FD) -> result ---
|
||||
|
||||
/*
|
||||
Allows a state array, pointed to by the state argument, to be initialized for future use.
|
||||
|
||||
Returns: the previous state array or nil on failure
|
||||
|
||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/initstate.html ]]
|
||||
*/
|
||||
@(link_name=LINITSTATE)
|
||||
initstate :: proc(seed: c.uint, state: [^]byte, size: c.size_t) -> [^]byte ---
|
||||
|
||||
/*
|
||||
Sets the state array of the random number generator.
|
||||
|
||||
Returns: the previous state array or nil on failure
|
||||
|
||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/initstate.html ]]
|
||||
*/
|
||||
setstate :: proc(state: [^]byte) -> [^]byte ---
|
||||
|
||||
/*
|
||||
Use a non-linear additive feedback random-number generator employing a default state array
|
||||
size of 31 long integers to return successive pseudo-random numbers in the range from 0 to 231-1.
|
||||
The period of this random-number generator is approximately 16 x (231-1).
|
||||
The size of the state array determines the period of the random-number generator.
|
||||
Increasing the state array size shall increase the period.
|
||||
|
||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/initstate.html ]]
|
||||
*/
|
||||
random :: proc() -> c.long ---
|
||||
|
||||
/*
|
||||
Initializes the current state array using the value of seed.
|
||||
|
||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/initstate.html ]]
|
||||
*/
|
||||
@(link_name=LSRANDOM)
|
||||
srandom :: proc(seed: c.uint) ---
|
||||
|
||||
/*
|
||||
Creates a directory with a unique name derived from template.
|
||||
The application shall ensure that the string provided in template is a pathname ending
|
||||
with at least six trailing 'X' characters.
|
||||
|
||||
Returns: nil (setting errno) on failure, template on success
|
||||
|
||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkdtemp.html ]]
|
||||
*/
|
||||
mkdtemp :: proc(template: [^]byte) -> cstring ---
|
||||
|
||||
/*
|
||||
Creates a regular file with a unique name derived from template and return a file descriptor
|
||||
for the file open for reading and writing.
|
||||
The application shall ensure that the string provided in template is a pathname ending with
|
||||
at least six trailing 'X' characters.
|
||||
|
||||
Returns: -1 (setting errno) on failure, an open file descriptor on success
|
||||
|
||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkdtemp.html ]]
|
||||
*/
|
||||
mkstemp :: proc(template: cstring) -> FD ---
|
||||
|
||||
/*
|
||||
Allocates size bytes aligned on a boundary specified by alignment, and shall return a pointer
|
||||
to the allocated memory in memptr.
|
||||
|
||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_memalign.html ]]
|
||||
*/
|
||||
posix_memalign :: proc(memptr: ^[^]byte, alignment: c.size_t, size: c.size_t) -> Errno ---
|
||||
|
||||
/*
|
||||
Establishes a connection between a master device for a pseudo-terminal and a file descriptor.
|
||||
|
||||
Returns: -1 (setting errno) on failure, an open file descriptor otherwise
|
||||
|
||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_openpt.html ]]
|
||||
*/
|
||||
posix_openpt :: proc(oflag: O_Flags) -> FD ---
|
||||
|
||||
/*
|
||||
Returns the name of the slave pseudo-terminal device associated with a master pseudo-terminal device.
|
||||
|
||||
Returns: nil (setting errno) on failure, the name on success, which may be invalidated on subsequent calls
|
||||
|
||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/ptsname.html ]]
|
||||
*/
|
||||
ptsname :: proc(fildes: FD) -> cstring ---
|
||||
|
||||
/*
|
||||
Unlocks the slave pseudo-terminal device associated with the master to which fildes refers.
|
||||
|
||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/unlockpt.html ]]
|
||||
*/
|
||||
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.
|
||||
|
||||
Example:
|
||||
if posix.setenv("HOME", "/usr/home") != .OK {
|
||||
fmt.panicf("putenv failure: %v", posix.strerror(posix.errno()))
|
||||
}
|
||||
|
||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/setenv.html ]]
|
||||
*/
|
||||
setenv :: proc(envname: cstring, envval: cstring, overwrite: b32) -> result ---
|
||||
|
||||
/*
|
||||
Removes an environment variable from the environment of the calling process.
|
||||
|
||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/unsetenv.html ]]
|
||||
*/
|
||||
@(link_name=LUNSETENV)
|
||||
unsetenv :: proc(name: cstring) -> result ---
|
||||
|
||||
/*
|
||||
Computes a sequence of pseudo-random integers in the range [0, {RAND_MAX}].
|
||||
(The value of the {RAND_MAX} macro shall be at least 32767.)
|
||||
|
||||
If rand_r() is called with the same initial value for the object pointed to by seed and that object is not modified between successive returns and calls to rand_r(), the same sequence shall be generated.
|
||||
|
||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/rand_r.html ]]
|
||||
*/
|
||||
rand_r :: proc(seed: ^c.uint) -> c.int ---
|
||||
|
||||
/*
|
||||
Derive, from the pathname file_name, an absolute pathname that resolves to the same directory entry,
|
||||
whose resolution does not involve '.', '..', or symbolic links.
|
||||
|
||||
If resolved_name is not `nil` it should be larger than `PATH_MAX` and the result will use it as a backing buffer.
|
||||
If resolved_name is `nil` the returned string is allocated by `malloc`.
|
||||
|
||||
Returns: `nil` (setting errno) on failure, the "real path" otherwise
|
||||
|
||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/realpath.html ]]
|
||||
*/
|
||||
realpath :: proc(file_name: cstring, resolved_name: [^]byte = nil) -> cstring ---
|
||||
|
||||
/*
|
||||
Provides access to an implementation-defined encoding algorithm.
|
||||
The argument of setkey() is an array of length 64 bytes containing only the bytes with numerical
|
||||
value of 0 and 1.
|
||||
|
||||
If this string is divided into groups of 8, the low-order bit in each group is ignored; this gives a 56-bit key which is used by the algorithm.
|
||||
This is the key that shall be used with the algorithm to encode a string block passed to encrypt().
|
||||
|
||||
The setkey() function shall not change the setting of errno if successful.
|
||||
An application wishing to check for error situations should set errno to 0 before calling setkey().
|
||||
If errno is non-zero on return, an error has occurred.
|
||||
|
||||
Example:
|
||||
key: [64]byte
|
||||
// set key bytes...
|
||||
|
||||
posix.set_errno(.NONE)
|
||||
posix.setkey(raw_data(key))
|
||||
if errno := posix.errno(); errno != .NONE {
|
||||
fmt.panicf("setkey failure: %s", posix.strerror(errno))
|
||||
}
|
||||
|
||||
[[ More; https://pubs.opengroup.org/onlinepubs/9699919799/functions/setkey.html ]]
|
||||
*/
|
||||
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 {
|
||||
@(private) LPUTENV :: "__putenv50"
|
||||
@(private) LINITSTATE :: "__initstate60"
|
||||
@(private) LSRANDOM :: "__srandom60"
|
||||
@(private) LUNSETENV :: "__unsetenv13"
|
||||
} else {
|
||||
@(private) LPUTENV :: "putenv"
|
||||
@(private) LINITSTATE :: "initstate"
|
||||
@(private) LSRANDOM :: "srandom"
|
||||
@(private) LUNSETENV :: "unsetenv"
|
||||
}
|
||||
Reference in New Issue
Block a user