[Vm-dev] [commit] r2411 - Merging support files from cogvm branch.

commits at squeakvm.org commits at squeakvm.org
Thu Jun 9 08:25:49 UTC 2011


Author: andreas
Date: 2011-06-09 01:25:48 -0700 (Thu, 09 Jun 2011)
New Revision: 2411

Modified:
   trunk/platforms/Cross/plugins/FilePlugin/FilePlugin.h
   trunk/platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c
Log:
Merging support files from cogvm branch.

Modified: trunk/platforms/Cross/plugins/FilePlugin/FilePlugin.h
===================================================================
--- trunk/platforms/Cross/plugins/FilePlugin/FilePlugin.h	2011-06-09 08:22:15 UTC (rev 2410)
+++ trunk/platforms/Cross/plugins/FilePlugin/FilePlugin.h	2011-06-09 08:25:48 UTC (rev 2411)
@@ -8,6 +8,7 @@
 *   EMAIL:   
 *   RCSID:   $Id$
 *
+*	2009-05-15 EEM add stdio flag; reorder SQFile to make it more compact
 *	2005-03-26 IKP fix unaligned accesses to file member
 *	2004-06-10 IKP 64-bit cleanliness
 *	01/22/2002 JMM change off_t to squeakOffsetFileType
@@ -18,11 +19,13 @@
 
 /* squeak file record; see sqFilePrims.c for details */
 typedef struct {
-	int			 sessionID;	/* ikp: must be first */
-	void			*file;
-	int			 writable;
-	squeakFileOffsetType	 fileSize;
-	int			 lastOp;	/* 0 = uncommitted, 1 = read, 2 = write */
+  int			 sessionID;	/* ikp: must be first */
+  void			*file;
+  squeakFileOffsetType	 fileSize;	/* 64-bits we hope. */
+  char			 writable;
+  char			 lastOp; /* 0 = uncommitted, 1 = read, 2 = write */
+  char			 lastChar;
+  char			 isStdioStream;
 } SQFile;
 
 /* file i/o */
@@ -43,6 +46,7 @@
 sqInt   sqFileFlush(SQFile *f);
 sqInt   sqFileTruncate(SQFile *f,squeakFileOffsetType offset);
 sqInt   sqFileThisSession(void);
+sqInt   sqFileStdioHandlesInto(SQFile files[3]);
 
 /* directories */
 

Modified: trunk/platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c
===================================================================
--- trunk/platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c	2011-06-09 08:22:15 UTC (rev 2410)
+++ trunk/platforms/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c	2011-06-09 08:25:48 UTC (rev 2411)
@@ -9,8 +9,6 @@
 *   RCSID:   $Id$
 *
 *   NOTES: See change log below.
-*   	2010-12-28 dtl add sqFileStdioHandlesInto() adapted from Cog branch
-*	2008-08-29 bf  add stdin/stdout/stderr support
 *	2005-03-26 IKP fix unaligned accesses to file[Size] members
 * 	2004-06-10 IKP 64-bit cleanliness
 * 	1/28/02    Tim remove non-ansi stuff
@@ -28,7 +26,8 @@
 * handling code. Note that the win32 platform #defines NO_STD_FILE_SUPPORT
 * and thus bypasses this file
 */
-                                                      
+
+#include <errno.h>
 #include "sq.h"
 #ifndef NO_STD_FILE_SUPPORT
 #include "FilePlugin.h"
@@ -54,11 +53,13 @@
 	positioning operation to be done automatically if needed.
 
 	typedef struct {
+		int		sessionID;
 		File	*file;
-		int		sessionID;
-		int		writable;
 		squeakFileOffsetType		fileSize;  //JMM Nov 8th 2001 64bits we hope
-		int		lastOp;  // 0 = uncommitted, 1 = read, 2 = write //
+		char	writable;
+		char	lastOp;  		// 0 = uncommitted, 1 = read, 2 = write //
+		char	lastChar;		// one character peek for stdin //
+		char	isStdioStream;
 	} SQFile;
 
 ***/
@@ -78,20 +79,32 @@
 int thisSession = 0;
 extern struct VirtualMachine * interpreterProxy;
 
+/* Since SQFile instaces are held on the heap in 32-bit-aligned byte arrays we
+ * may need to use memcpy to avoid alignment faults.
+ */
+#if DOUBLE_WORD_ALIGNMENT
 static void setFile(SQFile *f, FILE *file)
 {
   void *in= (void *)&file;
   void *out= (void *)&f->file;
   memcpy(out, in, sizeof(FILE *));
 }
+#else
+# define setFile(f,fileptr) ((f)->file = (fileptr))
+#endif
 
