|
|
| |
| |
| |
|
|
| |
| |
| |
| |
| |
|
|
| |
| |
|
|
| package require platform |
| namespace eval ::platform::shell {} |
|
|
| |
| |
|
|
| |
|
|
| proc ::platform::shell::generic {shell} { |
| |
|
|
| CHECK $shell |
| LOCATE base out |
|
|
| set code {} |
| |
| |
| lappend code {package forget platform} |
| |
| lappend code [list source $base] |
| |
| lappend code {puts [platform::generic]} |
| |
| lappend code {exit 0} |
|
|
| set arch [RUN $shell [join $code \n]] |
|
|
| if {$out} {file delete -force $base} |
| return $arch |
| } |
|
|
| |
|
|
| proc ::platform::shell::identify {shell} { |
| |
|
|
| CHECK $shell |
| LOCATE base out |
|
|
| set code {} |
| |
| |
| lappend code {package forget platform} |
| |
| lappend code [list source $base] |
| |
| lappend code {puts [platform::identify]} |
| |
| lappend code {exit 0} |
|
|
| set arch [RUN $shell [join $code \n]] |
|
|
| if {$out} {file delete -force $base} |
| return $arch |
| } |
|
|
| |
|
|
| proc ::platform::shell::platform {shell} { |
| |
|
|
| CHECK $shell |
|
|
| set code {} |
| lappend code {puts $tcl_platform(platform)} |
| lappend code {exit 0} |
|
|
| return [RUN $shell [join $code \n]] |
| } |
|
|
| |
| |
|
|
| proc ::platform::shell::CHECK {shell} { |
| if {![file exists $shell]} { |
| return -code error "Shell \"$shell\" does not exist" |
| } |
| if {![file executable $shell]} { |
| return -code error "Shell \"$shell\" is not executable (permissions)" |
| } |
| return |
| } |
|
|
| proc ::platform::shell::LOCATE {bv ov} { |
| upvar 1 $bv base $ov out |
|
|
| |
| |
| |
| |
| |
| |
|
|
| |
| |
| |
|
|
| set pl [package ifneeded platform [package require platform]] |
| set base [lindex $pl end] |
|
|
| set out 0 |
| if {[lindex [file system $base]] ne "native"} { |
| set temp [TEMP] |
| file copy -force $base $temp |
| set base $temp |
| set out 1 |
| } |
| return |
| } |
|
|
| proc ::platform::shell::RUN {shell code} { |
| set c [TEMP] |
| set cc [open $c w] |
| puts $cc $code |
| close $cc |
|
|
| set e [TEMP] |
|
|
| set code [catch { |
| exec $shell $c 2> $e |
| } res] |
|
|
| file delete $c |
|
|
| if {$code} { |
| append res \n[read [set chan [open $e r]]][close $chan] |
| file delete $e |
| return -code error "Shell \"$shell\" is not executable ($res)" |
| } |
|
|
| file delete $e |
| return $res |
| } |
|
|
| proc ::platform::shell::TEMP {} { |
| set prefix platform |
|
|
| |
| |
|
|
| set tmpdir [DIR] |
|
|
| 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 {int(rand()*62)}]] |
| } |
| set newname [file join $tmpdir $newname] |
| 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]} { |
| return -code error "Directory $dirname is not writable" |
| } |
| set checked_dir_writable 1 |
| } |
| } else { |
| |
| close $channel |
| return [file normalize $newname] |
| } |
| } |
| } |
| if {$channel ne ""} { |
| return -code error "Failed to open a temporary file: $channel" |
| } else { |
| return -code error "Failed to find an unused temporary file name" |
| } |
| } |
|
|
| proc ::platform::shell::DIR {} { |
| |
| |
|
|
| global tcl_platform env |
|
|
| set attempdirs [list] |
|
|
| foreach tmp {TMPDIR TEMP TMP} { |
| if { [info exists env($tmp)] } { |
| lappend attempdirs $env($tmp) |
| } |
| } |
|
|
| switch $tcl_platform(platform) { |
| windows { |
| lappend attempdirs "C:\\TEMP" "C:\\TMP" "\\TEMP" "\\TMP" |
| } |
| macintosh { |
| set tmpdir $env(TRASH_FOLDER) |
| } |
| default { |
| lappend attempdirs \ |
| [file join / tmp] \ |
| [file join / var tmp] \ |
| [file join / usr tmp] |
| } |
| } |
|
|
| lappend attempdirs [pwd] |
|
|
| foreach tmp $attempdirs { |
| if { [file isdirectory $tmp] && [file writable $tmp] } { |
| return [file normalize $tmp] |
| } |
| } |
|
|
| |
| return -code error "Unable to determine a proper directory for temporary files" |
| } |
|
|
| |
| |
|
|
| package provide platform::shell 1.1.4 |
|
|