summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Include/myselect.h80
-rw-r--r--Modules/config.c.in4
-rw-r--r--Modules/selectmodule.c194
-rw-r--r--Modules/socketmodule.c22
-rw-r--r--Modules/stdwinmodule.c16
-rw-r--r--Modules/timemodule.c13
-rw-r--r--Objects/fileobject.c11
7 files changed, 321 insertions, 19 deletions
diff --git a/Include/myselect.h b/Include/myselect.h
new file mode 100644
index 0000000..fa8ade9
--- /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 <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 */
diff --git a/Modules/config.c.in b/Modules/config.c.in
index fb33b1c..0973b77 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 <stdio.h>
@@ -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 0000000..0a102bd
--- /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 <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");
+}
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 21ddf62..b1fc81f 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 <sys/types.h>, <sys/time.h>, <sys/param.h> */
+
#include <signal.h>
-#include <sys/types.h>
#include <sys/socket.h>
-#include <sys/time.h> /* Needed for struct timeval */
#include <netinet/in.h>
#include <sys/un.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
@@ -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 f81351d..4d2b48f 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 d969b3f..4a921f0 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 <errno.h>
#endif
-#ifdef _SEQUENT_
-#include <sys/select.h>
-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 <sys/select.h>
-#endif
+#include "myselect.h" /* Implies <sys/types.h>, <sys/time.h>, <sys/param.h> */
long
millitimer()
diff --git a/Objects/fileobject.c b/Objects/fileobject.c
index 47461f9..76bcad4 100644
--- a/Objects/fileobject.c
+++ b/Objects/fileobject.c
@@ -222,6 +222,16 @@ file_tell(f, args)
}
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;
object *args;
@@ -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},