PERFORCE change 214483 for review

Brooks Davis brooks at FreeBSD.org
Mon Jul 16 21:33:00 UTC 2012


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

Change 214483 by brooks at brooks_ecr_current on 2012/07/16 21:32:32

	Only display one of the photos on the main screen so we can
	steal the right corner for the browser.  Rework child management
	to catch dead child processes in a SIGCHLD handler rather than
	polling periodically.

Affected files ...

.. //depot/projects/ctsrd/beribsd/src/ctsrd/pictview/img/Makefile#2 edit
.. //depot/projects/ctsrd/beribsd/src/ctsrd/pictview/img/browser-thumb.png#1 add
.. //depot/projects/ctsrd/beribsd/src/ctsrd/pictview/pictview.c#9 edit

Differences ...

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

@@ -7,6 +7,7 @@
 	CatSword.png		\
 	Quill.png		\
 	Terminal.png		\
+	browser-thumb.png	\
 	busy0.png		\
 	busy1.png		\
 	keyboardA.png		\

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

@@ -40,6 +40,7 @@
 #include <fcntl.h>
 #include <libutil.h>
 #include <poll.h>
+#include <signal.h>
 #include <stdarg.h>
 #include <stdbool.h>
 #include <string.h>
@@ -48,12 +49,31 @@
 
 #include <de4tc.h>
 
+static pid_t browser_pid;
+static pid_t kbd_pid;
 
 // send keyboard output to stdout by default
 static int kbdfd = 0;
 
 u_int32_t *fb_buf;
 
+static void
+handle_sigchld(int sig __unused)
+{
+  pid_t pid;
+
+  if ((pid = wait4(-1, NULL, 0, NULL)) < 1)
+    err(1, "wait4");
+  else {
+    if (pid == browser_pid)
+      browser_pid = 0;
+    else if (pid == kbd_pid)
+      kbd_pid = 0;
+    else
+      warnx("unexpected pid from wait4(): %d", pid);
+  }
+}
+
 void
 pen_drawing_clear_screen(void)
 {
@@ -174,7 +194,6 @@
   int wait_poll_timeout = poll_timeout;
 
   static int pmaster;
-  static pid_t pid;
   int pslave, n;
   char *devpath, buf[1024];
   ssize_t rlen;
@@ -209,13 +228,12 @@
   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)
+    kbd_pid = fork();
+    if (kbd_pid < 0)
       err(1, "fork()");
-    else if (pid > 0) {
+    else if (kbd_pid > 0) {
       close(pslave);
       kbdfd = pmaster;
     } else {
@@ -306,28 +324,26 @@
 	}
     
     if (kbdfd != 0) {
+      if (kbd_pid == 0)
+	break;
+
       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;
+      else if (n < 0) {
+        if (errno == EINTR)
+          continue;
+        err(1, "poll");
+      }
       if (n < 0) {
         syslog(LOG_ALERT, "poll failed with %s", strerror(errno));
 	err(1, "poll");
@@ -381,9 +397,10 @@
  * Picture viewer including PNG image loader
  *****************************************************************************/
 
-static const int pictview_numimg=6;
+static const int pictview_numimg=7;
 //static u_int32_t* pictview_imgs[pictview_numimg];
-static u_int32_t* pictview_imgs[6];
+static u_int32_t* pictview_imgs[7];
+static int pictview_browser_img;
 static int pictview_quill_img;
 static int pictview_term_img;
 static int pictview_num_photo;
@@ -429,8 +446,11 @@
   busy_indicator();
   read_png_file("/usr/share/images/Terminal.png",        pictview_imgs[5], fb_width, fb_height);
   busy_indicator();
+  read_png_file("/usr/share/images/browser-thumb.png",   pictview_imgs[6], fb_width, fb_height);
+  busy_indicator();
   pictview_quill_img = 4;
   pictview_term_img = 5;
+  pictview_browser_img = 6;
   pictview_num_photo = 3;
 }
 
@@ -454,8 +474,8 @@
   imgmap[2][1] = -1;
 
   imgmap[0][2] = 1;
-  imgmap[1][2] = 2;
-  imgmap[2][2] = 3;
+  imgmap[1][2] = -1;
+  imgmap[2][2] = pictview_browser_img;
 
   // display off
   fb_fade2off();
@@ -591,6 +611,70 @@
 
 
 void
+run_browser(void)
+{
+  static int pmaster;
+  int pslave, n;
+  char buf[1024];
+  ssize_t rlen;
+  struct pollfd pfd[1];
+  
+  if (openpty(&pmaster, &pslave, NULL, NULL, NULL) == -1)
+    err(1, "openpty");
+  browser_pid = fork();
+  if (browser_pid < 0)
+    err(1, "fork()");
+  else if (browser_pid > 0)
+    close(pslave);
+  else {
+    close(pmaster);
+    if (login_tty(pslave) < 0) {
+      syslog(LOG_ALERT, "login_tty failed in child: %s", strerror(errno));
+      err(1, "tty_login");
+    }
+    execl("/usr/bin/browser", "browser", "-f", "-T", "/demo", NULL);
+    syslog(LOG_ALERT, "exec of /usr/bin/browser failed: %s", strerror(errno));
+    err(1, "execl()");
+  }
+
+  for(;;) {
+    /*
+     * If the child has exited, reset the state and return to the
+     * main screen.
+     */
+    if (browser_pid == 0) {
+      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, INFTIM);
+    if (n == 0)
+      continue;
+    else if (n < 0) {
+      if (errno == EINTR)
+        continue;
+      err(1, "poll");
+    }
+    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);
+    }
+  }
+}
+
+
+void
 pictview_slideshow()
 {
   int j, k;
@@ -626,6 +710,8 @@
       // show_text_buffer();
     else if(display_image == pictview_quill_img)
       pen_drawing();
+    else if(display_image == pictview_browser_img)
+      run_browser();
     else if((display_image>=1) && (display_image<=pictview_num_photo))
       pictview_pan(display_image);
   }
@@ -638,6 +724,7 @@
 {
   int tty;
   char *devpath;
+  struct sigaction act;
 
   fb_buf = malloc(sizeof(*fb_buf) * fb_width * fb_height);
 
@@ -652,6 +739,11 @@
   // pen_drawing();
   // line_pattern();
 
+  memset (&act, 0, sizeof(act));
+  act.sa_handler = handle_sigchld;
+  if (sigaction(SIGCHLD, &act, 0))
+    err(1, "sigacation");
+
   if (argc > 2)
     errx(1, "usage: pictview [tty]");
   if (argc == 2) {


More information about the p4-projects mailing list