From 996ee5db33fa849538b8214109a1ec99457195ef Mon Sep 17 00:00:00 2001 From: shivers Date: Sat, 24 Aug 1996 07:36:50 +0000 Subject: [PATCH] Hacked so that errno/intr error returns cause retries. --- scsh/fdports1.c | 51 ++++++++++++++++++++++++++++++++++++++------- scsh/fdports1.h | 2 +- scsh/jcontrol1.c | 2 ++ scsh/jcontrol2.scm | 1 + scsh/rdelim.scm | 26 ++++++++++++++--------- scsh/sighandlers1.c | 2 +- scsh/syscalls.c | 9 +++++--- scsh/syscalls.scm | 6 +++++- scsh/syscalls1.c | 32 ---------------------------- 9 files changed, 75 insertions(+), 56 deletions(-) diff --git a/scsh/fdports1.c b/scsh/fdports1.c index d610992..b87e084 100644 --- a/scsh/fdports1.c +++ b/scsh/fdports1.c @@ -179,12 +179,14 @@ int close_fdport(scheme_value port_data) int fd = EXTRACT_FIXNUM(*PortData_Fd(port_data)); FILE *f = fstar_cache[fd]; + if( fclose(f) ) return errno; + *PortData_Fd(port_data) = SCHFALSE; fdports[fd] = SCHFALSE; *PortData_Closed(port_data) = SCHTRUE; *PortData_Peek(port_data) = SCHFALSE; fstar_cache[fd] = NULL; - return fclose(f) ? errno : 0; + return 0; } else return EBADF; /* Already closed. */ } @@ -202,17 +204,23 @@ static int cloexec_fdport(scheme_value port_data) This is called right before an exec, which is sleazy; we should have the port-revealing machinery set and reset this value. + + If we get interrupted in the midst, we just bail out half-way. + The re-try loop will then have to repeat some work, but so what? + This whole function should go away. */ -void cloexec_unrevealed(void) +scheme_value cloexec_unrevealed(void) { int i; for(i=0; i 0) + return fread(p, 1, Min(len, fbufcount(f)), f); + + /* Otherwise, do a read. */ + return read(fileno(f), p, len); +} + #define MIN(a,b) (((a) < (b)) ? (a) : (b)) /* Not a function. */ int read_fdport_substring(scheme_value buf, int start, int end, scheme_value data) { - extern int read_stream_substring(scheme_value, int, int, FILE*); - scheme_value peek = *PortData_Peek(data); FILE *f = fstar_cache[EXTRACT_FIXNUM(*PortData_Fd(data))]; @@ -368,11 +400,14 @@ int read_fdport_substring(scheme_value buf, int start, int end, scheme_value dat return read_stream_substring(buf, start, end, f); } + +/* We assume either fileno(f) does blocking i/o or f is unbuffered. */ + int write_fdport_substring(scheme_value buf, int start, int end, scheme_value data) { - extern int write_stream_substring(scheme_value, int, int, FILE*); FILE *f = fstar_cache[EXTRACT_FIXNUM(*PortData_Fd(data))]; - return write_stream_substring(buf, start, end, f); + int retval = fwrite(StrByte(buf,start), 1, end-start, f); + return ferror(f) ? -1 : retval; /* -1: error, 0: eof */ } /* 1st return value says why we terminated the read: diff --git a/scsh/fdports1.h b/scsh/fdports1.h index 961b4d7..899ac0c 100644 --- a/scsh/fdports1.h +++ b/scsh/fdports1.h @@ -22,7 +22,7 @@ int set_fdbuf( scheme_value data, int policy, int bufsize ); int close_fdport(scheme_value port_data); -void cloexec_unrevealed(void); +scheme_value cloexec_unrevealed(void); int install_port(int fd, scheme_value port); diff --git a/scsh/jcontrol1.c b/scsh/jcontrol1.c index 6195947..973f78f 100644 --- a/scsh/jcontrol1.c +++ b/scsh/jcontrol1.c @@ -1,3 +1,5 @@ +/* This code is all obsolete & should be thrown away. 8/23/96 Olin. */ + #include #include #include diff --git a/scsh/jcontrol2.scm b/scsh/jcontrol2.scm index b09ae2f..d76c5f3 100644 --- a/scsh/jcontrol2.scm +++ b/scsh/jcontrol2.scm @@ -1,3 +1,4 @@ +;;; The signal-handling code in the last half of this file is obsolete. 8/23/96 ;;; Copyright (c) 1993 by Olin Shivers. ;;; Job control code. diff --git a/scsh/rdelim.scm b/scsh/rdelim.scm index d21ed1e..1827ac3 100644 --- a/scsh/rdelim.scm +++ b/scsh/rdelim.scm @@ -170,13 +170,16 @@ (if (fdport? port) ;; Direct C support for Unix file ports -- zippy quick. - (receive (terminator num-read) - (%read-delimited-fdport!/errno delims buf gobble? - port start end) - (if (integer? terminator) - (errno-error terminator %read-delimited! num-read - delims buf gobble? port start end) - (values terminator num-read))) + (let lp ((start start) (total 0)) + (receive (terminator num-read) + (%read-delimited-fdport!/errno delims buf gobble? + port start end) + (let ((total (+ num-read total))) + (cond ((not (integer? terminator)) (values terminator total)) + ((= terminator errno/intr) (lp (+ start num-read) total)) + (else (errno-error terminator %read-delimited! + num-read total + delims buf gobble? port start end)))))) ;; This is the code for other kinds of ports. ;; Mighty slow -- we read each char twice (peek first, then read). @@ -227,9 +230,12 @@ ;; Direct C support for Unix file ports -- zippy quick. ((fdport? port) - (receive (err num-read) (%skip-char-set-fdport/errno cset port) - (if err (errno-error err skip-char-set cset port num-read) - num-read))) + (let lp ((total 0)) + (receive (err num-read) (%skip-char-set-fdport/errno cset port) + (let ((total (+ total num-read))) + (cond ((not err) total) + ((= errno/intr err) (lp total)) + (errno-error err skip-char-set cset port total)))))) ;; This is the code for other kinds of ports. ;; Mighty slow -- we read each char twice (peek first, then read). diff --git a/scsh/sighandlers1.c b/scsh/sighandlers1.c index 3d0ef34..fdc675d 100644 --- a/scsh/sighandlers1.c +++ b/scsh/sighandlers1.c @@ -121,7 +121,7 @@ scheme_value set_sig_handler(int sig, scheme_value handler, int flags, return ENTER_FIXNUM(-1); } - /* We may need this for ohandler later, but it may get clobbered when + /* We may need this for ohandler later, but it may get clobbered ** when we set the new handler, so stash it away for now. */ old_scsh_handler = VECTOR_REF(Sinterrupt_handlersS, intnum); diff --git a/scsh/syscalls.c b/scsh/syscalls.c index 75f636c..48625f7 100644 --- a/scsh/syscalls.c +++ b/scsh/syscalls.c @@ -1042,11 +1042,14 @@ scheme_value df_init_fdports(long nargs, scheme_value *args) scheme_value df_cloexec_unrevealed(long nargs, scheme_value *args) { - extern void cloexec_unrevealed(void); + extern scheme_value cloexec_unrevealed(void); + scheme_value ret1; + scheme_value r1; cig_check_nargs(0, nargs, "cloexec_unrevealed"); - cloexec_unrevealed(); - return SCHFALSE; + r1 = cloexec_unrevealed(); + ret1 = r1; + return ret1; } scheme_value df_install_port(long nargs, scheme_value *args) diff --git a/scsh/syscalls.scm b/scsh/syscalls.scm index 7331966..4976177 100644 --- a/scsh/syscalls.scm +++ b/scsh/syscalls.scm @@ -1021,7 +1021,11 @@ (define-foreign %init-fdports! (init_fdports) ignore) -(define-foreign cloexec-unrevealed-ports (cloexec_unrevealed) ignore) +(define-foreign %cloexec-unrevealed-ports (cloexec_unrevealed) desc) + +(define (cloexec-unrevealed-ports) + ;; Loop if interrupted. + (and (%cloexec-unrevealed-ports) (cloexec-unrevealed-ports))) (define-foreign %install-port/errno (install_port (integer fd) (desc port)) diff --git a/scsh/syscalls1.c b/scsh/syscalls1.c index 3029410..7516214 100644 --- a/scsh/syscalls1.c +++ b/scsh/syscalls1.c @@ -261,43 +261,11 @@ int read_fdes_substring(scheme_value buf, int start, int end, int fd) return read(fd, StrByte(buf,start), end-start); } -#define Min(a,b) (((a) < (b)) ? (a) : (b)) /* Not a function. */ - -/* Note the clearerr() call. This is so a ^D on a tty input stream -** doesn't shut the stream down forever. SunOS doesn't handle this according -** to POSIX spec, so we have to explicitly hack this case. -*/ - -int read_stream_substring(scheme_value buf, int start, int end, FILE *f) -{ - char *p = StrByte(buf,start); - int len = end-start; - - clearerr(f); - - /* If there's data in the buffer, use it. */ - - if (fbufcount(f) > 0) - return fread(p, 1, Min(len, fbufcount(f)), f); - - /* Otherwise, do a read. */ - return read(fileno(f), p, len); -} - - int write_fdes_substring(scheme_value buf, int start, int end, int fd) { return write(fd, StrByte(buf,start), end-start); } -/* We assume either fileno(f) does blocking i/o or f is unbuffered. */ - -int write_stream_substring(scheme_value buf, int start, int end, FILE *f) -{ - int retval = fwrite(StrByte(buf,start), 1, end-start, f); - return ferror(f) ? -1 : retval; /* -1: error, 0: eof */ -} - /* ** Stat hackery