aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTristan Riehs <tristan.riehs@inria.fr>2026-01-25 17:58:22 +0100
committerTristan Riehs <tristan.riehs@inria.fr>2026-01-25 17:58:22 +0100
commit016ddf36a4f530bd79289baf106f21b716c877f0 (patch)
tree90bb1332c543c953f46e24261fb1f14a2efad471
parent0d511aaa1f2bf147240605d288c348ef88407af2 (diff)
Factorize child process execution code
-rw-r--r--src/main.c124
1 files changed, 66 insertions, 58 deletions
diff --git a/src/main.c b/src/main.c
index 1107624..c33ea36 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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);
}