There are two ways to make temporary files: 1. Tcl offered [file tempfile] for creating temporary files. 2. [Tcllib] provides commands for tempdir and tempfile: <
> http://tcllib.sourceforge.net/doc/fileutil.html However this page is delicated to ways to create temperory files by adding a bit of Tcl code, for people who targets distributions older than Tcl 8.6 (not having [file tempfile]) and do not wish to depend on tcllib. ---- The temp directory is put in to different environment variables on different systems. Examples are: Mac OS X: TMPDIR (tested on 10.8.5) Windows 2000: TMP and TEMP (tested on Windows 2000 SP3) CygWin: TMP and TEMP (tested on Cygwin 1.7.9) A scriptlet to do this: set tmpdir [pwd] if {[file exists "/tmp"]} { set tmpdir "/tmp"} catch {set tmpdir $::env(TRASH_FOLDER)} ;# very old Machintosh. Mac OS X doesn't have this. catch {set tmpdir $::env(TMP)} catch {set tmpdir $::env(TEMP)} If you just want one temp file: ====== set filename [file join $tmpdir [pid]] ====== If you want multiple tmpfiles, consider appending things like the application name, counter, time stamp, etc. For example: ====== set file [file join $tmpdir $appname.[pid].[incr ::globalCounter]] ====== ''DKF'' - Or create in a subdirectory/subfolder ====== if {![file exists [file join $tmpdir [pid]]]} { file mkdir [file join $tmpdir [pid]] } set file [file join $tmpdir [pid] [incr ::globalCounter]] ====== ''[Michael Schlenker]'' - Be aware of potential race conditions while opening temp files. The linux secure programming howto has some nice examples for the linux platform: http://en.tldp.org/HOWTO/Secure-Programs-HOWTO/avoid-race.html To be sure to get a new tempfile (and not some evil symlink) try something like: ====== set access [list RDWR CREAT EXCL TRUNC] set perm 0600 if {[catch {open $file $access $perm} fid ]} { # something went wrong error "Could not open tempfile." } # ok everything went well ====== ---- I had some luck with the following procedure on a UNIX box. Maybe, somebody can check if it works for windows. ====== proc tempfile {prefix suffix} { set chars "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" set nrand_chars 10 set maxtries 10 set access [list RDWR CREAT EXCL TRUNC] set permission 0600 set channel "" set checked_dir_writable 0 set mypid [pid] for {set i 0} {$i < $maxtries} {incr i} { set newname $prefix for {set j 0} {$j < $nrand_chars} {incr j} { append newname [string index $chars \ [expr ([clock clicks] ^ $mypid) % 62]] } append newname $suffix if {[file exists $newname]} { after 1 } else { if {[catch {open $newname $access $permission} channel]} { if {!$checked_dir_writable} { set dirname [file dirname $newname] if {![file writable $dirname]} { error "Directory $dirname is not writable" } set checked_dir_writable 1 } } else { # Success return [list $newname $channel] } } } if {[string compare $channel ""]} { error "Failed to open a temporary file: $chanel" } else { error "Failed to find an unused temporary file name" } } ====== Igor Volobouev ---- [Stu] - My version of mkstemp(3) ====== proc randazAZchar {} { return [format %c [expr {int(rand() * 26) + [expr {int(rand() * 10) > 5 ? 97 : 65}]}]] } proc randazAZstring {length} { set s {} for {set i $length} {$i > 0} {incr i -1} {append s [randazAZchar]} return $s } proc makeTempFile {template} { if {[set xi [string first "X" $template]] == -1} { set n $template set p {} set rl 0 } else { set n [string range $template 0 [expr {$xi - 1}]] set p [pid] set rl [expr {[string length $template] - $xi - [string length $p]}] if {$rl < 0} { set p [string range $p 0 end-[expr {$rl * -1}]] set rl 0 } } for {set i [expr {int(pow(26, ($rl <= 6 ? $rl : 6)))}]} {$i > 0} {incr i -1} { set fn $n[randazAZstring $rl]$p if {![catch {open $fn {CREAT EXCL RDWR} 0600} fd]} { file delete $fn return $fd } if {[lindex $::errorCode 1] ne "EEXIST" || [lindex $::errorCode 0] ne "POSIX"} { break } } return -code error -errorcode $::errorCode $fd } ====== ---- wld Have a look at [GUID and UUID] for generating unique filenames for temp-files. ---- [MHo] 2011-05-011: I think I have noted it somewhere in the wiki before, but I could not find it right now....: The logic within [fileutil]´s '''tempdir''' is not always correct on Windows platforms. Only the ''machine specific'' locations are tried, but in an multiuser environment (or even if only one user works on a machine) the ''user specific'' locations should be checked first (though, if the file name is unique, too, there should be no clashes in using one global folder for multiple users), as it not always true that the user has write access to the global temp folders (but for shure in it's own temp folder). The safest way to check where the user's temp folder is, is looking in the environment variables TEMP or TMP. ---- <> Security | Tutorial | File