Commit Graph

29 Commits

Author SHA1 Message Date
anth64 2c4d27f915 fix(linux): prevent segfault from invalid module indices during rapid reloads
When spamming file changes rapidly, inotify can report stale UNLOAD/RELOAD
events for modules that were already unloaded by previous events in the same
poll cycle. This caused is_mod_loaded() to return -1, which was then cast to
size_t (18446744073709551615) and used as an array index, causing segfaults.

Additionally, event counts were calculated before validation, causing loops to
run more iterations than valid indices were populated, reading garbage values.

Changes:
- stk.c: Check if is_mod_loaded() returns valid index (>= 0) before adding
  to unload/reload lists
- stk.c: Reset and recalculate counts after populating arrays with only valid
  indices to prevent loop overrun
- Skip processing events for modules that are no longer loaded

This completes the Linux stability fixes started in v0.0.2.
2026-02-11 00:17:33 +01:00
anth64 f83f2051ef fix(linux): prevent segfaults during rapid module reloads
Fixes multiple issues causing segfaults when hot-reloading modules
on Linux, particularly when file changes are detected rapidly:

- Enable is_file_ready() check on Linux to prevent loading partially-written
  shared libraries (previously only used on Windows/BSD)
- Fix event deduplication on Linux to actually remove duplicate inotify events
  instead of just marking them, preventing double-free on same module
- Reorder reload operations to unload old module only after successfully
  copying new version, avoiding invalid state when copy fails

Changes:
- platform.c: Remove __linux__ guards around is_file_ready() function
- platform.c: Add compaction step after deduplication to remove -1 entries
- stk.c: Move module unload to after platform_copy_file() in reload loop

These changes make Linux hot-reload as robust as Windows/BSD implementations.
2026-02-09 22:25:02 +01:00
anth64 2f4b91c729 refactor(stk): change stk_init() return type to uint8_t
- Change function signature from int to uint8_t for clarity
- Makes return type intent explicit as status flag
2026-01-31 22:40:21 +01:00
anth64 4bd1f00b5b refactor: transition return types to uint8_t and improve error reporting
- Update module load and memory functions to use fixed-width uint8_t
- Implement STK_MOD_REALLOC_FAILURE for granular memory error tracking
- Clean up logging prefixes in stk_poll for consistency
- Update error string helper to support new module error codes
2026-01-31 19:56:36 +01:00
anth64 69b4907ff2 fix: resolve Windows segfaults by using platform-specific path separators
On Windows, module IDs were failing to load because paths were being
constructed with hardcoded forward slashes. Oops...

- Added platform.h to centralize path separator macros.
- Updated build_path in stk.c to use STK_PATH_SEP_STR instead of "/".
- Cleaned up redundant platform logic in module.c.
2026-01-31 19:03:19 +01:00
anth64 1e97b69fcd feat: add comprehensive error handling with typed error codes
Add strict error handling for stk initialization and platform operations.
stk_init() now fails fast on critical errors and returns typed error codes
that users can handle programmatically.

Changes:
- Add STK_INIT_* error codes for init failures (memory, tmpdir, watch)
- Add STK_PLATFORM_* error codes for platform operation results
- Check platform_mkdir() and fail if temp directory cannot be created
- Check platform_directory_watch_start() and fail if watch cannot initialize
- Add error_cleanup path in platform_directory_watch_start() to properly
  free resources on critical Windows failures.
- Replace all platform error checks with STK_PLATFORM_OPERATION_SUCCESS
- Log FATAL errors with when critical operations fail
- Add warning logs for non-critical failures

Critical failures now return specific error codes:
- STK_INIT_MEMORY_ERROR: Module memory allocation failed
- STK_INIT_TMPDIR_ERROR: Cannot create temp directory
- STK_INIT_WATCH_ERROR: Cannot start directory watching

Individual module load failures remain non-fatal and are handled logged.
2026-01-31 15:04:20 +01:00
anth64 336a096b82 feat: add error handling for module loading
Modules that fail to load no longer crash or leak memory:
- Check return values from stk_module_load_init() and stk_module_load()
- Log errors with specific failure reasons (library load, symbol lookup, init)
- Track successful_loads counter separately from file_count
- Only increment module_count for modules that actually loaded
- Trim allocated arrays when some modules fail to load
- Continue loading other modules when one fails

This prevents crashes from accessing uninitialized module slots and
avoids memory leaks from over-allocation.
2026-01-30 07:41:18 +01:00
anth64 8ea9ac084f fix: swap STK_MOD_RELOAD and STK_MOD_UNLOAD event handlers
Cases were reversed during if-else to switch refactoring, causing segfault
on module shutdown. Oops...
2026-01-30 07:24:34 +01:00
anth64 aba10d7dac fix: sync module types and replace WIP constants
* Types: Corrected stk.c to use stk_init_mod_func and stk_shutdown_mod_func instead of generic types.
* Errors: Replaced -3 placeholder with STK_MOD_INIT_FAILURE.
* Cleanup: Moved typedefs in module.c for consistency.
2026-01-29 23:11:42 +01:00
anth64 baa75e897f refactor(module): centralize path parsing and add OS-specific separator
- Define STK_PATH_SEP macro to handle Windows and Unix path separators.
- Refactor extract_module_id to use STK_PATH_SEP.
- Simplify stk_module_load by delegating module ID extraction to extract_module_id.
2026-01-29 22:16:48 +01:00
anth64 92e33ff265 refactor(stk): replace if-else chains with switch statements in stk_poll
- Update event processing to use switch statements.
- Clean up redundant goto jumps after memory reallocation.
2026-01-29 21:25:44 +01:00
anth64 fb80c3a6c5 feat: implement hot-reload polling with dynamic array management
Implement complete hot-reload logic in stk_poll() supporting reload,
load, and unload operations. Module arrays dynamically grow/shrink
with automatic defragmentation to maintain tight memory layout.

