UnixOperatingSystem.st
changeset 7510 46a848d466b5
parent 7509 c8964822d8fd
child 7511 d6b7d28b135e
--- a/UnixOperatingSystem.st	Tue Jul 15 14:19:45 2003 +0200
+++ b/UnixOperatingSystem.st	Tue Jul 15 16:03:28 2003 +0200
@@ -9050,25 +9050,32 @@
 !
 
 selectOnAnyReadable:readFdArray writable:writeFdArray exception:exceptFdArray 
-        into:resultFdArray withTimeOut:millis
-    "wait for any fd in readFdArray (an Array of integers) to become ready for 
-     reading, writeFdArray to become ready for writing, or exceptFdArray to 
-     arrive exceptional data (i.e. out-of-band data).
-     Timeout after t milliseconds or, if the timeout time is 0, immediately..
+        readableInto:readableResultFdArray writableInto:writableResultFdArray 
+        exceptionInto:exceptionResultFdArray
+        withTimeOut:millis
+
+    "wait for any fd in readFdArray (an Array of integers) to become ready for reading, 
+     writeFdArray to become ready for writing, 
+     or exceptFdArray to arrive exceptional data (i.e. out-of-band data).
+     Timeout after t milliseconds or - if the timeout time is 0 - immediately..
      Empty fd-sets will always wait. Zero time can be used to poll file-
      descriptors (i.e. to check if I/O possible without blocking).
