PERFORCE change 213635 for review

Brooks Davis brooks at FreeBSD.org
Fri Jun 29 04:06:19 UTC 2012


http://p4web.freebsd.org/@@213635?ac=10

Change 213635 by brooks at brooks_ecr_current on 2012/06/29 04:06:16

	Add proper support to ttys which allows pictview to be run by
	init from /etc/ttys.

Affected files ...

.. //depot/projects/ctsrd/beribsd/src/ctsrd/pictview/Makefile#5 edit
.. //depot/projects/ctsrd/beribsd/src/ctsrd/pictview/pictview.c#6 edit

Differences ...

==== //depot/projects/ctsrd/beribsd/src/ctsrd/pictview/Makefile#5 (text+ko) ====

@@ -9,7 +9,7 @@
 
 WARNS=	0
 
-LDADD+= 	 -lde4tc -lvuln_png -lz -lm
+LDADD+= 	 -lde4tc -lvuln_png -lz -lm -lutil
 # Disable the stack protector, we want to be vulnerable
 SSP_CFLAGS=
 

==== //depot/projects/ctsrd/beribsd/src/ctsrd/pictview/pictview.c#6 (text+ko) ====

@@ -29,16 +29,22 @@
  */
 
 #include <sys/types.h>
+#include <sys/ioctl.h>
 #include <sys/stat.h>
+#include <sys/wait.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <syslog.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <libutil.h>
+#include <poll.h>
 #include <stdarg.h>
-#include <fcntl.h>
+#include <stdbool.h>
+#include <string.h>
+#include <termios.h>
 #include <unistd.h>
-#include <errno.h>
-#include <err.h>
-#include <stdbool.h>
 
 #include <de4tc.h>
 
@@ -48,8 +54,6 @@
 
 u_int32_t *fb_buf;
 
-
-
 void
 pen_drawing_clear_screen(void)
 {
@@ -140,6 +144,20 @@
   read_png_file("/usr/share/images/keyboardC.png", keyboard_imgs[3], keyboard_width, keyboard_height);
 }
 
+static void
+writeall(int fd, const char *buf, size_t len)
+{
+  int wlen = 0, n;
+
+  while (wlen != len) {
+    n = write(fd, buf + wlen, len - wlen);
+    if (n < 0) {
+      syslog(LOG_ALERT, "write failed: %s", strerror(errno));
+      err(1, "write");
+    }
+    wlen += n;
+  }
+}
 
 void
 keyboard_on(void)
@@ -152,6 +170,16 @@
   int prev_keymode = -1;
   int keyYpos = fb_height-keyboard_height;
 
+  const int poll_timeout = touch_timeout;
+  int wait_poll_timeout = poll_timeout;
+
+  static int pmaster;
+  static pid_t pid;
+  int pslave, n;
+  char *devpath, buf[1024];
+  ssize_t rlen;
+  struct pollfd pfd[1];
+
   // extra mapping codes:
   // ctrl key  = \xff -> keymode=3
   // num key   = \xfe -> keymode=2
@@ -180,6 +208,28 @@
   keymap[1][1][3] = '\xff';
   keymap[2][1][3] = '\xff';
 
+  if (kbdfd < 0) {
+    /* XXX: need to handle the case of the shell exiting. */
+    if (openpty(&pmaster, &pslave, NULL, NULL, NULL) == -1)
+      err(1, "openpty");
+    pid = fork();
+    if (pid < 0)
+      err(1, "fork()");
+    else if (pid > 0) {
+      close(pslave);
+      kbdfd = pmaster;
+    } else {
+      close(pmaster);
+      if (login_tty(pslave) < 0) {
+        syslog(LOG_ALERT, "login_tty failed in child: %s", strerror(errno));
+	err(1, "tty_login");
+      }
+      execl("/bin/sh", "sh", NULL);
+      syslog(LOG_ALERT, "exec of /bin/sh failed: %s", strerror(errno));
+      err(1, "execl()");
+    }
+  }
+
   fb_fade2off();
   fb_fade2text(127);
   do {
@@ -236,9 +286,7 @@
 	  }
 	  if(ic < 0x80) {
 	    // printf("key = \"%c\" = 0x%02x\n", c, ic);
-            /* XXX: should handle full buffers */
-	    if (write(kbdfd, &c, 1) == -1)
-	      err(1, "write");
+	    writeall(kbdfd, &c, 1);
 	    // cancel shift and ctrl modes after character sent
 	    if((keymode==1) || (keymode==3))
 	      keymode=0;
@@ -256,6 +304,43 @@
 	    keyYpos -= fb_height; // put on screen
 	  prev_keymode = -1; // redraw keyboard
 	}
