summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKoen Kooi <koen@openembedded.org>2007-11-02 08:22:15 +0000
committerKoen Kooi <koen@openembedded.org>2007-11-02 08:22:15 +0000
commit8590812f7560356ae5e1a1b6f66ccf5c6c5546ed (patch)
treea4c7d5b6c4f684fa3898ff6f35e3744d2d718d4f
parent1e74e6927b7f76871668b2ef3483fc6ff12f415f (diff)
pty: Commit by andrew :: r3327 /trunk/src/host/qemu-neo1973/pty.c: (link)
Avoid spinning after the slave pty closes.
-rw-r--r--packages/gsm/pty/pty.c30
-rw-r--r--packages/gsm/pty_0.0.bb1
2 files changed, 27 insertions, 4 deletions
diff --git a/packages/gsm/pty/pty.c b/packages/gsm/pty/pty.c
index 8e13d60f15..4a33d0efd3 100644
--- a/packages/gsm/pty/pty.c
+++ b/packages/gsm/pty/pty.c
@@ -22,6 +22,7 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
+#include <poll.h>
#define CHECK(val, name) \
if (val == -1) { \
@@ -32,7 +33,8 @@
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
-static int forward2(int in0, int out0, int in1, int out1) {
+static int forward2(int in0, int out0, int in1, int out1,
+ int (*closed)(int fd)) {
int inpos = 0, inlen = 0, outpos = 0, outlen = 0, ret, n;
fd_set rfds, wfds;
char in[0x100], out[0x100];
@@ -66,6 +68,13 @@ static int forward2(int in0, int out0, int in1, int out1) {
sizeof(out) - max(ret, outlen));
if (ret > 0)
outlen += ret;
+ if (ret < 0 && errno == EIO && closed) {
+ in1 = out0 = closed(in1);
+ if (in1 < 0)
+ return in1;
+ n = max(max(in0, in1), max(out0, out1)) + 1;
+ continue;
+ }
}
if (FD_ISSET(out0, &wfds)) {
ret = write(out0, in + inpos,
@@ -88,6 +97,19 @@ static int forward2(int in0, int out0, int in1, int out1) {
return pause();
}
+static int reopen(int fd) {
+ const char *name = ttyname(fd);
+
+ CHECK(close(fd), close(pty));
+ fd = open(name, O_RDWR | O_NOCTTY);
+ CHECK(fd, open);
+ CHECK(grantpt(fd), grantpt);
+ CHECK(unlockpt(fd), unlockpt);
+
+ fprintf(stderr, "%s\n", ptsname(fd));
+ return fd;
+}
+
int main(int argc, char *argv[], char **envp) {
int sock, fd;
struct sockaddr_in sa;
@@ -108,7 +130,7 @@ int main(int argc, char *argv[], char **envp) {
return pause();
#endif
if (argc != 3)
- return forward2(0, fd, fd, 1);
+ return forward2(0, fd, fd, 1, reopen);
#if 0
/* Connect a sub-process with a pty */
@@ -121,7 +143,7 @@ int main(int argc, char *argv[], char **envp) {
i = fileno(popen(param, O_RDWR));
CHECK(i, popen);
free(param);
- return forward2(i, fd, fd, i);
+ return forward2(i, fd, fd, i, reopen);
#endif
/* Connect a TCP socket with a pty */
@@ -137,5 +159,5 @@ int main(int argc, char *argv[], char **envp) {
CHECK(sock, socket);
CHECK(connect(sock, (struct sockaddr *) &sa, sizeof(sa)), connect);
- return forward2(sock, fd, fd, sock);
+ return forward2(sock, fd, fd, sock, reopen);
}
diff --git a/packages/gsm/pty_0.0.bb b/packages/gsm/pty_0.0.bb
index f6ed30bf1a..39592a90a1 100644
--- a/packages/gsm/pty_0.0.bb
+++ b/packages/gsm/pty_0.0.bb
@@ -1,5 +1,6 @@
DESCRIPTION = "Forwards a socket to a tty"
LICENSE = "GPLv2"
+PR = "r1"
SRC_URI = "file://pty.c"