commit 126b027d222133ed53d6a70f2a12642b074e43fd from: Omar Polo date: Wed Dec 01 08:48:04 2021 UTC rewrite spawn to use varargs it's seems neater than packing an array on the spot, we just do that inside spawn before calling execvp. If we get too many arguments, just abort. This also changes how the forking is handled: I set RVSEL only for the child and call disable_handlers() and endwin() preemptively to avoid possible races with our children. commit - c71d4135f19f596d4b3a1160284e8a94f3cbc831 commit + 126b027d222133ed53d6a70f2a12642b074e43fd blob - bae5608fa11859f9709db8b6ce80fe993f8db480 blob + a6f38957aa1cbf6053caa7c54d3e255e8ab1f28a --- fm.c +++ fm.c @@ -129,6 +129,7 @@ static struct state { #define MAX(A, B) ((A) > (B) ? (A) : (B)) #define ISDIR(E) (strchr((E), '/') != NULL) #define CTRL(x) ((x) & 0x1f) +#define nitems(a) (sizeof(a)/sizeof(a[0])) /* Line Editing Macros. */ #define EDIT_FULL(E) ((E).left == (E).right) @@ -393,23 +394,41 @@ get_user_programs() /* Do a fork-exec to external program (e.g. $EDITOR). */ static void -spawn(char **args) +spawn(const char *argv0, ...) { pid_t pid; int status; + size_t i; + const char *argv[16], *last; + va_list ap; - setenv("RVSEL", fm.nfiles ? ENAME(ESEL) : "", 1); - pid = fork(); - if (pid > 0) { - /* fork() succeeded. */ - disable_handlers(); - endwin(); + va_start(ap, argv0); + argv[0] = argv0; + for (i = 1; i < nitems(argv); ++i) { + last = va_arg(ap, const char *); + if (last == NULL) + break; + argv[i] = last; + } + va_end(ap); + + if (last != NULL) + abort(); + + disable_handlers(); + endwin(); + + switch (pid = fork()) { + case -1: + quit("fork"); + case 0: /* child */ + setenv("RVSEL", fm.nfiles ? ENAME(ESEL) : "", 1); + execvp(argv[0], (char *const *)argv); + quit("execvp"); + default: waitpid(pid, &status, 0); enable_handlers(); kill(getpid(), SIGWINCH); - } else if (pid == 0) { - /* Child process. */ - execvp(args[0], args); } } @@ -446,9 +465,9 @@ open_with_env(char *program, char *path) strncpy(BUF1, program, BUFLEN - 1); strncat(BUF1, " ", BUFLEN - strlen(program) - 1); shell_escaped_cat(BUF1, path, BUFLEN - strlen(program) - 2); - spawn((char *[]) { RV_SHELL, "-c", BUF1, NULL }); + spawn(RV_SHELL, "-c", BUF1, NULL ); #else - spawn((char *[]) { program, path, NULL }); + spawn(program, path, NULL); #endif return 1; }