+    
+    if (kbdfd != 0) {
+      if (wait_poll_timeout > 0) {
+	wait_poll_timeout--;
+	continue;
+      }
+      wait_poll_timeout = poll_timeout;
+
+      /*
+       * If the child has exited, reset the state and return to the
+       * main screen.
+       */
+      if (wait4(pid, NULL, WNOHANG, NULL) != 0) {
+	kbdfd = -1;
+        close(pmaster);
+        break;
+      }
+
+      /* Check for output from the child and post it if needed */
+      pfd[0].fd = pmaster;
+      pfd[0].events = POLLIN;
+      n = poll(pfd, 1, 0);
+      if (n == 0)
+        continue;
+      if (n < 0) {
+        syslog(LOG_ALERT, "poll failed with %s", strerror(errno));
+	err(1, "poll");
+      }
+      if (pfd[0].revents & POLLIN) {
+        rlen = read(pfd[0].fd, buf, sizeof(buf));
+        if (rlen < 0) {
+          syslog(LOG_ALERT, "read failed: %s", strerror(errno));
+	  err(1, "read");
+        } else if (rlen > 0)
+	  writeall(0, buf, rlen);
+      }
+    }
   } while(!((touch_count==2) && (touch_gesture==0x49)));
 }
 
@@ -551,7 +636,7 @@
 int
 main(int argc, char *argv[])
 {
-  int ofd, pipefds[2];
+  int tty;
   pid_t pid;
   char *devpath;
 
@@ -571,34 +656,21 @@
   if (argc > 2)
     errx(1, "usage: pictview [tty]");
   if (argc == 2) {
-    if (pipe(pipefds) == -1)
-      err(1, "pipe()");
-    pid = fork();
-    if (pid < 0)
-      return (pid);
-    else if (pid > 0) {
-      /* XXX: should probably wait a bit and see if the child fails quickly */
-      kbdfd=pipefds[0];
-    } else {
-      if (dup2(pipefds[1], 0) == -1)
-        err(1, "dup2(%d, 0)", pipefds[1]);
-      if (argv[1][0] != '/')
-	asprintf(&devpath, "/dev/%s", argv[1]);
-      else
-	devpath = argv[1];
-      ofd = open(devpath, O_WRONLY);
-      if (ofd < 0)
-        err(1, "open(%s)", argv[1]);
-      if (dup2(ofd, 1) == -1) {
-        syslog(LOG_ALERT, "redir: dup2(%d, 1) failed with %d", ofd, errno);
-        exit(1);
-      }
-      if (dup2(ofd, 2) == -1) {
-        syslog(LOG_ALERT, "redir: dup2(%d, 2) failed with %d", ofd, errno);
-        exit(1);
-      }
-      execl("/bin/sh", "sh", "-i", NULL);
-      err(1, "execl()");
+    kbdfd = -1;
+    if (argv[1][0] != '/')
+      asprintf(&devpath, "/dev/%s", argv[1]);
+    else
+      devpath = argv[1];
+    syslog(LOG_ALERT, "opening '%s'", devpath);
+    if ((tty = open(devpath, O_RDWR)) < 0) {
+      syslog(LOG_ALERT, "open failed with %s", strerror(errno));
+      err(1, "open(%s)", devpath);
+    }
+    syslog(LOG_ALERT, "opened as %d", tty);
+
+    if (login_tty(tty) < 0) {
+      syslog(LOG_ALERT, "login_tty failed: %s", strerror(errno));
+      err(1, "login_tty()");
     }
   }
 


More information about the p4-projects mailing list