commit 7cdc7259c1b514197fee5a0d973f95fdf3347677
parent 2af5bbbb5355e9fcf311673f8051952c6b9b2509
Author: tgoodwin <tgoodwin>
Date: Tue, 17 Feb 1998 13:48:31 +0000
split some restartable syscall stuff out
don't declare slowbuf unless it's needed
Diffstat:
5 files changed, 40 insertions(+), 56 deletions(-)
diff --git a/Makefile.am b/Makefile.am
@@ -8,10 +8,20 @@ HISTBIN =
HISTMAN =
endif
+if H_R_S
+RDWR = rdwr-bsd.c
+ORDWR = rdwr.c
+else
+RDWR = rdwr.c
+ORDWR = rdwr-bsd.c
+endif
+
bin_PROGRAMS = rc
noinst_PROGRAMS = $(HISTBIN)
-rc_SOURCES = @ADDON@ builtins.c except.c exec.c execve.c fn.c footobar.c getopt.c glob.c glom.c hash.c heredoc.c input.c lex.c list.c main.c match.c nalloc.c open.c print.c redir.c sigmsgs.c signal.c status.c tree.c utils.c var.c wait.c walk.c which.c y.tab.c
+rc_SOURCES = @ADDON@ builtins.c except.c exec.c execve.c fn.c footobar.c getopt.c glob.c glom.c hash.c heredoc.c input.c lex.c list.c main.c match.c nalloc.c open.c print.c $(RDWR) redir.c sigmsgs.c signal.c status.c tree.c utils.c var.c wait.c walk.c which.c y.tab.c
+
+EXTRA_rc_SOURCES = $(ORDWR)
history_SOURCES = history.c
diff --git a/configure.ac b/configure.ac
@@ -137,6 +137,7 @@ main(){
esac
AC_SYS_RESTARTABLE_SYSCALLS
+AM_CONDITIONAL(H_R_S, test "$ac_cv_sys_restartable_syscalls" = yes)
dnl Do we have SysV SIGCLD semantics? In other words, if we set the
dnl action for SIGCLD to SIG_IGN does wait() always say ECHILD?
diff --git a/jbwrap.h b/jbwrap.h
@@ -1,9 +1,31 @@
#include <setjmp.h>
-/* certain braindamaged environments don't define jmp_buf as an array, so... */
+/* If we have POSIX sigjmp_buf and friends, use them. If we don't, just
+use a jmp_buf. This probably fails on a traditional SysV machine, where
+jmp_bufs don't preserve signal masks. I'm not worrying about this till
+someone reports it as a bug :-). */
+
+#if HAVE_SIGSETJMP
+#else
+#define sigjmp_buf jmp_buf
+#define sigsetjmp(x,y) setjmp(x)
+#define siglongjmp longjmp
+#endif /* HAVE_SIGSETJMP */
+
+
+/* Certain braindamaged environments don't define jmp_buf as an array,
+so wrap it in a structure. Potentially, we could use configure to do
+this only where it needs to be done, but the effort is probably not
+worth it. */
struct Jbwrap {
sigjmp_buf j;
};
-extern Jbwrap slowbuf; /* for getting out of interrupts while performing slow i/o on BSD */
+
+/* The slowbuf jump buffer is used to prevent "slow" system calls being
+restarted on systems like BSD where they are restarted after a signal. */
+
+#if HAVE_RESTARTABLE_SYSCALLS
+extern Jbwrap slowbuf;
+#endif
diff --git a/rc.h b/rc.h
@@ -36,14 +36,6 @@
#endif /*HAVE_SETPGRP */
-#if HAVE_SIGSETJMP
-/* Smells like POSIX. */
-#else
-/* Assume BSD. Probably fails on traditional SysV. */
-#define sigsetjmp setjmp
-#define siglongjmp longjmp
-#endif /* HAVE_SIGSETJMP */
-
typedef void builtin_t(char **);
typedef struct Block Block;
typedef struct Dup Dup;
@@ -366,6 +358,10 @@ extern Node *parsetree;
extern int yyparse(void);
extern void initparse(void);
+/* rdwr.c */
+extern void writeall(int, char *, size_t);
+extern int rc_read(int, char *, size_t);
+
/* redir.c */
extern void doredirs(void);
@@ -402,7 +398,6 @@ extern int starstrcmp(const void *, const void *);
extern void pr_error(char *);
extern void panic(char *);
extern void uerror(char *);
-extern void writeall(int, char *, size_t);
/* wait.c */
extern pid_t rc_fork(void);
@@ -414,4 +409,3 @@ extern bool forked;
/* walk.c */
extern bool walk(Node *, bool);
extern bool cond;
-
diff --git a/utils.c b/utils.c
@@ -65,49 +65,6 @@ extern bool isabsolute(char *path) {
return path[0] == '/' || (path[0] == '.' && (path[1] == '/' || (path[1] == '.' && path[2] == '/')));
}
-/* signal-safe read and write (for BSD slow devices). writeall also allows partial writes */
-static char *safe_buf;
-static size_t safe_remain;
-
-extern void writeall(int fd, char *buf, size_t remain) {
- int i;
-
- safe_buf = buf;
- safe_remain = remain;
- for (i = 0; safe_remain > 0; buf += i, safe_remain -= i) {
- interrupt_happened = FALSE;
- if (!sigsetjmp(slowbuf.j, 1)) {
- slow = TRUE;
- if (interrupt_happened)
- break;
- else if ((i = write(fd, safe_buf, safe_remain)) <= 0)
- break; /* abort silently on errors in write() */
- } else
- break;
- slow = FALSE;
- }
- slow = FALSE;
- sigchk();
-}
-
-extern int rc_read(int fd, char *buf, size_t n) {
- long /*ssize_t*/ r;
- interrupt_happened = FALSE;
- if (!sigsetjmp(slowbuf.j, 1)) {
- slow = TRUE;
- if (!interrupt_happened)
- r = read(fd, buf, n);
- else
- r = -2;
- } else
- r = -2;
- slow = FALSE;
- if (r == -2) {
- errno = EINTR;
- r = -1;
- }
- return r;
-}
/* duplicate a fd and close the old one only if necessary */