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