in reply to Restarting a script without dropping clients

Perhaps I'm still missing something after having read the whole thread so far. You don't have to close a filehandle then reopen it when you restart a program.

You can exec() the same program from itself with all files still open. The tough part becomes knowing how many files you have open.

Since you have control of the command line upon re-exec()ing your code, you can pass that on the command line. File descriptors can come in handy here. The fdopen(3) action of Perl's open() can make life bearable when needing to use numbers as file descriptors instead of having the file handles from the previous incarnation of the program. You can clone your descriptors back to filehandles as you please.

Update: Fixed a typo.



Christopher E. Stith
  • Comment on Re: Restarting a script without dropping clients

Replies are listed 'Best First'.
Re^2: Restarting a script without dropping clients
by mr_mischief (Monsignor) on Apr 27, 2006 at 20:44 UTC
    Ahbeyra asked me about this idea. TMTOWTDI -- a hard way and an easy way.

    The hard way:

    Now, I should mention I haven't actually tried this in Perl, but it works in C and the Camel documents it...

    The 'close on exec' flag is available through the Fcntl module as 'F_SETFD'. This flag is, at least in Perl, on by default execpt for 0, 1, and 2 (STDIN, STDOUT, and STDERR).

    What you do is clear this flag on all the descriptors you need to keep open, do your exec, pass somehow on the command line which descriptors should be open , then start playing with your still-open files.


    Then there's the easy way...

    The Camel also mentions the $^F variable ( AKA $SYSTEM_FD_MAX ). According to the Camel, "When Perl opens a new file (or pipe or socket), it checks the current setting of the $^F ($SYSTEM_FD_MAX) variable. If the numeric file descriptor used by that new filehandle is greater than $^F, the descriptor is marked as one to close. Otherwise, Perl leaves it alone, and new programs you exec will inherit access."

    So you could find your highest opened descriptor (or just choose an arbitrary very large number) and set $^F. Then, you can open your files, keep track of which are open in a temp file or on the command line for your new instance, and mess with your files via the descriptors in your newly exec()'ed process.

    I hope this clears things up a bit. I think this is functionality that is too often overlooked. Also, I'm not sure if this is available everywhere Perl runs, as it seems to me that it may depend on at least a loosely POSIX-like environment. The Fcntl method does require fcntl() availability on your platform. I have never seen any documentation hinting that the $^F method is similarly limited. Some other monks I'm sure know the answer to that.


    Christopher E. Stith