This is the new home of the egghelp.org community forum.
All data has been migrated (including user logins/passwords) to a new phpBB version.


For more information, see this announcement post. Click the X in the top right-corner of this box to dismiss this message.

Closing file handles opened by "open"

Old posts that have not been replied to for several years.
Locked
V
Variant

Closing file handles opened by "open"

Post by Variant »

I've written a random quote script which displays a random quote or action from one of the log files in my eggdrop directory. The script is here:

http://www.bludgeon.org/~rayvd/eggdrop/rand_quote.tcl

The script works great... except that the close function in TCL doesn't appear to actually close the file descriptor opened by "open". After a lot of people use the !quote feature, too many file descriptors will be open, and the bot will basically hang. An examination of eggdrop.log shows that the bot is unable to do much of anything because all file handles are in use. I have verified that the script opens hundreds of file handles (using the Linux 'lsof' command) and the only time at which they are closed is when the parent tcl script is ended (eggdrop).

Has anyone run into this before? Is there any work-around, or a way to close file handles without exiting the parent process? The only semi-solution I can think of is to write the program in an external script and call it from the TCL. But darnit, I already wrote it all in TCL, why doesn't close just work like it does in every other language?? :)

Ok, thanks!
p
ppslim
Revered One
Posts: 3914
Joined: Sun Sep 23, 2001 8:00 pm
Location: Liverpool, England

Post by ppslim »

Yes, Tcl provides the "close" command.

Your issue is with is with part of the script.

Code: Select all

proc has_string {file string} {
    set file_handle [open $file r]
    set lines [split [read $file_handle] "\n"]
    foreach line $lines {
        if {[regexp "<$string>|Action: $string" $line]} {
            return 1
        }
    }
    catch {close $file_handle}
    return 0
}
This function looks like it is intended to detect if a logfile has valid information, that could be used as a quote.

It operates by returning 1 if it does, and 0 if it doesnt.

However, it returns 1 at the quickest oportunity, without closing the file.

So for everyfile it checks, that is valid, a new file descriptor is left open.

Simply add

Code: Select all

catch {close $file_handle}
before the return 1, and you should have all your issues resolved.
V
Variant

Post by Variant »

D'oh! I take it all back... TCL is wonderful. Thanks for pointing out what I should have seen on my own. :oops:

:)
Locked