1 module caLib_util.tempdir; 2 3 import std.file : tempDir, mkdirRecurse, rmdirRecurse, exists, dirEntries, SpanMode, FileException; 4 import std.random : uniform; 5 import std.conv : to; 6 import std.path : buildNormalizedPath; 7 import std.exception : enforce; 8 9 10 private immutable string tempDirsRoot; 11 12 shared static this() 13 { 14 if(tempDir() == ".") 15 tempDirsRoot = makeTempDirsRoot(); 16 else 17 tempDirsRoot = tempDir(); 18 19 removeTempFiles(); 20 } 21 22 shared static ~this() 23 { 24 removeTempFiles(); 25 } 26 27 28 29 string makePrivateTempDir() { return makePrivateTempDir(0); } 30 31 string makePrivateTempDir(int n) 32 { 33 // we will only try to make a temporary directory 1000 times 34 enforce(n < 1000, 35 "Could not create a temporary directory"); 36 37 // the new temporary directory 38 string dir = buildNormalizedPath(tempDirsRoot, "caLib3_", 39 to!string(uniform(1000, 9999))); 40 41 // if it already exists, try again 42 if(exists(dir)) 43 return makePrivateTempDir(n+1); 44 45 // otherwise, make the directory and return the path to it 46 mkdirRecurse(dir); 47 return dir; 48 } 49 50 51 52 private void removeTempFiles() 53 { 54 if(!exists(tempDirsRoot)) 55 return; 56 57 auto dirs = dirEntries(tempDirsRoot, SpanMode.shallow); 58 59 foreach(dirPath ; dirs) 60 { 61 string dirName = dirPath[tempDirsRoot.length .. dirPath.length]; 62 if(dirName.length >= 7 && dirName[0 .. 7] == "caLib3_") 63 rmdirRecurse(dirPath); 64 } 65 } 66 67 68 69 private string makeTempDirsRoot() 70 { 71 assert(0, "Can't create temporary file:" ~ 72 "This os has no location for temporary files"); 73 }