paul_os.h
IntroductionCross-platform file, path, and system utilities for C/C++. DiscussionImplementation is included when PAUL_OS_IMPLEMENTATION or PAUL_IMPLEMENTATION is defined. On MacOS optional Cocoa support can be enabled by defining PAUL_OS_USE_COCOA and linking against `-framework Foundation.framework`.
Functions
directory_copyCopy a directory and contents bool directory_copy( const char *src_path, const char *dst_path, bool write_over, bool delete_src); ParametersReturn ValueReturns true/false on success directory_createCreate a directory bool directory_create( const char *path, bool recursive); ParametersReturn ValueReturns true/false on success DiscussionWIP directory_deleteDelete a directory bool directory_delete( const char *path, bool recursive, bool and_files); ParametersReturn ValueReturns true/false on success DiscussionWIP directory_existsCheck if a directory exists bool directory_exists( const char *path); ParametersReturn ValueReturns true if file exists DiscussionChecks if a path exists and is a directory (file will return false) directory_file_countGet the number of files inside a directory int directory_file_count( const char *path, bool recursive); ParametersReturn ValueReturns number of files in directory, -1 on error DiscussionThis doesn't count directories directory_globGlob a directory for files matching a pattern const char** directory_glob( const char *pattern, int *count); // !! ParametersReturn ValueReturns an array of strings containing the matched file paths, or NULL on error DiscussionThe result must be freed by the caller. The count will be set to the number of matches. The array and its elements must be freed by the caller. directory_item_countGet the number of files/directories inside a directory int directory_item_count( const char *path, bool recursive); ParametersReturn ValueReturns number of items in directory, -1 on error directory_iterIterate through a directory const char* directory_iter( dir_t *dir, bool *is_dir); ParametersReturn ValueReturns the name of the next item in the directory, or NULL if there are no more items DiscussionIf you need to exit an iteration early, call directory_iter_end(dir) directory_iter_endEnd a directory iteration prematurely void directory_iter_end( dir_t *dir); ParametersDiscussionThis will close the directory iterator and free any resources used. Normally this will be done at the end of the iteration. directory_renameMove a directory bool directory_rename( const char *old_path, const char *new_path, bool write_over); ParametersReturn ValueReturns true/false on success DiscussionWIP directory_sizeGet the size of a directory int directory_size( const char *path); ParametersReturn ValueReturns size of directory contents, -1 on error environment_variableGet an enviroment variable char* environment_variable( const char *name); // ! ParametersReturn ValueReturns enviroment variable string or NULL on failure DiscussionReturn value will need to be freed on success file_copyCopy a file bool file_copy( const char *src_path, const char *dst_path, bool write_over); ParametersReturn ValueReturns true/false on success DiscussionWIP file_deleteDelete a file from file system bool file_delete( const char *path); ParametersReturn ValueReturns true/false on success file_existsCheck if a file exists bool file_exists( const char *path); ParametersReturn ValueReturns true if file exists DiscussionChecks if a path exists and is a file (directory will return false) file_readRead a file from disk const char* file_read( const char *path, size_t *size); // ! ParametersReturn ValueReturns the contents of a file DiscussionReturn value will need to be freed on success file_renameMove a file bool file_rename( const char *old_path, const char *new_path, bool write_over); ParametersReturn ValueReturns true/false on success DiscussionWIP file_sizeGet file size int file_size( const char *path); ParametersReturn ValueReturns size of a file, -1 on error io_advanceAdvance the file stream cursor by n bytes bool io_advance( file_t file, long offset); ParametersReturn ValueReturns true/false on success io_closeClose file stream ParametersReturn ValueReturns true/false on success io_eofCheck if file is at the end ParametersReturn ValueReturns true is file is at the end io_flushFlush file stream ParametersReturn ValueReturns true/false on success io_openOpen file stream Parametersio_printPrint a message to a file stream Parametersio_printlnPrint a message to a file stream with a newline Parametersio_readRead n bytes from file stream ParametersReturn ValueReturns true/false on success DiscussionPlease ensure that size >= destination buffer size io_read_lineRead until newline or end of file bool io_read_line( file_t file, char *buffer, size_t size); ParametersReturn ValueReturns true/false on success io_seekSeek file stream position ParametersReturn ValueReturns true/false on success io_tellGet current position of file stream ParametersReturn ValueReturns the current file stream position, -1 on error io_truncateTruncate a file stream to a specific length bool io_truncate( file_t file, long size); ParametersReturn ValueReturns true/false on success io_validCheck if a file stream is valid ParametersReturn ValueCheck if a file stream is valid io_writeWrite n bytes to file stream ParametersReturn ValueReturns number of bytes read, -1 on error DiscussionPlease ensure that size is >= the source buffer size io_write_stringWrite a string to a file stream bool io_write_string( file_t file, const char *str); ParametersReturn ValueReturns true/false on success path_existsCheck if a path exists. This will return true for both files and directories. bool path_exists( const char *path); ParametersReturn ValueReturns true/false on success path_get_application_dirGet the application directory const char* path_get_application_dir( void); Return ValueReturns the application directory path_get_desktop_dirGet the desktop directory const char* path_get_desktop_dir( void); Return ValueReturns the desktop directory path_get_directory_nameGet the directory name from a path const char* path_get_directory_name( const char *path); // ! ParametersReturn ValueReturns the directory name or NULL if there is no directory name DiscussionThe result must be freed by the caller. path_get_documents_dirGet the documents directory const char* path_get_documents_dir( void); Return ValueReturns the documents directory path_get_downloads_dirGet the downloads directory const char* path_get_downloads_dir( void); Return ValueReturns the downloads directory path_get_file_extensionGet the file extension from a path const char* path_get_file_extension( const char *path); ParametersReturn ValueReturns the file extension or NULL if there is no extension path_get_file_nameGet the file name from a path const char* path_get_file_name( const char *path); ParametersReturn ValueReturns the file name or NULL if there is no file name path_get_file_name_no_extensionGet the file name without extension from a path const char* path_get_file_name_no_extension( const char *path); // ! ParametersReturn ValueReturns the file name without extension or NULL if there is no file name DiscussionThe result must be freed by the caller. path_get_home_dirGet the home directory const char* path_get_home_dir( void); Return ValueReturns the home directory path_get_music_dirGet the music directory const char* path_get_music_dir( void); Return ValueReturns the music directory path_get_parent_directoryGet the parent directory from a path const char* path_get_parent_directory( const char *path); // ! ParametersReturn ValueReturns the parent directory or NULL if there is no parent directory DiscussionThe result must be freed by the caller. path_get_picture_dirGet the picture directory const char* path_get_picture_dir( void); Return ValueReturns the picture directory path_get_root_dirGet the root directory const char* path_get_root_dir( void); Return ValueReturns the root directory path_get_video_dirGet the video directory const char* path_get_video_dir( void); Return ValueReturns the video directory path_get_working_directoryGet the current working directory const char* path_get_working_directory( void); Return ValueReturns the current working directory path_globGlob a pattern and call a callback for each match bool path_glob( const char *pattern, glob_callback callback, void *userdata); ParametersReturn ValueReturns true/false on success path_glob_blockGlob a pattern and call a block for each match bool path_glob_block( const char *pattern, glob_block callback, void *userdata); ParametersReturn ValueReturns true/false on success DiscussionBlocks are a clang/gcc extension. -fblocks must be enabled to use this. path_joinJoin two paths together const char* path_join( const char *a, const char *b); // ! ParametersReturn ValueReturns the joined path or NULL on error DiscussionThe result must be freed by the caller. path_join_vaJoin multiple paths together const char* path_join_va( int n, ...); // ! ParametersReturn ValueReturns the joined path or NULL on error DiscussionThe result must be freed by the caller. path_resolveResolve a path to an absolute path const char* path_resolve( const char *path); // ! ParametersReturn ValueReturns the resolved path or NULL on error DiscussionThis will attempt to resolve ~ to the user's home directory and ".." to the parent directory. The result must be freed by the caller. WIP. path_set_working_directorySet the current working directory bool path_set_working_directory( const char *path); ParametersReturn ValueReturns true/false on success path_splitSplit a path into its components const char** path_split( const char *path, size_t *count); // !! ParametersReturn ValueReturns an array of strings containing the parts of the path, or NULL on error DiscussionThe result must be freed by the caller. The count will be set to the number of parts. The array and its elements must be freed by the caller. path_walkWalk a directory and call a callback for each file/directory bool path_walk( const char *path, bool recursive, walk_callback callback, void *userdata); ParametersReturn ValueReturns true/false on success path_walk_blockWalk a directory and call a block for each file/directory bool path_walk_block( const char *path, bool recursive, walk_block callback, void *userdata); ParametersReturn ValueReturns true/false on success DiscussionBlocks are a clang/gcc extension. -fblocks must be enabled to use this. path_without_file_nameGet the directory name from a path const char* path_without_file_name( const char *path); // ! ParametersReturn ValueReturns the directory name or NULL if there is no directory name DiscussionThe result must be freed by the caller. Print a message to standard out Parametersprint_errPrint a message to standard error ParametersprintlnPrint a message to standard out with a newline #define println(MSG) io_println(io_out, MSG) Parametersprintln_errPrint a message to standard error with a newline #define println_err(MSG) io_println(io_err, MSG) ParametersshellExecute a shell command ParametersReturn ValueReturns the exit code of the command, negative on internal error DiscussionExecute a shell command (bourne shell syntax, |, >, <, &&, ;) shell_fmtParametersReturn ValueReturns the exit code of the command, negative on internal error Discussionshell with printf formatting Constantsio_errDiscussionStandard error io_inDiscussionStandard in io_invalidextern const file_t io_invalid; DiscussionInvalid file handler (-1) io_outDiscussionStandard out Typedefs
dir_ttypedef struct dir { const char *path; #ifdef PLATFORM_WINDOWS WIN32_FIND_DATA findData; HANDLE hFind; #elif defined(PLATFORM_POSIX) DIR *dir; #endif } dir_t; FieldsDiscussiondir_t is a wrapper around OS specific directory iterators file_ttypedef struct file { file_handle_t fd; } file_t; FieldsDiscussionfile_t is a wrapper around OS specific file handlers glob_blocktypedef int(^glob_block)( const char *pattern, const char *filename, void *userdata); ParametersReturn ValueReturns 0 to continue iteration, non-zero to stop DiscussionThis is a block version of glob_callback. Blocks are a clang/gcc extension. -fblocks must be enabled to use this. glob_callbacktypedef int( *glob_callback)( const char *pattern, const char *filename, void *userdata); ParametersReturn ValueReturns 0 to continue iteration, non-zero to stop shell_error_ttypedef enum shell_error { SHELL_OK = 0, SHELL_ERR_GENERIC = -1, SHELL_ERR_TOKENIZE = -2, SHELL_ERR_EVAL = -3, SHELL_ERR_PIPE = -4, SHELL_ERR_FORK = -5, SHELL_ERR_READ = -6 } shell_error_t; Constants
DiscussionError codes for shell() function shell_ioI/O capture and streaming control structure typedef struct shell_io { /* I/O capture and streaming control structure * * - Pass a non-NULL `shell_io *` to `shell()` to enable capture/streaming. * - If `out_cb` and/or `err_cb` are set, `shell()` invokes the callback * as chunks of data arrive on the child's STDOUT/STDERR. When callbacks * are provided, `shell()` does NOT fill the `out`/`err` buffers (they * will remain NULL). Callbacks are useful for streaming large outputs * without buffering everything in memory. * - If callbacks are NULL, `shell()` accumulates the full contents of * STDOUT and STDERR into freshly allocated, NUL-terminated buffers * stored in `out` and `err` respectively. The sizes are in `out_len` * and `err_len`. The caller is responsible for calling `free()` on * `out` and `err` when done. * - To provide input to the child, set `in` to a buffer of length * `in_len`. `shell()` will write the contents of `in` to the child's * STDIN and then close it. Ownership of `in` stays with the caller. * - Return values: non-negative return values are the child's exit code. * Negative return values are library-level errors (see SHELL_ERR_*). */ /* Captured output buffers (allocated by shell() when callbacks are NULL). */ char *out; /* captured stdout (NUL-terminated) */ size_t out_len; char *err; /* captured stderr (NUL-terminated) */ size_t err_len; /* Input to be written to child's STDIN before closing it. Not modified by shell(). */ const char *in; size_t in_len; /* Streaming callbacks. If non-NULL, shell() will call these with each * incoming chunk. Callbacks receive `userdata` as the last argument. * When callbacks are used, `out`/`err` buffers are not populated. */ shell_stream_cb_t out_cb; shell_stream_cb_t err_cb; void *userdata; } shell_io; Fields
Discussionshell_io is used to control input/output capture and streaming for the shell function. It allows capturing stdout and stderr into buffers or streaming them via callbacks. Input can be provided to the child process via a buffer. Callbacks receive chunks of data as they arrive, useful for large outputs. When callbacks are used, output buffers are not populated. The caller is responsible for freeing captured output buffers when done. shell_stream_cb_tCallback type for streaming output typedef void ( *shell_stream_cb_t)( const char *data, size_t len, void *userdata); walk_blocktypedef int(^walk_block)( const char *path, const char *filename, void *userdata); ParametersReturn ValueReturns 0 to continue walking, non-zero to stop DiscussionThis is a block version of walk_callback. Blocks are a clang/gcc extension. -fblocks must be enabled to use this. walk_callbacktypedef int( *walk_callback)( const char *path, const char *filename, void *userdata); ParametersReturn ValueReturns 0 to continue walking, non-zero to stop Enumerated Typesfile_mode_tenum file_mode_t { FILE_READ = 0x00000001, FILE_WRITE = 0x00000002, FILE_APPEND = 0x00000004 }; Constants
DiscussionFile permissions for io_open file_seek_tenum file_seek_t { FILE_START = 0, FILE_CURSOR, FILE_FINISH }; Constants
DiscussionFile offset positions for io_seek |