diff --git a/Include/myselect.h b/Include/myselect.h new file mode 100644 index 00000000000..fa8ade948a6 --- /dev/null +++ b/Include/myselect.h @@ -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 +#include /* Implies everywhere, as far as I know */ +#include + + +/* Hacks for various systems that need hand-holding... */ + +#ifdef _SEQUENT_ +#include +/* 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 +#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 */ diff --git a/Modules/config.c.in b/Modules/config.c.in index fb33b1cd3de..0973b77b602 100644 --- a/Modules/config.c.in +++ b/Modules/config.c.in @@ -34,7 +34,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #ifdef __DATE__ #define DATE __DATE__ #else -#define DATE ">= 3 Jun 1992" +#define DATE ">= 23 Jun 1992" #endif #include @@ -122,6 +122,7 @@ extern void initposix(); extern void initpwd(); extern void initgrp(); extern void initmarshal(); +extern void initselect(); #ifdef USE_AUDIO extern void initaudio(); @@ -171,6 +172,7 @@ struct { {"pwd", initpwd}, {"grp", initgrp}, {"marshal", initmarshal}, + {"select", initselect}, /* Optional modules */ diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c new file mode 100644 index 00000000000..0a102bd0eaf --- /dev/null +++ b/Modules/selectmodule.c @@ -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 +#include +#include + +/* 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= 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 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"); +} diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 21ddf62bbd8..b1fc81f40e4 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -73,17 +73,13 @@ Socket methods: #include "allobjects.h" #include "modsupport.h" +#include "myselect.h" /* Implies , , */ + #include -#include #include -#include /* Needed for struct timeval */ #include #include #include -#ifdef _AIX /* I *think* this works */ -/* AIX defines fd_set in a separate file. Sigh... */ -#include -#endif /* 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 */ static object * @@ -699,6 +708,7 @@ static struct methodlist sock_methods[] = { {"bind", sock_bind}, {"close", sock_close}, {"connect", sock_connect}, + {"fileno", sock_fileno}, {"listen", sock_listen}, {"makefile", sock_makefile}, {"recv", sock_recv}, diff --git a/Modules/stdwinmodule.c b/Modules/stdwinmodule.c index f81351dc4f0..4d2b48f40e5 100644 --- a/Modules/stdwinmodule.c +++ b/Modules/stdwinmodule.c @@ -2102,11 +2102,27 @@ stdwin_getscrmm(self, args) 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[] = { {"askfile", stdwin_askfile}, {"askstr", stdwin_askstr}, {"askync", stdwin_askync}, {"fetchcolor", stdwin_fetchcolor}, +#ifdef unix + {"fileno", stdwin_connectionnumber}, + {"connectionnumber", stdwin_connectionnumber}, +#endif {"fleep", stdwin_fleep}, {"getactive", stdwin_getactive}, {"getcutbuffer", stdwin_getcutbuffer}, diff --git a/Modules/timemodule.c b/Modules/timemodule.c index d969b3f28b5..4a921f034e7 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -68,14 +68,6 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #endif -#ifdef _SEQUENT_ -#include -struct timezone { - int tz_minuteswest; - int tz_dsttime; -}; -#endif - /* Time methods */ static object * @@ -285,10 +277,7 @@ millitimer() #ifdef BSD_TIME -#ifdef _AIX /* I *think* this works */ -/* AIX defines fd_set in a separate file. Sigh... */ -#include -#endif +#include "myselect.h" /* Implies , , */ long millitimer() diff --git a/Objects/fileobject.c b/Objects/fileobject.c index 47461f99a59..76bcad4faac 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -221,6 +221,16 @@ file_tell(f, args) 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 * file_flush(f, args) fileobject *f; @@ -462,6 +472,7 @@ file_write(f, args) static struct methodlist file_methods[] = { {"close", file_close}, {"flush", file_flush}, + {"fileno", file_fileno}, {"isatty", file_isatty}, {"read", file_read}, {"readline", file_readline},