core/os

os

Types

27

File

File :: struct { impl: rawptr, stream: File_Stream, }Source

Type 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, }Source

File_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) }Source

A subset of the io.Stream_Mode with added File specific modes

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, }Source

Type 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.

General_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, }Source

General 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, }Source

Process

Process :: struct { pid: int, handle: uintptr, }Source

Represents 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, }Source

The 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, }Source

Contains information about the process as obtained by the process_info() procedure.

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, }Source

Process_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, }Source

The state of the process after it has finished execution.

Constants

35

MAX_RW

MAX_RW :: 1 << 30Source

Most 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_INHERITABLE

O_INHERITABLE :: File_Flags = File_Flags{.Inheritable}Source

If 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.

Variables

8

Procedures

281

base

base :: proc(path: string) -> (string)Source

Gets 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_mode

change_mode :: proc(name: string, mode: Permissions) -> (Error)Source

Changes 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)Source

Changes 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.

close

close :: proc(f: ^File) -> (Error)Source

Close 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.

create

create :: proc(name: string) -> (^File, Error)Source

create 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)Source

Creates 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)Source

Obtain 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)Source

Gets 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)Source

environ 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

exit

exit :: proc(code: int) -> ()Source

Tells 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)Source

Gets 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.

fd

fd :: proc(f: ^File) -> (uintptr)Source

fd returns the file descriptor of the file f passed. If the file is not valid, an invalid handle will be returned.

get_egid

get_egid :: proc() -> (int)Source

Obtain 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)Source

get_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)Source

get_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)Source

Obtain 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_gid

get_gid :: proc() -> (int)Source

Obtain the GID of the current process.

Note(windows): Windows doesn't follow the posix permissions model, so the function simply returns -1.

get_ppid

get_ppid :: proc() -> (int)Source

Obtain 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_relative_path

get_relative_path :: proc(base: string, target: string, allocator: runtime.Allocator) -> (path: string, err: Error)Source

Get 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)Source

Obtain the UID of the current process.

Note(windows): Windows doesn't follow the posix permissions model, so the function simply returns -1.

glob

glob :: proc(pattern: string, allocator: mem.Allocator = context.allocator) -> (matches: []string, err: Error)Source

glob 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

long_ext

long_ext :: proc(path: string) -> (string)Source

Gets 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)Source

lookup_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)Source

This 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.

match

match :: proc(pattern: string, name: string) -> (matched: bool, err: Error)Source

match 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 found

name

name :: proc(f: ^File) -> (string)Source

name 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)Source

open 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.

pipe

pipe :: proc() -> (r: ^File, w: ^File, err: Error)Source

Create 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)Source

Check 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.

process_exec

process_exec :: proc(desc: Process_Desc, allocator: runtime.Allocator, loc = #caller_location) -> (state: Process_State, stdout: []u8, stderr: []u8, err: Error)Source

Execute 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)Source

Obtain 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)Source

Obtain 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_start

process_start :: proc(desc: Process_Desc) -> (Error, Process)Source

Create 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_wait

process_wait :: proc(process: Process, timeout = TIMEOUT_INFINITE) -> (Error, Process_State)Source

Wait 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.

read

read :: proc(f: ^File, p: []u8) -> (n: int, err: Error)Source

read 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_at

read_at :: proc(f: ^File, p: []u8, offset: i64) -> (n: int, err: Error)Source

read_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_directory_iterator

read_directory_iterator :: proc(it: ^Read_Directory_Iterator) -> (fi: File_Info, index: int, ok: bool)Source

Returns 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_full

read_full :: proc(f: ^File, buf: []u8) -> (n: int, err: Error)Source

read_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))`.

remove_all

remove_all :: proc(path: string) -> (Error)Source

Delete 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.

seek

seek :: proc(f: ^File, offset: i64, whence: io.Seek_From) -> (ret: i64, err: Error)Source

seek 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.

split_filename

split_filename :: proc(filename: string) -> (base: string, ext: string)Source

Split 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)Source

Split 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_list

split_path_list :: proc(path: string, allocator: runtime.Allocator) -> (list: []string, err: Error)Source

Split 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.

stem

stem :: proc(path: string) -> (string)Source

Gets 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.

sync

sync :: proc(f: ^File) -> (Error)Source

sync 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_directory

temp_directory :: proc(allocator: runtime.Allocator) -> (Error, string)Source

Returns 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)Source

This 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_writer

to_writer :: proc(f: ^File) -> (s: io.Stream)Source

This 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)Source

truncate 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.

user_cache_dir

user_cache_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error)Source

Files 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/.cache

user_config_dir

user_config_dir :: proc(allocator: runtime.Allocator, roaming: untyped boolean = false) -> (dir: string, err: Error)Source

Application settings/preferences

Windows:  C:\Users\Alice\AppData\Local ("C:\Users\Alice\AppData\Roaming" if `roaming`)
macOS:    /Users/Alice/Library/Application Support
Linux:    /home/alice/.config

NOTE: (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)Source

User-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/share

NOTE: (Windows only) roaming is for syncing across multiple devices within a domain network

user_state_dir

user_state_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error)Source

Non-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/state

walker_walk

walker_walk :: proc(w: ^Walker) -> (fi: File_Info, ok: bool)Source

Returns 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)Source

write 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)Source

write_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)`.

Procedure Groups

9

Reference search

Find anything

Documentation preferences

Settings

System theme variants

Used only while Theme is set to System.