Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I find a filename from a filehandle in Tcl?

Similar to Can I find a filename from a filehandle in Perl? but in Tcl.

I plan to cache filename-filehandle associations anyway, so I'm asking purely out of curiosity--particularly of the "operating system wizardry" mentioned in the link. Is it possible in Tcl?

If it matters, I'm (forced into) using Tcl 8.0.5 on SunOS 5.10.

like image 224
slackwing Avatar asked Feb 28 '12 17:02

slackwing


People also ask

How do I search for a file in Tcl?

-path pathPrefix Search for files with the given pathPrefix where the rest of the name matches the given patterns. This allows searching for files with names similar to a given file (as opposed to a directory) even when the names contain glob-sensitive characters.

How do I read a file from a directory in Tcl?

-- reading a file. The Tcl file commands are file, open, close, gets and read, and puts, seek, tell, and eof, fblocked, fconfigure, Tcl_StandardChannels(3), flush, fileevent, filename. One way to get file data in Tcl is to 'slurp' up the file into a text variable.

Which access mode of Tcl file will create file automatically?

Opening Files This is the default mode used when no accessMode is specified. Opens a text file for writing, if it does not exist, then a new file is created else existing file is truncated.


2 Answers

With a version of Tcl that old, you really don't have all that many options. The simplest is to do a little bit of wrapping of open and close:

rename open _original_open
rename close _original_close

proc open {filename args} {
    global fileForChannel
    set channel [eval [list _original_open $filename] $args]
    set fileForChannel($channel) $filename
    return $channel
}
proc close {channel} {
    global fileForChannel
    catch {unset fileForChannel($channel)}
    _original_close $channel
}

Then, you can get the filename for an open channel $ch by just reading $fileForChannel($ch).

like image 76
Donal Fellows Avatar answered Sep 23 '22 14:09

Donal Fellows


I looked and did not find any way to get file name from handle, so I created my own solution. This solution uses the trace command to catch when the open command exits. At which time, both file names and handles are available, so I associate them to each other via the global fileNameFromHandle array.

# This script demonstrate the use of the trace command to keep track
# the relationship between file handles and file names

# ======================================================================
# Setup trace to track file handle vs. file name
array set fileNameFromHandle {}
proc trace_proc {command code result op} {
    if {$code != 0} return; # Ignore failed calls

    set filename [lindex $command 1]; # command = {open filename mode}
    set filehandle $result
    set ::fileNameFromHandle($filehandle) $filename
}
proc getFileName {handle} { return $::fileNameFromHandle($handle) }
trace add execution open leave trace_proc

# ======================================================================
# Main
set handle1 [open file1.txt r]

# Do something with the files

# Need filename from handle?
puts "Handle: $handle1, filename: [getFileName $handle1]"

close $handle1

Update

I don't have Tcl 8.0.5, to verify if this solution works. Please try it out and let me know. You can also trace the close command to remove the association.

like image 31
Hai Vu Avatar answered Sep 25 '22 14:09

Hai Vu