core/os
os
Types
27Error
Error :: union {
General_Error,
io.Error,
runtime.Allocator_Error,
Platform_Error,
}SourceError is a union of different classes of errors that could be returned from procedures in this package.
File
File :: struct {
impl: rawptr,
stream: File_Stream,
}SourceType representing a file handle.
This struct represents an OS-specific file-handle, which can be one of
the following:
- File
- Directory
- Pipe
- Named pipe
- Block Device
- Character device
- Symlink
- Socket
See `File_Type` enum for more information on file types.File_Flag
File_Flag :: enum int {
Read = 0,
Write = 1,
Append = 2,
Create = 3,
Excl = 4,
Sync = 5,
Trunc = 6,
Sparse = 7,
Inheritable = 8,
Non_Blocking = 9,
Unbuffered_IO = 10,
}SourceFile_Flags
File_Flags :: bit_set[File_Flag; uint]SourceRepresents the file flags for a file handle
File_Impl
File_Impl :: struct {
file: File,
name: string,
fd: linux.Fd,
allocator: runtime.Allocator,
buffer: []u8,
rw_mutex: sync.RW_Mutex,
p_mutex: sync.Mutex,
}SourceFile_Info
File_Info :: struct {
fullpath: string,
name: string,
inode: u128,
size: i64,
mode: Permissions,
type: File_Type,
creation_time: time.Time,
modification_time: time.Time,
access_time: time.Time,
}SourceFile_Info describes a file and is returned from stat, fstat, and lstat.
File_Stream
File_Stream :: struct {
procedure: File_Stream_Proc,
data: rawptr,
}SourceFile_Stream_Mode
File_Stream_Mode :: enum int {
Close = 0,
Flush = 1,
Read = 2,
Read_At = 3,
Write = 4,
Write_At = 5,
Seek = 6,
Size = 7,
Destroy = 8,
Query = 9, // query what modes are available on `io.Stream`
Fstat = 10, // File specific (not available on io.Stream)
}SourceA subset of the io.Stream_Mode with added File specific modes
File_Stream_Proc
File_Stream_Proc :: proc(
stream_data: rawptr,
mode: File_Stream_Mode,
p: []u8,
offset: i64,
whence: io.Seek_From,
allocator: runtime.Allocator,
) -> (n: i64, err: Error)SourceSuperset interface of io.Stream_Proc with the added runtime.Allocator parameter needed for the Fstat mode
File_Type
File_Type :: enum int {
// The type of a file could not be determined for the current platform.
Undetermined = 0,
// Represents a regular file.
Regular = 1,
// Represents a directory.
Directory = 2,
// Represents a symbolic link.
Symlink = 3,
// Represents a named pipe (FIFO).
Named_Pipe = 4,
// Represents a socket.
// **Note(windows)**: Not returned on windows
Socket = 5,
// Represents a block device.
// **Note(windows)**: On windows represents all devices.
Block_Device = 6,
// Represents a character device.
// **Note(windows)**: Not returned on windows
Character_Device = 7,
}SourceType representing the type of a file handle.
**Note(windows)**: Socket handles can not be distinguished from
files, as they are just a normal file handle that is being treated by
a special driver. Windows also makes no distinction between block and
character devices.Fstat_Callback
Fstat_Callback :: proc(f: ^File, allocator: runtime.Allocator) -> (File_Info, Error)SourceGeneral_Error
General_Error :: enum u32 {
None = 0,
Exist = 1,
Not_Exist = 2,
Timeout = 3,
Broken_Pipe = 4,
Invalid_File = 5,
Invalid_Dir = 6,
Invalid_Path = 7,
Invalid_Callback = 8,
Invalid_Command = 9,
Pattern_Has_Separator = 10,
Pattern_Syntax_Error = 11, // Indicates an error in `glob` or `match` pattern.
No_HOME_Variable = 12,
Env_Var_Not_Found = 13,
}SourceGeneral errors that are common within this package which cannot
be categorized by `io.Error` nor `runtime.Allocator_Error`.Permission_Flag
Permission_Flag :: enum u32 {
Execute_Other = 0,
Write_Other = 1,
Read_Other = 2,
Execute_Group = 3,
Write_Group = 4,
Read_Group = 5,
Execute_User = 6,
Write_User = 7,
Read_User = 8,
}SourcePermissions
Permissions :: bit_set[Permission_Flag; u32]SourceProcess
Process :: struct {
pid: int,
handle: uintptr,
}SourceRepresents a process handle.
When a process dies, the OS is free to re-use the pid of that process. The Process struct represents a handle to the process that will refer to a specific process, even after it has died.
Note(linux): The handle will be referring to pidfd.
Process_Desc
Process_Desc :: struct {
// The working directory of the process. If the string has length 0, the
// working directory is assumed to be the current working directory of the
// current process.
working_dir: string,
// The command to run. Each element of the slice is a separate argument to
// the process. The first element of the slice would be the executable.
command: []string,
// A slice of strings, each having the format `KEY=VALUE` representing the
// full environment that the child process will receive.
// In case this slice is `nil`, the current process' environment is used.
// NOTE(laytan): maybe should be `Maybe([]string)` so you can do `nil` == current env, empty == empty/no env.
env: []string,
// The `stderr` handle to give to the child process. It can be either a file
// or a writeable end of a pipe. Passing `nil` will shut down the process'
// stderr output.
stderr: ^File,
// The `stdout` handle to give to the child process. It can be either a file
// or a writeabe end of a pipe. Passing a `nil` will shut down the process'
// stdout output.
stdout: ^File,
// The `stdin` handle to give to the child process. It can either be a file
// or a readable end of a pipe. Passing a `nil` will shut down the process'
// input.
stdin: ^File,
}SourceThe description of how a process should be created.
Process_Info
Process_Info :: struct {
// The information about a process the struct contains. `pid` is always
// stored, no matter what.
fields: Process_Info_Fields,
// The ID of the process.
pid: int,
// The ID of the parent process.
ppid: int,
// The process priority.
priority: int,
// The path to the executable, which the process runs.
executable_path: string,
// The command line supplied to the process.
command_line: string,
// The arguments supplied to the process.
command_args: []string,
// The environment of the process.
environment: []string,
// The username of the user who started the process.
username: string,
// The current working directory of the process.
working_dir: string,
}SourceContains information about the process as obtained by the process_info() procedure.
Process_Info_Field
Process_Info_Field :: enum int {
Executable_Path = 0,
PPid = 1,
Priority = 2,
Command_Line = 3,
Command_Args = 4,
Environment = 5,
Username = 6,
Working_Dir = 7,
}SourceProcess_Info_Fields
Process_Info_Fields :: bit_set[Process_Info_Field; 0..7]SourceBit set specifying which fields of the Process_Info struct need to be obtained by the process_info() procedure. Each bit corresponds to a field in the Process_Info struct.
Process_Open_Flag
Process_Open_Flag :: enum int {
// Request for reading from the virtual memory of another process.
Mem_Read = 0,
// Request for writing to the virtual memory of another process.
Mem_Write = 1,
}SourceProcess_Open_Flags
Process_Open_Flags :: bit_set[Process_Open_Flag; 0..1]SourceProcess_State
Process_State :: struct {
// The ID of the process.
pid: int,
// Specifies whether the process has terminated or is still running.
exited: bool,
// The exit code of the process, if it has exited.
// Will also store the number of the exception or signal that has crashed the
// process.
exit_code: int,
// Specifies whether the termination of the process was successful or not,
// i.e. whether it has crashed or not.
// **Note(windows)**: On windows `true` is always returned, as there is no
// reliable way to obtain information about whether the process has crashed.
success: bool,
// The time the process has spend executing in kernel time.
system_time: time.Duration,
// The time the process has spend executing in userspace.
user_time: time.Duration,
}SourceThe state of the process after it has finished execution.
Read_Directory_Iterator
Read_Directory_Iterator :: struct {
f: ^File,
err: struct {
err: Error,
path: [dynamic]u8,
},
index: int,
impl: Read_Directory_Iterator_Impl,
}SourceRead_Directory_Iterator_Impl
Read_Directory_Iterator_Impl :: struct {
prev_fi: File_Info,
dirent_backing: []u8,
dirent_buflen: int,
dirent_off: int,
}SourceTemp_Allocator
Temp_Allocator :: struct {
arena: ^runtime.Arena,
allocator: runtime.Allocator,
tmp: runtime.Arena_Temp,
loc: runtime.Source_Code_Location,
}SourceWalker
Walker :: struct {
todo: queue.Queue(string),
skip_dir: bool,
err: struct {
path: [dynamic]u8,
err: Error,
},
iter: Read_Directory_Iterator,
}SourceA recursive directory walker.
Note that none of the fields should be accessed directly.
_Platform_Error
_Platform_Error :: ErrnoSourceConstants
35ALL_INFO
ALL_INFO :: Process_Info_Fields = Process_Info_Fields{.Executable_Path, .PPid, .Priority, .Command_Line, .Command_Args, .Environment, .Username, .Working_Dir}SourceERROR_NONE
ERROR_NONE :: Error = Error{}SourceMAX_RW
MAX_RW :: 1 << 30SourceMost implementations will EINVAL at some point when doing big writes. In practice a read/write call would probably never read/write these big buffers all at once, which is why the number of bytes is returned and why there are procs that will call this in a loop for you. We set a max of 1GB to keep alignment and to be safe.
O_APPEND
O_APPEND :: File_Flags = File_Flags{.Append}SourceO_CREATE
O_CREATE :: File_Flags = File_Flags{.Create}SourceO_EXCL
O_EXCL :: File_Flags = File_Flags{.Excl}SourceO_INHERITABLE
O_INHERITABLE :: File_Flags = File_Flags{.Inheritable}SourceIf specified, the file handle is inherited upon the creation of a child
process. By default all handles are created non-inheritable.
**Note**: The standard file handles (stderr, stdout and stdin) are always
initialized as inheritable.O_RDONLY
O_RDONLY :: File_Flags = File_Flags{.Read}SourceO_RDWR
O_RDWR :: File_Flags = File_Flags{.Read, .Write}SourceO_SPARSE
O_SPARSE :: File_Flags = File_Flags{.Sparse}SourceO_SYNC
O_SYNC :: File_Flags = File_Flags{.Sync}SourceO_TRUNC
O_TRUNC :: File_Flags = File_Flags{.Trunc}SourceO_WRONLY
O_WRONLY :: File_Flags = File_Flags{.Write}SourcePIDFD_UNASSIGNED
PIDFD_UNASSIGNED :: _ = ~uintptr(0)SourcePath_List_Separator
Path_List_Separator :: _Path_List_SeparatorSourceOS-Specific
Path_Separator
Path_Separator :: _Path_SeparatorSourceOS-Specific
Path_Separator_Chars
Path_Separator_Chars :: `/\`SourcePath_Separator_String
Path_Separator_String :: _Path_Separator_StringSourceOS-Specific
Permissions_All
Permissions_All :: Permissions = Permissions_Read_All + Permissions_Write_All + Permissions_Execute_AllSourcePermissions_Default
Permissions_Default :: Permissions_Default_DirectorySourcePermissions_Default_Directory
Permissions_Default_Directory :: Permissions = Permissions_Read_All + Permissions_Write_All + Permissions_Execute_AllSourcePermissions_Default_File
Permissions_Default_File :: Permissions = Permissions_Read_All + Permissions_Write_AllSourcePermissions_Execute_All
Permissions_Execute_All :: Permissions = Permissions{.Execute_User, .Execute_Group, .Execute_Other}SourcePermissions_Read_All
Permissions_Read_All :: Permissions = Permissions{.Read_User, .Read_Group, .Read_Other}SourcePermissions_Read_Write_All
Permissions_Read_Write_All :: Permissions = Permissions_Read_All + Permissions_Write_AllSourcePermissions_Write_All
Permissions_Write_All :: Permissions = Permissions{.Write_User, .Write_Group, .Write_Other}SourcePlatform_Error
Platform_Error :: _Platform_ErrorSourceA platform specific error
TIMEOUT_INFINITE
TIMEOUT_INFINITE :: time.MIN_DURATIONSourceIn procedures that explicitly state this as one of the allowed values, specifies an infinite timeout.
_OPENDIR_FLAGS
_OPENDIR_FLAGS :: linux.Open_Flags = {.NONBLOCK, .DIRECTORY, .LARGEFILE, .CLOEXEC}Source_Path_List_Separator
_Path_List_Separator :: ':'Source_Path_Separator
_Path_Separator :: '/'Source_Path_Separator_String
_Path_Separator_String :: "/"Source_heap_allocator_proc
_heap_allocator_proc :: runtime.heap_allocator_procSourcetemp_allocator_begin
temp_allocator_begin :: runtime.arena_temp_beginSourcetemp_allocator_end
temp_allocator_end :: runtime.arena_temp_endSourceVariables
8_errno_strings
_errno_strings :: [linux.Errno]string = [linux.Errno]string{
.NONE = "",
.EPERM = "Operation not permitted",
.ENOENT = "No such file or directory",
.ESRCH = "No such process",
.EINTR = "Interrupted system call",
.EIO = "Input/ouSource_stderr
_stderr :: File = File{
stream = {
procedure = _file_stream_proc,
},
}Source_stdin
_stdin :: File = File{
stream = {
procedure = _file_stream_proc,
},
}Source_stdout
_stdout :: File = File{
stream = {
procedure = _file_stream_proc,
},
}Sourceargs
args :: _ = get_args()SourceArguments to the current process.
stderr
stderr :: ^File = nilSourcestderr is an open file pointing to the standard error file stream
stdin
stdin :: ^File = nilSourcestdin is an open file pointing to the standard input file stream
stdout
stdout :: ^File = nilSourcestdout is an open file pointing to the standard output file stream
Procedures
281TEMP_ALLOCATOR_GUARD
TEMP_ALLOCATOR_GUARD :: proc(collisions: []runtime.Allocator, loc = #caller_location) -> (Temp_Allocator)SourceTEMP_ALLOCATOR_GUARD_END
TEMP_ALLOCATOR_GUARD_END :: proc(temp: Temp_Allocator)Source_are_paths_identical
_are_paths_identical :: proc(a: string, b: string) -> (identical: bool)SourceThis implementation is for all systems that have POSIX-compliant filesystem paths.
_chdir
_chdir :: proc(name: string) -> (Error)Source_chmod
_chmod :: proc(name: string, mode: Permissions) -> (Error)Source_chown
_chown :: proc(name: string, uid: int, gid: int) -> (Error)SourceNOTE: will throw error without super user priviledges
_chtimes
_chtimes :: proc(name: string, atime: time.Time, mtime: time.Time) -> (Error)Source_clean_path_handle_start
_clean_path_handle_start :: proc(path: string, buffer: []u8) -> (rooted: bool, start: int)Source_clone
_clone :: proc(f: ^File) -> (clone: ^File, err: Error)Source_close
_close :: proc(f: ^File_Impl) -> (Error)Source_destroy
_destroy :: proc(f: ^File_Impl) -> (Error)Source_error_string
_error_string :: proc(errno: i32) -> (string)Source_exists
_exists :: proc(name: string) -> (bool)Source_fchdir
_fchdir :: proc(f: ^File) -> (Error)Source_fchmod
_fchmod :: proc(f: ^File, mode: Permissions) -> (Error)Source_fchown
_fchown :: proc(f: ^File, uid: int, gid: int) -> (Error)SourceNOTE: will throw error without super user priviledges
_fchtimes
_fchtimes :: proc(f: ^File, atime: time.Time, mtime: time.Time) -> (Error)Source_fd
_fd :: proc(f: ^File) -> (uintptr)Source_file_size
_file_size :: proc(f: ^File_Impl) -> (n: i64, err: Error)Source_flush
_flush :: proc(f: ^File_Impl) -> (Error)Source_fstat
_fstat :: proc(f: ^File, allocator: runtime.Allocator) -> (Error, File_Info)Source_fstat_internal
_fstat_internal :: proc(fd: linux.Fd, allocator: runtime.Allocator) -> (fi: File_Info, err: Error)Source_get_absolute_path
_get_absolute_path :: proc(path: string, allocator: runtime.Allocator) -> (absolute_path: string, err: Error)Source_get_common_path_len
_get_common_path_len :: proc(base: string, target: string) -> (int)Source_get_executable_path
_get_executable_path :: proc(allocator: runtime.Allocator) -> (path: string, err: Error)Source_get_full_path
_get_full_path :: proc(fd: linux.Fd, allocator: runtime.Allocator) -> (fullpath: string, err: Error)Source_get_platform_error
_get_platform_error :: proc(errno: linux.Errno) -> (Error)Source_get_relative_path_handle_start
_get_relative_path_handle_start :: proc(base: string, target: string) -> (bool)Source_get_working_directory
_get_working_directory :: proc(allocator: runtime.Allocator) -> (path: string, err: Error)Source_glob
_glob :: proc(dir: string, pattern: string, matches: ^[dynamic]string, allocator: mem.Allocator = context.allocator) -> (m: [dynamic]string, e: Error)SourceInternal implementation of glob, not meant to be used by the user. Prefer glob.
_is_absolute_path
_is_absolute_path :: proc(path: string) -> (bool)Source_is_path_separator
_is_path_separator :: proc(c: u8) -> (bool)Source_is_reserved_name
_is_reserved_name :: proc(path: string) -> (bool)Source_is_tty
_is_tty :: proc(f: ^File) -> (bool)Source_lchown
_lchown :: proc(name: string, uid: int, gid: int) -> (Error)SourceNOTE: will throw error without super user priviledges
_link
_link :: proc(old_name: string, new_name: string) -> (Error)Source_lstat
_lstat :: proc(name: string, allocator: runtime.Allocator) -> (fi: File_Info, err: Error)Source_mkdir
_mkdir :: proc(path: string, perm: Permissions) -> (Error)Source_mkdir_all
_mkdir_all :: proc(path: string, perm: Permissions) -> (Error)Source_name
_name :: proc(f: ^File) -> (string)Source_new_file
_new_file :: proc(fd: uintptr, _: string, allocator: runtime.Allocator) -> (f: ^File, err: Error)Source_open
_open :: proc(name: string, flags: File_Flags, perm: Permissions) -> (f: ^File, err: Error)Source_open_buffered
_open_buffered :: proc(name: string, buffer_size: uint, flags: File_Flags = File_Flags{.Read}, perm: Permissions) -> (f: ^File, err: Error)Source_pipe
_pipe :: proc() -> (r: ^File, w: ^File, err: Error)Source_pipe_has_data
_pipe_has_data :: proc(r: ^File) -> (ok: bool, err: Error)Source_prefix_and_suffix
_prefix_and_suffix :: proc(pattern: string) -> (prefix: string, suffix: string, err: Error)SourceSplits pattern by the last wildcard "", if it exists, and returns the prefix and suffix parts which are split by the last ""
_process_close
_process_close :: proc(process: Process) -> (Error)Source_process_state_update_times
_process_state_update_times :: proc(state: ^Process_State) -> (err: Error)Source_read
_read :: proc(f: ^File_Impl, p: []u8) -> (Error, i64)Source_read_at
_read_at :: proc(f: ^File_Impl, p: []u8, offset: i64) -> (Error, i64)Source_read_directory_iterator
_read_directory_iterator :: proc(it: ^Read_Directory_Iterator) -> (fi: File_Info, index: int, ok: bool)Source_read_directory_iterator_destroy
_read_directory_iterator_destroy :: proc(it: ^Read_Directory_Iterator)Source_read_directory_iterator_init
_read_directory_iterator_init :: proc(it: ^Read_Directory_Iterator, f: ^File)Source_read_entire_pseudo_file_cstring
_read_entire_pseudo_file_cstring :: proc(name: cstring, allocator: runtime.Allocator) -> ([]u8, Error)Source_read_entire_pseudo_file_string
_read_entire_pseudo_file_string :: proc(name: string, allocator: runtime.Allocator) -> (b: []u8, e: Error)Source_read_link
_read_link :: proc(name: string, allocator: runtime.Allocator) -> (s: string, e: Error)Source_read_link_cstr
_read_link_cstr :: proc(name_cstr: cstring, allocator: runtime.Allocator) -> (Error, string)Source_reap_terminated
_reap_terminated :: proc(process: Process) -> (state: Process_State, err: Error)Source_remove
_remove :: proc(name: string) -> (Error)Source_remove_all
_remove_all :: proc(path: string) -> (Error)Source_rename
_rename :: proc(old_name: string, new_name: string) -> (Error)Source_same_file
_same_file :: proc(fi1: File_Info, fi2: File_Info) -> (bool)Source_seek
_seek :: proc(f: ^File_Impl, offset: i64, whence: io.Seek_From) -> (ret: i64, err: Error)Source_set_working_directory
_set_working_directory :: proc(dir: string) -> (Error)Source_split_path
_split_path :: proc(path: string) -> (dir: string, file: string)Source_standard_stream_init
_standard_stream_init :: proc()Source_stat
_stat :: proc(name: string, allocator: runtime.Allocator) -> (fi: File_Info, err: Error)SourceNOTE: _stat and _lstat are using _fstat to avoid a race condition when populating fullpath
_symlink
_symlink :: proc(old_name: string, new_name: string) -> (Error)Source_sync
_sync :: proc(f: ^File) -> (Error)Source_temp_dir
_temp_dir :: proc(allocator: runtime.Allocator) -> (runtime.Allocator_Error, string)Source_timed_wait_on_handle
_timed_wait_on_handle :: proc(process: Process, timeout: time.Duration) -> (process_state: Process_State, err: Error)Source_timed_wait_on_pid
_timed_wait_on_pid :: proc(process: Process, timeout: time.Duration) -> (process_state: Process_State, err: Error)Source_truncate
_truncate :: proc(f: ^File, size: i64) -> (Error)Source_user_cache_dir
_user_cache_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error)Source_user_config_dir
_user_config_dir :: proc(allocator: runtime.Allocator, _roaming: bool) -> (dir: string, err: Error)Source_user_data_dir
_user_data_dir :: proc(allocator: runtime.Allocator, _roaming: bool) -> (dir: string, err: Error)Source_user_desktop_dir
_user_desktop_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error)Source_user_documents_dir
_user_documents_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error)Source_user_downloads_dir
_user_downloads_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error)Source_user_home_dir
_user_home_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error)Source_user_log_dir
_user_log_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error)Source_user_music_dir
_user_music_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error)Source_user_pictures_dir
_user_pictures_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error)Source_user_public_dir
_user_public_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error)Source_user_state_dir
_user_state_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error)Source_user_videos_dir
_user_videos_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error)Source_write
_write :: proc(f: ^File_Impl, p: []u8) -> (nt: i64, err: Error)Source_write_at
_write_at :: proc(f: ^File_Impl, p: []u8, offset: i64) -> (nt: i64, err: Error)Source_xdg_lookup
_xdg_lookup :: proc(xdg_key: string, fallback_suffix: string, allocator: runtime.Allocator) -> (dir: string, err: Error)Source_xdg_user_dirs_lookup
_xdg_user_dirs_lookup :: proc(xdg_key: string, allocator: runtime.Allocator) -> (dir: string, err: Error)SourceIf <config-dir>/user-dirs.dirs doesn't exist, or xdg_key can't be found there: returns ""
are_paths_identical
are_paths_identical :: proc(a: string, b: string) -> (identical: bool)SourceCompare two paths for exactness without normalization.
This procedure takes into account case-sensitivity on differing systems.
base
base :: proc(path: string) -> (string)SourceGets the file name and extension from a path.
e.g.
'path/to/name.tar.gz' -> 'name.tar.gz'
'path/to/name.txt' -> 'name.txt'
'path/to/name' -> 'name'
Returns "." if the path is an empty string.change_directory
change_directory :: proc(name: string) -> (Error)SourceChanges the current working directory to the named directory.
change_mode
change_mode :: proc(name: string, mode: Permissions) -> (Error)SourceChanges the mode/permissions of the named file to mode.
If the file is a symbolic link, it changes the mode of the link's target.
On Windows, only `{.Write_User}` of `mode` is used, and controls whether or not
the file has a read-only attribute. Use `{.Read_User}` for a read-only file and
`{.Read_User, .Write_User}` for a readable & writable file.change_owner
change_owner :: proc(name: string, uid: int, gid: int) -> (Error)SourceChanges the numeric uid and gid of a named file. If the file is a symbolic link,
it changes the `uid` and `gid` of the link's target.
On Windows, it always returns an error.change_owner_do_not_follow_links
change_owner_do_not_follow_links :: proc(name: string, uid: int, gid: int) -> (Error)SourceChanges the numeric uid and gid of the file f. If the file is a symbolic link,
it changes the `uid` and `gid` of the lin itself.
On Windows, it always returns an error.change_times
change_times :: proc(name: string, atime: time.Time, mtime: time.Time) -> (Error)SourceChanges the access atime and modification mtime times of a named file.
chdir
chdir :: proc(name: string) -> (Error)Sourcechmod
chmod :: proc(name: string, mode: Permissions) -> (Error)Sourcechown
chown :: proc(name: string, uid: int, gid: int) -> (Error)Sourcechtimes
chtimes :: proc(name: string, atime: time.Time, mtime: time.Time) -> (Error)Sourceclean_path
clean_path :: proc(path: string, allocator: runtime.Allocator) -> (cleaned: string, err: runtime.Allocator_Error)SourceNormalize a path.
Allocates Using Provided Allocator
This will remove duplicate separators and unneeded references to the current or parent directory.
clear_env
clear_env :: proc()Sourceclone
clone :: proc(f: ^File) -> (^File, Error)Sourceclone returns a new ^File based on the passed file f with the same underlying file descriptor.
clone_string
clone_string :: proc(s: string, allocator: runtime.Allocator) -> (res: string, err: runtime.Allocator_Error)Sourceclone_to_cstring
clone_to_cstring :: proc(s: string, allocator: runtime.Allocator) -> (res: cstring, err: runtime.Allocator_Error)Sourceclose
close :: proc(f: ^File) -> (Error)SourceClose a file and its stream.
Any further use of the file or its stream should be considered to be in the
same class of bugs as a use-after-free.concatenate
concatenate :: proc(strings: []string, allocator: runtime.Allocator) -> (res: string, err: runtime.Allocator_Error)Sourceconcatenate_strings_from_buffer
concatenate_strings_from_buffer :: proc(buf: []u8, strings) -> (string)Sourcecopy_directory_all
copy_directory_all :: proc(dst: string, src: string, dst_perm = Permissions_Default) -> (Error)SourceRecursively copies a directory to dst from src
copy_file
copy_file :: proc(dst_path: string, src_path: string) -> (Error)Sourcecreate
create :: proc(name: string) -> (^File, Error)Sourcecreate creates or truncates a named file name.
If the file already exists, it is truncated.
If the file does not exist, it is created with the `Permissions_Default_File` permissions.
If successful, a `^File` is return which can be used for I/O.
And error is returned if any is encountered.create_temp_file
create_temp_file :: proc(dir: string, pattern: string, additional_flags: File_Flags) -> (f: ^File, err: Error)SourceCreates a new temperatory file in the directory dir.
Opens the file for reading and writing, with Permissions_Read_Write_All permissions, and returns the new ^File. The filename is generated by taking a pattern, and adding a randomized string to the end. If the pattern includes an "", the random string replaces the last "". If dir is an empty string, temp_directory() will be used.
The caller must close the file once finished with.
current_process_info
current_process_info :: proc(selection: Process_Info_Fields, allocator: runtime.Allocator) -> (Error, Process_Info)SourceObtain information about the current process.
This procedure obtains the information, specified by selection parameter about the currently running process.
Use free_process_info to free the memory allocated by this procedure. The free_process_info procedure needs to be called, even if this procedure returned an error, as some of the fields may have been allocated.
Note: The resulting information may or may contain the fields specified by the selection parameter. Always check whether the returned Process_Info struct has the required fields before checking the error code returned by this procedure.
dir
dir :: proc(path: string) -> (string)SourceGets the parent directory path from a path.
e.g.
'/home/foo/bar.tar.gz' -> '/home/foo'
'path/to/name.tar.gz' -> 'path/to'
Returns "." if the path is an empty string.environ
environ :: proc(allocator: runtime.Allocator) -> ([]string, Error)Sourceenviron returns a copy of strings representing the environment, in the form "key=value" NOTE: the slice of strings and the strings with be allocated using the supplied allocator
error_string
error_string :: proc(ferr: Error) -> (string)SourceAttempts to return the error ferr as a string without any allocation
exists
exists :: proc(path: string) -> (bool)Sourceexists returns whether or not a named file exists.
exit
exit :: proc(code: int) -> ()SourceTells the OS to exit the current process directly.
IMPORTANT: @(fini) blocks won't be executed.
If you want @(fini) cleanup to happen, call runtime._cleanup_runtime first.
ext
ext :: proc(path: string) -> (string)SourceGets the file extension from a path, including the dot.
The file extension is such that stem_path(path) + ext(path) = base(path).
Only the last dot is considered when splitting the file extension. See long_ext.
e.g.
'name.tar.gz' -> '.gz'
'name.txt' -> '.txt'
Returns an empty string if there is no dot.
Returns an empty string if there is a trailing path separator.fchange_directory
fchange_directory :: proc(f: ^File) -> (Error)SourceChanges the current working directory to the file, which must be a directory.
fchange_mode
fchange_mode :: proc(f: ^File, mode: Permissions) -> (Error)SourceChanges the current mode permissions of the file f.
fchange_owner
fchange_owner :: proc(f: ^File, uid: int, gid: int) -> (Error)SourceChanges the numeric uid and gid of the file f. If the file is a symbolic link,
it changes the `uid` and `gid` of the link's target.
On Windows, it always returns an error.fchange_times
fchange_times :: proc(f: ^File, atime: time.Time, mtime: time.Time) -> (Error)SourceChanges the access atime and modification mtime times of the file f.
fchdir
fchdir :: proc(f: ^File) -> (Error)Sourcefchmod
fchmod :: proc(f: ^File, mode: Permissions) -> (Error)Sourcefchown
fchown :: proc(f: ^File, uid: int, gid: int) -> (Error)Sourcefchtimes
fchtimes :: proc(f: ^File, atime: time.Time, mtime: time.Time) -> (Error)Sourcefd
fd :: proc(f: ^File) -> (uintptr)Sourcefd returns the file descriptor of the file f passed. If the file is not valid, an invalid handle will be returned.
file_allocator
file_allocator :: proc() -> (runtime.Allocator)Sourcefile_info_clone
file_info_clone :: proc(fi: File_Info, allocator: runtime.Allocator) -> (cloned: File_Info, err: runtime.Allocator_Error)Sourcefile_info_delete
file_info_delete :: proc(fi: File_Info, allocator: runtime.Allocator)Sourcefile_info_slice_delete
file_info_slice_delete :: proc(infos: []File_Info, allocator: runtime.Allocator)Sourcefile_size
file_size :: proc(f: ^File) -> (n: i64, err: Error)Sourcefile_size returns the length of the file f in bytes and an error, if any is encountered.
flush
flush :: proc(f: ^File) -> (Error)Sourceflush flushes a file f
free_process_info
free_process_info :: proc(pi: Process_Info, allocator: runtime.Allocator)SourceFree the information about the process.
This procedure frees the memory occupied by process info using the provided allocator. The allocator needs to be the same allocator that was supplied to the process_info function.
fstat
fstat :: proc(f: ^File, allocator: runtime.Allocator) -> (Error, File_Info)Sourceget_absolute_path
get_absolute_path :: proc(path: string, allocator: runtime.Allocator) -> (absolute_path: string, err: Error)SourceGet the absolute path to path with respect to the process's current directory.
Allocates Using Provided Allocator
get_current_thread_id
get_current_thread_id :: proc() -> (int)SourceObtain the current thread id
get_egid
get_egid :: proc() -> (int)SourceObtain the effective GID of the current process.
The effective GID is typically the same as the GID of the process. In case the process was run by a user with elevated permissions, the process may lower the privilege to perform some tasks without privilege. In these cases the real GID of the process and the effective GID are different.
Note(windows): Windows doesn't follow the posix permissions model, so the function simply returns -1.
get_env_alloc
get_env_alloc :: proc(key: string, allocator: runtime.Allocator) -> (string)Sourceget_env retrieves the value of the environment variable named by the key It returns the value, which will be empty if the variable is not present To distinguish between an empty value and an unset value, use lookup_env NOTE: the value will be allocated with the supplied allocator
get_env_buf
get_env_buf :: proc(buf: []u8, key: string) -> (string)Sourceget_env retrieves the value of the environment variable named by the key It returns the value, which will be empty if the variable is not present To distinguish between an empty value and an unset value, use lookup_env NOTE: this version takes a backing buffer for the string value
get_euid
get_euid :: proc() -> (int)SourceObtain the effective UID of the current process.
The effective UID is typically the same as the UID of the process. In case the process was run by a user with elevated permissions, the process may lower the privilege to perform some tasks without privilege. In these cases the real UID of the process and the effective UID are different.
Note(windows): Windows doesn't follow the posix permissions model, so the function simply returns -1.
get_executable_directory
get_executable_directory :: proc(allocator: runtime.Allocator) -> (path: string, err: Error)SourceGet the directory for the currently running executable.
Allocates Using Provided Allocator
get_executable_path
get_executable_path :: proc(allocator: runtime.Allocator) -> (path: string, err: Error)SourceGet the path for the currently running executable.
Allocates Using Provided Allocator
get_gid
get_gid :: proc() -> (int)SourceObtain the GID of the current process.
Note(windows): Windows doesn't follow the posix permissions model, so the function simply returns -1.
get_pid
get_pid :: proc() -> (int)SourceObtain the ID of the current process.
get_ppid
get_ppid :: proc() -> (int)SourceObtain the ID of the parent process.
Note(windows): Windows does not mantain strong relationships between parent and child processes. This function returns the ID of the process that has created the current process. In case the parent has died, the ID returned by this function can identify a non-existent or a different process.
get_processor_core_count
get_processor_core_count :: proc() -> (int)SourceReturn the number of cores
get_relative_path
get_relative_path :: proc(base: string, target: string, allocator: runtime.Allocator) -> (path: string, err: Error)SourceGet the relative path needed to change directories from base to target.
Allocates Using Provided Allocator
The result is such that join_path(base, get_relative_path(base, target)) is equivalent to target.
NOTE: This procedure expects both base and target to be normalized first, which can be done by calling clean_path on them if needed.
This procedure will return an Invalid_Path error if base begins with a reference to the parent directory (".."). Use get_working_directory with join_path to construct absolute paths for both arguments instead.
get_uid
get_uid :: proc() -> (int)SourceObtain the UID of the current process.
Note(windows): Windows doesn't follow the posix permissions model, so the function simply returns -1.
get_working_directory
get_working_directory :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error)SourceGet the working directory of the current process.
Allocates Using Provided Allocator
getwd
getwd :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error)Sourceglob
glob :: proc(pattern: string, allocator: mem.Allocator = context.allocator) -> (matches: []string, err: Error)Sourceglob returns the names of all files matching pattern or nil if there are no matching files The syntax of patterns is the same as "match". The pattern may describe hierarchical names such as /usr/*/bin (assuming '/' is a separator)
glob ignores file system errors
heap_allocator
heap_allocator :: proc() -> (runtime.Allocator)SourceReturns the default heap_allocator for this specific platform.
heap_allocator_proc
heap_allocator_proc :: proc(
allocator_data: rawptr,
mode: runtime.Allocator_Mode,
size: int,
alignment: int,
old_memory: rawptr,
old_size: int,
loc: _ = #caller_location,
) -> ([]u8, runtime.Allocator_Error)Sourceis_absolute_path
is_absolute_path :: proc(path: string) -> (bool)SourceReturn true if path is an absolute path as opposed to a relative one.
is_dir
is_dir :: proc(path: string) -> (bool)Sourceis_directory
is_directory :: proc(path: string) -> (bool)SourceReturns whether or not the type of a named file is a File_Type.Directory file.
is_file
is_file :: proc(path: string) -> (bool)Sourceis_file returns whether or not the type of a named file is a File_Type.Regular file.
is_path_separator
is_path_separator :: proc(c: u8) -> (bool)SourceReturn true if c is a character used to separate paths into directory and file hierarchies on the current system.
is_platform_error
is_platform_error :: proc(ferr: Error) -> (err: i32, ok: bool)SourceAttempts to convert an Error into a platform specific error as an integer. ok is false if not possible
is_reserved_name
is_reserved_name :: proc(path: string) -> (bool)Sourceis_tty
is_tty :: proc(f: ^File) -> (bool)Sourceis_tty returns true if f is a TTY, false if not.
join_filename
join_filename :: proc(base: string, ext: string, allocator: runtime.Allocator) -> (joined: string, err: Error)SourceJoin base and ext with the system's filename extension separator.
Allocates Using Provided Allocator
For example, join_filename("foo", "tar.gz") will result in "foo.tar.gz".
join_path
join_path :: proc(elems: []string, allocator: runtime.Allocator) -> (joined: string, err: runtime.Allocator_Error)SourceJoin all elems with the system's path separator and normalize the result.
Allocates Using Provided Allocator
For example, join_path({"/home", "foo", "bar.txt"}) will result in "/home/foo/bar.txt".
last_write_time
last_write_time :: proc(f: ^File) -> (time.Time, Error)Sourcelast_write_time_by_name
last_write_time_by_name :: proc(path: string) -> (time.Time, Error)Sourcelchown
lchown :: proc(name: string, uid: int, gid: int) -> (Error)Sourcelink
link :: proc(old_name: string, new_name: string) -> (Error)Sourcelink creates a new_name as a hard link to the old_name file.
long_ext
long_ext :: proc(path: string) -> (string)SourceGets the file extension from a path, including the dot.
The long file extension is such that short_stem(path) + long_ext(path) = base(path).
The first dot is used to split off the file extension, unlike ext which uses the last dot.
e.g.
'name.tar.gz' -> '.tar.gz'
'name.txt' -> '.txt'
Returns an empty string if there is no dot.
Returns an empty string if there is a trailing path separator.lookup_env_alloc
lookup_env_alloc :: proc(key: string, allocator: runtime.Allocator) -> (value: string, found: bool)Sourcelookup_env gets the value of the environment variable named by the key If the variable is found in the environment the value (which can be empty) is returned and the boolean is true Otherwise the returned value will be empty and the boolean will be false NOTE: the value will be allocated with the supplied allocator
lookup_env_buf
lookup_env_buf :: proc(buf: []u8, key: string) -> (value: string, err: Error)SourceThis version of lookup_env doesn't allocate and instead requires the user to provide a buffer. Note that it is limited to environment names and values of 512 utf-16 values each due to the necessary utf-8 <> utf-16 conversion.
lstat
lstat :: proc(name: string, allocator: runtime.Allocator) -> (Error, File_Info)Sourcemake_directory
make_directory :: proc(name: string, perm = Permissions_Default_Directory) -> (Error)SourceMake a new directory.
If path is relative, it will be relative to the process's current working directory.
make_directory_all
make_directory_all :: proc(path: string, perm = Permissions_Default_Directory) -> (Error)SourceMake a new directory, creating new intervening directories when needed.
If path is relative, it will be relative to the process's current working directory.
make_directory_temp
make_directory_temp :: proc(dir: string, pattern: string, allocator: runtime.Allocator) -> (temp_path: string, err: Error)SourceCreates a new temporary directory in the directory dir, and returns the path of the new directory.
The directory name is generated by taking a pattern, and adding a randomized string to the end. If the pattern includes an "", the random string replaces the last "". If dir is an empty tring, temp_directory() will be used.
match
match :: proc(pattern: string, name: string) -> (matched: bool, err: Error)Sourcematch states whether "name" matches the shell pattern
Pattern syntax is:
pattern:
{term}
term:
'*' matches any sequence of non-/ characters
'?' matches any single non-/ character
'[' ['^'] { character-range } ']'
character classification (cannot be empty)
c matches character c (c != '*', '?', '\\', '[')
'\\' c matches character c
character-range
c matches character c (c != '\\', '-', ']')
'\\' c matches character c
lo '-' hi matches character c for lo <= c <= hi
`match` requires that the pattern matches the entirety of the name, not just a substring.
The only possible error returned is `.Syntax_Error` or an allocation error.
NOTE(bill): This is effectively the shell pattern matching system foundmkdir
mkdir :: proc(name: string, perm = Permissions_Default_Directory) -> (Error)Sourcemkdir_all
mkdir_all :: proc(path: string, perm = Permissions_Default_Directory) -> (Error)Sourcemkdir_temp
mkdir_temp :: proc(dir: string, pattern: string, allocator: runtime.Allocator) -> (temp_path: string, err: Error)Sourcemodification_time
modification_time :: proc(f: ^File) -> (time.Time, Error)SourceReturns the modification time of the file f.
The resolution of the timestamp is system-dependent.modification_time_by_path
modification_time_by_path :: proc(path: string) -> (time.Time, Error)SourceReturns the modification time of the named file path.
The resolution of the timestamp is system-dependent.name
name :: proc(f: ^File) -> (string)Sourcename returns the name of the file. The lifetime of this string lasts as long as the file handle itself.
new_file
new_file :: proc(handle: uintptr, name: string) -> (^File)Source@(require_results) open_buffered :: proc(name: string, buffer_size: uint, flags := File_Flags{.Read}, perm := 0o777) -> (^File, Error) {
if buffer_size == 0 {
return _open(name, flags, perm)
}
return _open_buffered(name, buffer_size, flags, perm)
}
`new_file` returns a new `^File` with the given file descriptor `handle` and `name`.
The return value will only be `nil` IF the `handle` is not a valid file descriptor.open
open :: proc(name: string, flags: File_Flags = File_Flags{.Read}, perm = Permissions_Default) -> (^File, Error)Sourceopen is a generalized open call, which defaults to opening for reading.
If the file does not exist, and the `{.Create}` flag is passed, it is created with the permissions `perm`,
and please note that the containing directory must exist otherwise and an error will be returned.
If successful, a `^File` is return which can be used for I/O.
And error is returned if any is encountered.perm_number
perm_number :: proc(perm: int) -> (Permissions)Sourceperm_number converts an integer value perm to the bit set Permissions
pipe
pipe :: proc() -> (r: ^File, w: ^File, err: Error)SourceCreate an anonymous pipe.
This procedure creates an anonymous pipe, returning two ends of the pipe, r and w. The file r is the readable end of the pipe. The file w is a writeable end of the pipe.
Pipes are used as an inter-process communication mechanism, to communicate between a parent and a child process. The child uses one end of the pipe to write data, and the parent uses the other end to read from the pipe (or vice-versa). When a parent passes one of the ends of the pipe to the child process, that end of the pipe needs to be closed by the parent, before any data is attempted to be read.
Although pipes look like files and is compatible with most file APIs in package os, the way it's meant to be read is different. Due to asynchronous nature of the communication channel, the data may not be present at the time of a read request. The other scenario is when a pipe has no data because the other end of the pipe was closed by the child process.
pipe_has_data
pipe_has_data :: proc(r: ^File) -> (ok: bool, err: Error)SourceCheck if the pipe has any data.
This procedure checks whether a read-end of the pipe has data that can be read, and returns true, if the pipe has readable data, and false if the pipe is empty. This procedure does not block the execution of the current thread.
Note: If the other end of the pipe was closed by the child process, the .Broken_Pipe can be returned by this procedure. Handle these errors accordingly.
print_error
print_error :: proc(f: ^File, ferr: Error, msg: string)Sourceprint_error is a utility procedure which will print an error ferr to a specified file f.
process_exec
process_exec :: proc(desc: Process_Desc, allocator: runtime.Allocator, loc = #caller_location) -> (state: Process_State, stdout: []u8, stderr: []u8, err: Error)SourceExecute the process and capture stdout and stderr streams.
This procedure creates a new process, with a given command and environment strings as parameters, and waits until the process finishes execution. While the process is running, this procedure accumulates the output of its stdout and stderr streams and returns byte slices containing the captured data from the streams.
This procedure expects that stdout and stderr fields of the desc parameter are left at default, i.e. a nil value. You can not capture stdout/stderr and redirect it to a file at the same time.
This procedure does not free stdout and stderr slices before an error is returned. Make sure to call delete on these slices.
process_info_by_handle
process_info_by_handle :: proc(process: Process, selection: Process_Info_Fields, allocator: runtime.Allocator) -> (Error, Process_Info)SourceObtain information about a process.
This procedure obtains information, specified by selection parameter about a process that has been opened by the application, specified in the process parameter.
Use free_process_info to free the memory allocated by this procedure. The free_process_info procedure needs to be called, even if this procedure returned an error, as some of the fields may have been allocated.
Note: The resulting information may or may contain the fields specified by the selection parameter. Always check whether the returned Process_Info struct has the required fields before checking the error code returned by this procedure.
process_info_by_pid
process_info_by_pid :: proc(pid: int, selection: Process_Info_Fields, allocator: runtime.Allocator) -> (Error, Process_Info)SourceObtain information about a process.
This procedure obtains an information, specified by selection parameter of a process given by pid.
Use free_process_info to free the memory allocated by this procedure. The free_process_info procedure needs to be called, even if this procedure returned an error, as some of the fields may have been allocated.
Note: The resulting information may or may contain the fields specified by the selection parameter. Always check whether the returned Process_Info struct has the required fields before checking the error code returned by this procedure.
process_kill
process_kill :: proc(process: Process) -> (Error)SourceKill a process.
This procedure kills a process, specified by it's handle, process.
The process is forced to exit and can't ignore the request.
process_list
process_list :: proc(allocator: runtime.Allocator) -> ([]int, Error)SourceObtain ID's of all processes running in the system.
process_open
process_open :: proc(pid: int, flags: Process_Open_Flags = Process_Open_Flags {}) -> (Error, Process)SourceOpen a process handle using it's pid.
This procedure obtains a process handle of a process specified by pid. This procedure can be subject to race conditions. See the description of Process.
Use the process_wait() procedure (optionally prefaced with a process_kill()) to close and free the process handle.
process_start
process_start :: proc(desc: Process_Desc) -> (Error, Process)SourceCreate a new process and obtain its handle.
This procedure creates a new process, with a given command and environment strings as parameters. Use environ() to inherit the environment of the current process.
The desc parameter specifies the description of how the process should be created. It contains information such as the command line, the environment of the process, the starting directory and many other options. Most of the fields in the struct can be set to nil or an empty value.
Use the process_wait() procedure (optionally prefaced with a process_kill()) to close and free the process handle.
This procedure is not thread-safe. It may alter the inheritance properties of file handles in an unpredictable manner. In case multiple threads change handle inheritance properties, make sure to serialize all those calls.
process_terminate
process_terminate :: proc(process: Process) -> (Error)SourceTerminate a process.
This procedure terminates a process, specified by it's handle, process.
The process is requested to exit and can ignore the request.
process_wait
process_wait :: proc(process: Process, timeout = TIMEOUT_INFINITE) -> (Error, Process_State)SourceWait for a process event.
This procedure blocks the execution until the process has exited or the timeout (if specified) has reached zero. If the timeout is TIMEOUT_INFINITE, no timeout restriction is imposed and the procedure can block indefinitely.
If the timeout is 0, no blocking will be done and the current state is returned.
If the timeout has expired, the General_Error.Timeout is returned as the error.
If an error is returned for any other reason, other than timeout, the process state is considered undetermined.
random_string
random_string :: proc(buf: []u8) -> (string)Sourceread
read :: proc(f: ^File, p: []u8) -> (n: int, err: Error)Sourceread reads up to len(p) bytes from the file f, and then stores them in p.
It returns the number of bytes read and an error, if any is encountered.
At the end of a file, it returns `0, io.EOF`.read_all_directory
read_all_directory :: proc(f: ^File, allocator: runtime.Allocator) -> (fi: []File_Info, err: Error)SourceReads the file f (assuming it is a directory) and returns all of the unsorted directory entries.
read_all_directory_by_path
read_all_directory_by_path :: proc(path: string, allocator: runtime.Allocator) -> (fi: []File_Info, err: Error)SourceReads the named directory by path (assuming it is a directory) and returns all of the unsorted directory entries.
read_at
read_at :: proc(f: ^File, p: []u8, offset: i64) -> (n: int, err: Error)Sourceread_at reads up to len(p) bytes from the file f at the byte offset offset, and then stores them in p.
It returns the number of bytes read and an error, if any is encountered.
`read_at` always returns a non-nil error when `n < len(p)`.
At the end of a file, the error is `io.EOF`.read_at_least
read_at_least :: proc(f: ^File, buf: []u8, min: int) -> (n: int, err: Error)Sourceread_at_least reads from f into buf until it has read at least min bytes.
It returns the number of bytes copied and an error if fewer bytes were read.
The error is only an `io.EOF` if no bytes were read.read_dir
read_dir :: proc(f: ^File, n: int, allocator: runtime.Allocator) -> (files: []File_Info, err: Error)Sourceread_directory
read_directory :: proc(f: ^File, n: int, allocator: runtime.Allocator) -> (files: []File_Info, err: Error)SourceReads the file f (assuming it is a directory) and returns the unsorted directory entries.
This returns up to `n` entries OR all of them if `n <= 0`.read_directory_by_path
read_directory_by_path :: proc(path: string, n: int, allocator: runtime.Allocator) -> (fi: []File_Info, err: Error)SourceReads the named directory by path (assuming it is a directory) and returns the unsorted directory entries.
This returns up to `n` entries OR all of them if `n <= 0`.read_directory_iterator
read_directory_iterator :: proc(it: ^Read_Directory_Iterator) -> (fi: File_Info, index: int, ok: bool)SourceReturns the next file info entry for the iterator's directory.
The given File_Info is reused in subsequent calls so a copy (file_info_clone) has to be made to extend its lifetime.
Example:
package main
import "core:fmt"
import "core:os"
main :: proc() {
f, oerr := os.open("core")
ensure(oerr == nil)
defer os.close(f)
it := os.read_directory_iterator_create(f)
defer os.read_directory_iterator_destroy(&it)
for info in os.read_directory_iterator(&it) {
// Optionally break on the first error:
// Supports not doing this, and keeping it going with remaining items.
// _ = os.read_directory_iterator_error(&it) or_break
// Handle error as we go:
// Again, no need to do this as it will keep going with remaining items.
if path, err := os.read_directory_iterator_error(&it); err != nil {
fmt.eprintfln("failed reading %s: %s", path, err)
continue
}
// Or, do not handle errors during iteration, and just check the error at the end.
fmt.printfln("%#v", info)
}
// Handle error if one happened during iteration at the end:
if path, err := os.read_directory_iterator_error(&it); err != nil {
fmt.eprintfln("read directory failed at %s: %s", path, err)
}
}read_directory_iterator_create
read_directory_iterator_create :: proc(f: ^File) -> (it: Read_Directory_Iterator)SourceCreates a directory iterator with the given directory.
For an example on how to use the iterator, see read_directory_iterator.
read_directory_iterator_destroy
read_directory_iterator_destroy :: proc(it: ^Read_Directory_Iterator)SourceDestroys a directory iterator.
read_directory_iterator_error
read_directory_iterator_error :: proc(it: ^Read_Directory_Iterator) -> (path: string, err: Error)SourceRetrieve the last error that happened during iteration.
read_directory_iterator_init
read_directory_iterator_init :: proc(it: ^Read_Directory_Iterator, f: ^File)SourceInitialize a directory iterator with the given directory.
This procedure may be called on an existing iterator to reuse it for another directory.
For an example on how to use the iterator, see read_directory_iterator.
read_entire_file_from_file
read_entire_file_from_file :: proc(f: ^File, allocator: runtime.Allocator, loc = #caller_location) -> (data: []u8, err: Error)Sourceread_entire_file_from_file reads the entire file f into memory allocated with allocator.
A slice of bytes and an error is returned, if any error is encountered.read_entire_file_from_path
read_entire_file_from_path :: proc(name: string, allocator: runtime.Allocator, loc = #caller_location) -> (data: []u8, err: Error)Sourceread_entire_file_from_path reads the entire named file name into memory allocated with allocator.
A slice of bytes and an error is returned, if any error is encountered.read_full
read_full :: proc(f: ^File, buf: []u8) -> (n: int, err: Error)Sourceread_full reads exactly len(buf) bytes from f into buf.
It returns the number of bytes copied and an error if fewer bytes were read.
The error is only an `io.EOF` if no bytes were read.
It is equivalent to `read_at_least(f, buf, len(buf))`.read_link
read_link :: proc(name: string, allocator: runtime.Allocator) -> (Error, string)Sourceread_link returns the destinction of the named symbolic link name.
read_ptr
read_ptr :: proc(f: ^File, data: rawptr, len: int) -> (n: int, err: Error)Sourceread_ptr is a utility procedure that reads the bytes points at data with length len.
It is equivalent to: `read(f, ([^]byte)(data)[:len])`read_slice
read_slice :: proc(f: ^File, slice: S) -> (n: int, err: Error)Sourceread_slice is a utility procedure that writes the bytes points at slice.
It is equivalent to: `read(f, ([^]byte)(raw_data(slice))[:len(slice)*size_of(slice[0])])`remove
remove :: proc(name: string) -> (Error)Sourceremove removes a named file or (empty) directory.
remove_all
remove_all :: proc(path: string) -> (Error)SourceDelete path and all files and directories inside of path if it is a directory.
If path is relative, it will be relative to the process's current working directory.
rename
rename :: proc(old_path: string, new_path: string) -> (Error)Sourcerename renames (moves) old_path to new_path.
replace_environment_placeholders
replace_environment_placeholders :: proc(path: string, allocator: runtime.Allocator) -> (res: string)SourceAlways allocates for consistency.
replace_path_separators
replace_path_separators :: proc(path: string, new_sep: rune, allocator: runtime.Allocator) -> (new_path: string, err: Error)SourceReturns the result of replacing each path separator character in the path with the new_sep rune.
Allocates Using Provided Allocator
same_file
same_file :: proc(fi1: File_Info, fi2: File_Info) -> (bool)SourceReturns true if two File_Infos are equivalent.
seek
seek :: proc(f: ^File, offset: i64, whence: io.Seek_From) -> (ret: i64, err: Error)Sourceseek sets the offsets for the next read or write on a file to a specified offset,
according to what `whence` is set.
`.Start` is relative to the origin of the file.
`.Current` is relative to the current offset.
`.End` is relative to the end.
It returns the new offset and an error, if any is encountered.
Prefer `read_at` or `write_at` if the offset does not want to be changed.set_env
set_env :: proc(key: string, value: string) -> (Error)Sourceset_env sets the value of the environment variable named by the key Returns Error on failure
set_working_directory
set_working_directory :: proc(dir: string) -> (err: Error)SourceChange the working directory of the current process.
Allocates Using Provided Allocator
setwd
setwd :: proc(dir: string) -> (err: Error)Sourceshort_stem
short_stem :: proc(path: string) -> (string)SourceGets the name of a file from a path.
The short stem is such that short_stem(path) + long_ext(path) = base(path), where long_ext is the extension returned by split_filename_all.
The first dot is used to split off the file extension, unlike stem which uses the last dot.
e.g.
'name.tar.gz' -> 'name'
'name.txt' -> 'name'
Returns an empty string if there is no stem. e.g: '.gitignore'.
Returns an empty string if there's a trailing path separator.split_filename
split_filename :: proc(filename: string) -> (base: string, ext: string)SourceSplit a filename from its extension.
This procedure splits on the last separator.
If the filename begins with a separator, such as ".readme.txt", the separator will be included in the filename, resulting in ".readme" and "txt".
For example, split_filename("foo.tar.gz") will return "foo.tar" and "gz".
split_filename_all
split_filename_all :: proc(filename: string) -> (base: string, ext: string)SourceSplit a filename from its extension.
This procedure splits on the first separator.
If the filename begins with a separator, such as ".readme.txt.gz", the separator will be included in the filename, resulting in ".readme" and "txt.gz".
For example, split_filename_all("foo.tar.gz") will return "foo" and "tar.gz".
split_path
split_path :: proc(path: string) -> (dir: string, filename: string)SourceSplit a path into a directory hierarchy and a filename.
For example, split_path("/home/foo/bar.tar.gz") will return "/home/foo" and "bar.tar.gz".
split_path_list
split_path_list :: proc(path: string, allocator: runtime.Allocator) -> (list: []string, err: Error)SourceSplit a string that is separated by a system-specific separator, typically used for environment variables specifying multiple directories.
Allocates Using Provided Allocator
For example, there is the "PATH" environment variable on POSIX systems which this procedure can split into separate entries.
stat
stat :: proc(name: string, allocator: runtime.Allocator) -> (Error, File_Info)Sourcestat returns a File_Info describing the named file from the file system.
The resulting `File_Info` must be deleted with `file_info_delete`.stat_do_not_follow_links
stat_do_not_follow_links :: proc(name: string, allocator: runtime.Allocator) -> (Error, File_Info)SourceReturns a File_Info describing the named file from the file system.
If the file is a symbolic link, the `File_Info` returns describes the symbolic link,
rather than following the link.
The resulting `File_Info` must be deleted with `file_info_delete`.stem
stem :: proc(path: string) -> (string)SourceGets the name of a file from a path.
The stem of a file is such that stem(path) + ext(path) = base(path).
Only the last dot is considered when splitting the file extension. See short_stem.
e.g.
'name.tar.gz' -> 'name.tar'
'name.txt' -> 'name'
Returns an empty string if the path is empty
Returns an empty string if there is no stem. e.g: '.gitignore'.
Returns an empty string if there's a trailing path separator.string_from_null_terminated_bytes
string_from_null_terminated_bytes :: proc(b: []u8) -> (res: string)Sourcesymlink
symlink :: proc(old_name: string, new_name: string) -> (Error)Sourcesymlink creates a new_name as a symbolic link to the old_name file.
sync
sync :: proc(f: ^File) -> (Error)Sourcesync commits the current contents of the file f to stable storage.
This usually means flushing the file system's in-memory copy to disk.temp_allocator_scope
temp_allocator_scope :: proc(tmp: Temp_Allocator) -> (runtime.Arena_Temp)Sourcetemp_dir
temp_dir :: proc(allocator: runtime.Allocator) -> (Error, string)Sourcetemp_directory
temp_directory :: proc(allocator: runtime.Allocator) -> (Error, string)SourceReturns the default directory to use for temporary files.
On Unix systems, it typically returns $TMPDIR if non-empty, otherwlse `/tmp`.
On Windows, it uses `GetTempPathW`, returning the first non-empty value from one of the following:
* `%TMP%`
* `%TEMP%`
* `%USERPROFILE %`
* or the Windows directory
See https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppathw for more information.
On wasi, it returns `/tmp`.to_reader
to_reader :: proc(f: ^File) -> (s: io.Stream)SourceThis is an alias of to_stream which converts a file f to an io.Stream.
It can be useful to indicate what the stream is meant to be used for as a reader,
even if it has no logical difference.to_stream
to_stream :: proc(f: ^File) -> (s: io.Stream)SourceConverts a file f into an io.Stream
to_writer
to_writer :: proc(f: ^File) -> (s: io.Stream)SourceThis is an alias of to_stream which converts a file f to an io.Stream.
It can be useful to indicate what the stream is meant to be used for as a writer,
even if it has no logical difference.truncate
truncate :: proc(f: ^File, size: i64) -> (Error)Sourcetruncate changes the size of the file f to size in bytes.
This can be used to shorten or lengthen a file.
It does not change the "offset" of the file.unset_env
unset_env :: proc(key: string) -> (bool)Sourceunset_env unsets a single environment variable Returns true on success, false on failure
user_cache_dir
user_cache_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error)SourceFiles that applications can regenerate/refetch at a loss of speed, e.g. shader caches
Sometimes deleted for system maintenance
Windows: C:\Users\Alice\AppData\Local
macOS: /Users/Alice/Library/Caches
Linux: /home/alice/.cacheuser_config_dir
user_config_dir :: proc(allocator: runtime.Allocator, roaming: untyped boolean = false) -> (dir: string, err: Error)SourceApplication settings/preferences
Windows: C:\Users\Alice\AppData\Local ("C:\Users\Alice\AppData\Roaming" if `roaming`)
macOS: /Users/Alice/Library/Application Support
Linux: /home/alice/.configNOTE: (Windows only) roaming is for syncing across multiple devices within a domain network
user_data_dir
user_data_dir :: proc(allocator: runtime.Allocator, roaming: untyped boolean = false) -> (dir: string, err: Error)SourceUser-hidden application data
Windows: C:\Users\Alice\AppData\Local ("C:\Users\Alice\AppData\Roaming" if `roaming`)
macOS: /Users/Alice/Library/Application Support
Linux: /home/alice/.local/shareNOTE: (Windows only) roaming is for syncing across multiple devices within a domain network
user_desktop_dir
user_desktop_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error)SourceWindows: C:\Users\Alice\Desktop
macOS: /Users/Alice/Desktop
Linux: /home/alice/Desktopuser_documents_dir
user_documents_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error)SourceWindows: C:\Users\Alice\Documents
macOS: /Users/Alice/Documents
Linux: /home/alice/Documentsuser_downloads_dir
user_downloads_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error)SourceWindows: C:\Users\Alice\Downloads
macOS: /Users/Alice/Downloads
Linux: /home/alice/Downloadsuser_home_dir
user_home_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error)SourceWindows: C:\Users\Alice
macOS: /Users/Alice
Linux: /home/aliceuser_log_dir
user_log_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error)SourceApplication log files
Windows: C:\Users\Alice\AppData\Local
macOS: /Users/Alice/Library/Logs
Linux: /home/alice/.local/stateuser_music_dir
user_music_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error)SourceWindows: C:\Users\Alice\Music
macOS: /Users/Alice/Music
Linux: /home/alice/Musicuser_pictures_dir
user_pictures_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error)SourceWindows: C:\Users\Alice\Pictures
macOS: /Users/Alice/Pictures
Linux: /home/alice/Picturesuser_public_dir
user_public_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error)SourceWindows: C:\Users\Alice\Public
macOS: /Users/Alice/Public
Linux: /home/alice/Publicuser_state_dir
user_state_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error)SourceNon-essential application data, e.g. history, ui layout state
Windows: C:\Users\Alice\AppData\Local
macOS: /Users/Alice/Library/Application Support
Linux: /home/alice/.local/stateuser_videos_dir
user_videos_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error)SourceWindows: C:\Users\Alice\Videos
macOS: /Users/Alice/Movies
Linux: /home/alice/Videosvolume_name
volume_name :: proc(path: string) -> (string)SourceReturns leading volume name.
e.g.
"C:\foo\bar\baz" will return "C:" on Windows.
Everything else will be "".walker_create_file
walker_create_file :: proc(f: ^File) -> (w: Walker)Sourcewalker_create_path
walker_create_path :: proc(path: string) -> (w: Walker)Sourcewalker_destroy
walker_destroy :: proc(w: ^Walker)Sourcewalker_error
walker_error :: proc(w: ^Walker) -> (path: string, err: Error)SourceReturns the last error that occurred during the walker's operations.
Can be called while iterating, or only at the end to check if anything failed.
walker_init_file
walker_init_file :: proc(w: ^Walker, f: ^File)Sourcewalker_init_path
walker_init_path :: proc(w: ^Walker, path: string)Sourcewalker_skip_dir
walker_skip_dir :: proc(w: ^Walker)SourceMarks the current directory to be skipped (not entered into).
walker_walk
walker_walk :: proc(w: ^Walker) -> (fi: File_Info, ok: bool)SourceReturns the next file info in the iterator, files are iterated in breadth-first order.
If an error occurred opening a directory, you may get zero'd info struct and walker_error will return the error.
Example:
package main
import "core:fmt"
import "core:strings"
import "core:os"
main :: proc() {
w := os.walker_create("core")
defer os.walker_destroy(&w)
for info in os.walker_walk(&w) {
// Optionally break on the first error:
// _ = walker_error(&w) or_break
// Or, handle error as we go:
if path, err := os.walker_error(&w); err != nil {
fmt.eprintfln("failed walking %s: %s", path, err)
continue
}
// Or, do not handle errors during iteration, and just check the error at the end.
// Skip a directory:
if strings.has_suffix(info.fullpath, ".git") {
os.walker_skip_dir(&w)
continue
}
fmt.printfln("%#v", info)
}
// Handle error if one happened during iteration at the end:
if path, err := os.walker_error(&w); err != nil {
fmt.eprintfln("failed walking %s: %v", path, err)
}
}write
write :: proc(f: ^File, p: []u8) -> (n: int, err: Error)Sourcewrite writes len(p) bytes from p to the file f. It returns the number of bytes written to
and an error, if any is encountered.
`write` returns a non-nil error when `n != len(p)`.write_at
write_at :: proc(f: ^File, p: []u8, offset: i64) -> (n: int, err: Error)Sourcewrite_at writes len(p) bytes from p to the file f starting at byte offset offset.
It returns the number of bytes written to and an error, if any is encountered.
`write_at` returns a non-nil error when `n != len(p)`.write_byte
write_byte :: proc(f: ^File, b: u8) -> (n: int, err: Error)Sourcewrite_byte writes a byte b to file f.
Returns the number of bytes written and an error, if any is encountered.write_encoded_rune
write_encoded_rune :: proc(f: ^File, r: rune) -> (n: int, err: Error)Sourcewrite_encoded_rune writes a rune r as an UTF-8 encoded string which with escaped control codes to file f.
Returns the number of bytes written and an error, if any is encountered.write_entire_file_from_bytes
write_entire_file_from_bytes :: proc(name: string, data: []u8, perm: Permissions_Read_All = Permissions_Read_All + {.Write_User}, truncate: untyped boolean = true) -> (Error)Sourcewrite_entire_file_from_bytes writes the contents of data into named file name.
It defaults with the permssions `perm := Permissions_Read_All + {.Write_User}`, and `truncate`s by default.
An error is returned if any is encountered.write_entire_file_from_string
write_entire_file_from_string :: proc(name: string, data: string, perm: Permissions_Read_All = Permissions_Read_All + {.Write_User}, truncate: untyped boolean = true) -> (Error)Sourcewrite_entire_file_from_string writes the contents of data into named file name.
It defaults with the permssions `perm := Permissions_Read_All + {.Write_User}`, and `truncate`s by default.
An error is returned if any is encountered.write_ptr
write_ptr :: proc(f: ^File, data: rawptr, len: int) -> (n: int, err: Error)Sourcewrite_ptr is a utility procedure that writes the bytes points at data with length len.
It is equivalent to: `write(f, ([^]byte)(data)[:len])`write_rune
write_rune :: proc(f: ^File, r: rune) -> (n: int, err: Error)Sourcewrite_rune writes a rune r as an UTF-8 encoded string to file f.
Returns the number of bytes written and an error, if any is encountered.write_slice
write_slice :: proc(f: ^File, slice: S) -> (n: int, err: Error)Sourcewrite_slice is a utility procedure that writes the bytes points at slice.
It is equivalent to: `write(f, ([^]byte)(raw_data(slice))[:len(slice)*size_of(slice[0])])`write_string
write_string :: proc(f: ^File, s: string) -> (n: int, err: Error)Sourcewrite_string writes a string s to file f.
Returns the number of bytes written and an error, if any is encountered.write_strings
write_strings :: proc(f: ^File, strings) -> (n: int, err: Error)Sourcewrite_strings writes a variadic list of strings strings to file f.
Returns the number of bytes written and an error, if any is encountered.Procedure Groups
9_read_entire_pseudo_file
_read_entire_pseudo_file :: proc{_read_entire_pseudo_file_string, _read_entire_pseudo_file_cstring}SourceFor reading Linux system files that stat to size 0
get_env
get_env :: proc{get_env_alloc, get_env_buf}Sourcelookup_env
lookup_env :: proc{lookup_env_alloc, lookup_env_buf}Sourceperm
perm :: proc{perm_number}Sourceprocess_info
process_info :: proc{process_info_by_pid, process_info_by_handle, current_process_info}SourceObtain information about the specified process.
read_entire_file
read_entire_file :: proc{read_entire_file_from_path, read_entire_file_from_file}Sourcewalker_create
walker_create :: proc{walker_create_path, walker_create_file}SourceCreates a walker, either using a path or a file pointer to a directory the walker will start at.
For an example on how to use the walker, see walker_walk.
walker_init
walker_init :: proc{walker_init_path, walker_init_file}SourceInitializes a walker, either using a path or a file pointer to a directory the walker will start at.
You are allowed to repeatedly call this to reuse it for later walks.
For an example on how to use the walker, see walker_walk.
write_entire_file
write_entire_file :: proc{write_entire_file_from_bytes, write_entire_file_from_string}Sourcewrite_entire_file writes the contents of data into named file name.
It defaults with the permssions `perm := Permissions_Read_All + {.Write_User}`, and `truncate`s by default.
An error is returned if any is encountered.