[anaconda-storage-branch PATCH] Fix up errors in doPwMount() (#491192)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Kickstart]     [Fedora Users]     [Fedora Legacy List]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]
  Powered by Linux