diff options
Diffstat (limited to 'src/commands/xargs.c')
-rw-r--r-- | src/commands/xargs.c | 187 |
1 files changed, 0 insertions, 187 deletions
diff --git a/src/commands/xargs.c b/src/commands/xargs.c deleted file mode 100644 index 3008c3c..0000000 --- a/src/commands/xargs.c +++ /dev/null @@ -1,187 +0,0 @@ -#include "../command.h" -#include <stdio.h> -#include <stdlib.h> - -static struct { - bool null_seperated; - bool ignore_empty; - bool print_command; - bool prompt_command; - int max_args; - FILE* file; -} flags; - -static void help(void) { - printf("Usage: xargs [OPTIONS] [PROG ARGS]\n\n"); - printf("Run PROG on every item given by stdin\n\n"); - printf("\t-0\tInput is separated by NULs\n"); - printf("\t-a FILE\tRead from FILE instead of stdin\n"); - printf("\t-r\tDon't run command if input is empty\n"); - printf("\t-t\tPrint the command on stderr before execution\n"); - printf("\t-p\tAsk user whether to run each command\n"); - printf("\t-n N\tPass no more than N args to PROG\n"); -} - -static int short_arg(char c, char* next) { - UNUSED(next); - - switch (c) { - case '0': - flags.null_seperated = true; - break; - case 'a': - check_arg(next); - flags.file = get_file(next, "r"); - return ARG_USED; - case 'r': - flags.ignore_empty = true; - break; - case 't': - flags.print_command = true; - break; - case 'p': - flags.prompt_command = true; - break; - case 'n': { - long int n; - - check_arg(next); - n = get_number(next); - - if (n < 1) { - error("max arg count must be at least 1"); - } - - flags.max_args = n; - return ARG_USED; - } - default: - return ARG_INVALID; - } - return ARG_UNUSED; -} - -char* read_next(FILE* file, int arg_count) { - - int size, capacity; - char* buf; - char c; - - if (flags.max_args != -1 && arg_count == flags.max_args) return NULL; - - size = 0; - capacity = 8; - buf = malloc(sizeof(char) * capacity); - - while(c = getc(file), true) { - if (c == EOF && size == 0) { - free(buf); - return NULL; - } - - if (size == capacity) { - capacity *= 2; - buf = realloc(buf, sizeof(char) * capacity); - } - - if (c == '\0' || c == EOF || (!flags.null_seperated && c == '\n')) { - buf[size++] = '\0'; - return buf; - } else { - buf[size++] = c; - } - } -} - -void read_args(FILE* file, char*** args, int* size, int* capacity) { - char* arg; - static int read = 0; - while (arg = read_next(file, read), true) { - if (*size == *capacity) { - *capacity *= 2; - *args = realloc(*args, sizeof(char*) * *capacity); - } - (*args)[(*size)++] = arg; - read++; - if (arg == NULL) break; - } -} - -COMMAND(xargs) { - - int start, arg_start, arg_on_stack_count; - int size, capacity, i; - char* command; - char** args; - - flags.null_seperated = false; - flags.ignore_empty = false; - flags.print_command = false; - flags.print_command = false; - flags.max_args = -1; - flags.file = stdin; - - start = parse_args(argc, argv, help, short_arg, NULL); - - if (start >= argc) { - command = "echo"; - } else { - command = argv[start]; - } - - arg_start = start + 1; - - if (arg_start >= argc) { - arg_on_stack_count = 0; - arg_start = argc - 1; - } else { - arg_on_stack_count = argc - arg_start; - } - - size = arg_on_stack_count + 1; - capacity = size + 8; - - args = malloc(sizeof(char*) * capacity); - args[0] = command; - memcpy(&args[1], &argv[arg_start], arg_on_stack_count * sizeof(char*)); - read_args(flags.file, &args, &size, &capacity); - - if (flags.ignore_empty && size < 2) goto cleanup; - - if (flags.prompt_command || flags.print_command) { - for (i = 0; i < size - 1; i++) { - fprintf(stderr, "%s ", args[i]); - } - fprintf(stderr, "\b\n"); - } - - if (flags.prompt_command) { - FILE* in; - char c; - - fprintf(stderr, "Run command? "); - fflush(stderr); - - in = get_tty_stream("r"); - c = getc(in); - fclose(in); - - if (c != 'y' && c != 'Y') { - fprintf(stderr, "Skipping...\n"); - goto cleanup; - } - } - - if (execvp(command, args) == -1) { - error("error: failed to execute command: %s", strerror(errno)); - } - -cleanup: - - for (i = arg_on_stack_count + 1; i < size - 1; i++) { - free(args[i]); - } - fclose(flags.file); - - return EXIT_SUCCESS; -} |