diff options
| author | Tristan Riehs <tristan.riehs@inria.fr> | 2026-01-25 17:58:22 +0100 |
|---|---|---|
| committer | Tristan Riehs <tristan.riehs@inria.fr> | 2026-01-25 17:58:22 +0100 |
| commit | 016ddf36a4f530bd79289baf106f21b716c877f0 (patch) | |
| tree | 90bb1332c543c953f46e24261fb1f14a2efad471 | |
| parent | 0d511aaa1f2bf147240605d288c348ef88407af2 (diff) | |
Factorize child process execution code
| -rw-r--r-- | src/main.c | 124 |
1 files changed, 66 insertions, 58 deletions
@@ -97,6 +97,40 @@ static void assert_db_exists(void) exit(EXIT_FAILURE); } +/* Execute command in a child process, then wait for the child to exit before + * returning. If any error occurs, including in the child process, then if EXIT + * is non-zero, exit, else return -1. Return 0 on success. */ +static int ftag_execvp(char *const *cmd, int can_exit) +{ + int status = 0; + int rc = fork(); + if (rc == 0) { + execvp(cmd[0], cmd); + fprintf(stderr, "exec: %s: ", cmd[0]); + perror(""); + } + else if (rc > 0) { + int status; + wait(&status); + if (!(WIFEXITED(status) && WEXITSTATUS(status) == 0)) { + fprintf(stderr, + "ftag: child process exited abnormally\n"); + if (can_exit) + exit(EXIT_FAILURE); + else + status = -1; + } + } + else { + perror("fork"); + if (can_exit) + exit(EXIT_FAILURE); + else + status = -1; + } + return status; +} + /* Copy the file whose path is IN at path OUT. OUT is created or overwritten if * needed. */ static void copy_file(const char *in, const char *out) @@ -138,39 +172,25 @@ static void copy_file(const char *in, const char *out) static void copy_file_with_encryption(const char *in, const char *out, enum encrypt encrypt) { - int rc = fork(); char *crypt_param; assert(encrypt == ENCRYPT || encrypt == DECRYPT); if (encrypt == ENCRYPT) crypt_param = "--encrypt"; else crypt_param = "--decrypt"; - if (rc == 0) { - execlp("gpg", - "gpg", - "--output", out, - "--yes", /* do not ask for overwriting files, maybe - * dangerous if GPG asks security questions */ - crypt_param, in, - NULL); - fprintf(stderr, "exec: gpg:"); - perror(""); - exit(EXIT_FAILURE); - } - else if (rc > 0) { - int status; - wait(&status); - if (!(WIFEXITED(status) && WEXITSTATUS(status) == 0)) { - fprintf(stderr, - "ftag file add: " - "child process exited abnormally\n"); - exit(EXIT_FAILURE); - } - } - else { - perror("fork"); - exit(EXIT_FAILURE); - } + /* use dups to suppress "discards const qualifier" warnings */ + char *in_dup = strdup(in); + char *out_dup = strdup(out); + char *cmd[] = { + "gpg", + "--output", out_dup, + "--yes", + crypt_param, in_dup, + NULL + }; + ftag_execvp(cmd, 1); + free(in_dup); + free(out_dup); } /* Prompt the user for yes or no (default is yes). Before calling, a prompt @@ -485,37 +505,25 @@ static void ftag_export(int argc, char **argv) free(line); /* step 3: invoke tar to build the archive */ - int error = 0; - rc = fork(); - if (rc == 0) { - execlp("tar", - "tar", - "--directory", "/tmp", - "--create", - "--gzip", - "--file", archive_file, - archive_dir, - NULL); - fprintf(stderr, "exec: tar:"); - perror(""); - exit(EXIT_FAILURE); - } - else if (rc > 0) { - int status; - wait(&status); - if (!(WIFEXITED(status) && WEXITSTATUS(status) == 0)) { - fprintf(stderr, "ftag export: child process exited abnormally\n"); - error = 1; - } - } - else { - perror("fork"); - error = 1; - } - - /* step 4: clean /tmp */ - execlp("rm", "rm", "--recursive", "--force", tmp_dir, NULL); - if (error) + char *cmd_tar[] = { + "tar", + "--directory", "/tmp", + "--create", + "--gzip", + "--file", archive_file, + archive_dir, + NULL + }; + rc = ftag_execvp(cmd_tar, 0); + char *cmd_rm[] = { + "rm", + "--recursive", + "--force", + tmp_dir, + NULL + }; + ftag_execvp(cmd_rm, 1); + if (rc != 0) exit(EXIT_FAILURE); } |
