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));
|
int fd = EXTRACT_FIXNUM(*PortData_Fd(port_data));
|
||||||
FILE *f = fstar_cache[fd];
|
FILE *f = fstar_cache[fd];
|
||||||
|
|
||||||
|
if( fclose(f) ) return errno;
|
||||||
|
|
||||||
*PortData_Fd(port_data) = SCHFALSE;
|
*PortData_Fd(port_data) = SCHFALSE;
|
||||||
fdports[fd] = SCHFALSE;
|
fdports[fd] = SCHFALSE;
|
||||||
*PortData_Closed(port_data) = SCHTRUE;
|
*PortData_Closed(port_data) = SCHTRUE;
|
||||||
*PortData_Peek(port_data) = SCHFALSE;
|
*PortData_Peek(port_data) = SCHFALSE;
|
||||||
fstar_cache[fd] = NULL;
|
fstar_cache[fd] = NULL;
|
||||||
return fclose(f) ? errno : 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else return EBADF; /* Already closed. */
|
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;
|
This is called right before an exec, which is sleazy;
|
||||||
we should have the port-revealing machinery set and reset
|
we should have the port-revealing machinery set and reset
|
||||||
this value.
|
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;
|
int i;
|
||||||
for(i=0; i<NUM_FDPORTS; i++) {
|
for(i=0; i<NUM_FDPORTS; i++) {
|
||||||
scheme_value port = fdports[i];
|
scheme_value port = fdports[i];
|
||||||
if( port != SCHFALSE ) {
|
if( port != SCHFALSE ) {
|
||||||
scheme_value data = *Port_PortData(port);
|
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);
|
port, fd);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
#endif
|
#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. */
|
fdports[fd] = SCHFALSE; /* Drop the port. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -340,12 +351,33 @@ void post_gc_fdports(void)
|
||||||
}
|
}
|
||||||
#endif
|
#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. */
|
#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)
|
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);
|
scheme_value peek = *PortData_Peek(data);
|
||||||
FILE *f = fstar_cache[EXTRACT_FIXNUM(*PortData_Fd(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);
|
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)
|
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))];
|
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:
|
/* 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);
|
int close_fdport(scheme_value port_data);
|
||||||
|
|
||||||
void cloexec_unrevealed(void);
|
scheme_value cloexec_unrevealed(void);
|
||||||
|
|
||||||
int install_port(int fd, scheme_value port);
|
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 <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <signal.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.
|
;;; Copyright (c) 1993 by Olin Shivers.
|
||||||
;;; Job control code.
|
;;; Job control code.
|
||||||
|
|
||||||
|
|
|
@ -170,13 +170,16 @@
|
||||||
(if (fdport? port)
|
(if (fdport? port)
|
||||||
|
|
||||||
;; Direct C support for Unix file ports -- zippy quick.
|
;; Direct C support for Unix file ports -- zippy quick.
|
||||||
(receive (terminator num-read)
|
(let lp ((start start) (total 0))
|
||||||
(%read-delimited-fdport!/errno delims buf gobble?
|
(receive (terminator num-read)
|
||||||
port start end)
|
(%read-delimited-fdport!/errno delims buf gobble?
|
||||||
(if (integer? terminator)
|
port start end)
|
||||||
(errno-error terminator %read-delimited! num-read
|
(let ((total (+ num-read total)))
|
||||||
delims buf gobble? port start end)
|
(cond ((not (integer? terminator)) (values terminator total))
|
||||||
(values terminator num-read)))
|
((= 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.
|
;; This is the code for other kinds of ports.
|
||||||
;; Mighty slow -- we read each char twice (peek first, then read).
|
;; Mighty slow -- we read each char twice (peek first, then read).
|
||||||
|
@ -227,9 +230,12 @@
|
||||||
|
|
||||||
;; Direct C support for Unix file ports -- zippy quick.
|
;; Direct C support for Unix file ports -- zippy quick.
|
||||||
((fdport? port)
|
((fdport? port)
|
||||||
(receive (err num-read) (%skip-char-set-fdport/errno cset port)
|
(let lp ((total 0))
|
||||||
(if err (errno-error err skip-char-set cset port num-read)
|
(receive (err num-read) (%skip-char-set-fdport/errno cset port)
|
||||||
num-read)))
|
(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.
|
;; This is the code for other kinds of ports.
|
||||||
;; Mighty slow -- we read each char twice (peek first, then read).
|
;; 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);
|
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.
|
** when we set the new handler, so stash it away for now.
|
||||||
*/
|
*/
|
||||||
old_scsh_handler = VECTOR_REF(Sinterrupt_handlersS, intnum);
|
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)
|
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");
|
cig_check_nargs(0, nargs, "cloexec_unrevealed");
|
||||||
cloexec_unrevealed();
|
r1 = cloexec_unrevealed();
|
||||||
return SCHFALSE;
|
ret1 = r1;
|
||||||
|
return ret1;
|
||||||
}
|
}
|
||||||
|
|
||||||
scheme_value df_install_port(long nargs, scheme_value *args)
|
scheme_value df_install_port(long nargs, scheme_value *args)
|
||||||
|
|
|
@ -1021,7 +1021,11 @@
|
||||||
|
|
||||||
(define-foreign %init-fdports! (init_fdports) ignore)
|
(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
|
(define-foreign %install-port/errno
|
||||||
(install_port (integer fd) (desc port))
|
(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);
|
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)
|
int write_fdes_substring(scheme_value buf, int start, int end, int fd)
|
||||||
{
|
{
|
||||||
return write(fd, StrByte(buf,start), end-start);
|
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
|
** Stat hackery
|
||||||
|
|
Loading…
Reference in New Issue