Hacked so that errno/intr error returns cause retries.
This commit is contained in:
parent
060badffa7
commit
996ee5db33
|
@ -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<NUM_FDPORTS; i++) {
|
||||
scheme_value port = fdports[i];
|
||||
if( port != SCHFALSE ) {
|
||||
scheme_value data = *Port_PortData(port);
|
||||
if( *PortData_Rev(data) == 0 ) cloexec_fdport(data);
|
||||
if( *PortData_Rev(data) == 0 )
|
||||
if( cloexec_fdport(data) == EINTR ) return ENTER_FIXNUM(EINTR);
|
||||
}
|
||||
}
|
||||
return SCHFALSE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -329,7 +337,10 @@ void post_gc_fdports(void)
|
|||
port, fd);
|
||||
fflush(stderr);
|
||||
#endif
|
||||
if( rev == 0 ) close_fdport(*Port_PortData(port));
|
||||
if( rev == 0 )
|
||||
/* Close, even if interrupted -- GC's must be atomic. */
|
||||
while( EINTR == close_fdport(*Port_PortData(port)) );
|
||||
|
||||
fdports[fd] = SCHFALSE; /* Drop the port. */
|
||||
}
|
||||
}
|
||||
|
@ -340,12 +351,33 @@ void post_gc_fdports(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#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.
|
||||
*/
|
||||
|
||||
static 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);
|
||||
}
|
||||
|
||||
#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:
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* This code is all obsolete & should be thrown away. 8/23/96 Olin. */
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue