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