More fixes in doPwMount(). There is still a problem with collecting the output of stderr, but I'm considering that minor for now. --- isys/imount.c | 141 +++++++++++++++++++++++++++++++++++++++----------------- 1 files changed, 98 insertions(+), 43 deletions(-) diff --git a/isys/imount.c b/isys/imount.c index fd51fde..9b07ba7 100644 --- a/isys/imount.c +++ b/isys/imount.c @@ -27,6 +27,7 @@ #include <sys/wait.h> #include <unistd.h> +#include "isys.h" #include "imount.h" #include "sundries.h" @@ -69,9 +70,11 @@ static int readFD(int fd, char **buf) { } int doPwMount(char *dev, char *where, char *fs, char *options, char **err) { - int rc, child, status, pipefd[2]; - char *opts = NULL, *device; - int programLogFD; + int i = 0, child, status, pipefd[2]; + char *opts = NULL, *device = NULL; + char *args[] = {"/bin/mount", "-n", "-t", fs, NULL, where, + NULL, NULL, NULL}; + FILE *programLog = NULL; if (mkdirChain(where)) return IMOUNT_ERR_ERRNO; @@ -87,83 +90,135 @@ int doPwMount(char *dev, char *where, char *fs, char *options, char **err) { } else { opts = strdup("nolock"); } + device = strdup(dev); } else { if ((options && strstr(options, "bind") == NULL) && strncmp(dev, "LABEL=", 6) && strncmp(dev, "UUID=", 5) && *dev != '/') { - if (asprintf(&device, "/dev/%s", dev) == -1) { - fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__, - strerror(errno)); - fflush(stderr); - abort(); - } + if (asprintf(&device, "/dev/%s", dev) == -1) { + fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__, + strerror(errno)); + fflush(stderr); + abort(); + } } else { - device = strdup(dev); + device = strdup(dev); } + if (options) opts = strdup(options); } - programLogFD = open("/tmp/program.log", O_APPEND|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); + if (asprintf(&args[4], device) == -1) { + fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__, strerror(errno)); + fflush(stderr); + abort(); + } if (pipe(pipefd)) return IMOUNT_ERR_ERRNO; - if (!(child = fork())) { + child = fork(); + if (child == 0) { int fd; + /* We're not reading in this process */ close(pipefd[0]); /* Close stdin entirely, redirect stdout to /tmp/program.log, and - * redirect stderr to a pipe so we can put error messages into exceptions. - * We'll only use these messages should mount also return an error code. + * redirect stderr to a pipe so we can put error messages into + * exceptions. We'll only use these messages should mount also + * return an error code. */ - fd = open("/dev/tty5", O_RDONLY); - close(STDIN_FILENO); + fd = open("/dev/null", O_RDONLY); dup2(fd, STDIN_FILENO); close(fd); - close(STDOUT_FILENO); - dup2(programLogFD, STDOUT_FILENO); + /* send stdout to a predefined output terminal */ + fd = open(OUTPUT_TERMINAL, O_WRONLY); + dup2(fd, STDOUT_FILENO); + /* send stderr to the parent */ dup2(pipefd[1], STDERR_FILENO); + /* Add mount options to the argument list if caller specified them */ if (opts) { - fprintf(stdout, "Running... /bin/mount -n -t %s -o %s %s %s\n", - fs, opts, device, where); - rc = execl("/bin/mount", - "/bin/mount", "-n", "-t", fs, "-o", opts, device, where, NULL); - exit(1); + if (asprintf(&args[6], "-o") == -1) { + abort(); + } + + if (asprintf(&args[7], opts) == -1) { + abort(); + } } - else { - fprintf(stdout, "Running... /bin/mount -n -t %s %s %s\n", - fs, device, where); - rc = execl("/bin/mount", "/bin/mount", "-n", "-t", fs, device, where, NULL); - exit(1); + + /* Log what we are about to run */ + programLog = fopen("/tmp/program.log", "a"); + if (programLog == NULL) { + abort(); } - } - close(pipefd[1]); + fprintf(programLog, "Running... "); - if (err != NULL) { - if (*err != NULL) { - rc = readFD(pipefd[0], err); - rc = write(programLogFD, *err, 4096); + while (args[i] != NULL) { + if (i == 0) { + fprintf(programLog, "["); + } else { + fprintf(programLog, ", "); + } + + fprintf(programLog, "'%s'", args[i]); + i++; } - } - close(pipefd[0]); - waitpid(child, &status, 0); + fprintf(programLog, "]\n"); + fclose(programLog); - close(programLogFD); + /* Run the mount command */ + if (execv("/bin/mount", args) == -1) { + abort(); + } - free(opts); - free(device); - if (!WIFEXITED(status) || (WIFEXITED(status) && WEXITSTATUS(status))) - return IMOUNT_ERR_OTHER; + _exit(1); + } else if (child == -1) { + /* Strange things are afoot at the Circle K */ + abort(); + } else { + /* Only reading from the pipe in the parent */ + close(pipefd[1]); - return 0; + waitpid(child, &status, 0); + close(pipefd[0]); + + /* If the caller provided a pointer to a buffer to store error + * error messages, read any from the pipe and stuff them in the + * buffer. We allow the buffer to come to us as NULL, so allocate + * memory as necessary. Abort on read, write, and memory errors. + */ + if (err != NULL) { + if (*err == NULL) { + i = readFD(pipefd[0], err); + + if ((i != -1) && (*err != NULL)) { + programLog = fopen("/tmp/program.log", "a"); + if (programLog == NULL) { + abort(); + } + + fprintf(programLog, "%s", *err); + fclose(programLog); + } + } + } + + free(opts); + free(device); + if (!WIFEXITED(status) || (WIFEXITED(status) && WEXITSTATUS(status))) + return IMOUNT_ERR_OTHER; + + return 0; + } } int mkdirChain(char * origChain) { -- 1.6.2 _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list