2025-11-10 16:02:53 +08:00
|
|
|
#include "detection/command/command.h"
|
2026-01-06 09:48:38 +08:00
|
|
|
#include "common/processing.h"
|
|
|
|
|
#include "common/FFstrbuf.h"
|
2025-11-10 16:02:53 +08:00
|
|
|
|
2026-03-29 09:28:49 +08:00
|
|
|
typedef struct FFCommandResultBundle {
|
2025-11-10 16:02:53 +08:00
|
|
|
FFProcessHandle handle;
|
|
|
|
|
const char* error;
|
|
|
|
|
} FFCommandResultBundle;
|
|
|
|
|
|
|
|
|
|
// FIFO, non-thread-safe list of running commands
|
|
|
|
|
static FFlist commandQueue = {
|
|
|
|
|
.elementSize = sizeof(FFCommandResultBundle),
|
|
|
|
|
};
|
|
|
|
|
|
2026-03-29 09:28:49 +08:00
|
|
|
static const char* spawnProcess(FFCommandOptions* options, FFProcessHandle* handle) {
|
|
|
|
|
if (options->text.length == 0) {
|
2025-11-10 16:02:53 +08:00
|
|
|
return "No command text specified";
|
2026-03-29 09:28:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ffProcessSpawn(options->param.length ? (char* const[]) {
|
|
|
|
|
options->shell.chars,
|
|
|
|
|
options->param.chars,
|
|
|
|
|
options->text.chars,
|
2026-03-30 10:17:45 +08:00
|
|
|
NULL
|
|
|
|
|
}
|
2026-03-29 09:28:49 +08:00
|
|
|
: (char* const[]) {options->shell.chars, options->text.chars, NULL},
|
|
|
|
|
options->useStdErr,
|
|
|
|
|
handle);
|
2025-11-10 16:02:53 +08:00
|
|
|
}
|
|
|
|
|
|
2026-03-29 09:28:49 +08:00
|
|
|
bool ffPrepareCommand(FFCommandOptions* options) {
|
|
|
|
|
if (!options->parallel) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2025-11-10 16:02:53 +08:00
|
|
|
|
|
|
|
|
FFCommandResultBundle* bundle = ffListAdd(&commandQueue);
|
|
|
|
|
bundle->error = spawnProcess(options, &bundle->handle);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-29 09:28:49 +08:00
|
|
|
const char* ffDetectCommand(FFCommandOptions* options, FFstrbuf* result) {
|
2025-11-10 22:48:22 +08:00
|
|
|
FFCommandResultBundle bundle = {};
|
2026-03-29 09:28:49 +08:00
|
|
|
if (!options->parallel) {
|
2025-11-10 16:02:53 +08:00
|
|
|
bundle.error = spawnProcess(options, &bundle.handle);
|
2026-03-29 09:28:49 +08:00
|
|
|
} else if (!ffListShift(&commandQueue, &bundle)) {
|
2025-11-11 09:28:44 +08:00
|
|
|
return "[BUG] command queue is empty";
|
2026-03-29 09:28:49 +08:00
|
|
|
}
|
2025-11-10 16:02:53 +08:00
|
|
|
|
2026-03-29 09:28:49 +08:00
|
|
|
if (bundle.error) {
|
2025-11-10 16:02:53 +08:00
|
|
|
return bundle.error;
|
2026-03-29 09:28:49 +08:00
|
|
|
}
|
2025-11-10 16:02:53 +08:00
|
|
|
|
|
|
|
|
bundle.error = ffProcessReadOutput(&bundle.handle, result);
|
2026-03-29 09:28:49 +08:00
|
|
|
if (bundle.error) {
|
2025-11-10 16:02:53 +08:00
|
|
|
return bundle.error;
|
2026-03-29 09:28:49 +08:00
|
|
|
}
|
2025-11-10 16:02:53 +08:00
|
|
|
|
|
|
|
|
ffStrbufTrimRightSpace(result);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|