This page is considered SPAM!
There are two preferred, modern ways to make temporary files:
1. Tcl offered [file tempfile] for creating temporary files.
1. [Tcllib] provides commands for tempdir and tempfile within the http://core.tcl.tk/tcllib/doc/trunk/embedded/www/tcllib/files/modules/fileutil/fileutil.html%|%fileutil%|% package.
This page is dedicated to ways to create temporary files by adding a bit of Tcl code, for people who target distributions older than Tcl 8.6 (not having [file tempfile]) and do not wish to depend on Tcllib.
** See Also **
[Extral], by Peter De Rijk: Provides commands for handling temporary files.
[fileutil]::tempfile and [fileutil::maketempir: Create temporary files and directories.
[ycl%|%ycl dir autocreate]: Creates a temporary directory. [TIP #431 Discussion] has some discussion and code for creating temporary directories.
** Description **
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 Macintosh. 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
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 {int(rand() * 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 {$channl eq {}} {
error [list {Failed to open a temporary file} $channel]
} else {
error [list {Failed to find an unused temporary file name}]
}
}
======
Igor Volobouev
[AMG]: Here's a shorter version of the same:
======
proc tempfile {{filenameVar {}}} {
set chars abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
if {$filenameVar ne {}} {
upvar 1 $filenameVar filename
}
for {set i 0} {$i < 10} {incr i} {
set filename /tmp/tcl_
for {set j 0} {$j < 10} {incr j} {
append filename [string index $chars [expr {int(rand() * 62)}]]
}
if {![catch {open $filename {RDWR CREAT EXCL} 0600} channel]} {
return $channel
}
}
error {failed to find an unused temporary file name}
}
======
[AMG]: And here's a variation which creates temporary directories:
======
proc temporaryDirectory {} {
set chars abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
for {set i 0} {$i < 10} {incr i} {
set path /tmp/tcl_
for {set j 0} {$j < 10} {incr j} {
append path [string index $chars [expr {int(rand() * 62)}]]
}
if {![file exists $path]} {
file mkdir $path
file attributes $path -permissions 0700
return $path
}
}
error {failed to find an unused temporary directory name}
}
======
However, it is racy because Tcl does not provide a way to atomically check for a directory's existence, create it if it doesn't exist, and give it specified permissions.
----
[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.
** Automatic disposal **
[dbohdan] 2015-04-26: I wrote the following procedure to manage temporary files in [tcltest] tests for [Sqawk]. It creates and opens temporary files, runs the code it was given and then automatically closes the files and deletes them. The design principle is the same as in [withOpenFile] and [with-path]. For Tcl 8.5 compatibility the procedure uses `::[fileutil]::tempfile` to generate filenames.
======
# Create and open temporary files (read/write), run a script then close and
# delete the files. $args is a list of the format {fnVarName1 chVarName1
# fnVarName2 chVarName2 ... script}.
proc with-temp-files args {
set files {}
set channels {}
set script [lindex $args end]
foreach {fnVarName chVarName} [lrange $args 0 end-1] {
set filename [::fileutil::tempfile]
uplevel 1 [list set $fnVarName $filename]
lappend files $filename
if {$chVarName ne {}} {
set channel [open $filename w+]
uplevel 1 [list set $chVarName $channel]
lappend channels $channel
}
}
uplevel 1 $script
foreach channel $channels {
catch {close $channel}
}
foreach filename $files {
file delete $filename
}
}
======
<<categories>> Security | Tutorial | File
[[[https://girisilbet.online%|%İlbet giriş]]]
[[[https://denemebonusuverensiteler2023.click%|%Deneme bonusu veren siteler]]]
[[[https://siyahbayrakaynaamir.org%|%Siyah bayrak ayna amir]]]