Changes for new UNIX-specific built-in module 'select' and new header for
interfaces to variants of select() system call, "myselect.h". This includes adding fileno() methods to files, sockets and stdwin.
This commit is contained in:
parent
5dc8eb0914
commit
ed233a5696
|
@ -0,0 +1,80 @@
|
||||||
|
/***********************************************************
|
||||||
|
Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
|
||||||
|
Netherlands.
|
||||||
|
|
||||||
|
All Rights Reserved
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and distribute this software and its
|
||||||
|
documentation for any purpose and without fee is hereby granted,
|
||||||
|
provided that the above copyright notice appear in all copies and that
|
||||||
|
both that copyright notice and this permission notice appear in
|
||||||
|
supporting documentation, and that the names of Stichting Mathematisch
|
||||||
|
Centrum or CWI not be used in advertising or publicity pertaining to
|
||||||
|
distribution of the software without specific, written prior permission.
|
||||||
|
|
||||||
|
STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||||
|
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
|
||||||
|
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||||
|
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
******************************************************************/
|
||||||
|
|
||||||
|
/* Common definitions for files that use the BSD select system call.
|
||||||
|
This is so complicated because every UNIX variant requires that
|
||||||
|
you include a different set of headers. Customizing this one file
|
||||||
|
should be easier than patching each of the files using select()... */
|
||||||
|
|
||||||
|
|
||||||
|
/* XXX You may have to include some of these only if not already included */
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/time.h> /* Implies <time.h> everywhere, as far as I know */
|
||||||
|
#include <sys/param.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* Hacks for various systems that need hand-holding... */
|
||||||
|
|
||||||
|
#ifdef _SEQUENT_
|
||||||
|
#include <sys/select.h>
|
||||||
|
/* Sequent doesn't seem to define struct timezone anywhere?!?! */
|
||||||
|
struct timezone {
|
||||||
|
int tz_minuteswest;
|
||||||
|
int tz_dsttime;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _AIX /* I *think* this works */
|
||||||
|
/* AIX defines fd_set in a separate file. Sigh... */
|
||||||
|
#include <sys/select.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* (Very) old versions of BSD don't define the FD_* set of macros.
|
||||||
|
The following will usually do... */
|
||||||
|
|
||||||
|
#ifndef FD_SETSIZE
|
||||||
|
#define FD_SETSIZE 256
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FD_SET
|
||||||
|
|
||||||
|
typedef long fd_mask;
|
||||||
|
|
||||||
|
#define NFDBITS (sizeof(fd_mask) * NBBY) /* bits per mask */
|
||||||
|
#ifndef howmany
|
||||||
|
#define howmany(x, y) (((x)+((y)-1))/(y))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct fd_set {
|
||||||
|
fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
|
||||||
|
} fd_set;
|
||||||
|
|
||||||
|
#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
|
||||||
|
#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
|
||||||
|
#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
|
||||||
|
#define FD_ZERO(p) bzero((char *)(p), sizeof(*(p)))
|
||||||
|
|
||||||
|
#endif /* FD_SET */
|
|
@ -34,7 +34,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#ifdef __DATE__
|
#ifdef __DATE__
|
||||||
#define DATE __DATE__
|
#define DATE __DATE__
|
||||||
#else
|
#else
|
||||||
#define DATE ">= 3 Jun 1992"
|
#define DATE ">= 23 Jun 1992"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -122,6 +122,7 @@ extern void initposix();
|
||||||
extern void initpwd();
|
extern void initpwd();
|
||||||
extern void initgrp();
|
extern void initgrp();
|
||||||
extern void initmarshal();
|
extern void initmarshal();
|
||||||
|
extern void initselect();
|
||||||
|
|
||||||
#ifdef USE_AUDIO
|
#ifdef USE_AUDIO
|
||||||
extern void initaudio();
|
extern void initaudio();
|
||||||
|
@ -171,6 +172,7 @@ struct {
|
||||||
{"pwd", initpwd},
|
{"pwd", initpwd},
|
||||||
{"grp", initgrp},
|
{"grp", initgrp},
|
||||||
{"marshal", initmarshal},
|
{"marshal", initmarshal},
|
||||||
|
{"select", initselect},
|
||||||
|
|
||||||
|
|
||||||
/* Optional modules */
|
/* Optional modules */
|
||||||
|
|
|
@ -0,0 +1,194 @@
|
||||||
|
/***********************************************************
|
||||||
|
Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
|
||||||
|
Netherlands.
|
||||||
|
|
||||||
|
All Rights Reserved
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and distribute this software and its
|
||||||
|
documentation for any purpose and without fee is hereby granted,
|
||||||
|
provided that the above copyright notice appear in all copies and that
|
||||||
|
both that copyright notice and this permission notice appear in
|
||||||
|
supporting documentation, and that the names of Stichting Mathematisch
|
||||||
|
Centrum or CWI not be used in advertising or publicity pertaining to
|
||||||
|
distribution of the software without specific, written prior permission.
|
||||||
|
|
||||||
|
STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||||
|
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
|
||||||
|
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||||
|
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
******************************************************************/
|
||||||
|
|
||||||
|
/* select - Module containing unix select(2) call */
|
||||||
|
|
||||||
|
#include "allobjects.h"
|
||||||
|
#include "modsupport.h"
|
||||||
|
#include "compile.h"
|
||||||
|
#include "ceval.h"
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
|
||||||
|
/* XXX Maybe you need to define the FD_* macros here when porting this code */
|
||||||
|
|
||||||
|
static object *SelectError;
|
||||||
|
|
||||||
|
/* XXX This module should be re-entrant! */
|
||||||
|
static object *fd2obj[FD_SETSIZE];
|
||||||
|
|
||||||
|
static
|
||||||
|
list2set(list, set)
|
||||||
|
object *list;
|
||||||
|
fd_set *set;
|
||||||
|
{
|
||||||
|
int i, len, v, max=-1;
|
||||||
|
object *o, *filenomethod, *fno;
|
||||||
|
|
||||||
|
FD_ZERO(set);
|
||||||
|
len = getlistsize(list);
|
||||||
|
for( i=0; i<len; i++ ) {
|
||||||
|
o = getlistitem(list, i);
|
||||||
|
if ( is_intobject(o) ) {
|
||||||
|
v = getintvalue(o);
|
||||||
|
} else if ( (filenomethod = getattr(o, "fileno")) != NULL ) {
|
||||||
|
fno = call_object(filenomethod, NULL);
|
||||||
|
if ( fno == NULL )
|
||||||
|
return -1;
|
||||||
|
if ( !is_intobject(fno) ) {
|
||||||
|
err_badarg();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
v = getintvalue(fno);
|
||||||
|
DECREF(fno);
|
||||||
|
} else {
|
||||||
|
err_badarg();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ( v >= FD_SETSIZE ) {
|
||||||
|
err_setstr(SystemError, "FD_SETSIZE too low in select()");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ( v > max ) max = v;
|
||||||
|
FD_SET(v, set);
|
||||||
|
fd2obj[v] = o;
|
||||||
|
}
|
||||||
|
return max+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static object *
|
||||||
|
set2list(set, max)
|
||||||
|
fd_set *set;
|
||||||
|
int max;
|
||||||
|
{
|
||||||
|
int i, num=0;
|
||||||
|
object *list, *o;
|
||||||
|
|
||||||
|
for(i=0; i<max; i++)
|
||||||
|
if ( FD_ISSET(i,set) )
|
||||||
|
num++;
|
||||||
|
list = newlistobject(num);
|
||||||
|
num = 0;
|
||||||
|
for(i=0; i<max; i++)
|
||||||
|
if ( FD_ISSET(i,set) ) {
|
||||||
|
if ( i > FD_SETSIZE ) {
|
||||||
|
err_setstr(SystemError, "FD_SETSIZE too low in select()");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
o = fd2obj[i];
|
||||||
|
if ( o == 0 ) {
|
||||||
|
err_setstr(SystemError,
|
||||||
|
"Bad filedescriptor returned from select()");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
INCREF(o);
|
||||||
|
setlistitem(list, num, o);
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
static object *
|
||||||
|
select_select(self, args)
|
||||||
|
object *self;
|
||||||
|
object *args;
|
||||||
|
{
|
||||||
|
object *ifdlist, *ofdlist, *efdlist;
|
||||||
|
fd_set ifdset, ofdset, efdset;
|
||||||
|
double timeout;
|
||||||
|
struct timeval tv, *tvp;
|
||||||
|
int seconds;
|
||||||
|
int imax, omax, emax, max;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
|
||||||
|
/* Get args. Looks funny because of optional timeout argument */
|
||||||
|
if ( getargs(args, "(OOOd)", &ifdlist, &ofdlist, &efdlist, &timeout) ) {
|
||||||
|
seconds = (int)timeout;
|
||||||
|
timeout = timeout - (double)seconds;
|
||||||
|
tv.tv_sec = seconds;
|
||||||
|
tv.tv_usec = (int)(timeout*1000000.0);
|
||||||
|
tvp = &tv;
|
||||||
|
} else {
|
||||||
|
/* Doesn't have 4 args, that means no timeout */
|
||||||
|
err_clear();
|
||||||
|
if (!getargs(args, "(OOO)", &ifdlist, &ofdlist, &efdlist) )
|
||||||
|
return 0;
|
||||||
|
tvp = (struct timeval *)0;
|
||||||
|
}
|
||||||
|
if ( !is_listobject(ifdlist) || !is_listobject(ofdlist) ||
|
||||||
|
!is_listobject(efdlist) ) {
|
||||||
|
err_badarg();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bzero((char *)fd2obj, sizeof(fd2obj)); /* Not really needed */
|
||||||
|
|
||||||
|
/* Convert lists to fd_sets, and get maximum fd number */
|
||||||
|
if( (imax=list2set(ifdlist, &ifdset)) < 0 )
|
||||||
|
return 0;
|
||||||
|
if( (omax=list2set(ofdlist, &ofdset)) < 0 )
|
||||||
|
return 0;
|
||||||
|
if( (emax=list2set(efdlist, &efdset)) < 0 )
|
||||||
|
return 0;
|
||||||
|
max = imax;
|
||||||
|
if ( omax > max ) max = omax;
|
||||||
|
if ( emax > max ) max = emax;
|
||||||
|
|
||||||
|
n = select(max, &ifdset, &ofdset, &efdset, tvp);
|
||||||
|
|
||||||
|
if ( n < 0 ) {
|
||||||
|
err_errno(SelectError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( n == 0 )
|
||||||
|
imax = omax = emax = 0; /* Speedup hack */
|
||||||
|
|
||||||
|
ifdlist = set2list(&ifdset, imax);
|
||||||
|
ofdlist = set2list(&ofdset, omax);
|
||||||
|
efdlist = set2list(&efdset, emax);
|
||||||
|
|
||||||
|
return mkvalue("OOO", ifdlist, ofdlist, efdlist);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct methodlist select_methods[] = {
|
||||||
|
{ "select", select_select },
|
||||||
|
{ 0, 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
initselect()
|
||||||
|
{
|
||||||
|
object *m, *d;
|
||||||
|
m = initmodule("select", select_methods);
|
||||||
|
d = getmoduledict(m);
|
||||||
|
SelectError = newstringobject("select.error");
|
||||||
|
if ( SelectError == NULL || dictinsert(d, "error", SelectError) )
|
||||||
|
fatal("Cannot define select.error");
|
||||||
|
}
|
|
@ -73,17 +73,13 @@ Socket methods:
|
||||||
#include "allobjects.h"
|
#include "allobjects.h"
|
||||||
#include "modsupport.h"
|
#include "modsupport.h"
|
||||||
|
|
||||||
|
#include "myselect.h" /* Implies <sys/types.h>, <sys/time.h>, <sys/param.h> */
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/time.h> /* Needed for struct timeval */
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#ifdef _AIX /* I *think* this works */
|
|
||||||
/* AIX defines fd_set in a separate file. Sigh... */
|
|
||||||
#include <sys/select.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Global variable holding the exception type for errors detected
|
/* Global variable holding the exception type for errors detected
|
||||||
|
@ -526,6 +522,19 @@ sock_connect(s, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* s.fileno() method */
|
||||||
|
|
||||||
|
static object *
|
||||||
|
sock_fileno(s, args)
|
||||||
|
sockobject *s;
|
||||||
|
object *args;
|
||||||
|
{
|
||||||
|
if (!getnoarg(args))
|
||||||
|
return NULL;
|
||||||
|
return newintobject((long) s->sock_fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* s.listen(n) method */
|
/* s.listen(n) method */
|
||||||
|
|
||||||
static object *
|
static object *
|
||||||
|
@ -699,6 +708,7 @@ static struct methodlist sock_methods[] = {
|
||||||
{"bind", sock_bind},
|
{"bind", sock_bind},
|
||||||
{"close", sock_close},
|
{"close", sock_close},
|
||||||
{"connect", sock_connect},
|
{"connect", sock_connect},
|
||||||
|
{"fileno", sock_fileno},
|
||||||
{"listen", sock_listen},
|
{"listen", sock_listen},
|
||||||
{"makefile", sock_makefile},
|
{"makefile", sock_makefile},
|
||||||
{"recv", sock_recv},
|
{"recv", sock_recv},
|
||||||
|
|
|
@ -2102,11 +2102,27 @@ stdwin_getscrmm(self, args)
|
||||||
return makepoint(width, height);
|
return makepoint(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef unix
|
||||||
|
static object *
|
||||||
|
stdwin_connectionnumber(self, args)
|
||||||
|
object *self;
|
||||||
|
object *args;
|
||||||
|
{
|
||||||
|
if (!getnoarg(args))
|
||||||
|
return NULL;
|
||||||
|
return newintobject((long) wconnectionnumber());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct methodlist stdwin_methods[] = {
|
static struct methodlist stdwin_methods[] = {
|
||||||
{"askfile", stdwin_askfile},
|
{"askfile", stdwin_askfile},
|
||||||
{"askstr", stdwin_askstr},
|
{"askstr", stdwin_askstr},
|
||||||
{"askync", stdwin_askync},
|
{"askync", stdwin_askync},
|
||||||
{"fetchcolor", stdwin_fetchcolor},
|
{"fetchcolor", stdwin_fetchcolor},
|
||||||
|
#ifdef unix
|
||||||
|
{"fileno", stdwin_connectionnumber},
|
||||||
|
{"connectionnumber", stdwin_connectionnumber},
|
||||||
|
#endif
|
||||||
{"fleep", stdwin_fleep},
|
{"fleep", stdwin_fleep},
|
||||||
{"getactive", stdwin_getactive},
|
{"getactive", stdwin_getactive},
|
||||||
{"getcutbuffer", stdwin_getcutbuffer},
|
{"getcutbuffer", stdwin_getcutbuffer},
|
||||||
|
|
|
@ -68,14 +68,6 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _SEQUENT_
|
|
||||||
#include <sys/select.h>
|
|
||||||
struct timezone {
|
|
||||||
int tz_minuteswest;
|
|
||||||
int tz_dsttime;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Time methods */
|
/* Time methods */
|
||||||
|
|
||||||
static object *
|
static object *
|
||||||
|
@ -285,10 +277,7 @@ millitimer()
|
||||||
|
|
||||||
#ifdef BSD_TIME
|
#ifdef BSD_TIME
|
||||||
|
|
||||||
#ifdef _AIX /* I *think* this works */
|
#include "myselect.h" /* Implies <sys/types.h>, <sys/time.h>, <sys/param.h> */
|
||||||
/* AIX defines fd_set in a separate file. Sigh... */
|
|
||||||
#include <sys/select.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
long
|
long
|
||||||
millitimer()
|
millitimer()
|
||||||
|
|
|
@ -221,6 +221,16 @@ file_tell(f, args)
|
||||||
return newintobject(offset);
|
return newintobject(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static object *
|
||||||
|
file_fileno(f, args)
|
||||||
|
fileobject *f;
|
||||||
|
object *args;
|
||||||
|
{
|
||||||
|
if (!getnoarg(args))
|
||||||
|
return NULL;
|
||||||
|
return newintobject((long) fileno(f->f_fp));
|
||||||
|
}
|
||||||
|
|
||||||
static object *
|
static object *
|
||||||
file_flush(f, args)
|
file_flush(f, args)
|
||||||
fileobject *f;
|
fileobject *f;
|
||||||
|
@ -462,6 +472,7 @@ file_write(f, args)
|
||||||
static struct methodlist file_methods[] = {
|
static struct methodlist file_methods[] = {
|
||||||
{"close", file_close},
|
{"close", file_close},
|
||||||
{"flush", file_flush},
|
{"flush", file_flush},
|
||||||
|
{"fileno", file_fileno},
|
||||||
{"isatty", file_isatty},
|
{"isatty", file_isatty},
|
||||||
{"read", file_read},
|
{"read", file_read},
|
||||||
{"readline", file_readline},
|
{"readline", file_readline},
|
||||||
|
|
Loading…
Reference in New Issue