[Vm-dev] [commit][3092] Fix line-buffered input in sqFilePluginBasicPrims. c when buffer size > 1.

commits at squeakvm.org commits at squeakvm.org
Fri Oct 3 16:44:43 UTC 2014


Revision: 3092
Author:   eliot
Date:     2014-10-03 09:44:41 -0700 (Fri, 03 Oct 2014)
Log Message:
-----------
Fix line-buffered input in sqFilePluginBasicPrims.c when buffer size > 1.
fread cannot be relied upon to answer lines.

Modified Paths:
--------------
    trunk/platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c

Property Changed:
----------------
    trunk/platforms/Cross/plugins/sqPluginsSCCSVersion.h

Modified: trunk/platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c
===================================================================
--- trunk/platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c	2014-10-03 00:09:21 UTC (rev 3091)
+++ trunk/platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c	2014-10-03 16:44:41 UTC (rev 3092)
@@ -298,20 +298,24 @@
 sqInt
 sqFileStdioHandlesInto(SQFile files[3])
 {
-#if defined(_IONBF) && 0
+	/* streams connected to a terminal are supposed to be line-buffered anyway.
+	 * And for some reason this has no effect on e.g. Mac OS X.  So use
+	 * fgets instead of fread when reading from these streams.
+	 */
+#if defined(_IOLBF) && 0
 	if (isatty(fileno(stdin)))
-# if 0
-		setvbuf(stdin,0,_IONBF,1);
-# else
-		setvbuf(stdin,0,_IOFBF,0);
-# endif
+		setvbuf(stdin,0,_IOLBF,0);
 #endif
 	files[0].sessionID = thisSession;
 	files[0].file = stdin;
 	files[0].fileSize = 0;
 	files[0].writable = false;
 	files[0].lastOp = READ_OP;
+#if 0
 	files[0].isStdioStream = true;
+#else
+	files[0].isStdioStream = isatty(fileno(stdin));
+#endif
 	files[0].lastChar = EOF;
 
 	files[1].sessionID = thisSession;
@@ -347,6 +351,10 @@
 #if COGMTVM
 	sqInt myThreadIndex;
 #endif
+#if COGMTVM && SPURVM
+	int wasPinned;
+	sqInt bufferOop = (sqInt)byteArrayIndex - BaseHeaderSize;
+#endif
 
 	if (!sqFileValid(f))
 		return interpreterProxy->success(false);
@@ -359,8 +367,15 @@
 			fseek(file, 0, SEEK_CUR);  /* seek between writing and reading */
 	}
 	dst = byteArrayIndex + startIndex;
+	if (f->isStdioStream) {
 #if COGMTVM
-	if (f->isStdioStream) {
+# if SPURVM
+		if (!(wasPinned = interpreterProxy->isPinned(bufferOop))) {
+			if (!(bufferOop = interpreterProxy->pinObject(bufferOop)))
+				return 0;
+			dst = bufferOop + BaseHeaderSize + startIndex;
+		}
+# else
 		if (interpreterProxy->isInMemory((sqInt)f)
 		 && interpreterProxy->isYoung((sqInt)f)
 		 || interpreterProxy->isInMemory((sqInt)dst)
@@ -368,17 +383,37 @@
 			interpreterProxy->primitiveFailFor(PrimErrObjectMayMove);
 			return 0;
 		}
+# endif
 		myThreadIndex = interpreterProxy->disownVM(DisownVMLockOutFullGC);
-	}
-#endif
-	do {
-		clearerr(file);
-		bytesRead = fread(dst, 1, count, file);
-	} while (bytesRead <= 0 && ferror(file) && errno == EINTR);
+#endif /* COGMTVM */
+		/* Line buffering in fread can't be relied upon, at least on Mac OS X
+		 * and mingw win32.  So do it the hard way.
+		 */
+		bytesRead = 0;
+		do {
+			clearerr(file);
+			if (fread(dst, 1, 1, file) == 1) {
+				bytesRead += 1;
+				if (dst[bytesRead-1] == '\n'
+				 || dst[bytesRead-1] == '\r')
+					break;
+			}
+		}
+		while (bytesRead <= 0 && ferror(file) && errno == EINTR);
 #if COGMTVM
-	if (f->isStdioStream)
 		interpreterProxy->ownVM(myThreadIndex);
-#endif
+# if SPURVM
+		if (!wasPinned)
+			interpreterProxy->unpinObject(bufferOop);
+# endif
+#endif /* COGMTVM */
+	}
+	else
+		do {
+			clearerr(file);
+			bytesRead = fread(dst, 1, count, file);
+		}
+		while (bytesRead <= 0 && ferror(file) && errno == EINTR);
 	/* support for skipping back 1 character for stdio streams */
 	if (f->isStdioStream)
 		if (bytesRead > 0)


Property changes on: trunk/platforms/Cross/plugins/sqPluginsSCCSVersion.h
___________________________________________________________________
Modified: checkindate
   - Mon Jun 16 13:39:17 PDT 2014
   + Fri Oct  3 09:44:15 PDT 2014



More information about the Vm-dev mailing list