Update shell_commander to use Str8 instead of const char *
This commit is contained in:
parent
2c9e4c91a0
commit
11949e69be
@ -1,6 +1,11 @@
|
|||||||
#include "commander.h"
|
#include "commander.h"
|
||||||
#include "aliases.h"
|
#include "aliases.h"
|
||||||
|
#include "commander_output.h"
|
||||||
|
#include "mem_allocator.h"
|
||||||
|
#include "mem_arena_allocator.h"
|
||||||
|
#include "misc_utils.h"
|
||||||
#include "shell_utils.h"
|
#include "shell_utils.h"
|
||||||
|
#include "str8.h"
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -10,62 +15,44 @@
|
|||||||
#define CMD_BUF_LEN 8192
|
#define CMD_BUF_LEN 8192
|
||||||
#define OUT_BUF_LEN 4096
|
#define OUT_BUF_LEN 4096
|
||||||
|
|
||||||
internal inline CMDError build_command_from_args(char *cmd, u64 buf_len, va_list args);
|
internal inline CMDResult execute_command(Str8RO *cmd, CMDOutHandling out_handling, Str8 *out_buf);
|
||||||
internal inline CMDResult execute_command(const char *cmd, CMDOutHandling out_handling, char *out_buf,
|
internal inline CMDError get_command_output(FILE *fp, CMDOutHandling out_handling, Str8 *out_buf);
|
||||||
u64 buf_size);
|
|
||||||
internal inline CMDError get_command_output(FILE *fp, CMDOutHandling out_handling, char *out_buf,
|
|
||||||
u64 buf_size);
|
|
||||||
|
|
||||||
CMDResult run_command(CMDOutHandling out_handling, char *out_buf, u64 buf_size, ...) {
|
CMDResult wapp_shell_commander_execute(CMDOutHandling out_handling, Str8 *out_buf, const Str8List *cmd) {
|
||||||
va_list args;
|
if (!cmd) {
|
||||||
va_start(args, buf_size);
|
return CMD_NO_EXIT(SHELL_ERR_INVALID_ARGS);
|
||||||
|
|
||||||
char cmd[CMD_BUF_LEN] = {0};
|
|
||||||
CMDError err = build_command_from_args(cmd, CMD_BUF_LEN, args);
|
|
||||||
if (err > SHELL_ERR_NO_ERROR) {
|
|
||||||
va_end(args);
|
|
||||||
return CMD_NO_EXIT(err);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
va_end(args);
|
Allocator arena = wapp_mem_arena_allocator_init(MB(100));
|
||||||
|
|
||||||
return execute_command(cmd, out_handling, out_buf, buf_size);
|
Str8 *cmd_str = wapp_str8_join(&arena, cmd, &wapp_str8_lit_ro(" "));
|
||||||
|
if (!cmd_str) {
|
||||||
|
wapp_mem_arena_allocator_destroy(&arena);
|
||||||
|
return CMD_NO_EXIT(SHELL_ERR_ALLOCATION_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Redirect output
|
||||||
|
cmd_str = wapp_str8_concat(&arena, cmd_str, &wapp_str8_lit_ro(" 2>&1"));
|
||||||
|
|
||||||
|
CMDResult output = execute_command(cmd_str, out_handling, out_buf);
|
||||||
|
|
||||||
|
wapp_mem_arena_allocator_destroy(&arena);
|
||||||
|
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal inline CMDError build_command_from_args(char *cmd, u64 buf_len,
|
internal inline CMDResult execute_command(Str8RO *cmd, CMDOutHandling out_handling, Str8 *out_buf) {
|
||||||
va_list args) {
|
char cmd_buf[CMD_BUF_LEN] = {0};
|
||||||
u64 size = 0;
|
wapp_str8_copy_to_cstr(cmd_buf, cmd, CMD_BUF_LEN);
|
||||||
u64 arg_len = 0;
|
|
||||||
|
|
||||||
const char *arg = va_arg(args, const char *);
|
FILE *fp = wapp_shell_utils_popen(cmd_buf, "r");
|
||||||
while (arg) {
|
|
||||||
arg_len = strlen(arg);
|
|
||||||
if (arg_len >= buf_len - size) {
|
|
||||||
return SHELL_ERR_CMD_BUF_FULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
strcat(cmd, arg);
|
|
||||||
cmd[size + arg_len] = ' ';
|
|
||||||
|
|
||||||
size += arg_len + 1;
|
|
||||||
|
|
||||||
arg = va_arg(args, const char *);
|
|
||||||
}
|
|
||||||
|
|
||||||
return SHELL_ERR_NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal inline CMDResult execute_command(const char *cmd,
|
|
||||||
CMDOutHandling out_handling,
|
|
||||||
char *out_buf, u64 buf_size) {
|
|
||||||
FILE *fp = wapp_shell_utils_popen(cmd, "r");
|
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
return CMD_NO_EXIT(SHELL_ERR_PROC_START_FAIL);
|
return CMD_NO_EXIT(SHELL_ERR_PROC_START_FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
CMDResult output;
|
CMDResult output;
|
||||||
|
|
||||||
CMDError err = get_command_output(fp, out_handling, out_buf, buf_size);
|
CMDError err = get_command_output(fp, out_handling, out_buf);
|
||||||
if (err > SHELL_ERR_NO_ERROR) {
|
if (err > SHELL_ERR_NO_ERROR) {
|
||||||
output = CMD_NO_EXIT(err);
|
output = CMD_NO_EXIT(err);
|
||||||
goto EXECUTE_COMMAND_CLOSE;
|
goto EXECUTE_COMMAND_CLOSE;
|
||||||
@ -94,24 +81,18 @@ EXECUTE_COMMAND_CLOSE:
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal inline CMDError get_command_output(FILE *fp,
|
internal inline CMDError get_command_output(FILE *fp, CMDOutHandling out_handling, Str8 *out_buf) {
|
||||||
CMDOutHandling out_handling,
|
Str8 out = wapp_str8_buf(OUT_BUF_LEN);
|
||||||
char *out_buf, u64 buf_size) {
|
|
||||||
char out[OUT_BUF_LEN] = {0};
|
|
||||||
u64 max_out_length = OUT_BUF_LEN - 1;
|
|
||||||
|
|
||||||
u64 buf_filled = 0;
|
out.size = fread((void *)out.buf, sizeof(u8), out.capacity, fp);
|
||||||
while (fgets(out, (i32)max_out_length, fp)) {
|
|
||||||
if (out_handling == SHELL_OUTPUT_CAPTURE && out_buf != NULL) {
|
if (out_handling == SHELL_OUTPUT_CAPTURE && out_buf != NULL) {
|
||||||
buf_filled += strlen(out);
|
if (out.size >= out_buf->capacity) {
|
||||||
if (buf_filled >= buf_size) {
|
|
||||||
return SHELL_ERR_OUT_BUF_FULL;
|
return SHELL_ERR_OUT_BUF_FULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcat(out_buf, out);
|
wapp_str8_concat_capped(out_buf, &out);
|
||||||
} else if (out_handling == SHELL_OUTPUT_PRINT) {
|
} else if (out_handling == SHELL_OUTPUT_PRINT) {
|
||||||
printf("%s", out);
|
printf(WAPP_STR8_SPEC, wapp_str8_varg(out));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return SHELL_ERR_NO_ERROR;
|
return SHELL_ERR_NO_ERROR;
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "aliases.h"
|
#include "aliases.h"
|
||||||
#include "commander_output.h"
|
#include "commander_output.h"
|
||||||
|
#include "str8.h"
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -12,10 +13,8 @@ BEGIN_C_LINKAGE
|
|||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
#define CMD_NO_EXIT(ERR) ((CMDResult){.exited = false, .exit_code = EXIT_FAILURE, .error = ERR})
|
#define CMD_NO_EXIT(ERR) ((CMDResult){.exited = false, .exit_code = EXIT_FAILURE, .error = ERR})
|
||||||
#define wapp_shell_commander_execute(HANDLE_OUTPUT, OUT_BUF, BUF_SIZE, ...) \
|
|
||||||
run_command(HANDLE_OUTPUT, OUT_BUF, BUF_SIZE, __VA_ARGS__, "2>&1", NULL)
|
|
||||||
|
|
||||||
CMDResult run_command(CMDOutHandling out_handling, char *out_buf, u64 buf_size, ...);
|
CMDResult wapp_shell_commander_execute(CMDOutHandling out_handling, Str8 *out_buf, const Str8List *cmd);
|
||||||
|
|
||||||
external CMDError get_output_status(FILE *fp, i32 *status_out);
|
external CMDError get_output_status(FILE *fp, i32 *status_out);
|
||||||
|
|
||||||
|
@ -17,7 +17,8 @@ typedef enum {
|
|||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SHELL_ERR_NO_ERROR,
|
SHELL_ERR_NO_ERROR,
|
||||||
SHELL_ERR_CMD_BUF_FULL,
|
SHELL_ERR_INVALID_ARGS,
|
||||||
|
SHELL_ERR_ALLOCATION_FAIL,
|
||||||
SHELL_ERR_PROC_START_FAIL,
|
SHELL_ERR_PROC_START_FAIL,
|
||||||
SHELL_ERR_OUT_BUF_FULL,
|
SHELL_ERR_OUT_BUF_FULL,
|
||||||
SHELL_ERR_PROC_EXIT_FAIL,
|
SHELL_ERR_PROC_EXIT_FAIL,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "test_shell_commander.h"
|
#include "test_shell_commander.h"
|
||||||
#include "commander.h"
|
#include "commander.h"
|
||||||
|
#include "str8.h"
|
||||||
#include "tester.h"
|
#include "tester.h"
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -7,7 +8,11 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
TestFuncResult test_commander_cmd_success(void) {
|
TestFuncResult test_commander_cmd_success(void) {
|
||||||
CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_DISCARD, NULL, 0, "echo", "hello world");
|
Str8List cmd = {0};
|
||||||
|
wapp_str8_list_push_back(&cmd, &wapp_str8_node_from_cstr("echo"));
|
||||||
|
wapp_str8_list_push_back(&cmd, &wapp_str8_node_from_cstr("hello world"));
|
||||||
|
|
||||||
|
CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_DISCARD, NULL, &cmd);
|
||||||
bool succeeded = result.exited && result.exit_code == EXIT_SUCCESS &&
|
bool succeeded = result.exited && result.exit_code == EXIT_SUCCESS &&
|
||||||
result.error == SHELL_ERR_NO_ERROR;
|
result.error == SHELL_ERR_NO_ERROR;
|
||||||
|
|
||||||
@ -15,7 +20,10 @@ TestFuncResult test_commander_cmd_success(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TestFuncResult test_commander_cmd_failure(void) {
|
TestFuncResult test_commander_cmd_failure(void) {
|
||||||
CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_DISCARD, NULL, 0, "grep");
|
Str8List cmd = {0};
|
||||||
|
wapp_str8_list_push_back(&cmd, &wapp_str8_node_from_cstr("grep"));
|
||||||
|
|
||||||
|
CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_DISCARD, NULL, &cmd);
|
||||||
bool failed = result.exited && result.exit_code != EXIT_SUCCESS &&
|
bool failed = result.exited && result.exit_code != EXIT_SUCCESS &&
|
||||||
result.error == SHELL_ERR_NO_ERROR;
|
result.error == SHELL_ERR_NO_ERROR;
|
||||||
|
|
||||||
@ -23,27 +31,36 @@ TestFuncResult test_commander_cmd_failure(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TestFuncResult test_commander_cmd_out_buf_success(void) {
|
TestFuncResult test_commander_cmd_out_buf_success(void) {
|
||||||
char buf[64] = {0};
|
Str8 buf = wapp_str8_buf(64);
|
||||||
char expected_output[64] = {0};
|
Str8 expected = wapp_str8_buf(64);
|
||||||
const char *msg = "hello world";
|
char msg[] = "hello world";
|
||||||
u64 length = strlen(msg);
|
wapp_str8_copy_cstr_capped(&expected, msg);
|
||||||
snprintf(expected_output, length + 2, "%s\n", msg);
|
wapp_str8_concat_capped(&expected, &wapp_str8_lit_ro("\n"));
|
||||||
|
|
||||||
CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_CAPTURE, buf, 64, "echo", msg);
|
Str8List cmd = {0};
|
||||||
|
wapp_str8_list_push_back(&cmd, &wapp_str8_node_from_cstr("echo"));
|
||||||
|
wapp_str8_list_push_back(&cmd, &wapp_str8_node_from_cstr(msg));
|
||||||
|
|
||||||
|
CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_CAPTURE, &buf, &cmd);
|
||||||
bool succeeded = result.exited && result.exit_code == EXIT_SUCCESS &&
|
bool succeeded = result.exited && result.exit_code == EXIT_SUCCESS &&
|
||||||
result.error == SHELL_ERR_NO_ERROR &&
|
result.error == SHELL_ERR_NO_ERROR && wapp_str8_equal(&buf, &expected);
|
||||||
strncmp(buf, expected_output, length) == 0;
|
|
||||||
|
|
||||||
return wapp_tester_result(succeeded);
|
return wapp_tester_result(succeeded);
|
||||||
}
|
}
|
||||||
|
|
||||||
TestFuncResult test_commander_cmd_out_buf_failure(void) {
|
TestFuncResult test_commander_cmd_out_buf_failure(void) {
|
||||||
char buf[4] = {0};
|
Str8 buf = wapp_str8_buf(4);
|
||||||
const char *msg = "hello world";
|
Str8 expected = wapp_str8_buf(64);
|
||||||
u64 length = strlen(msg);
|
char msg[] = "hello world";
|
||||||
CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_CAPTURE, buf, 4, "echo", msg);
|
wapp_str8_copy_cstr_capped(&expected, msg);
|
||||||
|
|
||||||
|
Str8List cmd = {0};
|
||||||
|
wapp_str8_list_push_back(&cmd, &wapp_str8_node_from_cstr("echo"));
|
||||||
|
wapp_str8_list_push_back(&cmd, &wapp_str8_node_from_cstr(msg));
|
||||||
|
|
||||||
|
CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_CAPTURE, &buf, &cmd);
|
||||||
bool failed = !result.exited && result.exit_code != EXIT_SUCCESS &&
|
bool failed = !result.exited && result.exit_code != EXIT_SUCCESS &&
|
||||||
result.error == SHELL_ERR_OUT_BUF_FULL && strncmp(buf, msg, length) != 0;
|
result.error == SHELL_ERR_OUT_BUF_FULL && !wapp_str8_equal(&buf, &expected);
|
||||||
|
|
||||||
return wapp_tester_result(failed);
|
return wapp_tester_result(failed);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user