#FEATURE by stefan
authorStefan Vogel <sv@exept.de>
Wed, 29 Apr 2020 10:31:29 +0200
changeset 25377 b3ee83b86f9b
parent 25376 88a3329875ba
child 25378 a95e315ed8b4
#FEATURE by stefan class: FileStream class changed: #newTemporaryIn:nameTemplate: create unique temp files even if the name template does not ensure unique names.
FileStream.st
--- a/FileStream.st	Tue Apr 28 16:22:44 2020 +0200
+++ b/FileStream.st	Wed Apr 29 10:31:29 2020 +0200
@@ -1,5 +1,3 @@
-"{ Encoding: utf8 }"
-
 "
  COPYRIGHT (c) 1989 by Claus Gittinger
 	      All Rights Reserved
@@ -448,56 +446,64 @@
      with every call to this method respectively.
      See also: #newTemporary which looks for a good temp directory."
 
-    |nameString random prevRandom prevNameString newTempFilename stream|
+    |nameString random prevRandom prevNameString newTempFilename stream nextSeqNr fn|
 
     [
-	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 nextLettersOrDigits:4.
+        ] doWhile:[random = prevRandom].
 
-	"Use random numbers in order to improve the security
-	 by making the generated names less predictable"
-	[
-	    random := RandomGenerator nextLettersOrDigits:4.
-	] doWhile:[random = prevRandom].
-
-	nameString := template bindWith:(OperatingSystem getProcessId) with:random.
+        nameString := template bindWith:(OperatingSystem getProcessId) with:random.
+        (prevNameString = nameString) ifTrue:[
+            "/ ouch - the given template seems to not generate unique file names.
+            "/ append a sequence number
+            nextSeqNr := (nextSeqNr ? 0) + 1.
+            fn := nameString asFilename.
+            nameString := (fn withoutSuffix name, '_', nextSeqNr asString) asFilename withSuffix:fn suffix.
+        ].    
 
-	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 FILE_SHARE_WRITE FILE_SHARE_READ).
-	] on:OpenError do:[:ex|
-	   ex errorCategory ~~ #existingReferentSignal ifTrue:[
-		"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 FILE_SHARE_WRITE FILE_SHARE_READ).
+        ] on:OpenError do:[:ex|
+           ex errorCategory ~~ #existingReferentSignal ifTrue:[
+                "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
      (not recommended - use above since it can be controlled via shell variables):
 
+     FileStream newTemporaryIn:'/tmp'     nameTemplate:'foo'
      FileStream newTemporaryIn:'/tmp'     nameTemplate:'foo%1_%2'
      FileStream newTemporaryIn:'/tmp'     nameTemplate:'foo%1_%2'
      FileStream newTemporaryIn:'/usr/tmp' nameTemplate:'foo%1_%2'
@@ -512,7 +518,7 @@
      FileStream newTemporaryIn:('source' asFilename) nameTemplate:'foo%1_%2'
     "
 
-    "Modified: / 12-10-2018 / 10:45:25 / Stefan Vogel"
+    "Modified: / 29-04-2020 / 09:38:15 / Stefan Vogel"
 !
 
 newTemporaryIn:aDirectoryOrNil withSuffix:aSuffixString