--- a/ExternalStream.st Mon Nov 13 18:30:12 1995 +0100
+++ b/ExternalStream.st Mon Nov 13 18:32:15 1995 +0100
@@ -66,66 +66,6 @@
%}
! !
-!ExternalStream primitiveFunctions!
-%{
-
-static int
-__fwrite(file, cp, len, buffered)
- FILE *file;
- char *cp;
-{
- int cnt;
-
-#ifdef LINUX
- errno = 0;
-
- /*
- * stdio library has a bug if interrupted
- * therefore, we go directly into write()
- */
- if (! buffered) {
- int cc, rest;
-
- cnt = 0;
- rest = len;
- do {
- cc = write(fileno(file), cp, rest);
- if (cc >= 0) {
- cp += cc;
- rest -= cc;
- cnt += cc;
- errno = EINTR; /* kludge */
- }
- } while ((cnt != len) && (errno == EINTR));
- } else {
- cnt = fwrite(cp, 1, len, file);
- if (errno == EINTR) errno = 0;
- }
-#else
- errno = 0;
- do {
- cnt = fwrite(cp, 1, len, file);
- if (cnt != len) {
- if (cnt >= 0) {
- cp += cnt;
- len -= cnt;
-# ifdef HPUX
- clearerr(file);
-# endif
- }
- }
- } while ((cnt != len) && (errno == EINTR));
- if (! buffered) {
- fflush(file);
- }
-#endif /* LINUX */
-
- return cnt;
-}
-
-%}
-! !
-
!ExternalStream class methodsFor:'documentation'!
copyright
@@ -143,7 +83,7 @@
!
version
- ^ '$Header: /cvs/stx/stx/libbasic/ExternalStream.st,v 1.64 1995-11-11 15:22:41 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/ExternalStream.st,v 1.65 1995-11-13 17:32:15 cg Exp $'
!
documentation
@@ -938,12 +878,15 @@
&& (_INST(mode) != @symbol(writeonly))) {
f = __FILEVal(fp);
+ if (_INST(buffered) == true) {
+ __READING__(f)
+ }
+
__BEGIN_INTERRUPTABLE__
do {
if (_INST(buffered) == false) {
cnt = read(fileno(f), &byte, 1);
} else {
- __READING__(f)
cnt = fread(&byte, 1, 1, f);
}
} while ((cnt < 0) && (errno == EINTR));
@@ -956,7 +899,9 @@
}
if (cnt == 0) {
_INST(hitEOF) = true;
- RETURN (nil);
+ if (errno == EWOULDBLOCK) {
+ RETURN (nil);
+ }
}
_INST(position) = nil;
_INST(lastErrorNumber) = __MKSMALLINT(errno);
@@ -970,24 +915,32 @@
nextBytesInto:anObject
"read bytes into an object, regardless of binary/text mode.
The number of bytes to read is defined by the objects size.
- Return the number of bytes written or nil on error. On EOF, 0 is returned.
- The object must have non-pointer indexed instvars
+ Return the number of bytes read. On EOF, 0 is returned.
+ If the receiver is some socket/pipe-like stream, an exception
+ is raised if the connection is broken.
+
+ The object to read into must have non-pointer indexed instvars
(i.e. it must be a ByteArray, String, Float- or DoubleArray).
+ If anObject is a string or byteArray and reused, this provides the
+ fastest possible physical I/O (since no new objects are allocated).
+
Use with care - non object oriented i/o.
Warning: in general, you cannot use this method to pass data from other
architectures since it does not care for byte order or float representation."
^ self nextBytes:(anObject size) into:anObject startingAt:1
- " to read 100 bytes from a stream:"
- "
+ " to read 100 bytes from a stream:
+
|b aStream|
+
aStream := 'smalltalk.rc' asFilename readStream.
b := ByteArray new:100.
aStream nextBytesInto:b.
aStream close.
b inspect
"
+
"
|s aStream|
aStream := 'smalltalk.rc' asFilename readStream.
@@ -1000,9 +953,15 @@
nextBytes:count into:anObject
"read the next count bytes into an object and return the number of
- bytes read or nil on error. On EOF, 0 is returned.
+ bytes read. On EOF, 0 is returned.
+ If the receiver is some socket/pipe-like stream, an exception
+ is raised if the connection is broken.
+
The object must have non-pointer indexed instvars (i.e. it must be
a ByteArray, String, Float- or DoubleArray).
+ If anObject is a string or byteArray and reused, this provides the
+ fastest possible physical I/O (since no new objects are allocated).
+
Use with care - non object oriented i/o.
Warning: in general, you cannot use this method to pass data from other
architectures since it does not care for byte order or float representation."
@@ -1012,12 +971,18 @@
nextBytes:count into:anObject startingAt:start
"read the next count bytes into an object and return the number of
- bytes read or 0 on EOF. Notice, that in contrast to other methods
+ bytes read or 0 on EOF.
+ If the receiver is some socket/pipe-like stream, an exception
+ is raised if the connection is broken.
+ Notice, that in contrast to other methods
here, this does NOT return nil on EOF, but the actual count.
Thus allowing read of partial blocks.
The object must have non-pointer indexed instvars
(i.e. it must be a ByteArray, String, Float- or DoubleArray).
+ If anObject is a string or byteArray and reused, this provides the
+ fastest possible physical I/O (since no new objects are allocated).
+
Use with care - non object oriented I/O.
Warning: in general, you cannot use this method to pass data from other
architectures since it does not care for byte order or float representation."
@@ -1056,9 +1021,16 @@
* mhmh - since we are interruptable, anObject may move.
* therefore, fetch the cp-pointer within the loop
*/
- __READING__(f)
+ if (_INST(buffered) == true) {
+ __READING__(f)
+ }
+
__BEGIN_INTERRUPTABLE__
do {
+ errno = 0;
+ /*
+ * because we are interruptable, refetch pointer
+ */
cp = (char *)__InstPtr(anObject) + nInstBytes + offs;
if (_INST(buffered) == false) {
ret = read(fileno(f), cp, cnt);
@@ -1070,19 +1042,24 @@
ret = fread(cp, 1, cnt, f);
}
} while ((ret < 0) && (errno == EINTR));
+
__END_INTERRUPTABLE__
cnt = ret;
- if (cnt >= 0) {
- if (cnt == 0)
- _INST(hitEOF) = true;
- else {
- pos = _INST(position);
- if (pos != nil)
- _INST(position) = __MKSMALLINT(__intVal(pos) + cnt);
+ if (cnt > 0) {
+ pos = _INST(position);
+ if (pos != nil) {
+ _INST(position) = __MKSMALLINT(__intVal(pos) + cnt);
}
RETURN (__MKSMALLINT(cnt));
}
+ if (cnt == 0) {
+ _INST(hitEOF) = true;
+ if (errno == EWOULDBLOCK) {
+ RETURN (__MKSMALLINT(cnt));
+ }
+ }
+
_INST(position) = nil;
_INST(lastErrorNumber) = __MKSMALLINT(errno);
}
@@ -1431,8 +1408,14 @@
*#endif
* }
*/
- __WRITING__(f)
- cnt = __fwrite(f, &c, 1, (_INST(buffered) == true));
+ if (_INST(buffered) == true) {
+ __WRITING__(f)
+ cnt = fwrite(&c, 1, 1, f);
+ } else {
+ do {
+ cnt = write(fileno(f), &c, 1);
+ } while ((cnt < 0) && (errno == EINTR));
+ }
__END_INTERRUPTABLE__
if (cnt == 1) {
@@ -1518,24 +1501,16 @@
if ( (offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs)) ) {
cp = (char *)__InstPtr(anObject) + nInstBytes + offs;
__BEGIN_INTERRUPTABLE__
-/*
- *#ifdef OLD
- * if (_INST(buffered) == false) {
- * cnt = write(fileno(f), cp, cnt);
- * } else
- *#endif
- * {
- * __WRITING__(f)
- * cnt = fwrite(cp, 1, cnt, f);
- * }
- *#ifndef OLD
- * if (_INST(buffered) == false) {
- * fflush(f);
- * }
- *#endif
- */
- __WRITING__(f)
- cnt = __fwrite(f, cp, cnt, (_INST(buffered) == true));
+
+ if (_INST(buffered) == true) {
+ __WRITING__(f)
+ cnt = fwrite(cp, 1, cnt, f);
+ } else {
+ do {
+ cp = (char *)__InstPtr(anObject) + nInstBytes + offs;
+ cnt = write(fileno(f), cp, cnt);
+ } while ((cnt < 0) && (errno == EINTR));
+ }
__END_INTERRUPTABLE__
@@ -1586,20 +1561,16 @@
f = __FILEVal(fp);
__BEGIN_INTERRUPTABLE__
-#ifdef OLD
- if (_INST(buffered) == false) {
- cnt = write(fileno(f), bytes, 2);
- } else
-#endif
- {
+
+ if (_INST(buffered) == true) {
__WRITING__(f)
cnt = fwrite(bytes, 1, 2, f);
+ } else {
+ do {
+ cnt = write(fileno(f), bytes, 2);
+ } while ((cnt < 0) && (errno == EINTR));
}
-#ifndef OLD
- if (_INST(buffered) == false) {
- fflush(f);
- }
-#endif
+
__END_INTERRUPTABLE__
if (cnt == 2) {
@@ -1650,20 +1621,16 @@
f = __FILEVal(fp);
__BEGIN_INTERRUPTABLE__
-#ifdef OLD
- if (_INST(buffered) == false) {
- cnt = write(fileno(f), bytes, 4);
- } else
-#endif
- {
+
+ if (_INST(buffered) == true) {
__WRITING__(f)
cnt = fwrite(bytes, 1, 4, f);
+ } else {
+ do {
+ cnt = write(fileno(f), bytes, 4);
+ } while ((cnt < 0) && (errno == EINTR));
}
-#ifndef OLD
- if (_INST(buffered) == false) {
- fflush(f);
- }
-#endif
+
__END_INTERRUPTABLE__
if (cnt == 4) {
@@ -1762,17 +1729,19 @@
&& (_INST(mode) != @symbol(writeonly))) {
f = __FILEVal(fp);
__BEGIN_INTERRUPTABLE__
- __READING__(f)
+
+ if (_INST(buffered) == true) {
+ __READING__(f)
+ }
do {
-#ifdef OLD
+ errno = 0;
if (_INST(buffered) == false) {
if (read(fileno(f), &ch, 1) != 1)
c = EOF;
else
c = ch;
} else
-#endif
{
c = getc(f);
}
@@ -1792,8 +1761,15 @@
}
RETURN ( _MKCHARACTER(c & 0xFF) );
}
+ if (errno == EWOULDBLOCK) {
+ _INST(hitEOF) = true;
+ RETURN(nil);
+ }
+
_INST(position) = nil;
- if (ferror(f) && (errno != 0)) {
+
+ if ((_INST(buffered) == false)
+ || (ferror(f) && (errno != 0))) {
_INST(lastErrorNumber) = __MKSMALLINT(errno);
} else {
_INST(hitEOF) = true;
@@ -1876,14 +1852,16 @@
__BEGIN_INTERRUPTABLE__
- __WRITING__(f)
-
- do {
- cnt = fwrite(&c, 1, 1, f);
- } while ((cnt != 1) && (errno == EINTR));
-
- if (_INST(buffered) == false) {
- fflush(f);
+ if (_INST(buffered) == true) {
+ __WRITING__(f)
+
+ do {
+ cnt = fwrite(&c, 1, 1, f);
+ } while ((cnt != 1) && (errno == EINTR));
+ } else {
+ do {
+ cnt = write(fileno(f), &c, 1);
+ } while ((cnt != 1) && (errno == EINTR));
}
__END_INTERRUPTABLE__
@@ -1923,11 +1901,14 @@
unsigned char *cp;
int len, cnt;
OBJ pos, fp;
+ int offs;
_INST(lastErrorNumber) = nil;
+
if (((fp = _INST(filePointer)) != nil)
&& (_INST(mode) != @symbol(readonly))) {
cp = NULL;
+ offs = 0;
if (__isString(aCollection) || __isSymbol(aCollection)) {
cp = _stringVal(aCollection);
len = _stringSize(aCollection);
@@ -1943,8 +1924,9 @@
cp = __ByteArrayInstPtr(aCollection)->ba_element;
len = _byteArraySize(aCollection);
nInst = __intVal(__ClassInstPtr(__qClass(aCollection))->c_ninstvars);
- cp += __OBJS2BYTES__(nInst);
- len -= __OBJS2BYTES__(nInst);
+ offs = __OBJS2BYTES__(nInst);
+ cp += offs;
+ len -= offs;
}
}
}
@@ -1953,68 +1935,24 @@
f = __FILEVal(fp);
__BEGIN_INTERRUPTABLE__
-#ifdef NONONO
-
-#ifdef OLD
- if (_INST(buffered) == false) {
- cnt = write(fileno(f), cp, len);
- } else
-#endif
- {
- __WRITING__(f)
-
-#ifdef LINUX
- errno = 0;
-
- /*
- * stdio library has a bug if interrupted
- * therefore, we go directly into write()
- */
- if (_INST(buffered) == false) {
- int cc, rest;
-
- cnt = 0;
- rest = len;
- do {
- cc = write(fileno(f), cp, rest);
- if (cc >= 0) {
- cp += cc;
- rest -= cc;
- cnt += cc;
- errno = EINTR; /* kludge */
- }
- } while ((cnt != len) && (errno == EINTR));
- } else {
- cnt = fwrite(cp, 1, len, f);
- if (errno == EINTR) errno = 0;
- }
-#else
- errno = 0;
- do {
- cnt = fwrite(cp, 1, len, f);
- if (cnt != len) {
- if (cnt >= 0) {
- /* if (errno == EINTR) */
- {
- cp += cnt;
- len -= cnt;
-# ifdef HPUX
- clearerr(f);
-# endif
- }
- }
- }
- } while ((cnt != len) && (errno == EINTR));
-#endif /* LINUX */
- }
if (_INST(buffered) == false) {
- fflush(f);
+ int cc, rest;
+
+ cnt = 0;
+ do {
+ /*
+ * refetch pointer in case of an interrupt
+ */
+ cp = __ByteArrayInstPtr(aCollection)->ba_element + offs;
+ cnt = write(fileno(f), cp, len);
+ } while ((cnt < 0) && (errno == EINTR));
+ } else {
+ __WRITING__(f)
+ cnt = fwrite(cp, 1, len, f);
+ if (errno == EINTR) errno = 0;
}
-#endif
-
- __WRITING__(f)
- cnt = __fwrite(f, cp, len, (_INST(buffered) == true));
+
__END_INTERRUPTABLE__
if (cnt == len) {
@@ -2029,6 +1967,9 @@
}
%}.
lastErrorNumber notNil ifTrue:[^ self writeError].
+ filePointer isNil ifTrue:[^ self errorNotOpen].
+ (mode == #readonly) ifTrue:[^ self errorReadOnly].
+
^ super nextPutAll:aCollection
!
@@ -2041,7 +1982,7 @@
FILE *f;
unsigned char *cp;
- int len, cnt, index1, index2;
+ int offs, len, cnt, index1, index2;
OBJ fp;
_INST(lastErrorNumber) = nil;
@@ -2049,6 +1990,7 @@
&& (_INST(mode) != @symbol(readonly))) {
if (__bothSmallInteger(start, stop)) {
cp = NULL;
+ offs = 0;
if (_INST(binary) != true) {
if (__isString(aCollection) || __isSymbol(aCollection)) {
cp = _stringVal(aCollection);
@@ -2065,13 +2007,16 @@
cp = __ByteArrayInstPtr(aCollection)->ba_element;
len = _byteArraySize(aCollection);
nInst = __intVal(__ClassInstPtr(__qClass(aCollection))->c_ninstvars);
- cp += __OBJS2BYTES__(nInst);
- len -= __OBJS2BYTES__(nInst);
+ offs = __OBJS2BYTES__(nInst);
+ cp += offs;
+ len -= offs;
}
}
}
+
if (cp != NULL) {
f = __FILEVal(fp);
+
index1 = __intVal(start);
index2 = __intVal(stop);
if ((index1 < 1) || (index2 > len) || (index2 < index1)) {
@@ -2080,32 +2025,22 @@
if (index2 > len)
index2 = len;
+ len = index2 - index1 + 1;
+
__BEGIN_INTERRUPTABLE__
- len = index2 - index1 + 1;
-
-/*
- * __WRITING__(f)
- *
- * do {
- * cnt = fwrite(cp + index1 - 1, 1, len, f);
- * if (cnt != len) {
- * if (cnt >= 0) {
- * if (errno == EINTR) {
- * cp += cnt;
- * len -= cnt;
- * }
- * }
- * }
- * } while ((cnt != len) && (errno == EINTR));
- *
- * if (_INST(buffered) == false) {
- * fflush(f);
- * }
- */
- __WRITING__(f)
- cnt = __fwrite(f, cp+index1-1, len, (_INST(buffered) == true));
+
+ if (_INST(buffered) == true) {
+ __WRITING__(f)
+ cnt = fwrite(cp+index1-1, 1, len, f);
+ } else {
+ do {
+ cp = __ByteArrayInstPtr(aCollection)->ba_element + offs;
+ cnt = write(fileno(f), cp+offs, len);
+ } while ((cnt < 0) && (errno == EINTR));
+ }
__END_INTERRUPTABLE__
+
if (cnt == len) {
if (_INST(position) != nil) {
_INST(position) = __MKSMALLINT(__intVal(_INST(position)) + len);
@@ -2138,17 +2073,17 @@
__BEGIN_INTERRUPTABLE__
- __WRITING__(f)
-
- do {
+ if (_INST(buffered) == true) {
+ __WRITING__(f)
cnt = fwrite("\n", 1, 1, f);
- } while ((cnt != 1) && (errno == EINTR));
-
- if (_INST(buffered) == false) {
- fflush(f);
+ } else {
+ do {
+ cnt = write(fileno(f), "\n", 1);
+ } while ((cnt < 0) && (errno == EINTR));
}
__END_INTERRUPTABLE__
+
if (cnt == 1) {
if (_INST(position) != nil) {
_INST(position) = __MKSMALLINT(__intVal(_INST(position)) + 1);
@@ -2217,15 +2152,6 @@
for (;;) {
if (_buffered) {
-#ifdef OLD
-/*
- do {
-*/
- ch = getc(f);
-/*
- } while ((ch < 0) && (errno == EINTR));
-*/
-#else
errno = 0;
do {
if (feof(f)) {
@@ -2234,7 +2160,7 @@
}
ch = getc(f);
} while ((ch < 0) && (errno == EINTR));
-#endif
+
if (ch == EOF) {
if (ferror(f)) {
if (errno == EINTR) {
@@ -2276,6 +2202,7 @@
}
#endif
__END_INTERRUPTABLE__
+
if (rslt != NULL) {
/*
* that strlen can be avoided and replaced by (nextPtr - buffer)
@@ -2318,9 +2245,9 @@
%{ /* NOCONTEXT */
FILE *f;
- int len, cnt;
+ int len, cnt, len1;
OBJ pos, fp;
- char *s;
+ char *cp;
_INST(lastErrorNumber) = nil;
if (((fp = _INST(filePointer)) != nil)
@@ -2328,62 +2255,47 @@
if (_INST(binary) != true) {
if (__isString(aString)) {
f = __FILEVal(fp);
- s = (char *) _stringVal(aString);
+ cp = (char *) _stringVal(aString);
len = _stringSize(aString);
__BEGIN_INTERRUPTABLE__
-/*
- *#ifdef OLD
- * if (_INST(buffered) == false) {
- * cnt = write(fileno(f), s, len);
- * } else
- *#endif
- * {
- * __WRITING__(f)
- * cnt = fwrite(s, 1, len, f);
- * }
- * if (cnt == len) {
- *#ifdef OLD
- * if (_INST(buffered) == false) {
- * cnt = write(fileno(f), "\n", 1);
- * } else
- *#endif
- * {
- * cnt = fwrite("\n", 1, 1, f);
- * }
- *#ifndef OLD
- * if (_INST(buffered) == false) {
- * if (fflush(f) == EOF) goto end;
- * }
- *#endif
- * if (cnt == 1) {
- * pos = _INST(position);
- * if (pos != nil) {
- * _INST(position) = __MKSMALLINT(__intVal(pos)+len+1);
- * }
- * __END_INTERRUPTABLE__
- * RETURN ( self );
- * }
- * }
- */
- __WRITING__(f)
- cnt = __fwrite(f, s, len, (_INST(buffered) == true));
+
+ if (_INST(buffered) == true) {
+ __WRITING__(f)
+ cnt = fwrite(cp, 1, len, f);
+ } else {
+ do {
+ cnt = write(fileno(f), cp, len);
+ } while ((cnt < 0) && (errno == EINTR));
+ }
+
if (cnt == len) {
- if (_INST(useCRLF) == true)
- cnt = __fwrite(f, "\r\n", 2, (_INST(buffered) == true));
- else
- cnt = __fwrite(f, "\n", 1, (_INST(buffered) == true));
+ len1 = len;
+
+ if (_INST(useCRLF) == true) {
+ cp = "\r\n"; len = 2;
+ } else {
+ cp = "\n"; len = 1;
+ }
+ if (_INST(buffered) == true) {
+ cnt = fwrite(cp, 1, len, f);
+ } else {
+ do {
+ cnt = write(fileno(f), cp, len);
+ } while ((cnt < 0) && (errno == EINTR));
+ }
+
if (cnt > 0) {
pos = _INST(position);
if (pos != nil) {
- _INST(position) = __MKSMALLINT(__intVal(pos)+len+cnt);
+ _INST(position) = __MKSMALLINT(__intVal(pos)+len1+cnt);
}
__END_INTERRUPTABLE__
+
RETURN ( self );
}
}
-
-end:
+
__END_INTERRUPTABLE__
_INST(lastErrorNumber) = __MKSMALLINT(errno);
}
@@ -2581,17 +2493,22 @@
%{ /* NOCONTEXT */
FILE *f;
- OBJ fp, _true = true;
+ OBJ fp;
int c;
- if (_INST(hitEOF) == _true) {
- RETURN (_true);
+ if (_INST(hitEOF) == true) {
+ RETURN (true);
}
+ if (_INST(buffered) == false) {
+ RETURN (false);
+ }
+
_INST(lastErrorNumber) = nil;
+
if ((fp = _INST(filePointer)) != nil) {
f = __FILEVal(fp);
#ifdef OLD
- RETURN ( feof(f) ? _true : false );
+ RETURN ( feof(f) ? true : false );
#else
__READING__(f)
@@ -2608,8 +2525,8 @@
if (ferror(f) && (errno != 0)) {
_INST(lastErrorNumber) = __MKSMALLINT(errno);
} else {
- _INST(hitEOF) = _true;
- RETURN (_true);
+ _INST(hitEOF) = true;
+ RETURN (true);
}
#endif
}