[U-Boot] Sandbox: auto exiting on pipe closure

Mike Frysinger vapier at gentoo.org
Mon Apr 23 23:51:23 CEST 2012


On Monday 23 April 2012 02:41:08 Wolfgang Denk wrote:
> 2) Sandbox does no handle EOF on stadin; this makes it impossible to
>    use it in test scripts.  For example, something like this should
>    work:
> 
>    	$ echo printenv | ./u-boot
> 
>    [As woraround I have to use ``echo 'printenv;reset' | ./u-boot'';
>    this works, but is not really intuitive nore useful.]

(raw) patch below handles that.  it doesn't handle this though:
	./u-boot <<<help
but maybe i'm the only one who uses that form
-mike

diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c
index 36637af..a579b3c 100644
--- a/arch/sandbox/cpu/os.c
+++ b/arch/sandbox/cpu/os.c
@@ -22,6 +22,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <getopt.h>
+#include <poll.h>
 #include <stdlib.h>
 #include <termios.h>
 #include <time.h>
@@ -253,3 +254,43 @@ int os_parse_args(struct sandbox_state *state, int argc, char *argv[])
 
 	return 0;
 }
+
+static short os_poll_flags(short flags)
+{
+	short ret = 0;
+	if (flags & POLLIN)
+		ret |= OS_POLLIN;
+	if (flags & POLLHUP)
+		ret |= OS_POLLHUP;
+	return ret;
+}
+
+static short poll_flags(short os_flags)
+{
+	short ret = 0;
+	if (os_flags & OS_POLLIN)
+		ret |= POLLIN;
+	if (os_flags & OS_POLLHUP)
+		ret |= POLLHUP;
+	return ret;
+}
+
+int os_poll(struct os_pollfd *fds, ulong nfds, int timeout)
+{
+	struct pollfd _fds[nfds];
+	int ret;
+	ulong i;
+
+	for (i = 0; i < nfds; ++i) {
+		_fds[i].fd = fds[i].fd;
+		_fds[i].events = poll_flags(fds[i].events);
+		_fds[i].revents = poll_flags(fds[i].revents);
+	}
+	ret = poll(_fds, nfds, timeout);
+	for (i = 0; i < nfds; ++i) {
+		fds[i].fd = _fds[i].fd;
+		fds[i].events = os_poll_flags(_fds[i].events);
+		fds[i].revents = os_poll_flags(_fds[i].revents);
+	}
+	return ret;
+}
diff --git a/drivers/serial/sandbox.c b/drivers/serial/sandbox.c
index 1927c16..9d7ef6b 100644
--- a/drivers/serial/sandbox.c
+++ b/drivers/serial/sandbox.c
@@ -48,16 +48,30 @@ void serial_puts(const char *str)
 	os_write(1, str, strlen(str));
 }
 
+static short serial_tstc_timeout(int timeout)
+{
+	struct os_pollfd fds = {
+		.fd = 0,
+		.events = OS_POLLIN,
+	};
+
+	os_poll(&fds, 1, timeout);
+	return fds.revents;
+}
+
 int serial_getc(void)
 {
 	char buf;
-	ssize_t count;
+	short flags;
+
+	flags = serial_tstc_timeout(1);
+	if (!(flags & OS_POLLIN) && (flags & OS_POLLHUP))
+		os_exit(0);
 
-	count = os_read(0, &buf, 1);
-	return count == 1 ? buf : 0;
+	return os_read(0, &buf, 1) == 1 ? buf : 0;
 }
 
 int serial_tstc(void)
 {
-	return 0;
+	return !!(serial_tstc_timeout(0) & OS_POLLIN);
 }
diff --git a/include/os.h b/include/os.h
index 699682a..bc9fde2 100644
--- a/include/os.h
+++ b/include/os.h
@@ -136,4 +136,15 @@ u64 os_get_nsec(void);
  */
 int os_parse_args(struct sandbox_state *state, int argc, char *argv[]);
 
+struct os_pollfd {
+	int fd;
+	short events;
+	short revents;
+};
+
+#define OS_POLLIN 0x01
+#define OS_POLLHUP 0x10
+
+int os_poll(struct os_pollfd *fds, ulong nfds, int timeout);
+
 #endif


More information about the U-Boot mailing list