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 dedicated 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. <> Security | Tutorial | File