diff options
Diffstat (limited to 'lib/commands')
| -rw-r--r-- | lib/commands/commands.c | 107 |
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 |
