# HG changeset patch # User Claus Gittinger # Date 1374695809 -7200 # Node ID 3a22ba499a8284d3f6da50accfb99debba19cb10 # Parent ed80f8050fdc5650184d738224cc17afb9feb514 open non-inheritable (to avoid subprocesses from getting my files) diff -r ed80f8050fdc -r 3a22ba499a82 FileStream.st --- a/FileStream.st Wed Jul 24 08:57:20 2013 +0000 +++ b/FileStream.st Wed Jul 24 21:56:49 2013 +0200 @@ -230,19 +230,19 @@ Therefore, the instance variable canPosition is set according to this and an error is raised, if a position: is attemted. I know, this is ugly, but what else could we do ? - Late note: who cares for VMS these days? - (and how much useless effort has been put in the past, - to support lousy operating systems?) + Late note: who cares for VMS these days? + (and how much useless effort has been put in the past, + to support lousy operating systems?) [instance variables:] - pathName the files path (if known) - canPosition positionable - read above comment + pathName the files path (if known) + canPosition positionable - read above comment [author:] - Claus Gittinger + Claus Gittinger [see also:] - Filename DirectoryStream PipeStream Socket + Filename DirectoryStream PipeStream Socket " ! @@ -393,45 +393,45 @@ "create atomically a new file and return the file stream - use this for temporary files. The created file has the name '/tmp/stxtmp_xx_nn' where xx is our unix process id, and nn is a unique number, incremented with every call to this method. - If any of the environment variables ST_TMPDIR or TMPDIR is set, + If any of the environment variables ST_TMPDIR or TMPDIR is set, its value defines the temp directory." ^ self newTemporaryIn:Filename tempDirectory " - FileStream newTemporary - FileStream newTemporary + FileStream newTemporary + FileStream newTemporary " ! newTemporaryIn:aDirectoryOrNil "create atomically a new file and return the file stream - use this for temporary files. The created file is in aDirectoryPrefix and named 'stxtmp_xx_nn', - where xx is our unix process id, and nn is a unique number, incremented + where xx is our unix process id, and nn is a unique number, incremented with every call to this method." ^ self newTemporaryIn:aDirectoryOrNil nameTemplate:Filename tempFileNameTemplate "temp files in '/tmp': - FileStream newTemporary + FileStream newTemporary " - "temp files somewhere + "temp files somewhere (not recommended - use above since it can be controlled via shell variables): - FileStream newTemporaryIn:'/tmp' - FileStream newTemporaryIn:'/tmp' - FileStream newTemporaryIn:'/usr/tmp' - FileStream newTemporaryIn:'/' + FileStream newTemporaryIn:'/tmp' + FileStream newTemporaryIn:'/tmp' + FileStream newTemporaryIn:'/usr/tmp' + FileStream newTemporaryIn:'/' " "a local temp file: - FileStream newTemporaryIn:'' - FileStream newTemporaryIn:nil - FileStream newTemporaryIn:'.' - FileStream newTemporaryIn:('source' asFilename) + FileStream newTemporaryIn:'' + FileStream newTemporaryIn:nil + FileStream newTemporaryIn:'.' + FileStream newTemporaryIn:('source' asFilename) " ! @@ -445,48 +445,48 @@ |nameString random prevRandom prevNameString newTempFilename stream| [ - prevRandom := random. - prevNameString := nameString. + prevRandom := random. + prevNameString := nameString. - "Use random numbers in order to improve the security - by making the generated names less predictable" - [ - random := RandomGenerator new nextInteger. - ] doWhile:[random = prevRandom]. + "Use random numbers in order to improve the security + by making the generated names less predictable" + [ + random := RandomGenerator new nextInteger. + ] doWhile:[random = prevRandom]. - nameString := template bindWith:(OperatingSystem getProcessId) with:random. + nameString := template bindWith:(OperatingSystem getProcessId) with:random. - aDirectoryOrNil isNil ifTrue:[ - newTempFilename := nameString. - ] ifFalse:[ - newTempFilename := aDirectoryOrNil asFilename constructString:nameString. - ]. + aDirectoryOrNil isNil ifTrue:[ + newTempFilename := nameString. + ] ifFalse:[ + newTempFilename := aDirectoryOrNil asFilename constructString:nameString. + ]. - [ - stream := self open:newTempFilename withMode:#(CREATE_NEW GENERIC_READ_WRITE). - ] on:OpenError do:[:ex| - (OperatingSystem errorHolderForNumber:ex errorCode) errorCategory ~~ #existingReferentSignal ifFalse:[ - "some fundamental error, raise exception" - ex reject. - ]. - prevNameString = nameString ifTrue:[ - "no more names - probably a bad template" - ex reject. - ]. - "file exists, retry another one" - ]. + [ + stream := self open:newTempFilename withMode:#(CREATE_NEW GENERIC_READ_WRITE). + ] on:OpenError do:[:ex| + (OperatingSystem errorHolderForNumber:ex errorCode) errorCategory ~~ #existingReferentSignal ifFalse:[ + "some fundamental error, raise exception" + ex reject. + ]. + prevNameString = nameString ifTrue:[ + "no more names - probably a bad template" + ex reject. + ]. + "file exists, retry another one" + ]. ] doWhile:[ - stream isNil and:[prevNameString ~= nameString] "/ if namestring didn't change, the template is bad + stream isNil and:[prevNameString ~= nameString] "/ if namestring didn't change, the template is bad ]. ^ stream "temp files in '/tmp': - FileStream newTemporaryIn:'/tmp' asFilename nameTemplate:'foo%1_%2' + FileStream newTemporaryIn:'/tmp' asFilename nameTemplate:'foo%1_%2' This must fail on the second try: - FileStream newTemporaryIn:'/tmp' asFilename nameTemplate:'foo' - FileStream newTemporaryIn:'c:\temp' asFilename nameTemplate:'foo' + FileStream newTemporaryIn:'/tmp' asFilename nameTemplate:'foo' + FileStream newTemporaryIn:'c:\temp' asFilename nameTemplate:'foo' " "temp files somewhere @@ -507,16 +507,16 @@ " ! -newTemporaryIn:aDirectoryOrNil withSuffix:aSuffixString +newTemporaryIn:aDirectoryOrNil withSuffix:aSuffixString "create atomically a new file and return the file stream - use this for temporary files. The created file is in aDirectoryPrefix and named 'stxtmp_xx_nn', where xx is our unix process id, and nn is a unique number, incremented with every call to this method." - - ^ self - newTemporaryIn:aDirectoryOrNil - nameTemplate:(Filename tempFileNameTemplate asFilename - withSuffix:aSuffixString) asString + + ^ self + newTemporaryIn:aDirectoryOrNil + nameTemplate:(Filename tempFileNameTemplate asFilename + withSuffix:aSuffixString) asString " FileStream newTemporaryWithSuffix:'txt' @@ -580,9 +580,9 @@ |stream| stream := self new pathName:aFilenameString. - stream - readwrite; "/ assume read/write mode, but this depends on the args - openWithMode:anArrayOrString attributes:nil. + stream + readwrite; "/ assume read/write mode, but this depends on the args + openWithMode:anArrayOrString attributes:nil. ^ stream ! @@ -731,7 +731,7 @@ " 'Make.proto' asFilename readingFileDo:[:s| - s accessRights + s accessRights ] " ! @@ -742,18 +742,18 @@ or FileStreamm>>#accessRights." (OperatingSystem changeAccessModeOfFd:self fileDescriptor to:opaqueData) ifFalse:[ - ^ self fileName accessDeniedError:self + ^ self fileName accessDeniedError:self ]. " 'Make.proto' asFilename readingFileDo:[:s| - s accessRights:s accessRights + s accessRights:s accessRights ] " " '/' asFilename readingFileDo:[:s| - s accessRights:s accessRights + s accessRights:s accessRights ] " ! ! @@ -859,7 +859,7 @@ executor := super executor. removeOnClose == true ifTrue:[ - executor setPathName:pathName removeOnClose:true. + executor setPathName:pathName removeOnClose:true. ]. ^ executor ! ! @@ -1170,7 +1170,7 @@ This is required to reposition nonPositionable streams, such as tape-streams or variable-record-RMS files under VMS. Caveat: - This should really be done transparently by the stdio library." + This should really be done transparently by the stdio library." ^ self slowPosition0Based:newPos ! ! @@ -1197,8 +1197,8 @@ aStream nextPutAll:'(FileStream oldFileNamed:'. aStream nextPutAll:pathName storeString. (self position ~~ 0) ifTrue:[ - aStream nextPutAll:'; position:'. - self position storeOn:aStream + aStream nextPutAll:'; position:'. + self position storeOn:aStream ]. aStream nextPut:$) @@ -1262,368 +1262,369 @@ int pass = 0; if (!__isNonNilObject(encodedPathName) - || !(__isStringLike(openmode) || __isArrayLike(openmode))) - goto badArgument; + || !(__isStringLike(openmode) || __isArrayLike(openmode))) + goto badArgument; retry: #ifdef __VMS__ if (__isStringLike(encodedPathName)) { - do { - /* - * allow passing additional RMS arguments. - * stupid: DEC does not seem to offer an interface for passing a char **. - */ - __threadErrno = 0; + do { + /* + * allow passing additional RMS arguments. + * stupid: DEC does not seem to offer an interface for passing a char **. + */ + __threadErrno = 0; - { - if (__isArray(attributeSpec)) { - OBJ *ap = __ArrayInstPtr(attributeSpec)->a_element; - int numAttrib = 0; - int i; + { + if (__isArray(attributeSpec)) { + OBJ *ap = __ArrayInstPtr(attributeSpec)->a_element; + int numAttrib = 0; + int i; - numAttrib = __arraySize(attributeSpec); - for (i=0; i MAXPATHLEN) l = MAXPATHLEN; - for (i=0; i MAXPATHLEN) l = MAXPATHLEN; + for (i=0; i= 0) { - __threadErrno = 0; - f = fdopen(fd, __openmode); - if (f == NULL) { - close(fd); // fdopen failed, close before retry. - } - } + if (fd >= 0) { + __threadErrno = 0; + f = fdopen(fd, __openmode); + if (f == NULL) { + close(fd); // fdopen failed, close before retry. + } + } } # endif /* not WIN32 */ @@ -1631,80 +1632,80 @@ if (f == NULL) { - /* - * If no filedescriptors available, try to finalize - * possibly collected fd's and try again. - */ - if (pass == 0 && (__threadErrno == ENFILE || __threadErrno == EMFILE)) { - pass = 1; - __SSEND0(@global(ObjectMemory), @symbol(scavenge), 0); - __SSEND0(@global(ObjectMemory), @symbol(finalize), 0); - goto retry; - } + /* + * If no filedescriptors available, try to finalize + * possibly collected fd's and try again. + */ + if (pass == 0 && (__threadErrno == ENFILE || __threadErrno == EMFILE)) { + pass = 1; + __SSEND0(@global(ObjectMemory), @symbol(scavenge), 0); + __SSEND0(@global(ObjectMemory), @symbol(finalize), 0); + goto retry; + } badArgument: getOutOfHere: - __INST(lastErrorNumber) = __mkSmallInteger(__threadErrno); - __INST(position) = nil; + __INST(lastErrorNumber) = __mkSmallInteger(__threadErrno); + __INST(position) = nil; } else { #ifdef __VMS__ - /* - * check to see if this is positionable ... - */ - __INST(canPosition) = false; + /* + * check to see if this is positionable ... + */ + __INST(canPosition) = false; # ifndef _POSIX_C_SOURCE - { - struct stat statBuffer; + { + struct stat statBuffer; - if (fstat(fileno(f), &statBuffer) >= 0) { - switch (statBuffer.st_fab_rfm) { - case FAB$C_UDF: /* undefined (also stream binary) */ - case FAB$C_VAR: /* variable length records */ - case FAB$C_VFC: /* variable fixed control */ - case FAB$C_STM: /* RMS-11 stream (valid only for sequen) */ - default: - __INST(canPosition) = false; - break; + if (fstat(fileno(f), &statBuffer) >= 0) { + switch (statBuffer.st_fab_rfm) { + case FAB$C_UDF: /* undefined (also stream binary) */ + case FAB$C_VAR: /* variable length records */ + case FAB$C_VFC: /* variable fixed control */ + case FAB$C_STM: /* RMS-11 stream (valid only for sequen) */ + default: + __INST(canPosition) = false; + break; - case FAB$C_FIX: /* fixed length records */ - case FAB$C_STMLF: /* LF stream (valid only for sequential) */ - case FAB$C_STMCR: /* CR stream (valid only for sequential) */ - __INST(canPosition) = true; - break; - } - } - } + case FAB$C_FIX: /* fixed length records */ + case FAB$C_STMLF: /* LF stream (valid only for sequential) */ + case FAB$C_STMCR: /* CR stream (valid only for sequential) */ + __INST(canPosition) = true; + break; + } + } + } # endif #else /* not VMS */ - __INST(canPosition) = true; + __INST(canPosition) = true; #endif /* not VMS */ - if (@global(FileOpenTrace) == true) { - console_fprintf(stderr, "fopen %s [FileStream] -> %x\n", __stringVal(pathName), f); - } - if (f != NULL) { - OBJ fp; + if (@global(FileOpenTrace) == true) { + console_fprintf(stderr, "fopen %s [FileStream] -> %x\n", __stringVal(pathName), f); + } + if (f != NULL) { + OBJ fp; - wasBlocked = __BLOCKINTERRUPTS(); + wasBlocked = __BLOCKINTERRUPTS(); #if 0 - // The original code was: - __INST(handle) = fp = __MKEXTERNALADDRESS(f); __STORE(self, fp); - // but for that, gcc generates wrong code, which loads self (volatile) into - // a register (bp), then calls __MKEXTERNALADDRESS, then stores indirect bp. - // That is wrong if a scavenge occurs in __MKEXTERNALADDRESS, as bp is now still pointing to the old - // object. + // The original code was: + __INST(handle) = fp = __MKEXTERNALADDRESS(f); __STORE(self, fp); + // but for that, gcc generates wrong code, which loads self (volatile) into + // a register (bp), then calls __MKEXTERNALADDRESS, then stores indirect bp. + // That is wrong if a scavenge occurs in __MKEXTERNALADDRESS, as bp is now still pointing to the old + // object. #else - fp = __MKEXTERNALADDRESS(f); - __INST(handle) = fp; - __STORE(self, fp); + fp = __MKEXTERNALADDRESS(f); + __INST(handle) = fp; + __STORE(self, fp); #endif - } + } } %}. handle notNil ifTrue:[ - position := 0. - handleType := #filePointer. - Lobby register:self. - wasBlocked == false ifTrue:[OperatingSystem unblockInterrupts]. + position := 0. + handleType := #filePointer. + Lobby register:self. + wasBlocked == false ifTrue:[OperatingSystem unblockInterrupts]. ]. ^ handle ! @@ -1779,14 +1780,14 @@ handle := self openFile:pathName withMode:openmode attributes:attributeSpec. handle isNil ifTrue:[ - " - the open failed for some reason ... - " - ^ self openError:lastErrorNumber. + " + the open failed for some reason ... + " + ^ self openError:lastErrorNumber. ]. position := 0. buffered isNil ifTrue:[ - buffered := true. "default is buffered" + buffered := true. "default is buffered" ]. ! @@ -1997,11 +1998,11 @@ !FileStream class methodsFor:'documentation'! version - ^ '$Header: /cvs/stx/stx/libbasic/FileStream.st,v 1.166 2013-07-08 19:22:38 stefan Exp $' + ^ '$Header: /cvs/stx/stx/libbasic/FileStream.st,v 1.167 2013-07-24 19:56:49 cg Exp $' ! version_CVS - ^ '$Header: /cvs/stx/stx/libbasic/FileStream.st,v 1.166 2013-07-08 19:22:38 stefan Exp $' + ^ '$Header: /cvs/stx/stx/libbasic/FileStream.st,v 1.167 2013-07-24 19:56:49 cg Exp $' ! !