aboutsummaryrefslogtreecommitdiff
path: root/lib/commands
diff options
context:
space:
mode:
Diffstat (limited to 'lib/commands')
-rw-r--r--lib/commands/commands.c107
1 files changed, 49 insertions, 58 deletions
diff --git a/lib/commands/commands.c b/lib/commands/commands.c
index 80710387..4a6272b9 100644
--- a/lib/commands/commands.c
+++ b/lib/commands/commands.c
@@ -18,16 +18,14 @@
#define WRITE_END 1
static void xpipe(int fd[2]) {
- if (pipe(fd) != 0)
- fail("Failed to create pipe: ", strerror(errno));
+ if (pipe(fd) != 0) fail("Failed to create pipe: ", strerror(errno));
}
-int run_command(Text_t exe, List_t arg_list, Table_t env_table,
- OptionalList_t input_bytes, List_t *output_bytes, List_t *error_bytes)
-{
+int run_command(Text_t exe, List_t arg_list, Table_t env_table, OptionalList_t input_bytes, List_t *output_bytes,
+ List_t *error_bytes) {
pthread_testcancel();
- struct sigaction sa = { .sa_handler = SIG_IGN }, oldint, oldquit;
+ struct sigaction sa = {.sa_handler = SIG_IGN}, oldint, oldquit;
sigaction(SIGINT, &sa, &oldint);
sigaction(SIGQUIT, &sa, &oldquit);
sigaddset(&sa.sa_mask, SIGCHLD);
@@ -40,7 +38,7 @@ int run_command(Text_t exe, List_t arg_list, Table_t env_table,
posix_spawnattr_init(&attr);
posix_spawnattr_setsigmask(&attr, &old);
posix_spawnattr_setsigdefault(&attr, &reset);
- posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSIGDEF|POSIX_SPAWN_SETSIGMASK);
+ posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK);
int child_inpipe[2], child_outpipe[2], child_errpipe[2];
if (input_bytes.length >= 0) xpipe(child_inpipe);
@@ -65,10 +63,11 @@ int run_command(Text_t exe, List_t arg_list, Table_t env_table,
const char *exe_str = Text$as_c_string(exe);
List_t arg_strs = {};
- List$insert_value(&arg_strs, exe_str, I(0), sizeof(char*));
+ List$insert_value(&arg_strs, exe_str, I(0), sizeof(char *));
for (int64_t i = 0; i < arg_list.length; i++)
- List$insert_value(&arg_strs, Text$as_c_string(*(Text_t*)(arg_list.data + i*arg_list.stride)), I(0), sizeof(char*));
- List$insert_value(&arg_strs, NULL, I(0), sizeof(char*));
+ List$insert_value(&arg_strs, Text$as_c_string(*(Text_t *)(arg_list.data + i * arg_list.stride)), I(0),
+ sizeof(char *));
+ List$insert_value(&arg_strs, NULL, I(0), sizeof(char *));
char **args = arg_strs.data;
extern char **environ;
@@ -76,24 +75,24 @@ int run_command(Text_t exe, List_t arg_list, Table_t env_table,
if (env_table.entries.length > 0) {
List_t env_list = {}; // List of const char*
for (char **e = environ; *e; e++)
- List$insert(&env_list, e, I(0), sizeof(char*));
+ List$insert(&env_list, e, I(0), sizeof(char *));
for (int64_t i = 0; i < env_table.entries.length; i++) {
- struct { Text_t key, value; } *entry = env_table.entries.data + env_table.entries.stride*i;
+ struct {
+ Text_t key, value;
+ } *entry = env_table.entries.data + env_table.entries.stride * i;
const char *env_entry = String(entry->key, "=", entry->value);
- List$insert(&env_list, &env_entry, I(0), sizeof(char*));
+ List$insert(&env_list, &env_entry, I(0), sizeof(char *));
}
- List$insert_value(&env_list, NULL, I(0), sizeof(char*));
- assert(env_list.stride == sizeof(char*));
+ List$insert_value(&env_list, NULL, I(0), sizeof(char *));
+ assert(env_list.stride == sizeof(char *));
env = env_list.data;
}
pid_t pid;
- int ret = exe_str[0] == '/' ?
- posix_spawn(&pid, exe_str, &actions, &attr, args, env)
- : posix_spawnp(&pid, exe_str, &actions, &attr, args, env);
- if (ret != 0)
- return -1;
+ int ret = exe_str[0] == '/' ? posix_spawn(&pid, exe_str, &actions, &attr, args, env)
+ : posix_spawnp(&pid, exe_str, &actions, &attr, args, env);
+ if (ret != 0) return -1;
posix_spawnattr_destroy(&attr);
posix_spawn_file_actions_destroy(&actions);
@@ -103,19 +102,16 @@ int run_command(Text_t exe, List_t arg_list, Table_t env_table,
if (error_bytes) close(child_errpipe[WRITE_END]);
struct pollfd pollfds[3] = {};
- if (input_bytes.length >= 0) pollfds[0] = (struct pollfd){.fd=child_inpipe[WRITE_END], .events=POLLOUT};
- if (output_bytes) pollfds[1] = (struct pollfd){.fd=child_outpipe[WRITE_END], .events=POLLIN};
- if (error_bytes) pollfds[2] = (struct pollfd){.fd=child_errpipe[WRITE_END], .events=POLLIN};
+ if (input_bytes.length >= 0) pollfds[0] = (struct pollfd){.fd = child_inpipe[WRITE_END], .events = POLLOUT};
+ if (output_bytes) pollfds[1] = (struct pollfd){.fd = child_outpipe[WRITE_END], .events = POLLIN};
+ if (error_bytes) pollfds[2] = (struct pollfd){.fd = child_errpipe[WRITE_END], .events = POLLIN};
- if (input_bytes.length > 0 && input_bytes.stride != 1)
- List$compact(&input_bytes, sizeof(char));
- if (output_bytes)
- *output_bytes = (List_t){.atomic=1, .stride=1, .length=0};
- if (error_bytes)
- *error_bytes = (List_t){.atomic=1, .stride=1, .length=0};
+ if (input_bytes.length > 0 && input_bytes.stride != 1) List$compact(&input_bytes, sizeof(char));
+ if (output_bytes) *output_bytes = (List_t){.atomic = 1, .stride = 1, .length = 0};
+ if (error_bytes) *error_bytes = (List_t){.atomic = 1, .stride = 1, .length = 0};
while (input_bytes.length > 0 || output_bytes || error_bytes) {
- (void)poll(pollfds, sizeof(pollfds)/sizeof(pollfds[0]), -1); // Wait for data or readiness
+ (void)poll(pollfds, sizeof(pollfds) / sizeof(pollfds[0]), -1); // Wait for data or readiness
bool did_something = false;
if (input_bytes.length >= 0 && pollfds[0].revents) {
if (input_bytes.length > 0) {
@@ -171,10 +167,8 @@ int run_command(Text_t exe, List_t arg_list, Table_t env_table,
int status = 0;
if (ret == 0) {
while (waitpid(pid, &status, 0) < 0 && errno == EINTR) {
- if (WIFEXITED(status) || WIFSIGNALED(status))
- break;
- else if (WIFSTOPPED(status))
- kill(pid, SIGCONT);
+ if (WIFEXITED(status) || WIFSIGNALED(status)) break;
+ else if (WIFSTOPPED(status)) kill(pid, SIGCONT);
}
}
@@ -195,8 +189,7 @@ typedef struct {
FILE *out;
} child_info_t;
-static void _line_reader_cleanup(child_info_t *child)
-{
+static void _line_reader_cleanup(child_info_t *child) {
if (child && child->out) {
fclose(child->out);
child->out = NULL;
@@ -207,8 +200,7 @@ static void _line_reader_cleanup(child_info_t *child)
}
}
-static Text_t _next_line(child_info_t *child)
-{
+static Text_t _next_line(child_info_t *child) {
if (!child || !child->out) return NONE_TEXT;
char *line = NULL;
@@ -219,19 +211,17 @@ static Text_t _next_line(child_info_t *child)
return NONE_TEXT;
}
- while (len > 0 && (line[len-1] == '\r' || line[len-1] == '\n'))
+ while (len > 0 && (line[len - 1] == '\r' || line[len - 1] == '\n'))
--len;
- if (u8_check((uint8_t*)line, (size_t)len) != NULL)
- fail("Invalid UTF8!");
+ if (u8_check((uint8_t *)line, (size_t)len) != NULL) fail("Invalid UTF8!");
Text_t line_text = Text$from_strn(line, len);
free(line);
return line_text;
}
-OptionalClosure_t command_by_line(Text_t exe, List_t arg_list, Table_t env_table)
-{
+OptionalClosure_t command_by_line(Text_t exe, List_t arg_list, Table_t env_table) {
posix_spawnattr_t attr;
posix_spawnattr_init(&attr);
@@ -246,10 +236,11 @@ OptionalClosure_t command_by_line(Text_t exe, List_t arg_list, Table_t env_table
const char *exe_str = Text$as_c_string(exe);
List_t arg_strs = {};
- List$insert_value(&arg_strs, exe_str, I(0), sizeof(char*));
+ List$insert_value(&arg_strs, exe_str, I(0), sizeof(char *));
for (int64_t i = 0; i < arg_list.length; i++)
- List$insert_value(&arg_strs, Text$as_c_string(*(Text_t*)(arg_list.data + i*arg_list.stride)), I(0), sizeof(char*));
- List$insert_value(&arg_strs, NULL, I(0), sizeof(char*));
+ List$insert_value(&arg_strs, Text$as_c_string(*(Text_t *)(arg_list.data + i * arg_list.stride)), I(0),
+ sizeof(char *));
+ List$insert_value(&arg_strs, NULL, I(0), sizeof(char *));
char **args = arg_strs.data;
extern char **environ;
@@ -257,24 +248,24 @@ OptionalClosure_t command_by_line(Text_t exe, List_t arg_list, Table_t env_table
if (env_table.entries.length > 0) {
List_t env_list = {}; // List of const char*
for (char **e = environ; *e; e++)
- List$insert(&env_list, e, I(0), sizeof(char*));
+ List$insert(&env_list, e, I(0), sizeof(char *));
for (int64_t i = 0; i < env_table.entries.length; i++) {
- struct { Text_t key, value; } *entry = env_table.entries.data + env_table.entries.stride*i;
+ struct {
+ Text_t key, value;
+ } *entry = env_table.entries.data + env_table.entries.stride * i;
const char *env_entry = String(entry->key, "=", entry->value);
- List$insert(&env_list, &env_entry, I(0), sizeof(char*));
+ List$insert(&env_list, &env_entry, I(0), sizeof(char *));
}
- List$insert_value(&env_list, NULL, I(0), sizeof(char*));
- assert(env_list.stride == sizeof(char*));
+ List$insert_value(&env_list, NULL, I(0), sizeof(char *));
+ assert(env_list.stride == sizeof(char *));
env = env_list.data;
}
pid_t pid;
- int ret = exe_str[0] == '/' ?
- posix_spawn(&pid, exe_str, &actions, &attr, args, env)
- : posix_spawnp(&pid, exe_str, &actions, &attr, args, env);
- if (ret != 0)
- return NONE_CLOSURE;
+ int ret = exe_str[0] == '/' ? posix_spawn(&pid, exe_str, &actions, &attr, args, env)
+ : posix_spawnp(&pid, exe_str, &actions, &attr, args, env);
+ if (ret != 0) return NONE_CLOSURE;
posix_spawnattr_destroy(&attr);
posix_spawn_file_actions_destroy(&actions);
@@ -284,8 +275,8 @@ OptionalClosure_t command_by_line(Text_t exe, List_t arg_list, Table_t env_table
child_info_t *child_info = GC_MALLOC(sizeof(child_info_t));
child_info->out = fdopen(child_outpipe[READ_END], "r");
child_info->pid = pid;
- GC_register_finalizer(child_info, (void*)_line_reader_cleanup, NULL, NULL, NULL);
- return (Closure_t){.fn=(void*)_next_line, .userdata=child_info};
+ GC_register_finalizer(child_info, (void *)_line_reader_cleanup, NULL, NULL, NULL);
+ return (Closure_t){.fn = (void *)_next_line, .userdata = child_info};
}
#undef READ_END