Now imports machine/stdio_dep.h interface spec.
This commit is contained in:
parent
bc338f2d53
commit
4ae0a89c53
|
@ -28,6 +28,7 @@
|
|||
#include "cstuff.h"
|
||||
#define NUM_FDPORTS 256
|
||||
#include "fdports.h"
|
||||
#include "machine/stdio_dep.h"
|
||||
|
||||
/* Make sure our exports match up w/the implementation: */
|
||||
#include "fdports1.h"
|
||||
|
|
148
scsh/select1.c
148
scsh/select1.c
|
@ -16,6 +16,7 @@
|
|||
#include "cstuff.h"
|
||||
#include "fdports.h" /* Accessors for Scheme I/O port internals. */
|
||||
#include "fdports1.h" /* Import fdes2fstar(). */
|
||||
#include "machine/stdio_dep.h" /* Import stdio buf-peeking ops. */
|
||||
|
||||
/* Make sure our exports match up w/the implementation: */
|
||||
#include "select1.h"
|
||||
|
@ -29,29 +30,25 @@ extern FILE *fdes2fstar(int fd);
|
|||
static void or2_fdset(fd_set *x, fd_set *y, int max_elt);
|
||||
static int copyback_fdvec(scheme_value portvec, fd_set *fdset);
|
||||
|
||||
/* RVEC, WVEC, and EVEC are Scheme vectors of integer file descriptors
|
||||
** and I/O ports. NSECS is an integer timeout value, or #f for infinite wait.
|
||||
** Do the select() call. Move every element we hit on to the front of
|
||||
** its vector. The number of hits are returned in R_NUMRDY, W_NUMRDY, and
|
||||
** E_NUMRDY. The principle return value is #f if we win, and a fixnum errno
|
||||
** value if we error out.
|
||||
/* RVEC, WVEC, and EVEC are Scheme vectors of integer file descriptors,
|
||||
** I/O ports, and #f's. NSECS is an integer timeout value, or #f for
|
||||
** infinite wait. Do the select() call, returning result fd_sets in the
|
||||
** passed pointers. Return 0 for OK, otherwise error is in errno.
|
||||
*/
|
||||
|
||||
scheme_value scm_select(scheme_value rvec, scheme_value wvec,
|
||||
scheme_value evec, scheme_value nsecs,
|
||||
int *r_numrdy, int *w_numrdy, int *e_numrdy)
|
||||
int do_select(scheme_value rvec, scheme_value wvec,
|
||||
scheme_value evec, scheme_value nsecs,
|
||||
fd_set *rset_ans, fd_set *wset_ans, fd_set *eset_ans)
|
||||
{
|
||||
struct timeval timeout, *tptr;
|
||||
fd_set rset_bufrdy, wset_bufrdy, eset_bufrdy; /* Buffered port hits. */
|
||||
fd_set rset_try, wset_try, eset_try; /* Real select() sets. */
|
||||
int rbuf_rdy=0, wbuf_rdy=0, bufrdy; /* Set if we find buffered I/O hits. */
|
||||
int max_fd = -1; /* Max fdes in the sets. */
|
||||
int nelts, i;
|
||||
int nfound;
|
||||
|
||||
FD_ZERO(&rset_try); FD_ZERO(&wset_try); FD_ZERO(&eset_try);
|
||||
FD_ZERO(rset_ans); FD_ZERO(wset_ans); FD_ZERO(eset_ans);
|
||||
FD_ZERO(&rset_bufrdy); FD_ZERO(&wset_bufrdy); FD_ZERO(&eset_bufrdy);
|
||||
*r_numrdy = *w_numrdy = *e_numrdy = 0;
|
||||
|
||||
/* Scan the readvec elts. */
|
||||
nelts = VECTOR_LENGTH(rvec);
|
||||
|
@ -61,21 +58,21 @@ scheme_value scm_select(scheme_value rvec, scheme_value wvec,
|
|||
|
||||
if( FIXNUMP(elt) ) { /* It's an integer fdes. */
|
||||
fd = EXTRACT_FIXNUM(elt);
|
||||
FD_SET(fd, &rset_try);
|
||||
FD_SET(fd, rset_ans);
|
||||
}
|
||||
|
||||
else { /* It better be a port. */
|
||||
else if( elt != SCHFALSE ) { /* It better be a port. */
|
||||
FILE *f;
|
||||
scheme_value data = *Port_PortData(elt);
|
||||
fd = EXTRACT_FIXNUM(*PortData_Fd(data));
|
||||
f = fdes2fstar(fd);
|
||||
if( !f ) return ENTER_FIXNUM(errno);
|
||||
if( !f ) return -1;
|
||||
else if( *PortData_Peek(data) != SCHFALSE /* Port has a peekchar */
|
||||
|| !ibuf_empty(f) ) { /* Stdio buf has chars. */
|
||||
FD_SET(fd, &rset_bufrdy);
|
||||
rbuf_rdy = 1; /* Hit. */
|
||||
}
|
||||
else FD_SET(fd, &rset_try); /* No buffered data. */
|
||||
else FD_SET(fd, rset_ans); /* No buffered data. */
|
||||
}
|
||||
|
||||
max_fd = max(max_fd, fd);
|
||||
|
@ -89,19 +86,19 @@ scheme_value scm_select(scheme_value rvec, scheme_value wvec,
|
|||
|
||||
if( FIXNUMP(elt) ) { /* It's an integer fdes. */
|
||||
fd = EXTRACT_FIXNUM(elt);
|
||||
FD_SET(fd, &wset_try);
|
||||
FD_SET(fd, wset_ans);
|
||||
}
|
||||
|
||||
else { /* It better be a port. */
|
||||
else if( elt != SCHFALSE ) { /* It better be a port. */
|
||||
FILE *f;
|
||||
fd = EXTRACT_FIXNUM(*PortFd(elt));
|
||||
f = fdes2fstar(fd);
|
||||
if( !f ) return ENTER_FIXNUM(errno);
|
||||
if( !f ) return -1;
|
||||
else if( !obuf_full(f) ) { /* I/O buf has room. */
|
||||
FD_SET(fd, &wset_bufrdy);
|
||||
wbuf_rdy = 1; /* Hit. */
|
||||
}
|
||||
else FD_SET(fd, &wset_try); /* No room. */
|
||||
else FD_SET(fd, wset_ans); /* No room. */
|
||||
}
|
||||
|
||||
max_fd = max(max_fd, fd);
|
||||
|
@ -115,12 +112,12 @@ scheme_value scm_select(scheme_value rvec, scheme_value wvec,
|
|||
|
||||
if( FIXNUMP(elt) ) { /* It's an integer fdes. */
|
||||
fd = EXTRACT_FIXNUM(elt);
|
||||
FD_SET(fd, &rset_try);
|
||||
FD_SET(fd, rset_ans);
|
||||
}
|
||||
|
||||
else { /* It better be a port. */
|
||||
else if( elt != SCHFALSE ) { /* It better be a port. */
|
||||
fd = EXTRACT_FIXNUM(*PortFd(elt));
|
||||
FD_SET(fd, &rset_try);
|
||||
FD_SET(fd, rset_ans);
|
||||
}
|
||||
|
||||
max_fd = max(max_fd, fd);
|
||||
|
@ -139,30 +136,38 @@ scheme_value scm_select(scheme_value rvec, scheme_value wvec,
|
|||
}
|
||||
else tptr = NULL; /* #f => Infinite wait. */
|
||||
|
||||
nfound = select1(max_fd+1, &rset_try, &wset_try, &eset_try, tptr);/*Do it.*/
|
||||
nfound = select1(max_fd+1, rset_ans, wset_ans, eset_ans, tptr); /* Do it.*/
|
||||
|
||||
/* EINTR is not an error return if we have hits on buffered ports
|
||||
** to report.
|
||||
*/
|
||||
if( nfound < 0 )
|
||||
if ( errno != EINTR || !bufrdy ) return ENTER_FIXNUM(errno);
|
||||
if ( errno != EINTR || !bufrdy ) return -1;
|
||||
else { /* EINTR, but we have hits on buffered ports to report. */
|
||||
FD_ZERO(&rset_try); /* This should never happen -- */
|
||||
FD_ZERO(&wset_try); /* EINTR on a zero-sec select() */
|
||||
FD_ZERO(&eset_try); /* -- but I'm paranoid. */
|
||||
FD_ZERO(rset_ans); /* This should never happen -- */
|
||||
FD_ZERO(wset_ans); /* EINTR on a zero-sec select() */
|
||||
FD_ZERO(eset_ans); /* -- but I'm paranoid. */
|
||||
}
|
||||
|
||||
/* OR together the buffered-io ready sets and the fd ready sets. */
|
||||
if( rbuf_rdy ) or2_fdset(&rset_try, &rset_bufrdy, max_fd);
|
||||
if( wbuf_rdy ) or2_fdset(&wset_try, &wset_bufrdy, max_fd);
|
||||
if( rbuf_rdy ) or2_fdset(rset_ans, &rset_bufrdy, max_fd);
|
||||
if( wbuf_rdy ) or2_fdset(wset_ans, &wset_bufrdy, max_fd);
|
||||
|
||||
*r_numrdy = copyback_fdvec(rvec, &rset_try);
|
||||
*w_numrdy = copyback_fdvec(wvec, &wset_try);
|
||||
*e_numrdy = copyback_fdvec(evec, &eset_try);
|
||||
|
||||
return SCHFALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* x = x or y */
|
||||
static void or2_fdset(fd_set *x, fd_set *y, int max_elt)
|
||||
{
|
||||
int i;
|
||||
for(i=max_elt+1; --i >= 0;)
|
||||
if( FD_ISSET(i,y) ) FD_SET(i,x);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* PORTVEC is a vector of integer file descriptors and Scheme ports.
|
||||
** Scan over the vector, and copy any elt whose file descriptor is in FDSET
|
||||
** to the front of the vector. Return the number of elts thus copied.
|
||||
|
@ -184,10 +189,73 @@ static int copyback_fdvec(scheme_value portvec, fd_set *fdset)
|
|||
}
|
||||
|
||||
|
||||
/* x = x or y */
|
||||
static void or2_fdset(fd_set *x, fd_set *y, int max_elt)
|
||||
/* Overwrite every inactive element in the vector with #f;
|
||||
** Return count of active elements.
|
||||
*/
|
||||
|
||||
static int clobber_inactives(scheme_value portvec, fd_set *fdset)
|
||||
{
|
||||
int i;
|
||||
for(i=max_elt+1; --i >= 0;)
|
||||
if( FD_ISSET(i,y) ) FD_SET(i,x);
|
||||
int count = 0;
|
||||
int i = VECTOR_LENGTH(portvec);
|
||||
|
||||
while( --i >= 0 ) {
|
||||
scheme_value elt = VECTOR_REF(portvec, i);
|
||||
if( elt != SCHFALSE ) {
|
||||
int fd = EXTRACT_FIXNUM((FIXNUMP(elt)) ? elt : *PortFd(elt));
|
||||
if( FD_ISSET(fd,fdset) ) {
|
||||
FD_CLR(fd,fdset); /* In case luser put elt in multiple times. */
|
||||
++count;
|
||||
}
|
||||
else VECTOR_REF(portvec, i) = SCHFALSE; /* Clobber. */
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
/* These two functions are the entry points to this file.
|
||||
*********************************************************
|
||||
*/
|
||||
|
||||
/* Copy active elts back to the front of their vector;
|
||||
** Return error indicator & number of hits for each vector.
|
||||
*/
|
||||
|
||||
scheme_value select_copyback(scheme_value rvec, scheme_value wvec,
|
||||
scheme_value evec, scheme_value nsecs,
|
||||
int *r_numrdy, int *w_numrdy, int *e_numrdy)
|
||||
{
|
||||
fd_set rset, wset, eset;
|
||||
|
||||
if( do_select(rvec, wvec, evec, nsecs, &rset, &wset, &eset) ) {
|
||||
*r_numrdy = *w_numrdy = *e_numrdy = 0;
|
||||
return ENTER_FIXNUM(errno);
|
||||
}
|
||||
|
||||
*r_numrdy = copyback_fdvec(rvec, &rset);
|
||||
*w_numrdy = copyback_fdvec(wvec, &wset);
|
||||
*e_numrdy = copyback_fdvec(evec, &eset);
|
||||
return SCHFALSE;
|
||||
}
|
||||
|
||||
|
||||
/* Overwrite non-active elements in the vectors with #f;
|
||||
** return error indicator & number of hits for each vector.
|
||||
*/
|
||||
|
||||
scheme_value select_filter(scheme_value rvec, scheme_value wvec,
|
||||
scheme_value evec, scheme_value nsecs,
|
||||
int *r_numrdy, int *w_numrdy, int *e_numrdy)
|
||||
{
|
||||
fd_set rset, wset, eset;
|
||||
|
||||
if( do_select(rvec, wvec, evec, nsecs, &rset, &wset, &eset) ) {
|
||||
*r_numrdy = *w_numrdy = *e_numrdy = 0;
|
||||
return ENTER_FIXNUM(errno);
|
||||
}
|
||||
|
||||
*r_numrdy = clobber_inactives(rvec, &rset);
|
||||
*w_numrdy = clobber_inactives(wvec, &wset);
|
||||
*e_numrdy = clobber_inactives(evec, &eset);
|
||||
return SCHFALSE;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <utime.h>
|
||||
|
||||
#include "cstuff.h"
|
||||
#include "machine/stdio_dep.h"
|
||||
|
||||
/* Make sure our exports match up w/the implementation: */
|
||||
#include "syscalls1.h"
|
||||
|
@ -500,10 +501,11 @@ char *scm_gethostname(void)
|
|||
char *errno_msg(int i)
|
||||
{
|
||||
/* temp hack until we figure out what to do about losing sys_errlist's */
|
||||
extern
|
||||
#ifdef HAVE_CONST_SYS_ERRLIST
|
||||
const
|
||||
#endif
|
||||
extern char *sys_errlist[];
|
||||
char *sys_errlist[];
|
||||
extern int sys_nerr;
|
||||
return ( i < 0 || i > sys_nerr ) ? NULL /* i.e., #f */
|
||||
: (char*) sys_errlist[i];
|
||||
|
|
Loading…
Reference in New Issue