|
ascii-chat 0.6.0
Real-time terminal-based video chat with ASCII art conversion
|
๐ Cross-platform abstractions for threading, sockets, and system calls, and hardware access More...
Files | |
| file | abstraction.c |
| ๐๏ธ Common platform abstraction stubs (OS-specific code in posix/ and windows/ subdirectories) | |
| file | abstraction.h |
| ๐ Cross-platform abstraction layer umbrella header for ascii-chat | |
| file | api.h |
| DLL export/import macros for cross-platform symbol visibility. | |
| file | cond.h |
| Cross-platform condition variable interface for ascii-chat. | |
| file | file.h |
| Cross-platform file I/O interface for ascii-chat. | |
| file | fs.h |
| Cross-platform file system operations. | |
| file | init.h |
| Platform initialization and static synchronization helpers. | |
| file | internal.h |
| Private implementation helpers for platform abstraction layer. | |
| file | memory.h |
| Cross-platform memory management utilities. | |
| file | mmap.h |
| Cross-platform memory-mapped file interface. | |
| file | mutex.h |
| Cross-platform mutex interface for ascii-chat. | |
| file | pipe.h |
| Cross-platform pipe/agent socket interface for ascii-chat. | |
| file | process.h |
| Cross-platform process execution utilities. | |
| file | question.h |
| Cross-platform interactive prompting utilities. | |
| file | rwlock.h |
| Cross-platform read-write lock interface for ascii-chat. | |
| file | socket.c |
| ๐ Common socket utility functions (cross-platform implementations) | |
| file | socket.h |
| Cross-platform socket interface for ascii-chat. | |
| file | string.h |
| Platform-independent safe string functions. | |
| file | symbols.c |
| ๐ Symbol resolution cache: llvm-symbolizer/addr2line wrapper with hashtable-backed caching | |
| file | symbols.h |
| Symbol Resolution Cache for Backtrace Addresses. | |
| file | system.c |
| ๐ง Shared cross-platform system utilities (included by posix/system.c and windows/system.c) | |
| file | system.h |
| Cross-platform system functions interface for ascii-chat. | |
| file | terminal.h |
| ๐ฅ๏ธ Cross-platform terminal interface for ascii-chat | |
| file | thread.c |
| ๐งต Thread utilities and helpers | |
| file | thread.h |
| ๐งต Cross-platform thread interface for ascii-chat | |
| file | util.h |
| Public platform utility API for string, memory, and file operations. | |
| file | windows_compat.h |
| Wrapper for windows.h with C23 alignment compatibility. | |
| file | windows_errno.h |
| Windows errno compatibility definitions. | |
Data Structures | |
| struct | platform_stat_t |
| File type information from stat() More... | |
| struct | static_mutex_t |
| Static mutex structure for global mutexes requiring static initialization. More... | |
| struct | static_rwlock_t |
| Static reader-writer lock structure for global rwlocks requiring static initialization. More... | |
| struct | static_cond_t |
| Static condition variable structure for global condition variables requiring static initialization. More... | |
| struct | platform_mmap |
| Memory-mapped file handle. More... | |
| struct | prompt_opts_t |
| Options for text prompts. More... | |
| struct | symbol_entry_t |
| Symbol cache entry structure for address-to-symbol mapping. More... | |
| struct | bin_cache_entry_t |
| Binary PATH cache entry structure for binary detection caching. More... | |
| struct | terminal_size_t |
| Terminal size structure. More... | |
| struct | terminal_capabilities_t |
| Complete terminal capabilities structure. More... | |
| struct | tty_info_t |
| TTY detection and management structure. More... | |
Macros | |
| #define | ASCIICHAT_API __attribute__((visibility("default"))) |
| Export symbols on Unix platforms (Linux, macOS) | |
| #define | PLATFORM_O_RDONLY O_RDONLY |
| Open file for reading only. | |
| #define | PLATFORM_O_WRONLY O_WRONLY |
| Open file for writing only. | |
| #define | PLATFORM_O_RDWR O_RDWR |
| Open file for reading and writing. | |
| #define | PLATFORM_O_CREAT O_CREAT |
| Create file if it doesn't exist. | |
| #define | PLATFORM_O_EXCL O_EXCL |
| Fail if file already exists (with O_CREAT) | |
| #define | PLATFORM_O_TRUNC O_TRUNC |
| Truncate file to zero length if it exists. | |
| #define | PLATFORM_O_APPEND O_APPEND |
| Append to end of file. | |
| #define | PLATFORM_O_BINARY 0 |
| Open file in binary mode (Windows) | |
| #define | STATIC_MUTEX_INIT {PTHREAD_MUTEX_INITIALIZER, 1} |
| #define | STATIC_RWLOCK_INIT {PTHREAD_RWLOCK_INITIALIZER, 1} |
| #define | STATIC_COND_INIT {PTHREAD_COND_INITIALIZER, 1} |
| #define | INVALID_PIPE_VALUE (-1) |
| Invalid pipe value (POSIX: -1) | |
| #define | PROMPT_OPTS_DEFAULT (prompt_opts_t){.echo = true, .same_line = false, .mask_char = 0} |
| Default prompt options (echo enabled, answer on next line) | |
| #define | PROMPT_OPTS_PASSWORD (prompt_opts_t){.echo = false, .same_line = true, .mask_char = '*'} |
| Prompt options for password input (no echo, asterisk masking, same line) | |
| #define | PROMPT_OPTS_INLINE (prompt_opts_t){.echo = true, .same_line = true, .mask_char = 0} |
| Prompt options for inline text input (echo enabled, same line) | |
| #define | INVALID_SOCKET_VALUE (-1) |
| Invalid socket value (POSIX: -1) | |
| #define | SOCKET_ERROR_WOULDBLOCK EWOULDBLOCK |
| #define | SOCKET_ERROR_INPROGRESS EINPROGRESS |
| #define | SOCKET_ERROR_AGAIN EAGAIN |
| #define | SAFE_IGNORE_PRINTF_RESULT(expr) ((void)(expr)) |
| #define | PATH_DELIM '/' |
| Platform-specific path separator character. | |
| #define | PATH_SEPARATOR_STR "/" |
| #define | PATH_ENV_SEPARATOR ":" |
| Platform-specific PATH environment variable separator. | |
| #define | FILE_PERM_PRIVATE 0600 |
| File permission: Private (owner read/write only) | |
| #define | DIR_PERM_PRIVATE 0700 |
| Directory permission: Private (owner read/write/execute only) | |
| #define | FILE_PERM_PUBLIC_READ 0644 |
| File permission: Public read, owner write. | |
| #define | FILE_PERM_MASK 0777 |
| Permission mask for all permissions. | |
| #define | PLATFORM_MAX_PATH_LENGTH 4096 |
| Maximum path length supported by the operating system. | |
| #define | PLATFORM_ACCESS_EXISTS 0 |
| Access modes for platform_access() | |
| #define | PLATFORM_ACCESS_WRITE 2 |
| Check if file/directory is writable. | |
| #define | PLATFORM_ACCESS_READ 4 |
| Check if file/directory is readable. | |
| #define | PLATFORM_O_RDONLY O_RDONLY |
| Open file for reading only. | |
| #define | PLATFORM_O_WRONLY O_WRONLY |
| Open file for writing only. | |
| #define | PLATFORM_O_RDWR O_RDWR |
| Open file for reading and writing. | |
| #define | PLATFORM_O_CREAT O_CREAT |
| Create file if it doesn't exist. | |
| #define | PLATFORM_O_EXCL O_EXCL |
| Fail if file already exists (with O_CREAT) | |
| #define | PLATFORM_O_TRUNC O_TRUNC |
| Truncate file to zero length if it exists. | |
| #define | PLATFORM_O_APPEND O_APPEND |
| Append to end of file. | |
| #define | PLATFORM_O_BINARY 0 |
| Open file in binary mode (Windows) | |
| #define | EINVAL 22 |
| #define | ERANGE 34 |
| #define | ETIMEDOUT 110 |
| #define | EINTR 4 |
| #define | EBADF 9 |
| #define | EAGAIN 11 |
| #define | EWOULDBLOCK 11 |
| #define | EPIPE 32 |
| #define | ECONNREFUSED 111 |
| #define | ENETUNREACH 101 |
| #define | EHOSTUNREACH 113 |
| #define | ECONNRESET 104 |
| #define | ENOTSOCK 88 |
Typedefs | |
| typedef pthread_cond_t | cond_t |
| Condition variable type (POSIX: pthread_cond_t) | |
| typedef struct platform_mmap | platform_mmap_t |
| Memory-mapped file handle. | |
| typedef pthread_mutex_t | mutex_t |
| Mutex type (POSIX: pthread_mutex_t) | |
| typedef int | pipe_t |
| Pipe handle type (POSIX: int file descriptor) | |
| typedef pthread_rwlock_t | rwlock_t |
| Read-write lock type (POSIX: pthread_rwlock_t) | |
| typedef int | socket_t |
| Socket handle type (POSIX: int) | |
| typedef void(* | signal_handler_t) (int) |
| Signal handler function type. | |
| typedef bool(* | console_ctrl_handler_t) (console_ctrl_event_t event) |
| Console control handler callback type. | |
| typedef bool(* | backtrace_frame_filter_t) (const char *frame) |
| Callback type for filtering backtrace frames. | |
| typedef pthread_t | asciichat_thread_t |
| Thread handle type (POSIX: pthread_t) | |
| typedef pthread_t | thread_id_t |
| Thread ID type (POSIX: pthread_t) | |
| typedef pthread_key_t | tls_key_t |
| Thread-local storage key type (POSIX: pthread_key_t) | |
Enumerations | |
| enum | console_ctrl_event_t { CONSOLE_CTRL_C = 0 , CONSOLE_CTRL_BREAK = 1 , CONSOLE_CLOSE = 2 , CONSOLE_LOGOFF = 3 , CONSOLE_SHUTDOWN = 4 } |
| Console control event types (cross-platform Ctrl+C handling) More... | |
| enum | terminal_color_mode_t { TERM_COLOR_AUTO = -1 , TERM_COLOR_NONE = 0 , TERM_COLOR_16 = 1 , TERM_COLOR_256 = 2 , TERM_COLOR_TRUECOLOR = 3 } |
| Terminal color support levels. More... | |
| enum | terminal_capability_flags_t { TERM_CAP_COLOR_16 = 0x0001 , TERM_CAP_COLOR_256 = 0x0002 , TERM_CAP_COLOR_TRUE = 0x0004 , TERM_CAP_UTF8 = 0x0008 , TERM_CAP_BACKGROUND = 0x0010 } |
| Terminal capability flags (bitmask) More... | |
| enum | render_mode_t { RENDER_MODE_FOREGROUND = 0 , RENDER_MODE_BACKGROUND = 1 , RENDER_MODE_HALF_BLOCK = 2 } |
| Render mode preferences. More... | |
Functions | |
| int | cond_init (cond_t *cond) |
| Initialize a condition variable. | |
| int | cond_destroy (cond_t *cond) |
| Destroy a condition variable. | |
| int | cond_wait (cond_t *cond, mutex_t *mutex) |
| Wait on a condition variable (blocking) | |
| int | cond_timedwait (cond_t *cond, mutex_t *mutex, int timeout_ms) |
| Wait on a condition variable with timeout. | |
| int | cond_signal (cond_t *cond) |
| Signal a condition variable (wake one waiting thread) | |
| int | cond_broadcast (cond_t *cond) |
| Broadcast to a condition variable (wake all waiting threads) | |
| asciichat_error_t | platform_mkdir (const char *path, int mode) |
| Create a directory. | |
| asciichat_error_t | platform_stat (const char *path, platform_stat_t *stat_out) |
| Get file statistics. | |
| int | platform_is_regular_file (const char *path) |
| Check if a path is a regular file. | |
| int | platform_is_directory (const char *path) |
| Check if a path is a directory. | |
| asciichat_error_t | platform_init (void) |
| Initialize platform-specific subsystems. | |
| void | platform_cleanup (void) |
| Cleanup platform-specific subsystems. | |
| size_t | platform_malloc_size (const void *ptr) |
| Get the size of an allocated memory block. | |
| void | platform_mmap_init (platform_mmap_t *mapping) |
| Initialize a platform_mmap_t structure. | |
| asciichat_error_t | platform_mmap_open (const char *path, size_t size, platform_mmap_t *out) |
| Memory-map a file for read/write access. | |
| void | platform_mmap_close (platform_mmap_t *mapping) |
| Unmap and close a memory-mapped file. | |
| void | platform_mmap_sync (platform_mmap_t *mapping, bool async) |
| Flush memory-mapped changes to disk. | |
| bool | platform_mmap_is_valid (const platform_mmap_t *mapping) |
| Check if a mapping is currently valid. | |
| int | debug_mutex_lock (mutex_t *mutex, const char *file_name, int line_number, const char *function_name) |
| int | debug_mutex_trylock (mutex_t *mutex, const char *file_name, int line_number, const char *function_name) |
| int | debug_mutex_unlock (mutex_t *mutex, const char *file_name, int line_number, const char *function_name) |
| bool | lock_debug_is_initialized (void) |
| int | mutex_init (mutex_t *mutex) |
| Initialize a mutex. | |
| int | mutex_destroy (mutex_t *mutex) |
| Destroy a mutex. | |
| int | mutex_lock_impl (mutex_t *mutex) |
| Lock a mutex (implementation function) | |
| int | mutex_trylock_impl (mutex_t *mutex) |
| Try to lock a mutex without blocking (implementation function) | |
| int | mutex_unlock_impl (mutex_t *mutex) |
| Unlock a mutex (implementation function) | |
| pipe_t | platform_pipe_connect (const char *path) |
| Connect to an agent via named pipe (Windows) or Unix socket (POSIX) | |
| int | platform_pipe_close (pipe_t pipe) |
| Close a pipe connection. | |
| ssize_t | platform_pipe_read (pipe_t pipe, void *buf, size_t len) |
| Read data from a pipe. | |
| ssize_t | platform_pipe_write (pipe_t pipe, const void *buf, size_t len) |
| Write data to a pipe. | |
| bool | platform_pipe_is_valid (pipe_t pipe) |
| Check if a pipe handle is valid. | |
| asciichat_error_t | platform_popen (const char *command, const char *mode, FILE **out_stream) |
| Execute a command and return a file stream for reading/writing. | |
| asciichat_error_t | platform_pclose (FILE **stream_ptr) |
| Close a process stream opened with platform_popen() | |
| int | platform_prompt_question (const char *prompt, char *buffer, size_t max_len, prompt_opts_t opts) |
| Prompt the user for text input. | |
| bool | platform_prompt_yes_no (const char *prompt, bool default_yes) |
| Prompt the user for a yes/no answer. | |
| bool | platform_is_interactive (void) |
| Check if interactive prompting is available. | |
| int | debug_rwlock_rdlock (rwlock_t *rwlock, const char *file_name, int line_number, const char *function_name) |
| int | debug_rwlock_wrlock (rwlock_t *rwlock, const char *file_name, int line_number, const char *function_name) |
| int | debug_rwlock_rdunlock (rwlock_t *rwlock, const char *file_name, int line_number, const char *function_name) |
| int | debug_rwlock_wrunlock (rwlock_t *rwlock, const char *file_name, int line_number, const char *function_name) |
| int | rwlock_init (rwlock_t *lock) |
| Initialize a read-write lock. | |
| int | rwlock_destroy (rwlock_t *lock) |
| Destroy a read-write lock. | |
| int | rwlock_init_impl (rwlock_t *lock) |
| Initialize a read-write lock (implementation function) | |
| int | rwlock_destroy_impl (rwlock_t *lock) |
| Destroy a read-write lock (implementation function) | |
| int | rwlock_rdlock_impl (rwlock_t *lock) |
| Acquire a read lock (implementation function) | |
| int | rwlock_wrlock_impl (rwlock_t *lock) |
| Acquire a write lock (implementation function) | |
| int | rwlock_rdunlock_impl (rwlock_t *lock) |
| Release a read lock (implementation function) | |
| int | rwlock_wrunlock_impl (rwlock_t *lock) |
| Release a write lock (implementation function) | |
| void | socket_optimize_for_streaming (socket_t sock) |
| Optimize socket for high-throughput video streaming. | |
| asciichat_error_t | socket_init (void) |
| Initialize socket subsystem (required on Windows) | |
| void | socket_cleanup (void) |
| Cleanup socket subsystem. | |
| socket_t | socket_create (int domain, int type, int protocol) |
| Create a new socket. | |
| int | socket_close (socket_t sock) |
| Close a socket. | |
| int | socket_bind (socket_t sock, const struct sockaddr *addr, socklen_t addrlen) |
| Bind a socket to an address. | |
| int | socket_listen (socket_t sock, int backlog) |
| Listen for incoming connections. | |
| socket_t | socket_accept (socket_t sock, struct sockaddr *addr, socklen_t *addrlen) |
| Accept an incoming connection. | |
| int | socket_connect (socket_t sock, const struct sockaddr *addr, socklen_t addrlen) |
| Connect to a remote address. | |
| ssize_t | socket_send (socket_t sock, const void *buf, size_t len, int flags) |
| Send data on a socket. | |
| ssize_t | socket_recv (socket_t sock, void *buf, size_t len, int flags) |
| Receive data from a socket. | |
| ssize_t | socket_sendto (socket_t sock, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) |
| Send data to a specific address (UDP) | |
| ssize_t | socket_recvfrom (socket_t sock, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen) |
| Receive data from a specific address (UDP) | |
| int | socket_setsockopt (socket_t sock, int level, int optname, const void *optval, socklen_t optlen) |
| Set socket option. | |
| int | socket_getsockopt (socket_t sock, int level, int optname, void *optval, socklen_t *optlen) |
| Get socket option. | |
| int | socket_shutdown (socket_t sock, int how) |
| Shutdown socket I/O. | |
| int | socket_getpeername (socket_t sock, struct sockaddr *addr, socklen_t *addrlen) |
| Get peer address. | |
| int | socket_getsockname (socket_t sock, struct sockaddr *addr, socklen_t *addrlen) |
| Get socket local address. | |
| int | socket_set_blocking (socket_t sock) |
| Set socket to blocking mode. | |
| int | socket_set_nonblocking (socket_t sock, bool nonblocking) |
| Set socket to non-blocking mode. | |
| int | socket_set_reuseaddr (socket_t sock, bool reuse) |
| Set SO_REUSEADDR socket option. | |
| int | socket_set_nodelay (socket_t sock, bool nodelay) |
| Set TCP_NODELAY socket option (disable Nagle's algorithm) | |
| int | socket_set_keepalive (socket_t sock, bool keepalive) |
| Set SO_KEEPALIVE socket option. | |
| int | socket_set_keepalive_params (socket_t sock, bool enable, int idle, int interval, int count) |
| Set TCP keepalive parameters. | |
| int | socket_set_linger (socket_t sock, bool enable, int timeout) |
| Set SO_LINGER socket option. | |
| int | socket_set_timeout (socket_t sock, uint32_t timeout_ms) |
| Set socket receive and send timeouts. | |
| int | socket_set_buffer_sizes (socket_t sock, int recv_size, int send_size) |
| Set socket buffer sizes. | |
| int | socket_get_peer_address (socket_t sock, struct sockaddr *addr, socklen_t *addrlen) |
| Get peer address (convenience function) | |
| int | socket_get_error (socket_t sock) |
| Get socket-specific error code. | |
| int | socket_get_last_error (void) |
| Get last socket error code. | |
| const char * | socket_get_error_string (void) |
| Get last socket error as string. | |
| int | socket_poll (struct pollfd *fds, nfds_t nfds, int timeout) |
| Poll sockets for events. | |
| int | socket_select (socket_t max_fd, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) |
| Select sockets for I/O readiness. | |
| void | socket_fd_zero (fd_set *set) |
| Clear an fd_set. | |
| void | socket_fd_set (socket_t sock, fd_set *set) |
| Add a socket to an fd_set. | |
| int | socket_fd_isset (socket_t sock, fd_set *set) |
| Check if a socket is in an fd_set. | |
| int | socket_get_fd (socket_t sock) |
| Get the underlying file descriptor (POSIX compatibility) | |
| bool | socket_is_valid (socket_t sock) |
| Check if a socket handle is valid. | |
| asciichat_error_t | symbol_cache_init (void) |
| Initialize the symbol cache. | |
| void | symbol_cache_cleanup (void) |
| Clean up the symbol cache and free all resources. | |
| const char * | symbol_cache_lookup (void *addr) |
| Look up a symbol for a given address. | |
| bool | symbol_cache_insert (void *addr, const char *symbol) |
| Insert a symbol into the cache. | |
| void | symbol_cache_get_stats (uint64_t *hits_out, uint64_t *misses_out, size_t *entries_out) |
| Get cache statistics. | |
| void | symbol_cache_print_stats (void) |
| Print cache statistics to logging system. | |
| char ** | symbol_cache_resolve_batch (void *const *buffer, int size) |
| Resolve multiple addresses using addr2line and cache results. | |
| void | symbol_cache_free_symbols (char **symbols) |
| Free symbol array returned by symbol_cache_resolve_batch. | |
| void | platform_sleep_ms (unsigned int ms) |
| Sleep for a specified number of milliseconds. | |
| uint64_t | platform_get_monotonic_time_us (void) |
| Get monotonic time in microseconds. | |
| asciichat_error_t | platform_localtime (const time_t *timer, struct tm *result) |
| Platform-safe localtime wrapper. | |
| asciichat_error_t | platform_gtime (const time_t *timer, struct tm *result) |
| Platform-safe gmtime wrapper. | |
| int | platform_get_pid (void) |
| Get the current process ID. | |
| const char * | platform_get_username (void) |
| Get the current username. | |
| signal_handler_t | platform_signal (int sig, signal_handler_t handler) |
| Set a signal handler. | |
| bool | platform_set_console_ctrl_handler (console_ctrl_handler_t handler) |
| Register a console control handler (for Ctrl+C, etc.) | |
| const char * | platform_getenv (const char *name) |
| Get an environment variable value. | |
| int | platform_setenv (const char *name, const char *value) |
| Set an environment variable. | |
| int | platform_isatty (int fd) |
| Check if a file descriptor is a terminal. | |
| const char * | platform_ttyname (int fd) |
| Get the name of the terminal associated with a file descriptor. | |
| int | platform_fsync (int fd) |
| Synchronize a file descriptor to disk. | |
| int | platform_backtrace (void **buffer, int size) |
| Get a backtrace of the current call stack. | |
| char ** | platform_backtrace_symbols (void *const *buffer, int size) |
| Convert backtrace addresses to symbol names. | |
| void | platform_backtrace_symbols_free (char **strings) |
| Free symbol array returned by platform_backtrace_symbols() | |
| void | platform_install_crash_handler (void) |
| Install crash handlers for the application. | |
| void | platform_print_backtrace_symbols (const char *label, char **symbols, int count, int skip_frames, int max_frames, backtrace_frame_filter_t filter) |
| Print pre-resolved backtrace symbols with consistent formatting. | |
| int | platform_format_backtrace_symbols (char *buffer, size_t buffer_size, const char *label, char **symbols, int count, int skip_frames, int max_frames, backtrace_frame_filter_t filter) |
| Format pre-resolved backtrace symbols to a buffer. | |
| void | platform_print_backtrace (int skip_frames) |
| Print a backtrace of the current call stack. | |
| asciichat_error_t | platform_memcpy (void *dest, size_t dest_size, const void *src, size_t count) |
| Platform-safe memcpy wrapper. | |
| asciichat_error_t | platform_memset (void *dest, size_t dest_size, int ch, size_t count) |
| Platform-safe memset wrapper. | |
| asciichat_error_t | platform_memmove (void *dest, size_t dest_size, const void *src, size_t count) |
| Platform-safe memmove wrapper. | |
| asciichat_error_t | platform_strcpy (char *dest, size_t dest_size, const char *src) |
| Platform-safe strcpy wrapper. | |
| asciichat_error_t | platform_resolve_hostname_to_ipv4 (const char *hostname, char *ipv4_out, size_t ipv4_out_size) |
| Resolve hostname to IPv4 address. | |
| asciichat_error_t | platform_load_system_ca_certs (char **pem_data_out, size_t *pem_size_out) |
| Load system CA certificates for TLS/HTTPS. | |
| bool | platform_is_binary_in_path (const char *bin_name) |
| Check if a binary is available in the system PATH. | |
| void | platform_cleanup_binary_path_cache (void) |
| Cleanup the binary PATH cache. | |
| bool | platform_get_executable_path (char *exe_path, size_t path_size) |
| Get the path to the current executable. | |
| bool | platform_get_temp_dir (char *temp_dir, size_t path_size) |
| Get the system temporary directory path. | |
| bool | platform_get_cwd (char *cwd, size_t path_size) |
| Get the current working directory of the process. | |
| int | platform_access (const char *path, int mode) |
| Check file/directory access permissions. | |
| asciichat_error_t | terminal_get_size (terminal_size_t *size) |
| Get terminal size. | |
| asciichat_error_t | terminal_set_raw_mode (bool enable) |
| Set terminal to raw mode. | |
| asciichat_error_t | terminal_set_echo (bool enable) |
| Set terminal echo mode. | |
| bool | terminal_supports_color (void) |
| Check if terminal supports color. | |
| bool | terminal_supports_unicode (void) |
| Check if terminal supports unicode. | |
| bool | terminal_supports_utf8 (void) |
| Check if terminal supports UTF-8. | |
| asciichat_error_t | terminal_clear_screen (void) |
| Clear the terminal screen. | |
| asciichat_error_t | terminal_move_cursor (int row, int col) |
| Move cursor to specified position. | |
| void | terminal_enable_ansi (void) |
| Enable ANSI escape sequences. | |
| asciichat_error_t | terminal_set_buffering (bool line_buffered) |
| Set terminal buffering mode. | |
| asciichat_error_t | terminal_flush (int fd) |
| Flush terminal output. | |
| asciichat_error_t | terminal_get_cursor_position (int *row, int *col) |
| Get current cursor position. | |
| asciichat_error_t | terminal_save_cursor (void) |
| Save cursor position. | |
| asciichat_error_t | terminal_restore_cursor (void) |
| Restore saved cursor position. | |
| asciichat_error_t | terminal_set_title (const char *title) |
| Set terminal window title. | |
| asciichat_error_t | terminal_ring_bell (void) |
| Ring terminal bell. | |
| asciichat_error_t | terminal_hide_cursor (int fd, bool hide) |
| Hide or show cursor. | |
| asciichat_error_t | terminal_set_scroll_region (int top, int bottom) |
| Set scroll region. | |
| asciichat_error_t | terminal_reset (int fd) |
| Reset terminal to default state. | |
| asciichat_error_t | terminal_cursor_home (int fd) |
| Move cursor to home position (top-left) | |
| asciichat_error_t | terminal_clear_scrollback (int fd) |
| Clear terminal scrollback buffer. | |
| terminal_capabilities_t | detect_terminal_capabilities (void) |
| Detect terminal capabilities. | |
| tty_info_t | get_current_tty (void) |
| Get current TTY information. | |
| bool | is_valid_tty_path (const char *path) |
| Check if a TTY path is valid. | |
| asciichat_error_t | get_terminal_size (unsigned short int *width, unsigned short int *height) |
| Get terminal size with multiple fallback methods. | |
| const char * | terminal_color_level_name (terminal_color_mode_t level) |
| Get name of color level. | |
| const char * | terminal_capabilities_summary (const terminal_capabilities_t *caps) |
| Get summary string of terminal capabilities. | |
| void | print_terminal_capabilities (const terminal_capabilities_t *caps) |
| Print terminal capabilities to stdout. | |
| void | test_terminal_output_modes (void) |
| Test terminal output modes. | |
| terminal_capabilities_t | apply_color_mode_override (terminal_capabilities_t caps) |
| Apply command-line overrides to detected capabilities. | |
| int | asciichat_thread_create (asciichat_thread_t *thread, void *(*func)(void *), void *arg) |
| Create a new thread. | |
| int | asciichat_thread_join (asciichat_thread_t *thread, void **retval) |
| Wait for a thread to complete (blocking) | |
| int | asciichat_thread_join_timeout (asciichat_thread_t *thread, void **retval, uint32_t timeout_ms) |
| Wait for a thread to complete with timeout. | |
| void | asciichat_thread_exit (void *retval) |
| Exit the current thread. | |
| thread_id_t | asciichat_thread_self (void) |
| Get the current thread's ID. | |
| int | asciichat_thread_equal (thread_id_t t1, thread_id_t t2) |
| Compare two thread IDs for equality. | |
| uint64_t | asciichat_thread_current_id (void) |
| Get the current thread's unique numeric ID. | |
| bool | asciichat_thread_is_initialized (asciichat_thread_t *thread) |
| Check if a thread handle has been initialized. | |
| void | asciichat_thread_init (asciichat_thread_t *thread) |
| Initialize a thread handle to an uninitialized state. | |
| asciichat_error_t | asciichat_thread_set_realtime_priority (void) |
| Set the current thread to real-time priority. | |
| asciichat_error_t | thread_create_or_fail (asciichat_thread_t *thread, void *(*func)(void *), void *arg, const char *thread_name, uint32_t client_id) |
| Create a thread with standardized error handling and logging. | |
| int | ascii_tls_key_create (tls_key_t *key, void(*destructor)(void *)) |
| Create a thread-local storage key. | |
| int | ascii_tls_key_delete (tls_key_t key) |
| Delete a thread-local storage key. | |
| void * | ascii_tls_get (tls_key_t key) |
| Get thread-local value for a key. | |
| int | ascii_tls_set (tls_key_t key, void *value) |
| Set thread-local value for a key. | |
| int | platform_snprintf (char *str, size_t size, const char *format,...) |
| Safe string formatting (snprintf replacement) | |
| int | platform_vsnprintf (char *str, size_t size, const char *format, va_list ap) |
| Safe variable-argument string formatting. | |
| char * | platform_strdup (const char *s) |
| Duplicate string (strdup replacement) | |
| char * | platform_strndup (const char *s, size_t n) |
| Duplicate string with length limit (strndup replacement) | |
| int | platform_strcasecmp (const char *s1, const char *s2) |
| Case-insensitive string comparison. | |
| int | platform_strncasecmp (const char *s1, const char *s2, size_t n) |
| Case-insensitive string comparison with length limit. | |
| char * | platform_strtok_r (char *str, const char *delim, char **saveptr) |
| Thread-safe string tokenization (strtok_r replacement) | |
| size_t | platform_strlcpy (char *dst, const char *src, size_t size) |
| Safe string copy with size tracking (strlcpy) | |
| size_t | platform_strlcat (char *dst, const char *src, size_t size) |
| Safe string concatenation with size tracking (strlcat) | |
| int | platform_strncpy (char *dst, size_t dst_size, const char *src, size_t count) |
| Safe string copy with explicit size bounds (strncpy replacement) | |
| void * | platform_aligned_alloc (size_t alignment, size_t size) |
| Allocate aligned memory. | |
| void | platform_aligned_free (void *ptr) |
| Free aligned memory. | |
| void | platform_memory_barrier (void) |
| Perform memory barrier/fence operation. | |
| const char * | platform_strerror (int errnum) |
| Get thread-safe error string. | |
| int | platform_get_last_error (void) |
| Get last platform error code. | |
| void | platform_set_last_error (int error) |
| Set platform error code. | |
| int | platform_open (const char *pathname, int flags,...) |
| Safe file open (open replacement) | |
| FILE * | platform_fopen (const char *filename, const char *mode) |
| Safe file open stream (fopen replacement) | |
| FILE * | platform_fdopen (int fd, const char *mode) |
| Convert file descriptor to stream (fdopen replacement) | |
| ssize_t | platform_read (int fd, void *buf, size_t count) |
| Safe file read (read replacement) | |
| int | platform_close (int fd) |
| Safe file close (close replacement) | |
| int | platform_unlink (const char *pathname) |
| Delete/unlink file. | |
| int | platform_chmod (const char *pathname, int mode) |
| Change file permissions/mode. | |
Variables | |
| int | errno |
Cross-Platform Utility Functions | |
| void | platform_sleep_usec (unsigned int usec) |
| High-precision sleep function with microsecond precision. | |
| ssize_t | platform_write (int fd, const void *buf, size_t count) |
| Platform-safe write function. | |
Safe String Formatting Functions | |
| int | safe_snprintf (char *buffer, size_t buffer_size, const char *format,...) |
| Safe version of snprintf that ensures null termination. | |
| int | safe_fprintf (FILE *stream, const char *format,...) |
| Safe version of fprintf. | |
| char * | platform_strcat (char *dest, size_t dest_size, const char *src) |
| Safe version of strcat with buffer size protection. | |
| int | safe_sscanf (const char *str, const char *format,...) |
| Safe version of sscanf with validation. | |
Platform Detection Macros | |
| #define | PLATFORM_WINDOWS 0 |
| Platform detection: 1 on Windows, 0 on POSIX. | |
| #define | PLATFORM_POSIX 1 |
| Platform detection: 1 on POSIX, 0 on Windows. | |
Compiler Attribute Macros | |
| #define | PACKED_STRUCT_BEGIN |
| Begin a packed structure (POSIX: no-op, uses attribute) | |
| #define | PACKED_STRUCT_END |
| End a packed structure (POSIX: no-op, uses attribute) | |
| #define | PACKED_ATTR __attribute__((packed)) |
| Packed structure attribute (POSIX: attribute((packed))) | |
| #define | ALIGNED_ATTR(x) __attribute__((aligned(x))) |
| Memory alignment attribute (POSIX: attribute((aligned))) | |
Thread-Local Storage and Alignment Macros | |
| #define | THREAD_LOCAL __thread |
| Thread-local storage keyword (POSIX: __thread) | |
| #define | ALIGNED_32 __attribute__((aligned(32))) |
| 32-byte alignment macro (POSIX: attribute((aligned(32)))) | |
| #define | ALIGNED_16 __attribute__((aligned(16))) |
| 16-byte alignment macro (POSIX: attribute((aligned(16)))) | |
Utility Macros | |
| #define | UNUSED(x) ((void)(x)) |
| Suppress unused parameter warnings. | |
Mutex Locking Macros | |
| #define | mutex_lock(mutex) (lock_debug_is_initialized() ? debug_mutex_lock(mutex, __FILE__, __LINE__, __func__) : mutex_lock_impl(mutex)) |
| Lock a mutex (with debug tracking in debug builds) | |
| #define | mutex_trylock(mutex) (lock_debug_is_initialized() ? debug_mutex_trylock(mutex, __FILE__, __LINE__, __func__) : mutex_trylock_impl(mutex)) |
| Try to lock a mutex without blocking (with debug tracking in debug builds) | |
| #define | mutex_unlock(mutex) (lock_debug_is_initialized() ? debug_mutex_unlock(mutex, __FILE__, __LINE__, __func__) : mutex_unlock_impl(mutex)) |
| Unlock a mutex (with debug tracking in debug builds) | |
Read-Write Lock Macros | |
| #define | rwlock_rdlock(lock) (lock_debug_is_initialized() ? debug_rwlock_rdlock(lock, __FILE__, __LINE__, __func__) : rwlock_rdlock_impl(lock)) |
| Acquire a read lock (with debug tracking in debug builds) | |
| #define | rwlock_wrlock(lock) (lock_debug_is_initialized() ? debug_rwlock_wrlock(lock, __FILE__, __LINE__, __func__) : rwlock_wrlock_impl(lock)) |
| Acquire a write lock (with debug tracking in debug builds) | |
| #define | rwlock_rdunlock(lock) (lock_debug_is_initialized() ? debug_rwlock_rdunlock(lock, __FILE__, __LINE__, __func__) : rwlock_rdunlock_impl(lock)) |
| Release a read lock (with debug tracking in debug builds) | |
| #define | rwlock_wrunlock(lock) (lock_debug_is_initialized() ? debug_rwlock_wrunlock(lock, __FILE__, __LINE__, __func__) : rwlock_wrunlock_impl(lock)) |
| Release a write lock (with debug tracking in debug builds) | |
๐ Cross-platform abstractions for threading, sockets, and system calls, and hardware access
This header provides the main entry point for the platform abstraction layer, enabling ascii-chat to run seamlessly on Windows, Linux, and macOS with a unified API. It serves as the umbrella header that includes all platform abstraction components.
Purpose:
The abstraction layer eliminates platform-specific code (#ifdef _WIN32 blocks) from application code by providing a unified API. All platform differences are hidden behind this abstraction layer, making the application code completely platform-independent.
Usage:
Organization:
The abstraction layer is organized into modular components, each with its own header file. This header includes them all:
thread.h): Thread creation, joining, detaching, thread IDsmutex.h, rwlock.h, cond.h): Mutexes, read-write locks, condition variablessocket.h): Socket operations, bind, listen, accept, send, recvterminal.h): Terminal size, raw mode, cursor control, ANSI supportsystem.h): Process info, environment variables, signals, backtracesstring.h): Safe string formatting and manipulationfile.h): Cross-platform file operationsPlatform Detection:
This header automatically detects the target platform using _WIN32 macro:
Compatibility Layer:
This header also provides platform compatibility macros and definitions:
Utility Macros:
PLATFORM_WINDOWS: Defined as 1 on Windows, 0 on POSIXPLATFORM_POSIX: Defined as 1 on POSIX, 0 on WindowsPACKED_STRUCT_BEGIN/END: Cross-platform packed struct supportALIGNED_ATTR(x): Memory alignment attributesTHREAD_LOCAL: Thread-local storage keywordALIGNED_32/ALIGNED_16: Specific alignment macrosUNUSED(x): Suppress unused parameter warningsThread-Local Storage:
Provides unified thread-local storage support:
__declspec(thread)__thread__threadInitialization:
Before using platform functions, call platform_init() (required on Windows for Winsock initialization). See platform/system.h for details.
platform/thread.h, platform/socket.h).#ifdef _WIN32) is contained in this header and implementation files. Application code never needs platform conditionals.This header defines the ASCIICHAT_API macro used to control symbol visibility in shared libraries (DLLs on Windows, .so/.dylib on Unix).
Windows DLL Behavior:
Unix Behavior:
Usage:
CRITICAL: This header must have ZERO dependencies
This header provides a unified condition variable interface that abstracts platform-specific implementations (Windows Condition Variables vs POSIX pthread condition variables).
The interface provides:
This header provides unified file operations with consistent behavior across Windows and POSIX platforms.
The interface provides:
Provides platform-independent file system functions including directory creation, file statistics, and type checking.
This header provides platform initialization functions and static initialization helpers for synchronization primitives that need to work before main().
This header contains PRIVATE implementation helpers and macros used ONLY by the platform abstraction layer implementation files.
IMPORTANT: This header must ONLY be included within lib/platform/ files. All external code should use platform/util.h for public platform utilities.
Provides platform-independent memory functions including querying allocated block sizes for memory debugging and leak tracking.
This header provides a unified interface for memory-mapped files across platforms. Memory-mapped files allow treating file contents as memory, enabling efficient shared state and crash-safe logging.
The interface provides:
Platform implementations:
This header provides a unified mutex interface that abstracts platform-specific implementations (Windows Critical Sections vs POSIX pthread mutexes).
The interface provides:
This header provides a unified interface for agent communication (SSH agent, GPG agent) that abstracts platform-specific implementations:
The interface provides:
Provides platform-independent process execution functions for running external programs (like ssh-keygen, gpg) and capturing their output.
Provides interactive prompting functionality across Windows, Linux, and macOS. Supports text input with optional echo, yes/no questions with defaults, and configurable answer placement (same line or next line).
All prompt functions handle terminal locking to prevent log interleaving, check for TTY availability, and support non-interactive mode detection.
This header provides a unified read-write lock interface that abstracts platform-specific implementations (Windows SRW Locks vs POSIX pthread read-write locks).
The interface provides:
This header provides a unified socket interface that abstracts platform-specific implementations (Windows Winsock2 vs POSIX sockets).
The interface provides:
This header provides safe string formatting and manipulation functions that satisfy clang-tidy cert-err33-c requirements. All functions ensure null termination and prevent buffer overflow, making them safe replacements for standard C library functions.
This header provides a high-performance symbol resolution cache system for converting backtrace addresses to human-readable symbol names. The system caches resolved symbols to avoid expensive addr2line subprocess spawns on every backtrace operation.
Symbol resolution without caching requires:
With caching:
The symbol cache uses a hashtable to store resolved symbols:
For efficient backtrace processing:
The system tracks:
These statistics enable performance monitoring and cache efficiency analysis.
This header provides unified system functions including process management, environment variables, TTY operations, and signal handling.
The interface provides:
This header provides unified terminal I/O operations including ANSI escape sequences, cursor control, and terminal configuration.
The interface provides:
This header provides a unified thread interface that abstracts platform-specific implementations (Windows threads vs POSIX pthreads).
The interface provides:
This header provides the public API for platform-specific utility functions that are needed by the main codebase. These utilities provide cross-platform implementations of common operations with consistent behavior across Windows, Linux, and macOS.
This header is the ONLY way to access platform implementation details from outside the platform/ directory. All platform-internal implementations remain private to the platform/ directory via platform/internal.h.
This header provides a single point to include windows.h with proper alignment. The pragma pack ensures Windows SDK types get 8-byte alignment as expected, then immediately restores default packing so application structs are unaffected.
This header provides POSIX-style errno constant definitions for Windows compatibility. Windows headers do not define these constants by default, so this header fills the gap to enable cross-platform code.
Windows uses WSA errors for socket operations, but many functions also use standard errno. This header ensures standard errno constants are available on Windows for consistent error handling.
This header defines the following errno constants:
Welcome! This guide will help you understand the platform abstraction layerโthe unsung hero that makes ascii-chat work seamlessly across Windows, Linux, and macOS.
Here's the thing about cross-platform development: every operating system has its own way of doing things. Windows uses different APIs than Linux. macOS has its quirks. Writing code that works everywhere usually means lots of #ifdef _WIN32 scattered throughout your codebase, making it a mess to read and maintain.
But what if you could write your code once and have it just work everywhere? That's exactly what the platform abstraction layer does. It provides a unified APIโone set of functions that work identically on all platforms. Under the hood, it translates your calls to the appropriate platform-specific APIs. You write clean, readable code, and the platform layer handles all the messy details.
Think of it like an adapter plug for international travel. You don't need to carry different devices for each countryโyou just bring one adapter that works everywhere. Same idea here!
The Big Achievement: Zero platform-specific code (#ifdef blocks) in application code!
Supported Platforms: Windows 10+, Linux (POSIX), macOS (POSIX)
The platform abstraction layer follows a comprehensive philosophy that guides every design decision. Understanding these principles will help you use the platform layer effectively and understand why it works the way it does.
Principle: Platform-specific code is 100% isolated in implementation files.
This is the most important principleโapplication code (src/) has ZERO #ifdef blocks for platform detection. All platform differences live in lib/platform/posix/ or lib/platform/windows/.
Why this matters:
Benefits of complete isolation:
Principle: Abstraction should add zero runtime cost in production.
The platform layer achieves this through:
In release builds:
No runtime overhead, no performance penalty! The abstraction disappears at compile time.
Principle: Enable extensive debugging without affecting production performance.
Debug builds can enable lock tracking, memory debugging, and verbose logging:
This gives you powerful debugging when you need it, zero cost when you don't.
Principle: Use POSIX semantics as the baseline, adapt Windows to match.
Why POSIX first?
The abstraction:
Example:
Principle: Use distinct types to prevent platform-specific mistakes.
Platform types are completely opaque to application code:
This prevents common mistakes like:
Principle: Support global synchronization primitives with zero runtime init cost.
You can declare global mutexes, locks, and condition variables without explicit initialization functions:
How it works:
PTHREAD_MUTEX_INITIALIZER)Both approaches are thread-safe and require zero explicit initialization!
Principle: The platform layer normalizes differences that don't matter to the application.
What gets normalized:
socket_t everywhereerrno convention everywherevoid* (*)(void*)Application code can assume consistent semantics without worrying about platform differences in function signatures, error handling, or data types.
Principle: Expose only what's needed.
The platform layer doesn't try to abstract everything. Instead, it provides a focused API that covers only what ascii-chat needs:
Complex platform features that ascii-chat doesn't use (e.g., Windows COM, macOS CoreFoundation, Linux-specific ioctls) are left out entirely. This keeps the abstraction layer small, maintainable, and focused.
Benefits of minimalism:
The platform abstraction layer uses a three-layer architecture that keeps everything clean and organized.
Layer 1: Header Definition (lib/platform/*.h)
Layer 2: POSIX Implementation (lib/platform/posix/*.c)
Layer 3: Windows Implementation (lib/platform/windows/*.c)
The build system automatically selects Layer 2 or Layer 3 based on the target platform.
Most application code only needs to include one header:
For specific components, you can include individual headers:
The abstraction.h header automatically includes all component headers, so you get the complete platform abstraction API in one include.
platform/internal.h is a private header that MUST only be included within the lib/platform/ directory. External code should never include it directly. All public utilities are available through platform/util.h, platform/abstraction.h, or specific component headers like platform/socket.h.The platform abstraction is organized into focused components, each handling a specific aspect of cross-platform development.
Thread creation, joining, and management with timeout support.
Basic thread operations:
Thread operations with timeout:
Thread identity and comparison:
Important platform differences:
Mutual exclusion locks for protecting shared data.
Basic mutex usage:
Try-lock (non-blocking):
Static initialization for global mutexes:
Platform implementations:
Read-write locks allow multiple concurrent readers but only one writer.
Why use read-write locks?
Basic usage:
Real-world example from ascii-chat:
Platform implementations:
Important note on Windows:
rwlock_rdunlock() and rwlock_wrunlock() call ReleaseSRWLock*()Condition variables enable threads to wait for specific conditions to become true.
Basic pattern:
Timeout waiting:
Broadcasting to multiple waiters:
Static initialization:
Network socket operations with automatic optimization and error handling.
Basic server:
Automatic socket optimization:
When you accept a connection, the platform layer automatically optimizes it:
You can override these settings if needed:
Non-blocking I/O:
Polling multiple sockets:
Platform differences:
socket_init() to initialize Winsock (done by platform_init())Terminal control, cursor manipulation, and capability detection.
Basic terminal setup:
Raw mode for interactive applications:
Cursor control:
Screen manipulation:
Platform-specific features:
System-level operations: sleep, signals, crash handlers, process info.
Sleep operations:
Platform sleep precision:
Process information:
Environment variables:
TTY detection:
Signal handling:
Crash handlers (automatic backtrace on crash):
Manual backtrace (for debugging):
Platform-specific signal support:
Safe string handling that works consistently across platforms.
Safe formatting:
Safe string copy:
Safe string concatenation:
Case-insensitive comparison:
String duplication:
Thread-safe tokenization:
Platform-safe file operations.
Opening files:
Reading and writing:
Closing files:
Force sync to disk:
One of the most powerful features of the platform abstraction layer is static initialization. You can declare global synchronization primitives without any explicit initialization code!
Traditional approach (error-prone):
Platform abstraction approach (correct):
The magic happens at different times on different platforms:
POSIX (Linux/macOS):
Windows:
Both approaches are:
Global mutex:
Global read-write lock:
Global condition variable:
The platform abstraction layer automatically installs crash handlers that capture backtraces when your program crashes. This is invaluable for debugging!
Crash handlers are automatically installed when you call platform_init():
No additional setup needed - it just works!
POSIX (Linux/macOS):
SIGSEGV - Segmentation fault (null pointer, buffer overflow)SIGABRT - Abort signal (assertion failures, abort() calls)SIGFPE - Floating point exception (divide by zero)SIGILL - Illegal instructionSIGBUS - Bus error (alignment issues)Windows:
EXCEPTION_ACCESS_VIOLATION - Access violation (like SIGSEGV)EXCEPTION_ARRAY_BOUNDS_EXCEEDED - Array bounds exceededEXCEPTION_DATATYPE_MISALIGNMENT - Data type misalignmentEXCEPTION_FLT_DIVIDE_BY_ZERO - Floating point divide by zeroEXCEPTION_FLT_INVALID_OPERATION - Floating point invalid operationEXCEPTION_ILLEGAL_INSTRUCTION - Illegal instructionEXCEPTION_INT_DIVIDE_BY_ZERO - Integer divide by zeroEXCEPTION_STACK_OVERFLOW - Stack overflowSIGABRT, SIGFPE, SIGILLWhen a crash occurs, you get a detailed report:
The backtrace shows:
Symbol resolution (function names in backtraces) works best with debug symbols:
Debug builds (recommended for development):
Release builds (limited symbol info):
Platform-specific symbol support:
backtrace_symbols() from execinfo.hbacktrace_symbols() from execinfo.hStackWalk64() and SymFromAddr() with dbghelp.dllCrash handlers work across all threads in your application:
SetUnhandledExceptionFilter() is process-widesigaction() with SA_SIGINFO works on all threadsExample with multiple threads:
The crash handler correctly identifies the crashing thread and its stack!
Windows has some unique characteristics that the platform layer handles for you.
Windows requires explicit initialization of the Winsock library before using sockets:
You never need to call WSAStartup() or WSACleanup() directly!
Modern Windows (Windows 10+) supports ANSI escape sequences, but they need to be explicitly enabled:
The terminal functions automatically use Console API calls on older Windows versions.
Windows uses different synchronization primitives than POSIX:
Mutexes (CRITICAL_SECTION):
Spin count of 4000 means the thread will spin 4000 times before sleeping, which improves performance for short-held locks.
Read-Write Locks (SRWLOCK):
SRW Locks are lightweight (8 bytes vs 40+ bytes for CRITICAL_SECTION) and very fast.
Condition Variables:
The Windows thread implementation is the most complex part of the platform layer (2500+ lines!) because it includes sophisticated crash handling:
Thread Creation Flow:
Exception Handling in Threads:
This nested exception handling ensures crashes are caught and reported even in worker threads!
Windows has limited signal support compared to POSIX:
Working signals:
SIGINT - Ctrl+C (works via SetConsoleCtrlHandler)SIGTERM - Termination request (limited support)SIGABRT - Abort signal (via C runtime)SIGFPE - Floating point exception (via C runtime)SIGILL - Illegal instruction (via C runtime)Non-working signals:
SIGWINCH - Terminal resize (defined but does nothing)The platform layer provides these as no-ops so your code compiles:
Use Windows Console API functions like GetConsoleScreenBufferInfo() to detect terminal size changes on Windows.
Windows backtraces use the DbgHelp library with multiple fallback strategies:
Primary method (StackWalk64):
Fallback methods:
This multi-strategy approach ensures you get the best possible backtrace even when debug symbols are missing or DbgHelp has issues.
POSIX implementation is generally simpler because the platform abstraction API is based on POSIX semantics.
Most POSIX functions are thin wrappers:
This keeps the abstraction lightweight and efficient on POSIX platforms.
POSIX platforms have complete signal support:
The platform layer uses sigaction() for thread-safe signal handling:
POSIX platforms use the standard execinfo.h backtrace API:
Symbol resolution works automatically if:
-fno-omit-frame-pointer)macOS is mostly POSIX-compliant but has a few quirks:
Thread timeout join: macOS doesn't have pthread_timedjoin_np(), so timeouts fall back to blocking:
Type name conflicts: macOS system headers define thread_t, so we use asciichat_thread_t to avoid conflicts:
Here are some complete, real-world examples of using the platform abstraction layer.
A simple echo server that handles multiple clients using threads:
Classic producer-consumer with condition variables:
Simple interactive menu using terminal I/O:
Here are the golden rules for using the platform abstraction layer effectively.
Rule: Always call platform_init() at program start and platform_cleanup() at exit.
Why this matters:
platform_init()platform_init()Rule: Never use #ifdef _WIN32 or #ifdef __linux__ in application code.
If you find yourself writing platform-specific code:
lib/platform/Rule: Use platform abstraction types, not native types.
Platform types are opaque - you don't need to know (or care) what they contain.
Rule: Always check return values from platform functions.
Platform functions return:
socket_is_valid())Rule: Use static initialization for global synchronization primitives.
Static initialization is:
Rule: Only join threads that were successfully created.
Or use a helper function:
Rule: Use socket_is_valid() to check socket validity, not comparisons.
Why this matters:
-1, valid sockets are >= 0INVALID_SOCKET (typically ~0), valid sockets can be any valueConverting existing code to use the platform abstraction layer is straightforward.
From POSIX pthreads:
From Windows threads:
From POSIX mutexes:
From Windows critical sections:
From POSIX sockets:
From Windows Winsock:
From termios (POSIX):
From POSIX signals:
Common issues and how to solve them.
Problem: Undefined reference to platform functions.
Solution: Make sure platform files are included in your build:
Problem: socket_create() returns invalid socket on Windows.
Solution: Call platform_init() before using sockets:
Problem: Crash when calling asciichat_thread_join().
Solution: Check if thread was successfully created:
Problem: Backtrace shows addresses but no function names.
Solution: Build with debug symbols:
On Linux, also install debug info:
Problem: Timeout functions seem to block forever on Windows.
Solution: This is expected - some timeout functions fall back to blocking on certain platforms. Use a separate watchdog thread if you need guaranteed timeouts:
The platform abstraction layer is designed for minimal overhead, but there are still some performance characteristics to be aware of.
Release builds have essentially zero abstraction overhead:
Example assembly comparison (mutex lock on Linux):
Debug builds can enable tracking that has some overhead:
This is acceptable in debug builds because:
The platform layer automatically optimizes accepted sockets:
These optimizations are specifically tuned for ascii-chat's video streaming use case. If you need different settings, you can override them:
Platform sleep precision varies:
For Windows, use multimedia timers if you need better precision:
Want to add new platform abstractions or improve existing ones?
When adding a new platform abstraction:
lib/platform/foo.h): lib/platform/posix/foo.c): lib/platform/windows/foo.c): Platform abstraction tests should:
Example test structure:
Want to learn more?
Platform Abstraction Documentation:
Individual Component Documentation:
External Resources:
Related Topics:
| #define ALIGNED_16 __attribute__((aligned(16))) |
#include <abstraction.h>
16-byte alignment macro (POSIX: attribute((aligned(16))))
Definition at line 391 of file abstraction.h.
| #define ALIGNED_32 __attribute__((aligned(32))) |
#include <abstraction.h>
32-byte alignment macro (POSIX: attribute((aligned(32))))
Definition at line 386 of file abstraction.h.
| #define ALIGNED_ATTR | ( | x | ) | __attribute__((aligned(x))) |
#include <abstraction.h>
Memory alignment attribute (POSIX: attribute((aligned)))
| x | Alignment in bytes (must be power of 2) |
Definition at line 263 of file abstraction.h.
| #define ASCIICHAT_API __attribute__((visibility("default"))) |
| #define DIR_PERM_PRIVATE 0700 |
| #define EAGAIN 11 |
#include <windows_errno.h>
Definition at line 81 of file windows_errno.h.
| #define EBADF 9 |
#include <windows_errno.h>
Definition at line 77 of file windows_errno.h.
| #define ECONNREFUSED 111 |
#include <windows_errno.h>
Definition at line 93 of file windows_errno.h.
| #define ECONNRESET 104 |
#include <windows_errno.h>
Definition at line 105 of file windows_errno.h.
| #define EHOSTUNREACH 113 |
#include <windows_errno.h>
Definition at line 101 of file windows_errno.h.
| #define EINTR 4 |
#include <windows_errno.h>
Definition at line 73 of file windows_errno.h.
| #define EINVAL 22 |
#include <windows_errno.h>
Definition at line 61 of file windows_errno.h.
| #define ENETUNREACH 101 |
#include <windows_errno.h>
Definition at line 97 of file windows_errno.h.
| #define ENOTSOCK 88 |
#include <windows_errno.h>
Definition at line 109 of file windows_errno.h.
| #define EPIPE 32 |
#include <windows_errno.h>
Definition at line 89 of file windows_errno.h.
| #define ERANGE 34 |
#include <windows_errno.h>
Definition at line 65 of file windows_errno.h.
| #define ETIMEDOUT 110 |
#include <windows_errno.h>
Definition at line 69 of file windows_errno.h.
| #define EWOULDBLOCK 11 |
#include <windows_errno.h>
Definition at line 85 of file windows_errno.h.
| #define FILE_PERM_MASK 0777 |
| #define FILE_PERM_PRIVATE 0600 |
| #define FILE_PERM_PUBLIC_READ 0644 |
| #define INVALID_PIPE_VALUE (-1) |
| #define INVALID_SOCKET_VALUE (-1) |
| #define mutex_lock | ( | mutex | ) | (lock_debug_is_initialized() ? debug_mutex_lock(mutex, __FILE__, __LINE__, __func__) : mutex_lock_impl(mutex)) |
#include <mutex.h>
Lock a mutex (with debug tracking in debug builds)
| mutex | Pointer to mutex to lock |
Locks the mutex, blocking if necessary until the lock is acquired.
Definition at line 140 of file mutex.h.
| #define mutex_trylock | ( | mutex | ) | (lock_debug_is_initialized() ? debug_mutex_trylock(mutex, __FILE__, __LINE__, __func__) : mutex_trylock_impl(mutex)) |
#include <mutex.h>
Try to lock a mutex without blocking (with debug tracking in debug builds)
| mutex | Pointer to mutex to try to lock |
Definition at line 157 of file mutex.h.
| #define mutex_unlock | ( | mutex | ) | (lock_debug_is_initialized() ? debug_mutex_unlock(mutex, __FILE__, __LINE__, __func__) : mutex_unlock_impl(mutex)) |
#include <mutex.h>
Unlock a mutex (with debug tracking in debug builds)
| mutex | Pointer to mutex to unlock |
Unlocks the mutex. The mutex must be locked by the current thread.
Definition at line 175 of file mutex.h.
| #define PACKED_ATTR __attribute__((packed)) |
#include <abstraction.h>
Packed structure attribute (POSIX: attribute((packed)))
On POSIX, use this attribute directly on structure definitions.
Definition at line 256 of file abstraction.h.
| #define PACKED_STRUCT_BEGIN |
#include <abstraction.h>
Begin a packed structure (POSIX: no-op, uses attribute)
Definition at line 238 of file abstraction.h.
| #define PACKED_STRUCT_END |
#include <abstraction.h>
End a packed structure (POSIX: no-op, uses attribute)
Definition at line 240 of file abstraction.h.
| #define PATH_DELIM '/' |
| #define PATH_ENV_SEPARATOR ":" |
| #define PLATFORM_ACCESS_EXISTS 0 |
| #define PLATFORM_ACCESS_READ 4 |
| #define PLATFORM_ACCESS_WRITE 2 |
| #define PLATFORM_MAX_PATH_LENGTH 4096 |
#include <system.h>
Maximum path length supported by the operating system.
Platform-specific values:
| #define PLATFORM_O_APPEND O_APPEND |
| #define PLATFORM_O_APPEND O_APPEND |
| #define PLATFORM_O_BINARY 0 |
| #define PLATFORM_O_BINARY 0 |
#include <util.h>
Open file in binary mode (Windows)
Definition at line 434 of file platform/util.h.
| #define PLATFORM_O_CREAT O_CREAT |
| #define PLATFORM_O_CREAT O_CREAT |
| #define PLATFORM_O_EXCL O_EXCL |
| #define PLATFORM_O_EXCL O_EXCL |
#include <util.h>
Fail if file already exists (with O_CREAT)
Definition at line 431 of file platform/util.h.
| #define PLATFORM_O_RDONLY O_RDONLY |
| #define PLATFORM_O_RDONLY O_RDONLY |
| #define PLATFORM_O_RDWR O_RDWR |
| #define PLATFORM_O_RDWR O_RDWR |
#include <util.h>
Open file for reading and writing.
Definition at line 429 of file platform/util.h.
| #define PLATFORM_O_TRUNC O_TRUNC |
| #define PLATFORM_O_TRUNC O_TRUNC |
#include <util.h>
Truncate file to zero length if it exists.
Definition at line 432 of file platform/util.h.
| #define PLATFORM_O_WRONLY O_WRONLY |
| #define PLATFORM_O_WRONLY O_WRONLY |
| #define PLATFORM_POSIX 1 |
#include <abstraction.h>
Platform detection: 1 on POSIX, 0 on Windows.
Definition at line 166 of file abstraction.h.
| #define PLATFORM_WINDOWS 0 |
#include <abstraction.h>
Platform detection: 1 on Windows, 0 on POSIX.
Definition at line 164 of file abstraction.h.
| #define PROMPT_OPTS_DEFAULT (prompt_opts_t){.echo = true, .same_line = false, .mask_char = 0} |
#include <question.h>
Default prompt options (echo enabled, answer on next line)
Definition at line 40 of file question.h.
| #define PROMPT_OPTS_INLINE (prompt_opts_t){.echo = true, .same_line = true, .mask_char = 0} |
#include <question.h>
Prompt options for inline text input (echo enabled, same line)
Definition at line 50 of file question.h.
| #define PROMPT_OPTS_PASSWORD (prompt_opts_t){.echo = false, .same_line = true, .mask_char = '*'} |
#include <question.h>
Prompt options for password input (no echo, asterisk masking, same line)
Definition at line 45 of file question.h.
| #define rwlock_rdlock | ( | lock | ) | (lock_debug_is_initialized() ? debug_rwlock_rdlock(lock, __FILE__, __LINE__, __func__) : rwlock_rdlock_impl(lock)) |
#include <rwlock.h>
Acquire a read lock (with debug tracking in debug builds)
| lock | Pointer to read-write lock |
Acquires a shared read lock. Multiple threads can hold read locks simultaneously. Blocks if a write lock is held.
Definition at line 194 of file rwlock.h.
| #define rwlock_rdunlock | ( | lock | ) | (lock_debug_is_initialized() ? debug_rwlock_rdunlock(lock, __FILE__, __LINE__, __func__) : rwlock_rdunlock_impl(lock)) |
#include <rwlock.h>
Release a read lock (with debug tracking in debug builds)
| lock | Pointer to read-write lock |
Releases a shared read lock held by the calling thread.
Definition at line 231 of file rwlock.h.
| #define rwlock_wrlock | ( | lock | ) | (lock_debug_is_initialized() ? debug_rwlock_wrlock(lock, __FILE__, __LINE__, __func__) : rwlock_wrlock_impl(lock)) |
#include <rwlock.h>
Acquire a write lock (with debug tracking in debug builds)
| lock | Pointer to read-write lock |
Acquires an exclusive write lock. Only one thread can hold a write lock, and it excludes all read locks. Blocks if any locks are held.
Definition at line 213 of file rwlock.h.
| #define rwlock_wrunlock | ( | lock | ) | (lock_debug_is_initialized() ? debug_rwlock_wrunlock(lock, __FILE__, __LINE__, __func__) : rwlock_wrunlock_impl(lock)) |
#include <rwlock.h>
Release a write lock (with debug tracking in debug builds)
| lock | Pointer to read-write lock |
Releases an exclusive write lock held by the calling thread.
Definition at line 249 of file rwlock.h.
| #define SAFE_IGNORE_PRINTF_RESULT | ( | expr | ) | ((void)(expr)) |
| #define SOCKET_ERROR_INPROGRESS EINPROGRESS |
| #define SOCKET_ERROR_WOULDBLOCK EWOULDBLOCK |
| #define STATIC_COND_INIT {PTHREAD_COND_INITIALIZER, 1} |
| #define STATIC_MUTEX_INIT {PTHREAD_MUTEX_INITIALIZER, 1} |
| #define STATIC_RWLOCK_INIT {PTHREAD_RWLOCK_INITIALIZER, 1} |
| #define THREAD_LOCAL __thread |
#include <abstraction.h>
Thread-local storage keyword (POSIX: __thread)
Definition at line 381 of file abstraction.h.
| #define UNUSED | ( | x | ) | ((void)(x)) |
#include <abstraction.h>
Suppress unused parameter warnings.
| x | Parameter name to mark as unused |
Use this macro to suppress compiler warnings about unused function parameters. Especially useful for callback functions where not all parameters are used.
Definition at line 733 of file abstraction.h.
| typedef pthread_t asciichat_thread_t |
#include <thread.h>
Thread handle type (POSIX: pthread_t)
Definition at line 42 of file platform/thread.h.
| typedef bool(* backtrace_frame_filter_t) (const char *frame) |
| typedef pthread_cond_t cond_t |
| typedef bool(* console_ctrl_handler_t) (console_ctrl_event_t event) |
#include <system.h>
Console control handler callback type.
| event | The control event that occurred |
| typedef pthread_mutex_t mutex_t |
| typedef int pipe_t |
| typedef struct platform_mmap platform_mmap_t |
#include <mmap.h>
Memory-mapped file handle.
Contains platform-specific handles and mapping information. Do not access members directly; use the platform_mmap_* functions.
| typedef pthread_rwlock_t rwlock_t |
| typedef void(* signal_handler_t) (int) |
| typedef int socket_t |
| typedef pthread_t thread_id_t |
#include <thread.h>
Thread ID type (POSIX: pthread_t)
Definition at line 44 of file platform/thread.h.
| typedef pthread_key_t tls_key_t |
#include <thread.h>
Thread-local storage key type (POSIX: pthread_key_t)
Definition at line 46 of file platform/thread.h.
| enum console_ctrl_event_t |
#include <system.h>
Console control event types (cross-platform Ctrl+C handling)
Definition at line 181 of file system.h.
| enum render_mode_t |
#include <terminal.h>
Render mode preferences.
Enumeration of rendering modes for ASCII art output. Different modes provide different visual effects and require different terminal capabilities.
Definition at line 467 of file terminal.h.
#include <terminal.h>
Terminal capability flags (bitmask)
Bitmask enumeration for terminal capabilities. Multiple flags can be combined to indicate support for various features. Used in terminal capability detection and rendering optimization.
Definition at line 446 of file terminal.h.
#include <terminal.h>
Terminal color support levels.
Enumeration of terminal color capability levels from no color support to full 24-bit truecolor support. Used for capability detection and rendering mode selection.
Definition at line 424 of file terminal.h.
| terminal_capabilities_t apply_color_mode_override | ( | terminal_capabilities_t | caps | ) |
#include <terminal.h>
Apply command-line overrides to detected capabilities.
| caps | Terminal capabilities structure to modify |
Applies any command-line option overrides to the detected terminal capabilities. Overrides may include:
Referenced by client_main(), main(), mirror_main(), tcp_client_send_terminal_capabilities(), and threaded_send_terminal_size_with_auto_detect().
| void * ascii_tls_get | ( | tls_key_t | key | ) |
#include <thread.h>
Get thread-local value for a key.
| key | TLS key |
Returns the thread-local value associated with the specified key for the calling thread.
Referenced by asciichat_instr_runtime_get().
| int ascii_tls_key_create | ( | tls_key_t * | key, |
| void(*)(void *) | destructor | ||
| ) |
#include <thread.h>
Create a thread-local storage key.
| key | Pointer to TLS key (output parameter) |
| destructor | Optional destructor function called when thread exits (may be NULL) |
Creates a new TLS key that can be used to store thread-specific data. If a destructor is provided, it will be called with the stored value when a thread terminates (if the value is non-NULL).
| int ascii_tls_key_delete | ( | tls_key_t | key | ) |
#include <thread.h>
Delete a thread-local storage key.
| key | TLS key to delete |
Deletes the specified TLS key. Does NOT call destructors for existing thread-local values. The caller is responsible for cleanup before deletion.
Referenced by asciichat_instr_runtime_global_shutdown().
| int ascii_tls_set | ( | tls_key_t | key, |
| void * | value | ||
| ) |
#include <thread.h>
Set thread-local value for a key.
| key | TLS key |
| value | Value to store |
Associates the specified value with the key for the calling thread.
Referenced by asciichat_instr_runtime_get().
| int asciichat_thread_create | ( | asciichat_thread_t * | thread, |
| void *(*)(void *) | func, | ||
| void * | arg | ||
| ) |
#include <thread.h>
Create a new thread.
| thread | Pointer to thread handle (output parameter) |
| func | Thread function to execute |
| arg | Argument to pass to thread function |
Creates a new thread that executes the given function with the provided argument. The thread handle is stored in the thread parameter.
Referenced by discover_session_parallel(), server_main(), tcp_server_run(), thread_create_or_fail(), and thread_pool_spawn().
| uint64_t asciichat_thread_current_id | ( | void | ) |
#include <thread.h>
Get the current thread's unique numeric ID.
Returns a unique numeric identifier for the current thread. This is more portable than thread_id_t for comparisons.
| int asciichat_thread_equal | ( | thread_id_t | t1, |
| thread_id_t | t2 | ||
| ) |
#include <thread.h>
Compare two thread IDs for equality.
| t1 | First thread ID |
| t2 | Second thread ID |
| void asciichat_thread_exit | ( | void * | retval | ) |
#include <thread.h>
Exit the current thread.
| retval | Return value to pass to thread joiner (or NULL) |
Terminates the calling thread and optionally passes a return value to any thread waiting to join.
| void asciichat_thread_init | ( | asciichat_thread_t * | thread | ) |
#include <thread.h>
Initialize a thread handle to an uninitialized state.
| thread | Pointer to thread handle |
Sets the thread handle to an uninitialized state. Useful for static initialization or resetting a thread handle.
Referenced by discover_session_parallel(), and stop_client_render_threads().
| bool asciichat_thread_is_initialized | ( | asciichat_thread_t * | thread | ) |
#include <thread.h>
Check if a thread handle has been initialized.
| thread | Pointer to thread handle |
Referenced by discover_session_parallel(), stop_client_render_threads(), and stop_client_threads().
| int asciichat_thread_join | ( | asciichat_thread_t * | thread, |
| void ** | retval | ||
| ) |
#include <thread.h>
Wait for a thread to complete (blocking)
| thread | Thread handle to wait for |
| retval | Pointer to store thread return value (or NULL to ignore) |
Blocks the calling thread until the specified thread terminates.
Referenced by discover_session_parallel(), server_main(), stop_client_render_threads(), stop_client_threads(), and thread_pool_stop_all().
| int asciichat_thread_join_timeout | ( | asciichat_thread_t * | thread, |
| void ** | retval, | ||
| uint32_t | timeout_ms | ||
| ) |
#include <thread.h>
Wait for a thread to complete with timeout.
| thread | Thread handle to wait for |
| retval | Pointer to store thread return value (or NULL to ignore) |
| timeout_ms | Timeout in milliseconds |
Waits for the specified thread to terminate, with a maximum wait time. Returns non-zero if the timeout expires before the thread completes.
Referenced by audio_start_thread().
| thread_id_t asciichat_thread_self | ( | void | ) |
#include <thread.h>
Get the current thread's ID.
Returns a platform-specific thread identifier for the calling thread.
Referenced by log_lock_terminal(), and log_plain_msg().
| asciichat_error_t asciichat_thread_set_realtime_priority | ( | void | ) |
#include <thread.h>
Set the current thread to real-time priority.
Attempts to set the current thread to real-time priority for time-critical operations like audio processing.
Platform-specific implementations:
Referenced by audio_set_realtime_priority().
| int cond_broadcast | ( | cond_t * | cond | ) |
#include <cond.h>
Broadcast to a condition variable (wake all waiting threads)
| cond | Pointer to condition variable to broadcast |
Wakes up all threads that are waiting on the condition variable. If no threads are waiting, the broadcast has no effect.
| int cond_destroy | ( | cond_t * | cond | ) |
#include <cond.h>
Destroy a condition variable.
| cond | Pointer to condition variable to destroy |
Destroys the condition variable and frees any associated resources. No threads should be waiting on the condition variable when this is called.
Referenced by acip_webrtc_transport_create(), discover_session_parallel(), and tcp_client_destroy().
| int cond_init | ( | cond_t * | cond | ) |
#include <cond.h>
Initialize a condition variable.
| cond | Pointer to condition variable to initialize |
Initializes the condition variable for use. Must be called before any other condition variable operations.
Referenced by acip_webrtc_transport_create(), discover_session_parallel(), and tcp_client_create().
| int cond_signal | ( | cond_t * | cond | ) |
#include <cond.h>
Signal a condition variable (wake one waiting thread)
| cond | Pointer to condition variable to signal |
Wakes up one thread that is waiting on the condition variable. If no threads are waiting, the signal is lost.
Referenced by __attribute__().
#include <cond.h>
Wait on a condition variable with timeout.
| cond | Pointer to condition variable to wait on |
| mutex | Pointer to mutex that must be locked by the calling thread |
| timeout_ms | Timeout in milliseconds |
Atomically unlocks the mutex and waits on the condition variable with a timeout. Returns non-zero if the timeout expires before the condition is signaled.
Referenced by discover_session_parallel().
#include <cond.h>
Wait on a condition variable (blocking)
| cond | Pointer to condition variable to wait on |
| mutex | Pointer to mutex that must be locked by the calling thread |
Atomically unlocks the mutex and waits on the condition variable. The mutex must be locked by the calling thread before calling this function. Upon return, the mutex will be locked again.
| int debug_mutex_lock | ( | mutex_t * | mutex, |
| const char * | file_name, | ||
| int | line_number, | ||
| const char * | function_name | ||
| ) |
#include <mutex.h>
| int debug_mutex_trylock | ( | mutex_t * | mutex, |
| const char * | file_name, | ||
| int | line_number, | ||
| const char * | function_name | ||
| ) |
#include <mutex.h>
| int debug_mutex_unlock | ( | mutex_t * | mutex, |
| const char * | file_name, | ||
| int | line_number, | ||
| const char * | function_name | ||
| ) |
#include <mutex.h>
| int debug_rwlock_rdlock | ( | rwlock_t * | rwlock, |
| const char * | file_name, | ||
| int | line_number, | ||
| const char * | function_name | ||
| ) |
#include <rwlock.h>
| int debug_rwlock_rdunlock | ( | rwlock_t * | rwlock, |
| const char * | file_name, | ||
| int | line_number, | ||
| const char * | function_name | ||
| ) |
#include <rwlock.h>
| int debug_rwlock_wrlock | ( | rwlock_t * | rwlock, |
| const char * | file_name, | ||
| int | line_number, | ||
| const char * | function_name | ||
| ) |
#include <rwlock.h>
| int debug_rwlock_wrunlock | ( | rwlock_t * | rwlock, |
| const char * | file_name, | ||
| int | line_number, | ||
| const char * | function_name | ||
| ) |
#include <rwlock.h>
| terminal_capabilities_t detect_terminal_capabilities | ( | void | ) |
#include <terminal.h>
Detect terminal capabilities.
Comprehensively detects terminal capabilities including:
Detection uses multiple methods:
Referenced by action_show_capabilities(), client_main(), log_redetect_terminal_capabilities(), main(), mirror_main(), tcp_client_send_terminal_capabilities(), and threaded_send_terminal_size_with_auto_detect().
| tty_info_t get_current_tty | ( | void | ) |
#include <terminal.h>
Get current TTY information.
Retrieves information about the current TTY (terminal). Returns file descriptor for TTY access, device path, and ownership information. Useful for advanced terminal operations that require direct TTY access.
| asciichat_error_t get_terminal_size | ( | unsigned short int * | width, |
| unsigned short int * | height | ||
| ) |
#include <terminal.h>
Get terminal size with multiple fallback methods.
| width | Pointer to store width in columns (must not be NULL) |
| height | Pointer to store height in rows (must not be NULL) |
Detects terminal size using multiple fallback methods for reliability:
Referenced by update_dimensions_for_full_height(), and update_dimensions_to_terminal_size().
| bool is_valid_tty_path | ( | const char * | path | ) |
#include <terminal.h>
Check if a TTY path is valid.
| path | Path to check (must not be NULL) |
Validates that a path points to a valid TTY (terminal) device. Checks device file existence and type on Unix systems.
| bool lock_debug_is_initialized | ( | void | ) |
#include <mutex.h>
Referenced by stats_logger_thread().
| int mutex_destroy | ( | mutex_t * | mutex | ) |
#include <mutex.h>
Destroy a mutex.
| mutex | Pointer to mutex to destroy |
Destroys the mutex and frees any associated resources. The mutex must not be locked when this is called.
Referenced by acip_webrtc_transport_create(), asciichat_instr_runtime_global_shutdown(), audio_destroy(), audio_init(), audio_ring_buffer_destroy(), buffer_pool_destroy(), discover_session_parallel(), framebuffer_create(), framebuffer_create_multi(), framebuffer_destroy(), log_destroy(), node_pool_destroy(), options_state_init(), options_state_shutdown(), server_connection_cleanup(), server_main(), session_create(), stats_cleanup(), tcp_client_create(), tcp_client_destroy(), tcp_server_shutdown(), thread_pool_destroy(), video_frame_buffer_destroy(), and webrtc_peer_manager_destroy().
| int mutex_init | ( | mutex_t * | mutex | ) |
#include <mutex.h>
Initialize a mutex.
| mutex | Pointer to mutex to initialize |
Initializes the mutex for use. Must be called before any other mutex operations.
Referenced by acip_webrtc_transport_create(), asciichat_instr_coverage_enabled(), asciichat_instr_runtime_get(), audio_init(), buffer_pool_create(), discover_session_parallel(), framebuffer_create(), framebuffer_create_multi(), log_init(), memory_backend_create(), node_pool_create(), options_state_init(), server_connection_init(), server_main(), session_create(), stats_init(), tcp_client_create(), tcp_server_init(), thread_pool_create(), video_frame_buffer_create(), and webrtc_peer_manager_create().
| int mutex_lock_impl | ( | mutex_t * | mutex | ) |
#include <mutex.h>
Lock a mutex (implementation function)
| mutex | Pointer to mutex to lock |
| int mutex_trylock_impl | ( | mutex_t * | mutex | ) |
#include <mutex.h>
Try to lock a mutex without blocking (implementation function)
| mutex | Pointer to mutex to try to lock |
Attempts to acquire the mutex lock without blocking. Returns immediately whether the lock was acquired or not.
| int mutex_unlock_impl | ( | mutex_t * | mutex | ) |
#include <mutex.h>
Unlock a mutex (implementation function)
| mutex | Pointer to mutex to unlock |
| int platform_access | ( | const char * | path, |
| int | mode | ||
| ) |
#include <system.h>
Check file/directory access permissions.
Platform-safe wrapper for access() / _access(). Tests whether the calling process has the requested access to the specified path.
Platform-specific implementations:
| path | File or directory path to check |
| mode | Access mode to test (PLATFORM_ACCESS_EXISTS, PLATFORM_ACCESS_WRITE, PLATFORM_ACCESS_READ) |
Referenced by get_log_dir().
| void * platform_aligned_alloc | ( | size_t | alignment, |
| size_t | size | ||
| ) |
#include <util.h>
Allocate aligned memory.
| alignment | Required alignment (must be power of 2) |
| size | Number of bytes to allocate |
Allocates memory with specified alignment. Should be freed with platform_aligned_free().
| void platform_aligned_free | ( | void * | ptr | ) |
#include <util.h>
Free aligned memory.
| ptr | Pointer returned from platform_aligned_alloc() |
Frees memory previously allocated with platform_aligned_alloc().
| int platform_backtrace | ( | void ** | buffer, |
| int | size | ||
| ) |
#include <system.h>
Get a backtrace of the current call stack.
| buffer | Array of pointers to store return addresses |
| size | Maximum number of frames to capture |
Captures the current call stack into the provided buffer. Returns the number of frames actually captured.
Referenced by asciichat_fatal_with_context().
| char ** platform_backtrace_symbols | ( | void *const * | buffer, |
| int | size | ||
| ) |
#include <system.h>
Convert backtrace addresses to symbol names.
| buffer | Array of return addresses from platform_backtrace() |
| size | Number of frames in buffer |
Converts the return addresses from platform_backtrace() into human-readable symbol names (function names, file names, line numbers).
Referenced by asciichat_fatal_with_context().
| void platform_backtrace_symbols_free | ( | char ** | strings | ) |
#include <system.h>
Free symbol array returned by platform_backtrace_symbols()
| strings | Array of symbol strings to free |
Frees the memory allocated by platform_backtrace_symbols().
Referenced by asciichat_clear_errno(), asciichat_errno_cleanup(), asciichat_fatal_with_context(), and asciichat_set_errno().
| int platform_chmod | ( | const char * | pathname, |
| int | mode | ||
| ) |
#include <util.h>
Change file permissions/mode.
| pathname | File path |
| mode | New file mode (permissions) |
Changes file permissions/mode. Cross-platform chmod replacement.
Referenced by add_known_host().
| void platform_cleanup | ( | void | ) |
#include <init.h>
Cleanup platform-specific subsystems.
Performs cleanup for platform-specific subsystems. Should be called during program shutdown.
Referenced by asciichat_shared_init().
| void platform_cleanup_binary_path_cache | ( | void | ) |
#include <system.h>
Cleanup the binary PATH cache.
Frees all cached binary PATH lookup results and destroys the cache. Should be called during program cleanup (e.g., in platform_cleanup()).
Definition at line 261 of file system.c.
References rwlock_destroy(), rwlock_wrlock, and rwlock_wrunlock.
Referenced by server_main().
| int platform_close | ( | int | fd | ) |
#include <util.h>
Safe file close (close replacement)
| fd | File descriptor to close |
Cross-platform file closing.
Referenced by asciichat_instr_runtime_destroy(), check_known_host(), check_known_host_no_identity(), display_cleanup(), log_destroy(), log_init(), and remove_known_host().
| FILE * platform_fdopen | ( | int | fd, |
| const char * | mode | ||
| ) |
#include <util.h>
Convert file descriptor to stream (fdopen replacement)
| fd | File descriptor |
| mode | Open mode string for the stream |
Associates a FILE stream with an existing file descriptor.
Referenced by check_known_host(), check_known_host_no_identity(), and remove_known_host().
| FILE * platform_fopen | ( | const char * | filename, |
| const char * | mode | ||
| ) |
#include <util.h>
Safe file open stream (fopen replacement)
| filename | File path to open |
| mode | Open mode string (e.g., "r", "w", "rb") |
Cross-platform file stream opening.
Referenced by add_known_host(), config_create_default(), parse_keys_from_file(), parse_public_key(), parse_ssh_private_key(), and validate_ssh_key_file().
| int platform_format_backtrace_symbols | ( | char * | buffer, |
| size_t | buffer_size, | ||
| const char * | label, | ||
| char ** | symbols, | ||
| int | count, | ||
| int | skip_frames, | ||
| int | max_frames, | ||
| backtrace_frame_filter_t | filter | ||
| ) |
#include <system.h>
Format pre-resolved backtrace symbols to a buffer.
Same format as platform_print_backtrace_symbols() but writes to a buffer.
| buffer | Output buffer |
| buffer_size | Size of output buffer |
| label | Header label (e.g., "Call stack") |
| symbols | Array of pre-resolved symbol strings |
| count | Number of symbols in the array |
| skip_frames | Number of frames to skip from the start |
| max_frames | Maximum frames to print (0 = unlimited) |
| filter | Optional filter callback to skip specific frames (NULL = no filtering) |
| int platform_fsync | ( | int | fd | ) |
#include <system.h>
Synchronize a file descriptor to disk.
| fd | File descriptor to sync |
Forces all buffered data for the file descriptor to be written to disk.
| bool platform_get_cwd | ( | char * | cwd, |
| size_t | path_size | ||
| ) |
#include <system.h>
Get the current working directory of the process.
Normalizes the result using platform-specific semantics and does not append a trailing directory separator.
| cwd | Buffer to store the current working directory |
| path_size | Size of the buffer in bytes |
Referenced by get_log_dir(), and path_validate_user_path().
| bool platform_get_executable_path | ( | char * | exe_path, |
| size_t | path_size | ||
| ) |
#include <system.h>
Get the path to the current executable.
Retrieves the full path to the currently running executable using platform-specific methods.
Platform-specific implementations:
| exe_path | Buffer to store the executable path |
| path_size | Size of the buffer |
| exe_path | Buffer to store the executable path |
| path_size | Size of the buffer |
Definition at line 351 of file system.c.
References errno, ERROR_BUFFER_OVERFLOW, ERROR_GENERAL, ERROR_INVALID_PARAM, ERROR_INVALID_STATE, SAFE_STRERROR, SET_ERRNO, and SET_ERRNO_SYS.
| int platform_get_last_error | ( | void | ) |
#include <util.h>
Get last platform error code.
Retrieves the last error that occurred. Equivalent to errno on POSIX.
| uint64_t platform_get_monotonic_time_us | ( | void | ) |
#include <system.h>
Get monotonic time in microseconds.
Returns a monotonically increasing time value in microseconds. Useful for measuring elapsed time without being affected by system clock changes. Thread-safe and lock-free.
Platform-specific implementations:
| int platform_get_pid | ( | void | ) |
#include <system.h>
Get the current process ID.
Referenced by asciichat_instr_runtime_get().
| bool platform_get_temp_dir | ( | char * | temp_dir, |
| size_t | path_size | ||
| ) |
#include <system.h>
Get the system temporary directory path.
Retrieves the path to the system's temporary directory using platform-specific methods. Verifies the directory exists and is writable.
Platform-specific implementations:
| temp_dir | Buffer to store the temporary directory path |
| path_size | Size of the buffer |
Referenced by get_log_dir(), and path_validate_user_path().
| const char * platform_get_username | ( | void | ) |
#include <system.h>
Get the current username.
Returns the username of the current user.
Referenced by server_connection_establish().
| const char * platform_getenv | ( | const char * | name | ) |
#include <system.h>
Get an environment variable value.
| name | Environment variable name |
Returns the value of the specified environment variable.
Referenced by client_audio_pipeline_process_duplex(), client_crypto_handshake(), crypto_handshake_client_key_exchange(), ed25519_verify_signature(), expand_path(), get_config_dir(), parse_ssh_private_key(), path_validate_user_path(), and prompt_unknown_host().
| asciichat_error_t platform_gtime | ( | const time_t * | timer, |
| struct tm * | result | ||
| ) |
#include <system.h>
Platform-safe gmtime wrapper.
Uses gmtime_s on Windows and gmtime_r on POSIX. Thread-safe on all platforms.
| timer | Pointer to time_t value |
| result | Pointer to struct tm to receive result |
Referenced by asciichat_instr_log_line().
| asciichat_error_t platform_init | ( | void | ) |
#include <init.h>
Initialize platform-specific subsystems.
Initializes platform-specific subsystems such as Winsock on Windows. Must be called before using any platform-specific functions.
Referenced by asciichat_shared_init().
| void platform_install_crash_handler | ( | void | ) |
#include <system.h>
Install crash handlers for the application.
Installs signal handlers for common crash signals (SIGSEGV, SIGABRT, etc.) that will print a backtrace before terminating the process.
| bool platform_is_binary_in_path | ( | const char * | bin_name | ) |
#include <system.h>
Check if a binary is available in the system PATH.
This function checks if the specified binary can be found in the PATH by searching each directory in the PATH environment variable. Results are cached to avoid repeated filesystem checks.
On Windows: Automatically appends .exe if needed, checks with GetFileAttributesA On Unix: Uses access() with X_OK to verify executable permission
| bin_name | Base name of the binary (e.g., "ssh-keygen", "llvm-symbolizer") On Windows, .exe extension is added automatically if not present |
Definition at line 288 of file system.c.
References bin_cache_entry_t::bin_name, ERROR_INVALID_STATE, ERROR_MEMORY, bin_cache_entry_t::in_path, LOG_COLOR_ERROR, LOG_COLOR_INFO, LOG_COLOR_RESET, LOG_COLOR_WARN, log_debug, log_get_color_array(), platform_strdup(), rwlock_rdlock, rwlock_rdunlock, rwlock_wrlock, rwlock_wrunlock, SAFE_FREE, SAFE_MALLOC, and SET_ERRNO.
| int platform_is_directory | ( | const char * | path | ) |
#include <fs.h>
Check if a path is a directory.
Convenience function that checks if a path points to a directory. Does not follow symbolic links.
| path | Path to check |
| bool platform_is_interactive | ( | void | ) |
#include <question.h>
Check if interactive prompting is available.
Use this to check before calling prompt functions in contexts where non-interactive operation is acceptable (e.g., scripted usage).
Referenced by client_crypto_handshake(), prompt_password(), and prompt_password_simple().
| int platform_is_regular_file | ( | const char * | path | ) |
#include <fs.h>
Check if a path is a regular file.
Convenience function that checks if a path points to a regular file. Does not follow symbolic links.
| path | File path to check |
| int platform_isatty | ( | int | fd | ) |
#include <system.h>
Check if a file descriptor is a terminal.
| fd | File descriptor to check |
Referenced by display_init(), main(), prompt_unknown_host(), and prompt_unknown_host_no_identity().
| asciichat_error_t platform_load_system_ca_certs | ( | char ** | pem_data_out, |
| size_t * | pem_size_out | ||
| ) |
#include <system.h>
Load system CA certificates for TLS/HTTPS.
Loads the operating system's trusted root CA certificates in PEM format. This allows TLS connections to trust the same CAs that the OS trusts.
Platform-specific paths:
| pem_data_out | Pointer to receive allocated PEM data (caller must free) |
| pem_size_out | Pointer to receive size of PEM data |
Referenced by https_get().
| asciichat_error_t platform_localtime | ( | const time_t * | timer, |
| struct tm * | result | ||
| ) |
#include <system.h>
Platform-safe localtime wrapper.
Uses localtime_s on Windows and localtime_r on POSIX. Thread-safe on all platforms.
| timer | Pointer to time_t value |
| result | Pointer to struct tm to receive result |
Referenced by asciichat_error_stats_print(), asciichat_print_error_context(), and get_current_time_formatted().
| size_t platform_malloc_size | ( | const void * | ptr | ) |
#include <memory.h>
Get the size of an allocated memory block.
Returns the size in bytes of the memory block pointed to by ptr. The block must have been allocated with malloc(), calloc(), or realloc().
Platform-specific implementations:
| ptr | Pointer to allocated memory block |
| asciichat_error_t platform_memcpy | ( | void * | dest, |
| size_t | dest_size, | ||
| const void * | src, | ||
| size_t | count | ||
| ) |
#include <system.h>
Platform-safe memcpy wrapper.
Uses memcpy_s on Windows when available (C11) and memcpy with bounds checking on POSIX. Provides consistent interface across platforms.
| dest | Destination buffer |
| dest_size | Size of destination buffer |
| src | Source buffer |
| count | Number of bytes to copy |
| asciichat_error_t platform_memmove | ( | void * | dest, |
| size_t | dest_size, | ||
| const void * | src, | ||
| size_t | count | ||
| ) |
#include <system.h>
Platform-safe memmove wrapper.
Uses memmove_s on Windows when available (C11) and memmove with bounds checking on POSIX. Handles overlapping memory regions safely.
| dest | Destination buffer |
| dest_size | Size of destination buffer |
| src | Source buffer |
| count | Number of bytes to move |
| void platform_memory_barrier | ( | void | ) |
#include <util.h>
Perform memory barrier/fence operation.
Ensures all memory operations before this call are visible to other threads before operations after this call. Platform-specific implementation using atomic operations or memory barriers.
| asciichat_error_t platform_memset | ( | void * | dest, |
| size_t | dest_size, | ||
| int | ch, | ||
| size_t | count | ||
| ) |
#include <system.h>
Platform-safe memset wrapper.
Uses memset_s on Windows when available (C11) and memset with bounds checking on POSIX. Provides consistent interface across platforms.
| dest | Destination buffer |
| dest_size | Size of destination buffer |
| ch | Value to set (cast to unsigned char) |
| count | Number of bytes to set |
| asciichat_error_t platform_mkdir | ( | const char * | path, |
| int | mode | ||
| ) |
#include <fs.h>
Create a directory.
Creates a directory with the specified permissions. If the directory already exists, this is not an error.
Platform-specific implementations:
| path | Directory path to create |
| mode | File permissions (0700 for owner rwx only, ignored on Windows) |
Referenced by get_log_dir().
| void platform_mmap_close | ( | platform_mmap_t * | mapping | ) |
#include <mmap.h>
Unmap and close a memory-mapped file.
Unmaps the memory region and closes the underlying file handle. Safe to call on an already-closed or uninitialized mapping.
| mapping | Mapping handle to close |
Referenced by log_mmap_destroy().
| void platform_mmap_init | ( | platform_mmap_t * | mapping | ) |
#include <mmap.h>
Initialize a platform_mmap_t structure.
Sets all fields to safe initial values. Call before first use.
| mapping | Pointer to mapping structure to initialize |
Referenced by log_mmap_init().
| bool platform_mmap_is_valid | ( | const platform_mmap_t * | mapping | ) |
#include <mmap.h>
Check if a mapping is currently valid.
| mapping | Mapping handle to check |
| asciichat_error_t platform_mmap_open | ( | const char * | path, |
| size_t | size, | ||
| platform_mmap_t * | out | ||
| ) |
#include <mmap.h>
Memory-map a file for read/write access.
Opens or creates a file and maps it into memory. The file is created if it doesn't exist, and resized to the specified size.
The mapping uses shared mode (MAP_SHARED on POSIX, FILE_MAP_ALL_ACCESS on Windows) so changes are visible to other processes and persist to the file.
| path | File path to map (created if doesn't exist) | |
| size | Desired mapping size in bytes | |
| [out] | out | Output mapping handle (must be initialized with platform_mmap_init) |
Example:
Referenced by log_mmap_init().
| void platform_mmap_sync | ( | platform_mmap_t * | mapping, |
| bool | async | ||
| ) |
#include <mmap.h>
Flush memory-mapped changes to disk.
Requests the kernel to flush any modified pages to the underlying file. This is typically not needed as the kernel flushes automatically, but can be used to ensure data persistence at specific points.
| mapping | Mapping handle to sync |
| async | If true, return immediately (async flush). If false, block until flush completes (sync flush). |
Referenced by log_mmap_destroy(), log_mmap_rotate(), log_mmap_sync(), and log_mmap_write().
| int platform_open | ( | const char * | pathname, |
| int | flags, | ||
| ... | |||
| ) |
#include <util.h>
Safe file open (open replacement)
| pathname | File path to open |
| flags | Open flags (O_RDONLY, O_WRONLY, O_RDWR, etc.) |
| ... | Variable arguments (mode for O_CREAT) |
Cross-platform file opening with consistent behavior. Use PLATFORM_O_* flags for portability.
Referenced by acds_identity_save(), audio_init(), check_known_host(), check_known_host_no_identity(), gpg_sign_with_key(), log_init(), remove_known_host(), and test_logging_disable().
| asciichat_error_t platform_pclose | ( | FILE ** | stream_ptr | ) |
#include <process.h>
Close a process stream opened with platform_popen()
Closes the stream and waits for the process to terminate. Returns the process exit status.
Platform-specific implementations:
| stream_ptr | Pointer to FILE* stream to close |
| int platform_pipe_close | ( | pipe_t | pipe | ) |
#include <pipe.h>
Close a pipe connection.
| pipe | Pipe handle to close |
Closes the pipe connection using the appropriate platform-specific function:
Referenced by ssh_agent_add_key(), ssh_agent_has_key(), ssh_agent_is_available(), and ssh_agent_sign().
| pipe_t platform_pipe_connect | ( | const char * | path | ) |
#include <pipe.h>
Connect to an agent via named pipe (Windows) or Unix socket (POSIX)
| path | Path to agent (named pipe path on Windows, socket path on POSIX) |
Connects to an agent using the appropriate platform-specific mechanism:
#include <pipe.h>
Check if a pipe handle is valid.
| pipe | Pipe handle to check |
| ssize_t platform_pipe_read | ( | pipe_t | pipe, |
| void * | buf, | ||
| size_t | len | ||
| ) |
#include <pipe.h>
Read data from a pipe.
| pipe | Pipe handle to read from |
| buf | Buffer to store read data |
| len | Maximum number of bytes to read |
Reads data from the pipe using the appropriate platform-specific function:
Referenced by gpg_get_public_key(), ssh_agent_add_key(), ssh_agent_has_key(), and ssh_agent_sign().
| ssize_t platform_pipe_write | ( | pipe_t | pipe, |
| const void * | buf, | ||
| size_t | len | ||
| ) |
#include <pipe.h>
Write data to a pipe.
| pipe | Pipe handle to write to |
| buf | Data buffer to write |
| len | Number of bytes to write |
Writes data to the pipe using the appropriate platform-specific function:
Referenced by gpg_get_public_key(), ssh_agent_add_key(), ssh_agent_has_key(), and ssh_agent_sign().
| asciichat_error_t platform_popen | ( | const char * | command, |
| const char * | mode, | ||
| FILE ** | out_stream | ||
| ) |
#include <process.h>
Execute a command and return a file stream for reading/writing.
Opens a process for communication, similar to POSIX popen(). Creates a unidirectional pipe to read from or write to the process.
Platform-specific implementations:
| command | Command line to execute (e.g., "ssh-keygen -l -f file.pub") |
| mode | File stream mode: "r" for reading, "w" for writing |
| out_stream | Pointer to receive the FILE* stream |
| void platform_print_backtrace | ( | int | skip_frames | ) |
#include <system.h>
Print a backtrace of the current call stack.
| skip_frames | Number of frames to skip from the top |
Captures a backtrace and prints it using platform_print_backtrace_symbols(). Useful for debugging crashes or errors.
| void platform_print_backtrace_symbols | ( | const char * | label, |
| char ** | symbols, | ||
| int | count, | ||
| int | skip_frames, | ||
| int | max_frames, | ||
| backtrace_frame_filter_t | filter | ||
| ) |
#include <system.h>
Print pre-resolved backtrace symbols with consistent formatting.
Uses colored format for all backtraces: [0] crypto_handshake_server_complete() (lib/crypto/handshake.c:1471) [1] server_crypto_handshake() (src/server/crypto.c:511)
| label | Header label (e.g., "Backtrace", "Call stack") |
| symbols | Array of pre-resolved symbol strings |
| count | Number of symbols in the array |
| skip_frames | Number of frames to skip from the start |
| max_frames | Maximum frames to print (0 = unlimited) |
| filter | Optional filter callback to skip specific frames (NULL = no filtering) |
Referenced by asciichat_fatal_with_context(), and asciichat_print_error_context().
| int platform_prompt_question | ( | const char * | prompt, |
| char * | buffer, | ||
| size_t | max_len, | ||
| prompt_opts_t | opts | ||
| ) |
#include <question.h>
Prompt the user for text input.
| prompt | The prompt message to display |
| buffer | Buffer to store the entered text |
| max_len | Maximum length of the buffer (including null terminator) |
| opts | Prompt options (use PROMPT_OPTS_DEFAULT, PROMPT_OPTS_PASSWORD, etc.) |
Displays a prompt and reads user input. The prompt format depends on opts:
When echo=false, input is hidden and optionally masked with mask_char.
Referenced by prompt_password(), and prompt_password_simple().
#include <question.h>
Prompt the user for a yes/no answer.
| prompt | The question to ask (without the yes/no suffix) |
| default_yes | If true, default is Yes (Y/n); if false, default is No (y/N) |
Displays a yes/no prompt with the default shown in uppercase:
Accepts: "yes", "y", "Y" for yes; "no", "n", "N" for no. Empty input (just Enter) returns the default value.
Referenced by client_crypto_handshake(), config_create_default(), prompt_unknown_host(), prompt_unknown_host_no_identity(), and server_main().
| ssize_t platform_read | ( | int | fd, |
| void * | buf, | ||
| size_t | count | ||
| ) |
#include <util.h>
Safe file read (read replacement)
| fd | File descriptor |
| buf | Buffer to read into |
| count | Number of bytes to read |
Cross-platform file reading.
| asciichat_error_t platform_resolve_hostname_to_ipv4 | ( | const char * | hostname, |
| char * | ipv4_out, | ||
| size_t | ipv4_out_size | ||
| ) |
#include <system.h>
Resolve hostname to IPv4 address.
Performs DNS resolution to convert a hostname to an IPv4 address string. Handles platform-specific networking initialization and cleanup.
| hostname | Hostname to resolve (e.g., "example.com") |
| ipv4_out | Buffer to store the resolved IPv4 address (e.g., "192.168.1.1") |
| ipv4_out_size | Size of the output buffer |
Referenced by validate_opt_ip_address().
| bool platform_set_console_ctrl_handler | ( | console_ctrl_handler_t | handler | ) |
#include <system.h>
Register a console control handler (for Ctrl+C, etc.)
| handler | Handler function to register, or NULL to unregister |
This provides cross-platform handling for console control events like Ctrl+C.
Unlike platform_signal() which uses CRT signal() on Windows (known issues), this function uses the native Windows API for reliable Ctrl+C handling.
Referenced by client_main(), and mirror_main().
| void platform_set_last_error | ( | int | error | ) |
#include <util.h>
Set platform error code.
| error | Error code to set |
Sets the current error code. Equivalent to errno on POSIX.
| int platform_setenv | ( | const char * | name, |
| const char * | value | ||
| ) |
#include <system.h>
Set an environment variable.
| name | Environment variable name |
| value | Environment variable value (or NULL to unset) |
Sets or unsets an environment variable.
Referenced by __attribute__().
| signal_handler_t platform_signal | ( | int | sig, |
| signal_handler_t | handler | ||
| ) |
#include <system.h>
Set a signal handler.
| sig | Signal number (e.g., SIGINT, SIGTERM) |
| handler | Signal handler function (or SIG_DFL, SIG_IGN) |
Registers a signal handler for the specified signal.
Referenced by client_main(), mirror_main(), and server_main().
| void platform_sleep_ms | ( | unsigned int | ms | ) |
#include <system.h>
Sleep for a specified number of milliseconds.
| ms | Number of milliseconds to sleep |
Sleeps the current thread for the specified duration.
Referenced by __attribute__(), acds_server_shutdown(), disconnect_client_for_bad_data(), and discovery_tui_select().
| void platform_sleep_usec | ( | unsigned int | usec | ) |
#include <abstraction.h>
High-precision sleep function with microsecond precision.
| usec | Number of microseconds to sleep |
Sleeps the current thread for the specified number of microseconds with high precision. Supports early wakeup via shutdown signaling.
Referenced by __attribute__(), adaptive_sleep_do(), audio_cleanup(), audio_stop_thread(), capture_stop_thread(), client_audio_render_thread(), client_main(), client_send_thread_func(), client_video_render_thread(), keepalive_stop_thread(), mirror_main(), protocol_stop_connection(), server_connection_establish(), stats_logger_thread(), and tcp_client_connect().
| int platform_snprintf | ( | char * | str, |
| size_t | size, | ||
| const char * | format, | ||
| ... | |||
| ) |
#include <util.h>
Safe string formatting (snprintf replacement)
| str | Destination buffer |
| size | Size of destination buffer |
| format | Printf-style format string |
| ... | Variable arguments for format string |
Cross-platform wrapper around snprintf that behaves consistently on Windows and POSIX systems.
| asciichat_error_t platform_stat | ( | const char * | path, |
| platform_stat_t * | stat_out | ||
| ) |
#include <fs.h>
Get file statistics.
Retrieves metadata about a file without following symbolic links.
Platform-specific implementations:
| path | File path to stat |
| stat_out | Pointer to platform_stat_t to receive results |
| int platform_strcasecmp | ( | const char * | s1, |
| const char * | s2 | ||
| ) |
#include <util.h>
Case-insensitive string comparison.
| s1 | First string |
| s2 | Second string |
Compares two strings case-insensitively.
Referenced by options_init(), validate_opt_log_level(), and validate_opt_reconnect().
| char * platform_strcat | ( | char * | dest, |
| size_t | dest_size, | ||
| const char * | src | ||
| ) |
#include <string.h>
Safe version of strcat with buffer size protection.
| dest | Destination buffer (must not be NULL) |
| dest_size | Size of destination buffer (must be > 0) |
| src | Source string to append (must not be NULL) |
Safely appends a source string to a destination buffer with buffer size protection. Prevents buffer overflow by validating available space before concatenation.
SAFETY FEATURES:
| asciichat_error_t platform_strcpy | ( | char * | dest, |
| size_t | dest_size, | ||
| const char * | src | ||
| ) |
#include <system.h>
Platform-safe strcpy wrapper.
Uses strcpy_s on Windows when available (C11) and strncpy with bounds checking on POSIX. Always null-terminates the destination string.
| dest | Destination buffer |
| dest_size | Size of destination buffer |
| src | Source string |
| char * platform_strdup | ( | const char * | s | ) |
#include <util.h>
Duplicate string (strdup replacement)
| s | String to duplicate |
Cross-platform string duplication. Allocated memory should be freed with free().
Referenced by config_create_default(), config_load_and_apply(), expand_path(), parse_ssh_private_key(), platform_is_binary_in_path(), remove_known_host(), symbol_cache_insert(), and symbol_cache_resolve_batch().
| const char * platform_strerror | ( | int | errnum | ) |
#include <util.h>
Get thread-safe error string.
| errnum | Error number (errno or GetLastError on Windows) |
Returns string description of error code. Thread-safe.
| size_t platform_strlcat | ( | char * | dst, |
| const char * | src, | ||
| size_t | size | ||
| ) |
#include <util.h>
Safe string concatenation with size tracking (strlcat)
| dst | Destination buffer (must be null-terminated) |
| src | Source string |
| size | Size of destination buffer |
Safely appends source to destination, truncating if necessary. Always null-terminates destination (if size > 0).
| size_t platform_strlcpy | ( | char * | dst, |
| const char * | src, | ||
| size_t | size | ||
| ) |
#include <util.h>
Safe string copy with size tracking (strlcpy)
| dst | Destination buffer |
| src | Source string |
| size | Size of destination buffer |
Safely copies string to destination, truncating if necessary. Always null-terminates destination (if size > 0).
| int platform_strncasecmp | ( | const char * | s1, |
| const char * | s2, | ||
| size_t | n | ||
| ) |
#include <util.h>
Case-insensitive string comparison with length limit.
| s1 | First string |
| s2 | Second string |
| n | Maximum number of characters to compare |
Compares up to n characters of two strings case-insensitively.
| int platform_strncpy | ( | char * | dst, |
| size_t | dst_size, | ||
| const char * | src, | ||
| size_t | count | ||
| ) |
#include <util.h>
Safe string copy with explicit size bounds (strncpy replacement)
| dst | Destination buffer |
| dst_size | Size of destination buffer |
| src | Source string |
| count | Maximum number of characters to copy |
Safely copies string with explicit destination size and character count limits. Always null-terminates destination on success.
Referenced by parse_private_key(), and parse_public_key().
| char * platform_strndup | ( | const char * | s, |
| size_t | n | ||
| ) |
#include <util.h>
Duplicate string with length limit (strndup replacement)
| s | String to duplicate |
| n | Maximum number of characters to copy |
Duplicates up to n characters from string. Allocated memory should be freed with free().
| char * platform_strtok_r | ( | char * | str, |
| const char * | delim, | ||
| char ** | saveptr | ||
| ) |
#include <util.h>
Thread-safe string tokenization (strtok_r replacement)
| str | String to tokenize (or NULL to continue tokenizing) |
| delim | Delimiter characters |
| saveptr | Pointer to save tokenization state |
Thread-safe version of strtok. State is maintained in saveptr between calls.
| const char * platform_ttyname | ( | int | fd | ) |
#include <system.h>
Get the name of the terminal associated with a file descriptor.
| fd | File descriptor |
Returns the name of the terminal device associated with the file descriptor.
| int platform_unlink | ( | const char * | pathname | ) |
#include <util.h>
Delete/unlink file.
| pathname | File path to delete |
Deletes a file. Cross-platform unlink replacement.
| int platform_vsnprintf | ( | char * | str, |
| size_t | size, | ||
| const char * | format, | ||
| va_list | ap | ||
| ) |
#include <util.h>
Safe variable-argument string formatting.
| str | Destination buffer |
| size | Size of destination buffer |
| format | Printf-style format string |
| ap | Variable argument list |
Variable-argument version of platform_snprintf.
| ssize_t platform_write | ( | int | fd, |
| const void * | buf, | ||
| size_t | count | ||
| ) |
#include <abstraction.h>
Platform-safe write function.
Safe file write (write replacement)
| fd | File descriptor to write to |
| buf | Buffer containing data to write |
| count | Number of bytes to write |
Cross-platform write function that handles Windows-specific quirks (e.g., CRLF line endings) and provides consistent behavior across platforms.
| fd | File descriptor |
| buf | Buffer to write from |
| count | Number of bytes to write |
Cross-platform file writing.
| void print_terminal_capabilities | ( | const terminal_capabilities_t * | caps | ) |
#include <terminal.h>
Print terminal capabilities to stdout.
| caps | Terminal capabilities structure (must not be NULL) |
Prints a detailed report of terminal capabilities to stdout including:
Referenced by client_main(), and main().
| int rwlock_destroy | ( | rwlock_t * | lock | ) |
#include <rwlock.h>
Destroy a read-write lock.
| lock | Pointer to read-write lock to destroy |
Destroys the read-write lock and frees any associated resources. The lock must not be held by any thread when this is called.
Referenced by mixer_create(), mixer_destroy(), platform_cleanup_binary_path_cache(), server_main(), symbol_cache_cleanup(), and timer_system_cleanup().
| int rwlock_destroy_impl | ( | rwlock_t * | lock | ) |
#include <rwlock.h>
Destroy a read-write lock (implementation function)
| lock | Pointer to read-write lock to destroy |
| int rwlock_init | ( | rwlock_t * | lock | ) |
#include <rwlock.h>
Initialize a read-write lock.
| lock | Pointer to read-write lock to initialize |
Initializes the read-write lock for use. Must be called before any other lock operations.
Referenced by mixer_create(), server_main(), symbol_cache_init(), and timer_system_init().
| int rwlock_init_impl | ( | rwlock_t * | lock | ) |
#include <rwlock.h>
Initialize a read-write lock (implementation function)
| lock | Pointer to read-write lock to initialize |
| int rwlock_rdlock_impl | ( | rwlock_t * | lock | ) |
#include <rwlock.h>
Acquire a read lock (implementation function)
| lock | Pointer to read-write lock |
Acquires a shared read lock. Multiple threads can hold read locks simultaneously. Blocks if a write lock is held.
| int rwlock_rdunlock_impl | ( | rwlock_t * | lock | ) |
#include <rwlock.h>
Release a read lock (implementation function)
| lock | Pointer to read-write lock |
Releases a shared read lock held by the calling thread.
| int rwlock_wrlock_impl | ( | rwlock_t * | lock | ) |
#include <rwlock.h>
Acquire a write lock (implementation function)
| lock | Pointer to read-write lock |
Acquires an exclusive write lock. Only one thread can hold a write lock, and it excludes all read locks. Blocks if any locks are held.
| int rwlock_wrunlock_impl | ( | rwlock_t * | lock | ) |
#include <rwlock.h>
Release a write lock (implementation function)
| lock | Pointer to read-write lock |
Releases an exclusive write lock held by the calling thread.
| int safe_fprintf | ( | FILE * | stream, |
| const char * | format, | ||
| ... | |||
| ) |
#include <string.h>
Safe version of fprintf.
Platform-safe fprintf wrapper.
| stream | File stream to write to (must not be NULL) |
| format | Format string (must not be NULL) |
| ... | Variable arguments for format string |
Formats and writes to a file stream with error checking. Validates that formatting operations succeed and returns meaningful error codes.
SAFETY FEATURES:
Uses fprintf_s on Windows and fprintf on POSIX.
| stream | File stream |
| format | Format string |
| ... | Variable arguments |
Referenced by add_known_host(), asciichat_fatal_with_context(), asciichat_print_error_context(), log_init(), log_labeled(), log_msg(), log_plain_msg(), and webcam_print_init_error_help().
| int safe_snprintf | ( | char * | buffer, |
| size_t | buffer_size, | ||
| const char * | format, | ||
| ... | |||
| ) |
#include <string.h>
Safe version of snprintf that ensures null termination.
Platform-safe snprintf wrapper.
| buffer | Buffer to write to (must not be NULL) |
| buffer_size | Size of the buffer (must be > 0) |
| format | Format string (must not be NULL) |
| ... | Variable arguments for format string |
Formats a string into a buffer with guaranteed null termination. Always ensures the buffer is null-terminated even if truncation occurs, unlike the standard snprintf() which may not null-terminate on some platforms.
SAFETY FEATURES:
Uses snprintf_s on Windows and snprintf with additional safety on POSIX. Always null-terminates the output buffer.
| buffer | Output buffer |
| buffer_size | Size of output buffer |
| format | Format string |
| ... | Variable arguments |
Referenced by build_github_gpg_url(), build_github_ssh_url(), build_gitlab_gpg_url(), build_gitlab_ssh_url(), check_gpg_key_expiry(), check_known_host(), check_known_host_no_identity(), config_create_default(), config_load_and_apply(), crypto_handshake_client_key_exchange(), crypto_handshake_server_auth_challenge(), crypto_handshake_server_start(), display_mitm_warning(), expand_path(), format_bytes_pretty(), format_gpg_key_display(), format_public_key(), get_config_dir(), get_known_hosts_path(), get_log_dir(), gpg_agent_sign(), gpg_get_public_key(), gpg_sign_detached_ed25519(), gpg_sign_with_key(), gpg_verify_signature_with_binary(), https_get(), options_init(), parse_gpg_key(), parse_private_key(), parse_ssh_private_key(), path_validate_user_path(), prompt_unknown_host(), prompt_unknown_host_no_identity(), remove_known_host(), stats_logger_thread(), and test_get_binary_path().
| int safe_sscanf | ( | const char * | str, |
| const char * | format, | ||
| ... | |||
| ) |
#include <string.h>
Safe version of sscanf with validation.
| str | String to parse (must not be NULL) |
| format | Format string (must not be NULL) |
| ... | Variable arguments for parsed values (must not be NULL) |
Safely parses a string using a format specification with input validation. Returns the number of successfully parsed items and validates input parameters.
SAFETY FEATURES:
#include <socket.h>
Accept an incoming connection.
| sock | Listening socket |
| addr | Pointer to store peer address (or NULL) |
| addrlen | Pointer to address length (input/output) |
Referenced by accept_with_timeout().
| int socket_bind | ( | socket_t | sock, |
| const struct sockaddr * | addr, | ||
| socklen_t | addrlen | ||
| ) |
#include <socket.h>
Bind a socket to an address.
| sock | Socket to bind |
| addr | Address to bind to |
| addrlen | Length of address structure |
| void socket_cleanup | ( | void | ) |
#include <socket.h>
Cleanup socket subsystem.
Cleans up the socket subsystem. On Windows, this cleans up Winsock. Should be called during program shutdown.
Referenced by server_main().
| int socket_close | ( | socket_t | sock | ) |
#include <socket.h>
Close a socket.
| sock | Socket to close |
Referenced by acds_client_connect(), acds_client_disconnect(), acds_client_handler(), disconnect_client_for_bad_data(), https_get(), server_main(), tcp_server_reject_client(), tcp_server_run(), and tcp_server_shutdown().
| int socket_connect | ( | socket_t | sock, |
| const struct sockaddr * | addr, | ||
| socklen_t | addrlen | ||
| ) |
#include <socket.h>
Connect to a remote address.
| sock | Socket to connect |
| addr | Remote address to connect to |
| addrlen | Length of address structure |
| socket_t socket_create | ( | int | domain, |
| int | type, | ||
| int | protocol | ||
| ) |
#include <socket.h>
Create a new socket.
| domain | Socket domain (e.g., AF_INET, AF_INET6, AF_UNIX) |
| type | Socket type (e.g., SOCK_STREAM, SOCK_DGRAM) |
| protocol | Protocol (typically 0 for automatic) |
Referenced by server_connection_establish(), and tcp_client_connect().
| int socket_fd_isset | ( | socket_t | sock, |
| fd_set * | set | ||
| ) |
#include <socket.h>
Check if a socket is in an fd_set.
| sock | Socket to check |
| set | fd_set to check in |
Referenced by accept_with_timeout(), connect_with_timeout(), recv_with_timeout(), send_with_timeout(), and tcp_server_run().
| void socket_fd_set | ( | socket_t | sock, |
| fd_set * | set | ||
| ) |
#include <socket.h>
Add a socket to an fd_set.
| sock | Socket to add |
| set | fd_set to add to |
Referenced by accept_with_timeout(), connect_with_timeout(), recv_with_timeout(), send_with_timeout(), and tcp_server_run().
| void socket_fd_zero | ( | fd_set * | set | ) |
#include <socket.h>
Clear an fd_set.
| set | fd_set to clear |
Referenced by accept_with_timeout(), connect_with_timeout(), recv_with_timeout(), send_with_timeout(), and tcp_server_run().
| int socket_get_error | ( | socket_t | sock | ) |
#include <socket.h>
Get socket-specific error code.
| sock | Socket to query |
Referenced by server_connection_establish().
| const char * socket_get_error_string | ( | void | ) |
#include <socket.h>
Get last socket error as string.
Referenced by acds_client_connect(), network_error_string(), and tcp_server_run().
| int socket_get_fd | ( | socket_t | sock | ) |
#include <socket.h>
Get the underlying file descriptor (POSIX compatibility)
| sock | Socket handle |
| int socket_get_last_error | ( | void | ) |
#include <socket.h>
Get last socket error code.
Referenced by tcp_server_run().
| int socket_get_peer_address | ( | socket_t | sock, |
| struct sockaddr * | addr, | ||
| socklen_t * | addrlen | ||
| ) |
#include <socket.h>
Get peer address (convenience function)
| sock | Connected socket |
| addr | Pointer to store peer address |
| addrlen | Pointer to address length (input/output) |
| int socket_getpeername | ( | socket_t | sock, |
| struct sockaddr * | addr, | ||
| socklen_t * | addrlen | ||
| ) |
#include <socket.h>
Get peer address.
| sock | Connected socket |
| addr | Pointer to store peer address |
| addrlen | Pointer to address length (input/output) |
| int socket_getsockname | ( | socket_t | sock, |
| struct sockaddr * | addr, | ||
| socklen_t * | addrlen | ||
| ) |
#include <socket.h>
Get socket local address.
| sock | Socket to query |
| addr | Pointer to store local address |
| addrlen | Pointer to address length (input/output) |
| int socket_getsockopt | ( | socket_t | sock, |
| int | level, | ||
| int | optname, | ||
| void * | optval, | ||
| socklen_t * | optlen | ||
| ) |
#include <socket.h>
Get socket option.
| sock | Socket to query |
| level | Option level (e.g., SOL_SOCKET, IPPROTO_TCP) |
| optname | Option name (e.g., SO_REUSEADDR, TCP_NODELAY) |
| optval | Pointer to store option value |
| optlen | Pointer to option length (input/output) |
Referenced by connect_with_timeout().
| asciichat_error_t socket_init | ( | void | ) |
#include <socket.h>
Initialize socket subsystem (required on Windows)
Initializes the socket subsystem. On Windows, this initializes Winsock. Must be called before any socket operations.
#include <socket.h>
Check if a socket handle is valid.
| sock | Socket handle to check |
Referenced by packet_send(), tcp_client_close(), tcp_client_connect(), tcp_client_destroy(), and tcp_client_shutdown().
| int socket_listen | ( | socket_t | sock, |
| int | backlog | ||
| ) |
#include <socket.h>
Listen for incoming connections.
| sock | Socket to listen on (must be bound) |
| backlog | Maximum length of the queue of pending connections |
| void socket_optimize_for_streaming | ( | socket_t | sock | ) |
#include <socket.c>
Optimize socket for high-throughput video streaming.
Consolidates socket configuration for real-time video streaming:
This common implementation applies to both POSIX and Windows platforms.
| sock | Socket to configure |
| sock | Socket to optimize |
Applies multiple socket optimizations for video streaming:
This function consolidates socket configuration that is needed for real-time video streaming. It gracefully handles buffer size negotiation by falling back to smaller sizes if the OS doesn't support large buffers.
Definition at line 36 of file socket.c.
References log_warn, and socket_setsockopt().
| int socket_poll | ( | struct pollfd * | fds, |
| nfds_t | nfds, | ||
| int | timeout | ||
| ) |
#include <socket.h>
Poll sockets for events.
| fds | Array of pollfd structures |
| nfds | Number of file descriptors to poll |
| timeout | Timeout in milliseconds (-1 for infinite) |
| ssize_t socket_recv | ( | socket_t | sock, |
| void * | buf, | ||
| size_t | len, | ||
| int | flags | ||
| ) |
#include <socket.h>
Receive data from a socket.
| sock | Socket to receive from |
| buf | Buffer to store received data |
| len | Maximum number of bytes to receive |
| flags | Socket flags (typically 0) |
| ssize_t socket_recvfrom | ( | socket_t | sock, |
| void * | buf, | ||
| size_t | len, | ||
| int | flags, | ||
| struct sockaddr * | src_addr, | ||
| socklen_t * | addrlen | ||
| ) |
#include <socket.h>
Receive data from a specific address (UDP)
| sock | Socket to receive from |
| buf | Buffer to store received data |
| len | Maximum number of bytes to receive |
| flags | Socket flags (typically 0) |
| src_addr | Pointer to store source address (or NULL) |
| addrlen | Pointer to address length (input/output) |
| int socket_select | ( | socket_t | max_fd, |
| fd_set * | readfds, | ||
| fd_set * | writefds, | ||
| fd_set * | exceptfds, | ||
| struct timeval * | timeout | ||
| ) |
#include <socket.h>
Select sockets for I/O readiness.
| max_fd | Highest file descriptor number (plus 1) |
| readfds | Set of sockets to check for read readiness (or NULL) |
| writefds | Set of sockets to check for write readiness (or NULL) |
| exceptfds | Set of sockets to check for exceptions (or NULL) |
| timeout | Timeout value (or NULL for infinite) |
Referenced by accept_with_timeout(), connect_with_timeout(), recv_with_timeout(), send_with_timeout(), and tcp_server_run().
| ssize_t socket_send | ( | socket_t | sock, |
| const void * | buf, | ||
| size_t | len, | ||
| int | flags | ||
| ) |
#include <socket.h>
Send data on a socket.
| sock | Socket to send on |
| buf | Data buffer to send |
| len | Number of bytes to send |
| flags | Socket flags (typically 0) |
| ssize_t socket_sendto | ( | socket_t | sock, |
| const void * | buf, | ||
| size_t | len, | ||
| int | flags, | ||
| const struct sockaddr * | dest_addr, | ||
| socklen_t | addrlen | ||
| ) |
#include <socket.h>
Send data to a specific address (UDP)
| sock | Socket to send on |
| buf | Data buffer to send |
| len | Number of bytes to send |
| flags | Socket flags (typically 0) |
| dest_addr | Destination address |
| addrlen | Length of destination address |
| int socket_set_blocking | ( | socket_t | sock | ) |
#include <socket.h>
Set socket to blocking mode.
| sock | Socket to configure |
Referenced by connect_with_timeout().
| int socket_set_buffer_sizes | ( | socket_t | sock, |
| int | recv_size, | ||
| int | send_size | ||
| ) |
#include <socket.h>
Set socket buffer sizes.
| sock | Socket to configure |
| recv_size | Receive buffer size in bytes |
| send_size | Send buffer size in bytes |
#include <socket.h>
Set SO_KEEPALIVE socket option.
| sock | Socket to configure |
| keepalive | true to enable keepalive, false to disable |
Referenced by server_connection_establish(), and tcp_client_connect().
#include <socket.h>
Set TCP keepalive parameters.
| sock | Socket to configure |
| enable | Enable/disable keepalive |
| idle | Idle time before sending first keepalive probe (seconds) |
| interval | Interval between keepalive probes (seconds) |
| count | Number of keepalive probes before connection failure |
Referenced by set_socket_keepalive().
#include <socket.h>
Set SO_LINGER socket option.
| sock | Socket to configure |
| enable | Enable/disable lingering |
| timeout | Linger timeout in seconds |
#include <socket.h>
Set TCP_NODELAY socket option (disable Nagle's algorithm)
| sock | Socket to configure |
| nodelay | true to disable Nagle's algorithm, false to enable |
#include <socket.h>
Set socket to non-blocking mode.
| sock | Socket to configure |
| nonblocking | true for non-blocking, false for blocking |
Referenced by set_socket_nonblocking().
#include <socket.h>
Set SO_REUSEADDR socket option.
| sock | Socket to configure |
| reuse | true to enable reuse, false to disable |
#include <socket.h>
Set socket receive and send timeouts.
| sock | Socket to configure |
| timeout_ms | Timeout in milliseconds |
Sets both SO_RCVTIMEO (receive timeout) and SO_SNDTIMEO (send timeout) to prevent indefinite blocking on socket operations.
Platform-specific implementations:
| sock | Socket to configure |
| timeout_ms | Timeout in milliseconds |
Cross-platform implementation that sets both SO_RCVTIMEO and SO_SNDTIMEO. Platform-specific socket_setsockopt() handles the differences between Windows (DWORD milliseconds) and POSIX (struct timeval).
Definition at line 81 of file socket.c.
References socket_setsockopt().
Referenced by acds_client_connect().
| int socket_setsockopt | ( | socket_t | sock, |
| int | level, | ||
| int | optname, | ||
| const void * | optval, | ||
| socklen_t | optlen | ||
| ) |
#include <socket.h>
Set socket option.
| sock | Socket to configure |
| level | Option level (e.g., SOL_SOCKET, IPPROTO_TCP) |
| optname | Option name (e.g., SO_REUSEADDR, TCP_NODELAY) |
| optval | Pointer to option value |
| optlen | Length of option value |
Referenced by set_socket_timeout(), socket_configure_buffers(), socket_optimize_for_streaming(), and socket_set_timeout().
| int socket_shutdown | ( | socket_t | sock, |
| int | how | ||
| ) |
#include <socket.h>
Shutdown socket I/O.
| sock | Socket to shutdown |
| how | Shutdown mode (SHUT_RD, SHUT_WR, SHUT_RDWR) |
Referenced by disconnect_client_for_bad_data(), server_connection_shutdown(), and tcp_client_shutdown().
| void symbol_cache_cleanup | ( | void | ) |
#include <symbols.h>
Clean up the symbol cache and free all resources.
Destroys the symbol cache and frees all cached symbols and internal structures. Should be called at application shutdown after all backtraces are complete.
Definition at line 419 of file symbols.c.
References log_debug, rwlock_destroy(), rwlock_wrlock, rwlock_wrunlock, SAFE_FREE, and symbol_entry_t::symbol.
Referenced by server_main().
| void symbol_cache_free_symbols | ( | char ** | symbols | ) |
#include <symbols.h>
Free symbol array returned by symbol_cache_resolve_batch.
| symbols | Array of symbol strings (can be NULL) |
Frees the array structure returned by symbol_cache_resolve_batch(). This only frees the array itself, not the individual symbol strings (which are owned by the cache).
Definition at line 1173 of file symbols.c.
References SAFE_FREE.
#include <symbols.h>
Get cache statistics.
| hits_out | Pointer to receive hit count (can be NULL) |
| misses_out | Pointer to receive miss count (can be NULL) |
| entries_out | Pointer to receive entry count (can be NULL) |
Retrieves cumulative statistics from the symbol cache. Useful for performance monitoring and cache efficiency analysis.
Definition at line 540 of file symbols.c.
References rwlock_rdlock, and rwlock_rdunlock.
| asciichat_error_t symbol_cache_init | ( | void | ) |
#include <symbols.h>
Initialize the symbol cache.
Initializes the global symbol cache system. Creates the hashtable and initializes statistics counters. Must be called before using any other symbol cache functions.
Definition at line 391 of file symbols.c.
References ERROR_THREAD, log_debug, rwlock_init(), and SET_ERRNO.
| bool symbol_cache_insert | ( | void * | addr, |
| const char * | symbol | ||
| ) |
#include <symbols.h>
Insert a symbol into the cache.
| addr | Address to cache (must not be NULL) |
| symbol | Symbol string to cache (must not be NULL, will be copied) |
Inserts a symbol into the cache for future lookups. The symbol string is copied and owned by the cache. If the address already exists in the cache, the symbol is updated.
Definition at line 482 of file symbols.c.
References symbol_entry_t::addr, platform_strdup(), rwlock_wrlock, rwlock_wrunlock, SAFE_FREE, SAFE_MALLOC, and symbol_entry_t::symbol.
Referenced by symbol_cache_resolve_batch().
| const char * symbol_cache_lookup | ( | void * | addr | ) |
#include <symbols.h>
Look up a symbol for a given address.
| addr | Address to resolve (must not be NULL) |
Performs a hashtable lookup to find the cached symbol for the given address. Returns NULL if the address is not in the cache (cache miss). Use symbol_cache_resolve_batch() to resolve uncached addresses.
Definition at line 460 of file symbols.c.
References rwlock_rdlock, rwlock_rdunlock, and symbol_entry_t::symbol.
Referenced by symbol_cache_resolve_batch().
| void symbol_cache_print_stats | ( | void | ) |
#include <symbols.h>
Print cache statistics to logging system.
Logs detailed statistics from the symbol cache including hit rate, miss count, and entry count. Useful for periodic performance monitoring.
Definition at line 554 of file symbols.c.
References log_info, rwlock_rdlock, and rwlock_rdunlock.
| char ** symbol_cache_resolve_batch | ( | void *const * | buffer, |
| int | size | ||
| ) |
#include <symbols.h>
Resolve multiple addresses using addr2line and cache results.
| buffer | Array of addresses to resolve (must not be NULL) |
| size | Number of addresses in buffer (must be > 0) |
Resolves multiple addresses to symbol names using addr2line. For each address:
This function is optimized for batch backtrace processing:
Definition at line 1052 of file symbols.c.
References log_error, NULL_SENTINEL, platform_strdup(), SAFE_CALLOC, SAFE_FREE, SAFE_MALLOC, SAFE_SNPRINTF, symbol_cache_insert(), symbol_cache_lookup(), SYMBOLIZER_ADDR2LINE, SYMBOLIZER_LLVM, and SYMBOLIZER_NONE.
| const char * terminal_capabilities_summary | ( | const terminal_capabilities_t * | caps | ) |
#include <terminal.h>
Get summary string of terminal capabilities.
| caps | Terminal capabilities structure (must not be NULL) |
Generates a human-readable summary string describing the terminal's capabilities including color level, UTF-8 support, and render mode. Useful for logging and debugging terminal configuration.
| asciichat_error_t terminal_clear_screen | ( | void | ) |
#include <terminal.h>
Clear the terminal screen.
Clears the terminal screen using ANSI escape sequences (Unix) or Windows Console API. Removes all visible characters and resets cursor position to top-left.
| asciichat_error_t terminal_clear_scrollback | ( | int | fd | ) |
#include <terminal.h>
Clear terminal scrollback buffer.
| fd | File descriptor for terminal (must be valid) |
Clears the terminal scrollback buffer (history of previous output). This removes all previous terminal output that can be scrolled back to view. Useful for starting with a clean terminal state.
| const char * terminal_color_level_name | ( | terminal_color_mode_t | level | ) |
#include <terminal.h>
Get name of color level.
| level | Color level enum value (terminal_color_mode_t) |
Converts a terminal color level enum value to a human-readable string name. Useful for logging and debugging terminal capability detection.
Referenced by handle_client_capabilities_packet().
| asciichat_error_t terminal_cursor_home | ( | int | fd | ) |
#include <terminal.h>
Move cursor to home position (top-left)
| fd | File descriptor for terminal (must be valid) |
Moves cursor to home position (row 1, column 1 - top-left corner). Equivalent to terminal_move_cursor(1, 1) but more efficient. Uses ANSI escape sequence ESC[H.
| void terminal_enable_ansi | ( | void | ) |
#include <terminal.h>
Enable ANSI escape sequences.
On Windows, enables ANSI escape sequence processing in the console. This allows Windows console to interpret ANSI escape codes (colors, cursor movement, etc.) that are normally only available on Unix terminals.
| asciichat_error_t terminal_flush | ( | int | fd | ) |
#include <terminal.h>
Flush terminal output.
| fd | File descriptor to flush (must be valid file descriptor) |
Forces all buffered output to be written to the terminal immediately. Ensures that all pending terminal output is displayed before continuing.
| asciichat_error_t terminal_get_cursor_position | ( | int * | row, |
| int * | col | ||
| ) |
#include <terminal.h>
Get current cursor position.
| row | Pointer to store row position (must not be NULL, 1-based) |
| col | Pointer to store column position (must not be NULL, 1-based) |
Queries the terminal for the current cursor position. Uses platform-specific methods to detect cursor location. Positions are returned in 1-based coordinates (row 1, column 1 is top-left).
| asciichat_error_t terminal_get_size | ( | terminal_size_t * | size | ) |
#include <terminal.h>
Get terminal size.
| size | Pointer to store terminal size (must not be NULL) |
Queries the terminal for its current dimensions (rows and columns). Uses platform-specific methods (ioctl on Unix, Windows Console API).
Referenced by sdp_detect_terminal_capabilities().
| asciichat_error_t terminal_hide_cursor | ( | int | fd, |
| bool | hide | ||
| ) |
#include <terminal.h>
Hide or show cursor.
| fd | File descriptor for terminal (must be valid) |
| hide | true to hide cursor, false to show cursor |
Controls terminal cursor visibility. Hiding the cursor is useful for full-screen ASCII art rendering where cursor flicker is distracting. Uses ANSI escape sequences (ESC[?25l to hide, ESC[?25h to show).
Referenced by ascii_write_destroy(), and ascii_write_init().
| asciichat_error_t terminal_move_cursor | ( | int | row, |
| int | col | ||
| ) |
#include <terminal.h>
Move cursor to specified position.
| row | Row position (1-based, top is row 1) |
| col | Column position (1-based, left is column 1) |
Moves the terminal cursor to the specified row and column position. Uses ANSI escape sequences (Unix) or Windows Console API. Positions are 1-based (top-left is row 1, column 1).
| asciichat_error_t terminal_reset | ( | int | fd | ) |
#include <terminal.h>
Reset terminal to default state.
| fd | File descriptor for terminal (must be valid) |
Resets terminal to default state including:
Useful for cleanup before program exit or when resetting terminal state.
| asciichat_error_t terminal_restore_cursor | ( | void | ) |
#include <terminal.h>
Restore saved cursor position.
Restores a previously saved cursor position. Uses ANSI escape sequence ESC[u to restore cursor position. Must be preceded by terminal_save_cursor().
| asciichat_error_t terminal_ring_bell | ( | void | ) |
#include <terminal.h>
Ring terminal bell.
Rings the terminal bell (beep sound). Uses ANSI escape sequence BEL or platform-specific API to trigger audible notification.
| asciichat_error_t terminal_save_cursor | ( | void | ) |
#include <terminal.h>
Save cursor position.
Saves the current cursor position for later restoration. Uses ANSI escape sequence ESC[s to save cursor position. Restore with terminal_restore_cursor().
| asciichat_error_t terminal_set_buffering | ( | bool | line_buffered | ) |
#include <terminal.h>
Set terminal buffering mode.
| line_buffered | true for line buffering, false for unbuffered |
Controls terminal output buffering mode:
Unbuffered mode is useful for real-time ASCII art rendering where immediate output is desired. Line buffering is more efficient for line-based output.
| asciichat_error_t terminal_set_echo | ( | bool | enable | ) |
#include <terminal.h>
Set terminal echo mode.
| enable | true to enable echo, false to disable |
Controls whether terminal input is echoed back to the display. When echo is disabled, input characters are not displayed (useful for password input or silent key capture).
Referenced by ascii_write_destroy(), and ascii_write_init().
| asciichat_error_t terminal_set_raw_mode | ( | bool | enable | ) |
#include <terminal.h>
Set terminal to raw mode.
| enable | true to enable raw mode, false to disable |
Controls terminal raw mode. In raw mode, terminal input is not processed:
Raw mode is useful for real-time input processing (keyboard events, etc.).
| asciichat_error_t terminal_set_scroll_region | ( | int | top, |
| int | bottom | ||
| ) |
#include <terminal.h>
Set scroll region.
| top | Top row of scroll region (1-based, must be > 0) |
| bottom | Bottom row of scroll region (1-based, must be >= top) |
Defines a scroll region within the terminal. Only the specified row range will scroll when text exceeds the bottom. Uses ANSI escape sequence ESC[top;bottomr. Useful for preserving header/footer regions while allowing content area to scroll.
| asciichat_error_t terminal_set_title | ( | const char * | title | ) |
#include <terminal.h>
Set terminal window title.
| title | Title string to set (must not be NULL) |
Sets the terminal window title to the specified string. Uses ANSI escape sequence ESC]0;titleBEL or platform-specific API. Title appears in window title bar or terminal tab.
| bool terminal_supports_color | ( | void | ) |
#include <terminal.h>
Check if terminal supports color.
Determines whether the terminal supports color output. Checks environment variables ($TERM, $COLORTERM) and terminal type to detect color capabilities.
| bool terminal_supports_unicode | ( | void | ) |
#include <terminal.h>
Check if terminal supports unicode.
Determines whether the terminal supports Unicode character output. Checks locale settings and terminal type for Unicode support.
| bool terminal_supports_utf8 | ( | void | ) |
#include <terminal.h>
Check if terminal supports UTF-8.
Determines whether the terminal supports UTF-8 encoding. Checks locale settings ($LC_ALL, $LANG) and terminal type for UTF-8 support.
Referenced by detect_client_utf8_support().
| void test_terminal_output_modes | ( | void | ) |
#include <terminal.h>
Test terminal output modes.
Tests various terminal output modes to verify capabilities. Outputs test patterns for different color modes (16-color, 256-color, truecolor) and rendering modes to verify terminal behavior.
| asciichat_error_t thread_create_or_fail | ( | asciichat_thread_t * | thread, |
| void *(*)(void *) | func, | ||
| void * | arg, | ||
| const char * | thread_name, | ||
| uint32_t | client_id | ||
| ) |
#include <thread.h>
Create a thread with standardized error handling and logging.
| thread | Thread handle to fill on success |
| func | Thread function to execute |
| arg | Argument to pass to thread function |
| thread_name | Human-readable name for logging (e.g., "video_render") |
| client_id | Client ID for error context in logs |
Wraps asciichat_thread_create() with unified error handling and logging. On success, logs at debug level. On failure, uses SET_ERRNO() to record error context and returns:
Definition at line 14 of file thread.c.
References ASCIICHAT_OK, asciichat_thread_create(), ERROR_INVALID_PARAM, ERROR_PLATFORM_INIT, log_debug, and SET_ERRNO.
|
extern |
#include <windows_errno.h>
Referenced by accept_with_timeout(), acds_identity_load(), asciichat_clear_errno(), config_create_default(), connect_with_timeout(), gpg_agent_connect(), gpg_sign_with_key(), gpg_verify_signature_with_binary(), packet_send(), parse_long(), parse_ulong(), parse_ulonglong(), platform_get_executable_path(), query_init(), recv_with_timeout(), safe_parse_audio_message(), safe_parse_size_message(), and send_with_timeout().