]> diplodocus.org Git - nmh/blobdiff - test/runpty.c
getcpy.c: Move interface to own file.
[nmh] / test / runpty.c
index e8db35f2ebdf2451fa0f3e0841da4cde59e2a69a..661d8753c343175cd5dabf7d2fc6620eacd5f4a7 100644 (file)
@@ -1,5 +1,4 @@
-/*
- * runpty.c - Run a process under a pseudo-tty
+/* runpty.c - Run a process under a pseudo-tty
  *
  * This code is Copyright (c) 2017, by the authors of nmh.  See the
  * COPYRIGHT file in the root directory of the nmh distribution for
 
 #define COMMAND_TIMEOUT 30
 
+static void run_command(char *argv[], int master_in, int master_out);
+static int open_master_pty(const char *desc);
 static void die(const char *fmt, ...);
 
 int
 main(int argc, char *argv[])
 {
-    int master_in, master_out, slave, cc, status;
+    int master_in, master_out, cc, status;
     time_t starttime, now;
-    const char *slavename;
     pid_t child;
     unsigned char readbuf[1024];
     FILE *output;
@@ -39,75 +39,14 @@ main(int argc, char *argv[])
             *argv, *argv);
     }
 
-    if ((master_in = posix_openpt(O_RDWR | O_NOCTTY)) < 0) {
-       die("Unable to open master pseudo-tty: %s\n", strerror(errno));
-    }
-
-    if ((master_out = posix_openpt(O_RDWR | O_NOCTTY)) < 0) {
-       die("Unable to open master pseudo-tty: %s\n", strerror(errno));
-    }
-
-    if (grantpt(master_in) < 0) {
-       die("Unable to grant permissions to master pty: %s\n",
-            strerror(errno));
-    }
-
-    if (grantpt(master_out) < 0) {
-       die("Unable to grant permissions to master pty: %s\n",
-            strerror(errno));
-    }
-
-    if (unlockpt(master_in) < 0) {
-       die("Unable to unlock master pty: %s\n", strerror(errno));
-    }
+    master_in = open_master_pty("input");
+    master_out = open_master_pty("output");
 
-    if (unlockpt(master_out) < 0) {
-       die("Unable to unlock master pty: %s\n", strerror(errno));
+    if ((child = fork()) == -1) {
+       die("fork() failed: %s\n", strerror(errno));
     }
-
-    child = fork();
-
-    /*
-     * Start the child process if we are in the child; open the two
-     * slave pseudo-ttys and close the masters after we are done with them.
-     */
-
     if (child == 0) {
-       if (!(slavename = ptsname(master_in))) {
-           die("Unable to determine name of slave pty: %s\n",
-                strerror(errno));
-       }
-
-       if ((slave = open(slavename, O_RDWR)) < 0) {
-           die("Unable to open slave pty \"%s\": %s\n", slavename,
-                strerror(errno));
-       }
-
-       dup2(slave, STDIN_FILENO);
-       close(slave);
-       close(master_in);
-
-       if (!(slavename = ptsname(master_out))) {
-           die("Unable to determine name of slave pty: %s\n",
-                strerror(errno));
-       }
-
-       if ((slave = open(slavename, O_RDWR | O_NOCTTY)) < 0) {
-           die("Unable to open slave pty \"%s\": %s\n", slavename,
-                strerror(errno));
-       }
-
-       dup2(slave, STDOUT_FILENO);
-       dup2(slave, STDERR_FILENO);
-       close(slave);
-       close(master_out);
-
-       execvp(argv[2], argv + 2);
-
-       die("execvp(%s) failed: %s\n", argv[2], strerror(errno));
-
-    } else if (child < 0) {
-       die("fork() failed: %s\n", strerror(errno));
+        run_command(argv + 2, master_in, master_out); /* Does not return. */
     }
 
     if (!(output = fopen(argv[1], "w"))) {
@@ -174,6 +113,68 @@ main(int argc, char *argv[])
     exit(0);
 }
 
+static void
+run_command(char *argv[], int master_in, int master_out)
+{
+    const char *slavename;
+    int slave;
+
+    /* Open the two slave pseudo-ttys and close the masters after we are
+     * done with them. */
+
+    if (!(slavename = ptsname(master_in))) {
+        die("Unable to determine name of slave pty: %s\n",
+            strerror(errno));
+    }
+
+    if ((slave = open(slavename, O_RDWR)) == -1) {
+        die("Unable to open slave pty \"%s\": %s\n", slavename,
+            strerror(errno));
+    }
+
+    dup2(slave, STDIN_FILENO);
+    close(slave);
+    close(master_in);
+
+    if (!(slavename = ptsname(master_out))) {
+        die("Unable to determine name of slave pty: %s\n",
+            strerror(errno));
+    }
+
+    if ((slave = open(slavename, O_RDWR | O_NOCTTY)) < 0) {
+        die("Unable to open slave pty \"%s\": %s\n", slavename,
+            strerror(errno));
+    }
+
+    dup2(slave, STDOUT_FILENO);
+    dup2(slave, STDERR_FILENO);
+    close(slave);
+    close(master_out);
+
+    execvp(*argv, argv);
+
+    die("execvp(%s) failed: %s\n", *argv, strerror(errno));
+}
+
+static int
+open_master_pty(const char *desc)
+{
+    int fd;
+
+    if ((fd = posix_openpt(O_RDWR | O_NOCTTY)) == -1) {
+       die("Unable to open master %s pseudo-tty: %s\n", desc, strerror(errno));
+    }
+    if (grantpt(fd) == -1) {
+       die("Unable to grant permissions to master %s pty: %s\n", desc,
+            strerror(errno));
+    }
+    if (unlockpt(fd) == -1) {
+       die("Unable to unlock master %s pty: %s\n", desc, strerror(errno));
+    }
+
+    return fd;
+}
+
 static void
 die(const char *fmt, ...)
 {