+#if DOUBLE_WORD_ALIGNMENT
 static void setSize(SQFile *f, squeakFileOffsetType size)
 {
   void *in= (void *)&size;
   void *out= (void *)&f->fileSize;
   memcpy(out, in, sizeof(squeakFileOffsetType));
 }
+#else
+# define setSize(f,size) ((f)->fileSize = (size))
+#endif
 
+#if DOUBLE_WORD_ALIGNMENT
 static FILE *getFile(SQFile *f)
 {
   FILE *file;
@@ -100,7 +113,11 @@
   memcpy(out, in, sizeof(FILE *));
   return file;
 }
+#else
+# define getFile(f) ((FILE *)((f)->file))
+#endif
 
+#if DOUBLE_WORD_ALIGNMENT
 static squeakFileOffsetType getSize(SQFile *f)
 {
   squeakFileOffsetType size;
@@ -109,28 +126,43 @@
   memcpy(out, in, sizeof(squeakFileOffsetType));
   return size;
 }
+#else
+# define getSize(f) ((f)->fileSize)
+#endif
 
+#if 0
+# define pentry(func) do { int fn = fileno(getFile(f)); if (f->isStdioStream) printf("\n"#func "(%s) %lld %d\n", fn == 0 ? "in" : fn == 1 ? "out" : "err", (long long)ftell(getFile(f)), f->lastChar); } while (0)
+# define pexit(expr) (f->isStdioStream && printf("\n\t^"#expr " %lld %d\n", (long long)(sqFileValid(f) ? ftell(getFile(f)) : -1), f->lastChar)), expr
+# define pfail() printf("\tFAIL\n");
+#else
+# define pentry(func) 0
+# define pexit(expr) expr
+# define pfail() 0
+#endif
 
 sqInt sqFileAtEnd(SQFile *f) {
 	/* Return true if the file's read/write head is at the end of the file. */
 
-	if (!sqFileValid(f)) return interpreterProxy->success(false);
-	return ftell(getFile(f)) >= getSize(f);
+	if (!sqFileValid(f))
+		return interpreterProxy->success(false);
+	pentry(sqFileAtEnd);
+	if (f->isStdioStream)
+		return pexit(feof(getFile(f)));
+	return ftell(getFile(f)) == getSize(f);
 }
 
 sqInt sqFileClose(SQFile *f) {
 	/* Close the given file. */
 
-	FILE *file;
-	if (!sqFileValid(f)) return interpreterProxy->success(false);
-	file = getFile(f);
-	if (file != stdin && file != stdout && file != stderr)
-	  fclose(file);
+	if (!sqFileValid(f))
+		return interpreterProxy->success(false);
+	fclose(getFile(f));
 	setFile(f, 0);
 	f->sessionID = 0;
 	f->writable = false;
 	setSize(f, 0);
 	f->lastOp = UNCOMMITTED;
+	return 1;
 }
 
 sqInt sqFileDeleteNameSize(char* sqFileName, sqInt sqFileNameSize) {
@@ -148,6 +180,7 @@
 	if (err) {
 		return interpreterProxy->success(false);
 	}
+	return 1;
 }
 
 squeakFileOffsetType sqFileGetPosition(SQFile *f) {
@@ -155,9 +188,15 @@
 
 	squeakFileOffsetType position;
 
-	if (!sqFileValid(f)) return interpreterProxy->success(false);
+	if (!sqFileValid(f))
+		return interpreterProxy->success(false);
+	pentry(sqFileGetPosition);
+	if (f->isStdioStream
+	 && !f->writable)
+		return pexit(f->lastChar == EOF ? 0 : 1);
 	position = ftell(getFile(f));
-	if (position == -1) return interpreterProxy->success(false);
+	if (position == -1)
+		return interpreterProxy->success(false);
 	return position;
 }
 
@@ -167,7 +206,7 @@
 	   Should be called once at startup time.
 	*/
 #if VM_PROXY_MINOR > 6
-	thisSession = (int) interpreterProxy->getThisSessionID();
+	thisSession = interpreterProxy->getThisSessionID();
 #else
 	thisSession = ioLowResMSecs() + time(NULL);
 	if (thisSession == 0) thisSession = 1;	/* don't use 0 */
@@ -179,15 +218,6 @@
 	return 1;
 }
 
