summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--input.c10
-rw-r--r--open.c18
-rw-r--r--proto.h2
-rw-r--r--rc.h1
5 files changed, 35 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 2a61ade..7f48915 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -674,3 +674,8 @@ Changes since rc-1.5b2
Bug: fn sigexit wasn't always cleared in child shells.
Bug: `~ () '*'' dumped core.
+
+2000-05-25
+
+ Portability: need special runes for read() returning EIO under job
+ control systems.
diff --git a/input.c b/input.c
index f59f29e..0f649e4 100644
--- a/input.c
+++ b/input.c
@@ -117,10 +117,18 @@ static int fdgchar() {
do {
r = rc_read(istack->fd, inbuf + 2, BUFSIZE);
sigchk();
- if (errno == EAGAIN) {
+ switch (errno) {
+ case EAGAIN:
if (!makeblocking(istack->fd))
panic("not O_NONBLOCK");
errno = EINTR;
+ break;
+ case EIO:
+ if (makesamepgrp(istack->fd))
+ errno = EINTR;
+ else
+ errno = EIO;
+ break;
}
} while (r < 0 && errno == EINTR);
if (r < 0) {
diff --git a/open.c b/open.c
index bac9f2c..60555b0 100644
--- a/open.c
+++ b/open.c
@@ -43,3 +43,21 @@ extern bool makeblocking(int fd) {
}
return TRUE;
}
+
+/* make a file descriptor the same pgrp as us. Returns TRUE if
+it changes anything. */
+
+extern bool makesamepgrp(int fd) {
+ pid_t grp;
+
+ grp = getpgrp();
+
+ if (tcgetpgrp(fd) == grp)
+ return FALSE;
+
+ if (tcsetpgrp(fd, grp) < 0) {
+ uerror("tcsetgrp");
+ return FALSE;
+ }
+ return TRUE;
+}
diff --git a/proto.h b/proto.h
index 7d2fe2a..517d357 100644
--- a/proto.h
+++ b/proto.h
@@ -79,6 +79,7 @@ extern char *sys_errlist[];
#else
/* BSD: fake it. */
#define setpgid(pid, pgrp) setpgrp(pid, pgrp)
+#define tcgetpgrp(fd, pgrp) ioctl((fd), TIOCGPGRP)
#define tcsetpgrp(fd, pgrp) ioctl((fd), TIOCSPGRP, &(pgrp))
#endif
@@ -86,6 +87,7 @@ extern char *sys_errlist[];
/* Nothing doing. */
#define setpgid()
+#define tcgetpgrp()
#define tcsetpgrp()
#endif /*HAVE_SETPGRP */
diff --git a/rc.h b/rc.h
index f582bd4..1ed5a07 100644
--- a/rc.h
+++ b/rc.h
@@ -305,6 +305,7 @@ extern void restoreblock(Block *);
/* open.c */
extern int rc_open(const char *, redirtype);
extern bool makeblocking(int);
+extern bool makesamepgrp(int);
/* print.c */
/*