-     The filedescriptors which are ready are returned in resultArray.
-
-     Return the number of selected filedescriptors"
+     The corresponding filedescriptors which are ready are returned in readableResultFdArray,
+     writableResultFdArray and exceptionResultFdArray respectively.
+
+     Return the (overall) number of selected filedescriptors.
+     readableResultFdArray, writableResultFdArray and exceptionResultFdArray will
+     get a nil-value stored into the slot after the last valid fileDescriptor;
+     Thus, the caller can simply scan these arrays upTo the end or a nil value."
 
 %{
     fd_set rset, wset, eset;
     struct timeval wt, et;
-    int f, maxF, i, lX, bX;
+    int maxF;
     INT t;
-    OBJ fd, retFd;
     int ret;
-    int count, resultCount;
+    int cntR = 0, cntW = 0, cntE = 0;
+    int resultSizeReadable = 0, resultSizeWritable = 0, resultSizeException = 0;
     int numFds = 0;
 #ifndef __isArrayLike
 # define __isArrayLike __isArray
@@ -9077,10 +9084,25 @@
     if (!__isSmallInteger(millis)) {
         goto fail;
     }
-    if (! __isArrayLike(resultFdArray)) {
-        goto fail;    
-    }
-    resultCount = __arraySize(resultFdArray);
+
+    if (readableResultFdArray != nil) {
+        if (! __isArrayLike(readableResultFdArray)) {
+            goto fail;    
+        }
+        resultSizeReadable = __arraySize(readableResultFdArray);
+    }
+    if (writableResultFdArray != nil) {
+        if (! __isArrayLike(writableResultFdArray)) {
+            goto fail;    
+        }
+        resultSizeWritable = __arraySize(writableResultFdArray);
+    }
+    if (exceptionResultFdArray != nil) {
+        if (! __isArrayLike(exceptionResultFdArray)) {
+            goto fail;    
+        }
+        resultSizeException = __arraySize(exceptionResultFdArray);
+    }
 
     FD_ZERO(&rset);
     FD_ZERO(&wset);
@@ -9088,12 +9110,16 @@
 
     maxF = -1;
     if (__isNonNilObject(readFdArray)) {
+        int i, count;
+
         if (! __isArrayLike(readFdArray)) {
             goto fail;    
         }
         count = __arraySize(readFdArray);
 
         for (i=0; i<count;i++) {
+            OBJ fd;
+
             fd = __ArrayInstPtr(readFdArray)->a_element[i];
             if (fd != nil) {
                 if (! __isSmallInteger(fd)) {
@@ -9101,6 +9127,8 @@
                         fprintf(stderr, "[OS] warning: funny read-fd (0x%x) given to select\n", fd);
                     }
                 } else {
+                    int f;
+
                     f = __intVal(fd);
                     if ((unsigned)f < FD_SETSIZE) {
                         FD_SET(f, &rset);
@@ -9117,11 +9145,15 @@
     }
 
     if (__isNonNilObject(writeFdArray)) {
+        int i, count;
+
         if (! __isArrayLike(writeFdArray)) {
             goto fail;    
         }
         count = __arraySize(writeFdArray);
         for (i=0; i<count;i++) {
+            OBJ fd;
+
             fd = __ArrayInstPtr(writeFdArray)->a_element[i];
             if (fd != nil) {
                 if (! __isSmallInteger(fd)) {
@@ -9129,6 +9161,8 @@
                         fprintf(stderr, "[OS] warning: funny write-fd (0x%x) given to select\n", fd);
                     }
                 } else {
+                    int f;
+
                     f = __intVal(fd);
                     if ((unsigned)f < FD_SETSIZE) {
                         FD_SET(f, &wset);       
@@ -9145,11 +9179,15 @@
     }
 
     if (__isNonNilObject(exceptFdArray)) {
+        int i, count;
+
         if (! __isArrayLike(exceptFdArray)) {
             goto fail;    
         }
         count = __arraySize(exceptFdArray);
         for (i=0; i<count;i++) {
+            OBJ fd;
+
             fd = __ArrayInstPtr(exceptFdArray)->a_element[i];
             if (fd != nil) {
                 if (! __isSmallInteger(fd)) {
@@ -9157,6 +9195,8 @@
                         fprintf(stderr, "[OS] warning: funny except-fd (0x%x) given to select\n", fd);
                     }
                 } else {
+                    int f;
+
                     f = __intVal(fd);
                     if ((unsigned)f < FD_SETSIZE) {
                         FD_SET(f, &eset);       
@@ -9208,20 +9248,45 @@
     __END_INTERRUPTABLE__
 
     if (ret > 0) {
-        int cnt = 0;
-        OBJ *__result = __arrayVal(resultFdArray);
+        OBJ *__resultR = __arrayVal(readableResultFdArray);
+        OBJ *__resultW = __arrayVal(writableResultFdArray);
+        OBJ *__resultE = __arrayVal(exceptionResultFdArray);
+        int i;
 
         for (i=0; i <= maxF; i++) {
-            if (FD_ISSET(i, &rset)
-             || FD_ISSET(i, &wset)
-             || FD_ISSET(i, &eset)) {
-                if (cnt < resultCount) {
-                    __result[cnt] = __MKSMALLINT(i);
+            if (FD_ISSET(i, &rset)) {
+                if (cntR < resultSizeReadable) {
+                    __resultR[cntR] = __MKSMALLINT(i);
                 }
-                cnt++;
+                cntR++;
+            }
+
+            if (FD_ISSET(i, &wset)) {
+                if (cntW < resultSizeWritable) {
+                    __resultW[cntW] = __MKSMALLINT(i);
+                }
+                cntW++;
+            }
+
+            if (FD_ISSET(i, &eset)) {
+                if (cntE < resultSizeException) {
+                    __resultE[cntE] = __MKSMALLINT(i);
+                }
+                cntE++;
             }
         }
-        RETURN (__MKSMALLINT(cnt));
+        /* add a delimiter */
+        if (cntR < resultSizeReadable) {
+            __resultR[cntR] = nil;
+        }
+        if (cntW < resultSizeWritable) {
+            __resultW[cntW] = nil;
+        }
+        if (cntE < resultSizeException) {
+            __resultE[cntE] = nil;
+        }
+        
+        RETURN (__MKSMALLINT(cntR+cntW+cntE));
     } else {
         if (ret < 0) {
             if (errno == EINTR) {
@@ -9242,8 +9307,6 @@
      * Return 0 (no filedescriptor ready)
      */
     RETURN (__MKSMALLINT(0));
-
-
 fail: ;
 %}.
     "
@@ -9255,13 +9318,13 @@
 !
 
 selectOnAnyReadable:readFdArray writable:writeFdArray exception:exceptFdArray withTimeOut:millis
-    "wait for any fd in readFdArray (an Array of integers) to become ready for 
-     reading, writeFdArray to become ready for writing, or exceptFdArray to 
-     arrive exceptional data (i.e. out-of-band data).
+    "wait for any fd in readFdArray (an Array of integers) to become ready for reading, 
+     writeFdArray to become ready for writing, 
+     or exceptFdArray to arrive exceptional data (i.e. out-of-band data).
      Timeout after t milliseconds or, if the timeout time is 0, immediately..
      Empty fd-sets will always wait. Zero time can be used to poll file-
      descriptors (i.e. to check if I/O possible without blocking).
-     Return first ready fd if I/O ok, nil if timed-out or interrupted."
+     Return the first ready fd if I/O ok, nil if timed-out or interrupted."
 
 %{
     fd_set rset, wset, eset;
@@ -9277,159 +9340,159 @@
 #endif
 
     if (__isSmallInteger(millis)) {
-	FD_ZERO(&rset);
-	FD_ZERO(&wset);
-	FD_ZERO(&eset);
-
-	maxF = -1;
-	if (__isNonNilObject(readFdArray)) {
-	    if (! __isArrayLike(readFdArray)) {
-		goto fail;    
-	    }
-	    count = __arraySize(readFdArray);
-
-	    for (i=0; i<count;i++) {
-		fd = __ArrayInstPtr(readFdArray)->a_element[i];
-		if (fd != nil) {
-		    if (! __isSmallInteger(fd)) {
-			if (@global(InfoPrinting) == true) {
-			    fprintf(stderr, "[OS] warning: funny read-fd (0x%x) given to select\n", fd);
-			}
-		    } else {
-			f = __intVal(fd);
-			if ((unsigned)f < FD_SETSIZE) {
-			    FD_SET(f, &rset);
-			    if (f > maxF) maxF = f;
-			    numFds++;
-			} else {
-			    if (@global(InfoPrinting) == true) {
-				fprintf(stderr, "[OS] warning: huge read-fd (0x%x) given to select\n", fd);
-			    }
-			}
-		    }
-		}
-	    }
-	}
-
-	if (__isNonNilObject(writeFdArray)) {
-	    if (! __isArrayLike(writeFdArray)) {
-		goto fail;    
-	    }
-	    count = __arraySize(writeFdArray);
-	    for (i=0; i<count;i++) {
-		fd = __ArrayInstPtr(writeFdArray)->a_element[i];
-		if (fd != nil) {
-		    if (! __isSmallInteger(fd)) {
-			if (@global(InfoPrinting) == true) {
-			    fprintf(stderr, "[OS] warning: funny write-fd (0x%x) given to select\n", fd);
-			}
-		    } else {
-			f = __intVal(fd);
-			if ((unsigned)f < FD_SETSIZE) {
-			    FD_SET(f, &wset);       
-			    if (f > maxF) maxF = f;
-			    numFds++;
-			} else {
-			    if (@global(InfoPrinting) == true) {
-				fprintf(stderr, "[OS] warning: huge write-fd (0x%x) given to select\n", fd);
-			    }
-			}
-		    }
-		}
-	    }
-	}
-
-	if (__isNonNilObject(exceptFdArray)) {
-	    if (! __isArrayLike(exceptFdArray)) {
-		goto fail;    
-	    }
-	    count = __arraySize(exceptFdArray);
-	    for (i=0; i<count;i++) {
-		fd = __ArrayInstPtr(exceptFdArray)->a_element[i];
-		if (fd != nil) {
-		    if (! __isSmallInteger(fd)) {
-			if (@global(InfoPrinting) == true) {
-			    fprintf(stderr, "[OS] warning: funny except-fd (0x%x) given to select\n", fd);
-			}
-		    } else {
-			f = __intVal(fd);
-			if ((unsigned)f < FD_SETSIZE) {
-			    FD_SET(f, &eset);       
-			    if (f > maxF) maxF = f;
-			    numFds++;
-			} else {
-			    if (@global(InfoPrinting) == true) {
-				fprintf(stderr, "[OS] warning: huge except-fd (0x%x) given to select\n", fd);
-			    }
-			}
-		    }
-		}
-	    }
-	}
-
-	t = __intVal(millis);
-	if (t) {
-	    wt.tv_sec = t / 1000;
-	    wt.tv_usec = (t % 1000) * 1000;
-	} else {
-	    wt.tv_sec = wt.tv_usec = 0;
-	}
-
-	/*
-	 * make certain, that interrupt gets us out of the select
-	 * However, we must then care for moved objects.
-	 */
-	__BEGIN_INTERRUPTABLE__
-	errno = 0;
-
-	if (t == 0) {
-	    /* 
-	     * if there is no timeout time, we can stay here interruptable.
-	     */
-	    do {
-		ret = select(maxF+1, &rset, &wset, &eset, &wt);
-	    } while ((ret < 0) && (errno == EINTR));
-	} else {
-	    do {
-		ret = select(maxF+1, &rset, &wset, &eset, &wt);
-		/* 
-		 * for now: dont loop; if we did, we had to adjust the vt-timeval;
-		 * could otherwise stay in this loop forever ...
-		 * Premature ret (before the time expired) must be handled by the caller.
-		 * A good solution is to update the wt-timeval and redo the select.
-		 */
-	    } while (0 /* (ret < 0) && (errno == EINTR) */ );
-	}
-	__END_INTERRUPTABLE__
-
-	if (ret > 0) {
-	    for (i=0; i <= maxF; i++) {
-		if (FD_ISSET(i, &rset)
-		 || FD_ISSET(i, &wset)
-		 || FD_ISSET(i, &eset)) {
-		    RETURN ( __MKSMALLINT(i) );
-		}
-	    }
-	} else {
-	    if (ret < 0) {
-		if (errno == EINTR) {
-		    errno = 0;
-		    @global(LastErrorNumber) = nil;
-		} else {
-		    if (@global(InfoPrinting) == true) {
-			fprintf(stderr, "OS [info]: select errno = %d\n", errno);
-		    }
-		    @global(LastErrorNumber) = __MKSMALLINT(errno);
-		}
-	    } else {
-		@global(LastErrorNumber) = nil;
-	    }
-	}
-
-	/*
-	 * Return nil (means time expired or interrupted)
-	 */
-	RETURN ( nil );
+        FD_ZERO(&rset);
+        FD_ZERO(&wset);
+        FD_ZERO(&eset);
+
+        maxF = -1;
+        if (__isNonNilObject(readFdArray)) {
+            if (! __isArrayLike(readFdArray)) {
+                goto fail;    
+            }
+            count = __arraySize(readFdArray);
+
+            for (i=0; i<count;i++) {
+                fd = __ArrayInstPtr(readFdArray)->a_element[i];
+                if (fd != nil) {
+                    if (! __isSmallInteger(fd)) {
+                        if (@global(InfoPrinting) == true) {
+                            fprintf(stderr, "[OS] warning: funny read-fd (0x%x) given to select\n", fd);
+                        }
+                    } else {
+                        f = __intVal(fd);
+                        if ((unsigned)f < FD_SETSIZE) {
+                            FD_SET(f, &rset);
+                            if (f > maxF) maxF = f;
+                            numFds++;
+                        } else {
+                            if (@global(InfoPrinting) == true) {
+                                fprintf(stderr, "[OS] warning: huge read-fd (0x%x) given to select\n", fd);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        if (__isNonNilObject(writeFdArray)) {
+            if (! __isArrayLike(writeFdArray)) {
+                goto fail;    
+            }
+            count = __arraySize(writeFdArray);
+            for (i=0; i<count;i++) {
+                fd = __ArrayInstPtr(writeFdArray)->a_element[i];
+                if (fd != nil) {
+                    if (! __isSmallInteger(fd)) {
+                        if (@global(InfoPrinting) == true) {
+                            fprintf(stderr, "[OS] warning: funny write-fd (0x%x) given to select\n", fd);
+                        }
+                    } else {
+                        f = __intVal(fd);
+                        if ((unsigned)f < FD_SETSIZE) {
+                            FD_SET(f, &wset);       
+                            if (f > maxF) maxF = f;
+                            numFds++;
+                        } else {
+                            if (@global(InfoPrinting) == true) {
+                                fprintf(stderr, "[OS] warning: huge write-fd (0x%x) given to select\n", fd);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        if (__isNonNilObject(exceptFdArray)) {
+            if (! __isArrayLike(exceptFdArray)) {
+                goto fail;    
+            }
+            count = __arraySize(exceptFdArray);
+            for (i=0; i<count;i++) {
+                fd = __ArrayInstPtr(exceptFdArray)->a_element[i];
+                if (fd != nil) {
+                    if (! __isSmallInteger(fd)) {
+                        if (@global(InfoPrinting) == true) {
+                            fprintf(stderr, "[OS] warning: funny except-fd (0x%x) given to select\n", fd);
+                        }
+                    } else {
+                        f = __intVal(fd);
+                        if ((unsigned)f < FD_SETSIZE) {
+                            FD_SET(f, &eset);       
+                            if (f > maxF) maxF = f;
+                            numFds++;
+                        } else {
+                            if (@global(InfoPrinting) == true) {
+                                fprintf(stderr, "[OS] warning: huge except-fd (0x%x) given to select\n", fd);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        t = __intVal(millis);
+        if (t) {
+            wt.tv_sec = t / 1000;
+            wt.tv_usec = (t % 1000) * 1000;
+        } else {
+            wt.tv_sec = wt.tv_usec = 0;
+        }
+
+        /*
+         * make certain, that interrupt gets us out of the select
+         * However, we must then care for moved objects.
+         */
+        __BEGIN_INTERRUPTABLE__
+        errno = 0;
+
+        if (t == 0) {
+            /* 
+             * if there is no timeout time, we can stay here interruptable.
+             */
+            do {
+                ret = select(maxF+1, &rset, &wset, &eset, &wt);
+            } while ((ret < 0) && (errno == EINTR));
+        } else {
+            do {
+                ret = select(maxF+1, &rset, &wset, &eset, &wt);
+                /* 
+                 * for now: dont loop; if we did, we had to adjust the vt-timeval;
+                 * could otherwise stay in this loop forever ...
+                 * Premature ret (before the time expired) must be handled by the caller.
+                 * A good solution is to update the wt-timeval and redo the select.
+                 */
+            } while (0 /* (ret < 0) && (errno == EINTR) */ );
+        }
+        __END_INTERRUPTABLE__
+
+        if (ret > 0) {
+            for (i=0; i <= maxF; i++) {
+                if (FD_ISSET(i, &rset)
+                 || FD_ISSET(i, &wset)
+                 || FD_ISSET(i, &eset)) {
+                    RETURN ( __MKSMALLINT(i) );
+                }
+            }
+        } else {
+            if (ret < 0) {
+                if (errno == EINTR) {
+                    errno = 0;
+                    @global(LastErrorNumber) = nil;
+                } else {
+                    if (@global(InfoPrinting) == true) {
+                        fprintf(stderr, "OS [info]: select errno = %d\n", errno);
+                    }
+                    @global(LastErrorNumber) = __MKSMALLINT(errno);
+                }
+            } else {
+                @global(LastErrorNumber) = nil;
+            }
+        }
+
+        /*
+         * Return nil (means time expired or interrupted)
+         */
+        RETURN ( nil );
     }
 
 fail: ;
@@ -12152,7 +12215,7 @@
 !UnixOperatingSystem class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.174 2003-07-15 12:19:45 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/UnixOperatingSystem.st,v 1.175 2003-07-15 14:03:04 cg Exp $'
 ! !
 
 UnixOperatingSystem initialize!