-static int setStdFilename(char* stdFilename, char *cFileName, char *sqFileName, sqInt sqFileNameSize)
-{
-  if (!strncmp(stdFilename, sqFileName,sqFileNameSize)) {
-    strcpy(cFileName, stdFilename);
-    return 1;
-  } else
-    return 0;
-}
-
 sqInt sqFileOpen(SQFile *f, char* sqFileName, sqInt sqFileNameSize, sqInt writeFlag) {
 	/* Opens the given file using the supplied sqFile structure
 	   to record its state. Fails with no side effects if f is
@@ -198,26 +228,18 @@
 	char cFileName[1001];
 
 	/* don't open an already open file */
-	if (sqFileValid(f)) return interpreterProxy->success(false);
+	if (sqFileValid(f))
+		return interpreterProxy->success(false);
 
 	/* copy the file name into a null-terminated C string */
 	if (sqFileNameSize > 1000) {
 		return interpreterProxy->success(false);
 	}
+	interpreterProxy->ioFilenamefromStringofLengthresolveAliases(cFileName, sqFileName, sqFileNameSize, true);
 
-	if (setStdFilename("/dev/stdin", cFileName, sqFileName, sqFileNameSize)) 
-	  setFile(f, stdin);
-	else if (setStdFilename("/dev/stdout", cFileName, sqFileName, sqFileNameSize))
-	  setFile(f, stdout);
-	else if (setStdFilename("/dev/stderr", cFileName, sqFileName, sqFileNameSize))
-	  setFile(f, stderr);
-	else
-	  interpreterProxy->ioFilenamefromStringofLengthresolveAliases(cFileName, sqFileName, sqFileNameSize, true);
-
 	if (writeFlag) {
 		/* First try to open an existing file read/write: */
-		if (getFile(f) == NULL)
-			setFile(f, fopen(cFileName, "r+b"));
+		setFile(f, fopen(cFileName, "r+b"));
 		if (getFile(f) == NULL) {
 			/* Previous call fails if file does not exist. In that case,
 			   try opening it in write mode to create a new, empty file.
@@ -232,8 +254,7 @@
 		}
 		f->writable = true;
 	} else {
-		if (getFile(f) == NULL)
-			setFile(f, fopen(cFileName, "rb"));
+		setFile(f, fopen(cFileName, "rb"));
 		f->writable = false;
 	}
 
@@ -250,6 +271,7 @@
 		fseek(file, 0, SEEK_SET);
 	}
 	f->lastOp = UNCOMMITTED;
+	return 1;
 }
 
 /*
@@ -260,26 +282,36 @@
 sqInt
 sqFileStdioHandlesInto(SQFile files[3])
 {
-#if defined(_IONBF)
+#if defined(_IONBF) && 0
 	if (isatty(fileno(stdin)))
-		setvbuf(stdin,0,_IONBF,0);
+# if 0
+		setvbuf(stdin,0,_IONBF,1);
+# else
+		setvbuf(stdin,0,_IOFBF,0);
+# endif
 #endif
 	files[0].sessionID = thisSession;
 	files[0].file = stdin;
 	files[0].fileSize = 0;
 	files[0].writable = false;
 	files[0].lastOp = READ_OP;
+	files[0].isStdioStream = true;
+	files[0].lastChar = EOF;
 
 	files[1].sessionID = thisSession;
 	files[1].file = stdout;
 	files[1].fileSize = 0;
 	files[1].writable = true;
+	files[1].isStdioStream = true;
+	files[1].lastChar = EOF;
 	files[1].lastOp = WRITE_OP;
 
 	files[2].sessionID = thisSession;
 	files[2].file = stderr;
 	files[2].fileSize = 0;
 	files[2].writable = true;
+	files[2].isStdioStream = true;
+	files[2].lastChar = EOF;
 	files[2].lastOp = WRITE_OP;
 
 	return 7;
@@ -296,14 +328,47 @@
 	char *dst;
 	size_t bytesRead;
 	FILE *file;
+#if COGMTVM
+	sqInt myThreadIndex;
+#endif
 
-	if (!sqFileValid(f)) return interpreterProxy->success(false);
-	file= getFile(f);
-	if (f->writable && (f->lastOp == WRITE_OP)) fseek(file, 0, SEEK_CUR);  /* seek between writing and reading */
+	if (!sqFileValid(f))
+		return interpreterProxy->success(false);
+	pentry(sqFileReadIntoAt);
+	file = getFile(f);
+	if (f->writable) {
+		if (f->isStdioStream)
+			return interpreterProxy->success(false);
+		if (f->lastOp == WRITE_OP)
+			fseek(file, 0, SEEK_CUR);  /* seek between writing and reading */
+	}
 	dst = byteArrayIndex + startIndex;
-	bytesRead = fread(dst, 1, count, file);
+#if COGMTVM
+	if (f->isStdioStream) {
+		if (interpreterProxy->isInMemory((sqInt)f)
+		 && interpreterProxy->isYoung((sqInt)f)
+		 || interpreterProxy->isInMemory((sqInt)dst)
+		 && interpreterProxy->isYoung((sqInt)dst)) {
+			interpreterProxy->primitiveFailFor(PrimErrObjectMayMove);
+			return 0;
+		}
+		myThreadIndex = interpreterProxy->disownVM(DisownVMLockOutFullGC);
+	}
+#endif
+	do {
+		clearerr(file);
+		bytesRead = fread(dst, 1, count, file);
+	} while (bytesRead <= 0 && ferror(file) && errno == EINTR);
+#if COGMTVM
+	if (f->isStdioStream)
+		interpreterProxy->ownVM(myThreadIndex);
+#endif
+	/* support for skipping back 1 character for stdio streams */
+	if (f->isStdioStream)
+		if (bytesRead > 0)
+			f->lastChar = dst[bytesRead-1];
 	f->lastOp = READ_OP;
-	return bytesRead;
+	return pexit(bytesRead);
 }
 
 sqInt sqFileRenameOldSizeNewSize(char* oldNameIndex, sqInt oldNameSize, char* newNameIndex, sqInt newNameSize) {
@@ -323,38 +388,61 @@
 	if (err) {
 		return interpreterProxy->success(false);
 	}
+	return 1;
 }
 
 sqInt sqFileSetPosition(SQFile *f, squeakFileOffsetType position) {
 	/* Set the file's read/write head to the given position. */
 
-	if (!sqFileValid(f)) return interpreterProxy->success(false);
+	if (!sqFileValid(f))
+		return interpreterProxy->success(false);
+	if (f->isStdioStream) {
+		pentry(sqFileSetPosition);
+		/* support one character of pushback for stdio streams. */
+		if (!f->writable
+		 && f->lastChar != EOF) {
+			squeakFileOffsetType currentPos = f->lastChar == EOF ? 0 : 1;
+			if (currentPos == position)
+				return pexit(1);
+			if (currentPos - 1 == position) {
+				ungetc(f->lastChar, getFile(f));
+				f->lastChar = EOF;
+				return pexit(1);
+			}
+		}
+		pfail();
+		return interpreterProxy->success(false);
+	}
 	fseek(getFile(f), position, SEEK_SET);
 	f->lastOp = UNCOMMITTED;
+	return 1;
 }
 
 squeakFileOffsetType sqFileSize(SQFile *f) {
 	/* Return the length of the given file. */
 
-	if (!sqFileValid(f)) return interpreterProxy->success(false);
+	if (!sqFileValid(f))
+		return interpreterProxy->success(false);
+	if (f->isStdioStream)
+		return interpreterProxy->success(false);
 	return getSize(f);
 }
 
 sqInt sqFileFlush(SQFile *f) {
-	/* Return the length of the given file. */
 
-	if (!sqFileValid(f)) return interpreterProxy->success(false);
+	if (!sqFileValid(f))
+		return interpreterProxy->success(false);
+	pentry(sqFileFlush);
 	fflush(getFile(f));
 	return 1;
 }
 
 sqInt sqFileTruncate(SQFile *f,squeakFileOffsetType offset) {
-	/* Truncate the file*/
 
-	if (!sqFileValid(f)) return interpreterProxy->success(false);
- 	if (sqFTruncate(getFile(f), offset)) {
-            return interpreterProxy->success(false);
-        } 
+	if (!sqFileValid(f))
+		return interpreterProxy->success(false);
+ 	if (sqFTruncate(getFile(f), offset))
+		return interpreterProxy->success(false);
 	setSize(f, ftell(getFile(f)));
 	return 1;
 }
@@ -378,8 +466,10 @@
 	squeakFileOffsetType position;
 	FILE *file;
 
-	if (!(sqFileValid(f) && f->writable)) return interpreterProxy->success(false);
-	file= getFile(f);
+	if (!(sqFileValid(f) && f->writable))
+		return interpreterProxy->success(false);
+	pentry(sqFileWriteFromAt);
+	file = getFile(f);
 	if (f->lastOp == READ_OP) fseek(file, 0, SEEK_CUR);  /* seek between reading and writing */
 	src = byteArrayIndex + startIndex;
 	bytesWritten = fwrite(src, 1, count, file);
@@ -393,12 +483,10 @@
 		interpreterProxy->success(false);
 	}
 	f->lastOp = WRITE_OP;
-	return bytesWritten;
+	return pexit(bytesWritten);
 }
 
 sqInt sqFileThisSession() {
 	return thisSession;
 }
-
 #endif /* NO_STD_FILE_SUPPORT */
-



More information about the Vm-dev mailing list