Refactor: extract platform abstraction for subprocess spawning

Move all Unix-specific syscalls (fork, execvp, waitpid, strerror, /tmp)
into a platform layer so the same spectrogram.c can target Windows
(CreateProcess) and WebAssembly (stubs). Key changes:

- src/platform.h: public API with spawn handle, error codes, path helpers
- src/platform_linux.c: fork/execvp implementation, /tmp, strerror
- src/platform_win32.c: CreateProcess implementation, temp dir lookup
- src/platform_web.c: stub implementations (no subprocess support on web)
- src/spectrogram.c: consume only platform.h; replace pid_t/fork/execvp
  with Platform_SpawnChild/WaitForChild; use Platform_GetTempDir() for
  /tmp path; replace strdup with malloc/memcpy for portability
- Build: add platform_*.c to gmake, Premake, and build_web.sh
This commit is contained in:
2026-05-14 18:16:21 -07:00
parent e42554e6fd
commit b6942d8577
8 changed files with 472 additions and 28 deletions
+65
View File
@@ -0,0 +1,65 @@
/*
* platform_web.c — Emscripten/WebAssembly stub implementation
*
* The web version cannot spawn child processes, so these functions
* return "not supported". A real implementation would use Emscripten's
* pthreads or asyncify if ffmpeg integration is needed.
*/
#include "platform.h"
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
/* ── Helpers ─────────────────────────────────────────────────────────── */
static char last_error_msg[256] = { 0 };
static void set_last_error(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
vsnprintf(last_error_msg, sizeof(last_error_msg), fmt, args);
va_end(args);
}
/* ── Platform API ────────────────────────────────────────────────────── */
PlatformError Platform_SpawnChild(const char *program, const char **argv,
PlatformSpawnHandle *out_handle) {
(void)program;
(void)argv;
set_last_error("Spawning child processes is not supported on the web");
out_handle->last_error = ENOSYS;
return PLATFORM_NOT_SUPPORTED;
}
PlatformError Platform_WaitForChild(PlatformSpawnHandle *handle) {
(void)handle;
return PLATFORM_NOT_SUPPORTED;
}
SpawnStatus Platform_GetExitStatus(const PlatformSpawnHandle *handle, int *code) {
(void)handle;
(void)code;
return SPAWN_WAITING;
}
void Platform_CloseSpawnHandle(PlatformSpawnHandle *handle) {
if (!handle) return;
handle->handle = NULL;
handle->status = SPAWN_WAITING;
handle->exit_code = 0;
handle->last_error = 0;
}
const char *Platform_GetLastErrorMessage(void) {
return last_error_msg;
}
const char *Platform_GetTempDir(void) {
/*
* Emscripten's virtual filesystem: "/" works as root.
* For persistent downloads/uploads, consider IDBFS mount.
*/
return "/";
}