- Grow arrays when loads exceed unloads
- Fill holes left by unloads with new modules
- Defragment and trim arrays when unloads exceed loads
- Unload before realloc to minimize peak memory usage
- Replace sprintf with safe C89 build_path() helper
2026-01-28 00:48:01 +01:00
anth64 9491b070d2 refactor(WIP): replace event stubs with module identification logic
Replace the placeholder TODO logs in the polling loop with logic to
resolve filesystem events into specific module indices.

- Centralizing State: Refactored is_module_loaded to is_mod_loaded to
  check against the global stk_module_ids array, removing the need to
  pass local buffers and preparing for unified lifetime management.
- Standardizing Identity: Updated extract_module_id to use a
  consistent output buffer.
- Categorized Event Processing: Implemented a two-pass approach in
  stk_poll to count event types (LOAD, UNLOAD, RELOAD) and allocate
  tracking arrays, replacing the previous stubbed switch statement.
- Mapping Events to Indices: The poll loop now resolves filenames
  back to their specific loaded indices via is_mod_loaded to
  identify exactly which mod_id and index require action.
- Improved Flow Control: Introduced a finish_stk_poll label to
  ensure consistent cleanup and return values when no events are
  detected or processing is complete.
2026-01-27 07:54:51 +01:00
anth64 c558032ea0 feat: prevent configuration changes after initialization
* Introduced stk_initialized flag.
* Updated all configuration setters (stk_set_mod_dir, stk_set_tmp_dir_name, stk_set_module_init_fn, and stk_set_module_shutdown_fn) to silently return if the library is already initialized.
* Ensures internal state consistency by locking paths and function entry points once stk_init has been called.
2026-01-25 17:02:44 +01:00
anth64 472cb3b163 feat: make module paths and entry points configurable
* Added functions to set mod dir, temp dir name, and module init/shutdown function names.
* Replaced hardcoded string literals with configurable static buffers in module.c.
* Improved string safety by replacing sprintf with strncpy/strncat.
* Updated stk_init local path buffers to handle maximum combined path lengths.
2026-01-25 16:52:52 +01:00
anth64 ac0125274d set default values for mod and tmp dir, removed arguments from stk init 2026-01-25 16:01:51 +01:00
anth64 f66a3bc00d fix: legacy printf compatibility and add polling logs
- Change %zu to %lu in stk_init to support older msvcrt.dll (Windows 7/XP)
- Update pluralization logic to correctly handle "0 mods" vs "1 mod"
- Add temporary stk_log calls to stk_poll for monitoring module events
2026-01-25 13:36:53 +01:00
anth64 404bf9503c fix: init file count to 0, just in case... 2026-01-19 23:16:32 +01:00
anth64 a290be5dcc feat: implement .tmp directory isolation for safe hot-reload
Add foundation for cross-platform hot-reload system by isolating
loaded modules from source files using a temporary directory.

Changes:
- Add configurable tmp directory parameter to stk_init()
  (defaults to mods/.tmp/ if not specified)
- Copy all modules from mods/ to .tmp/ on initialization
- Load modules exclusively from .tmp/ directory
- Clean up .tmp/ directory on shutdown
- Add cross-platform file operations:
  * platform_mkdir() - create directories
  * platform_copy_file() - copy files
  * platform_remove_file() - delete files
  * platform_remove_dir() - delete directory and contents
- Improve BSD kqueue implementation to detect file overwrites
  (adds individual file watches with NOTE_WRITE)

This isolates the loaded shared libraries from source files,
preventing segfaults when users overwrite mods using cp/copy
operations. The actual reload logic remains unimplemented
(marked as TODO in stk_poll switch cases).
2026-01-18 21:26:17 +01:00
anth64 38469a358f Replace dynamic allocations with fixed-size buffers and add module extension filtering
- Use fixed STK_PATH_MAX and STK_MOD_ID_BUFFER throughout for predictable memory
- Filter by platform-specific extensions (.so/.dll/.dylib) with compile-time length
- Add RELOAD event detection and is_module_loaded() helper
- Maintain feature parity across all platforms
2026-01-17 19:52:42 +01:00
anth64 a7d40929bf Change shutdown return type and hot reload WIP
- stk_shutdown now is a void return type
- detect if the module being loaded/unloaded is an existing module.
2025-11-07 07:55:44 +01:00
anth64 7169dd37b7 hot loading skeleton 2025-11-06 22:34:55 +01:00
anth64 35cc5afa9d Module discovery working for real this time
- Tested on Linux
- Allocate module memory before loading anything (seg fault fixed)
2025-11-02 19:41:56 +01:00
anth64 5c621c8367 Init/shutdown working
- stk_init/shutdown do what they are supposed to.
- buffer sizes moved to headers
2025-11-02 18:40:33 +01:00
anth64 7d7f02d1be use a constant for the mod dir buffer size 2025-11-02 12:44:10 +01:00
anth64 a66d9f9357 add mod dir 2025-11-02 12:30:26 +01:00
anth64 51ae8c7ab2 change shutdown log msg 2025-10-23 21:18:37 +02:00
anth64 8b26742c63 add logging 2025-10-21 00:10:51 +02:00
anth64 079921091f initial code + Makefile 2025-10-08 19:17:18 +02:00