http://qs1969.pair.com?node_id=485331

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

i'm curious as to how one would make a perl script run as a TSR (terminate and stay resident) program?

more specifically, i'm writing a script that listens on a particular port, and I'd like to be able to start it initially (ie: "perl jdataserver.pl"), and have it print out some diagnostic info, then return user control to the command prompt, but continue running in the background.

should i need to check on it afterward, I'd call it again with a flag ("perl jdataserver.pl -i") and it would print out some status information, then return to the background.

and, should i need to stop it later, i could call it again with a *different* flag ("perl jdataserver.pl -k") to essentially do a clean kill of the process.

i was thinking i could accomplish this sort of effect with two scripts...the server script would periodically lock a file, write status information to it, then unlock it. then the script I call would check for this file, read the status info from it, and display the info...

however, i figure there *has* to be a better way to do this. any ideas?

Replies are listed 'Best First'.
Re: making a perl script TSR? (on linux)
by Roger (Parson) on Aug 20, 2005 at 00:35 UTC
    Have a look at the module Net::Server, it has pretty much all you need to write a network server daemon.

    Should you want to kill your daemon cleanly, create a signal handler in the daemon that does a graceful shutdown, and have the program, when you run with '-k' flag, to send a signal to the daemon, which then initiates the shutdown procedure.

    You may also want to look at modules like Unix::Process (really just ps -ef) to discover the PID of the daemon process.

    You can also create a /var/lock/myserver.lock file as well when the server first goes TSR, that contains the PID of the server process. The program later (in kill mode) will read this file to get the PID, validate the PID using Unix::Process to make sure it is still running, then send the kill signal to the server to initiate a clean shutdown.

Re: making a perl script TSR? (on linux)
by cees (Curate) on Aug 20, 2005 at 03:12 UTC

    Check out this node Re: Writing a Perl Daemon for some example code that uses Proc::Daemon and Proc::PID_File to do the hard work.

    By the way, does anyone else thing that Terminate and Stay Resident is a dumb acronym? You are not terminating the program, it is just running in the background! I guess Disk Operation System wasn't really a brilliant TLA either...

      The term Terminate and Stay Resident made sense when it was originaly used. A basic overview was that for one program to provide extra functionality to the user after another program was started under a single task, real mode OS what it would do is load all the information and code it needed into memory, then tell the OS that it was quiting but not cleaning up it's memory. The OS would oblige and the program would 'stay resident' in memory after it had 'terminate'd. This program could say be a sound or mouse driver. Another program would come along and it would know about that some driver that it might like to use could be resident. It would ask the OS for a list of resident programs and their addresses in memory, and seeing one it was interested in it would take it's memory address and knowing that it alway provided a certain function at a predefined location after it's start of memory it would make a call to that location and the TSR could then take an action on the running programs behalf.
      DOS could also be considered resonable as many OSes for micro-computers of the day were stored in ROM not on a disk, thus the distinction that the OS was stored on writable media was important to some people.

      Coming from a DOS background, I had to second Ven'Tatsu on saying that the term really made sense at that time (at least for us poor DOS user's ;)

      Anyone remember Side Kick(TM), The Norton Guides(TM), etc. It was cool to have 640K 10Mhz XT computer and be able to run Turbo Pascal 3(TM) as editor and call those little gizmos to look-up a library reference or something.

      And, as Ven'Tatsu said, some programs apparently keep running, but then there were some (like the ones mentioned), that just were sitting there waiting for their Hot-Key to be pressed to become alive! Ah, many good memories... ;)

      And also the classic Assembler 101 assignment to make a TSR clock program. Wasn't that cool. ;)

      God bless you
      rruiz

Re: making a perl script TSR? (on linux)
by sgifford (Prior) on Aug 20, 2005 at 01:15 UTC
    It looks like Proc::Daemon does most of the important stuff (though I haven't used it myself). Nowadays, I usually use daemontools, which takes care of most of the hard parts, and provides a common interface to a wide variety of servers. You can also follow the instructions in the Perl FAQ.
Re: making a perl script TSR? (on linux)
by wink (Scribe) on Aug 20, 2005 at 00:54 UTC

    My immediate thought was '&' and signals. Following any command in Linux with an ampersand will cause it to run in the background (much like the bg command). The signals will allow you to control the script without having an interactive interface to it. As a comprehensive solution:

  • Create 2 scripts, we'll say the first is called jdataserver.pl, and the second is jdatalisten.pl
  • Have jdataserver.pl check for command-line options. If none are given, have it exec() jdatalisten.pl in the background (using bg or &, or is there a function in Perl?)
  • If the -i command-line option is given, have it check to see if jdatalisten.pl is running and if so send it a signal (there are user-defined ones on most OSes) that it knows how to catch.
  • If the -k command-line option is given, have it check to see if jdatalisten.pl is running and if so send it a SIGINT, SIGKILL, SIGQUIT, or whatever signal for it to catch.
  • Continue as desired for other functionality.

    This could possibly also be accomplished with a single script, just having it check for its own existence in the processes (although it would have to exclude its own pid). [id://roger] also had some good resources posted above.

Re: making a perl script TSR? (on linux)
by 5mi11er (Deacon) on Aug 20, 2005 at 17:53 UTC
    I just wanted to make sure you understood that you're asking how to write what is now called a daemon in unix terms, and what windows calls a service. The term TSR is no longer applicable on modern OSes...

    -Scott

Re: making a perl script TSR? (on linux)
by phaylon (Curate) on Aug 20, 2005 at 18:32 UTC
    You can also use SuperSearch or Google(Groups) to search for detaching a perl-script from a tty, if that's the actual thing you want to achieve. As I remember TSR, that's more a "single-task" term.

    Ordinary morality is for ordinary people. -- Aleister Crowley
Re: making a perl script TSR? (on linux)
by Anonymous Monk on Aug 23, 2005 at 19:30 UTC
    If you wanted to, you could, rather than have one script dump *EVERYTHING* to a file, you could have it just dump its PID, then communicate with it via signals.

    ie: when the handler script runs, have it send the server script a SIGINT (kill("INT",$pid)) and open and write to a pipe to the server script; then have the server script, on receipt of a SIGINT, open and read from a pipe, or something like that.

    it may not be pretty, but it would work well IF you know what you're doing. Of course, if you don't, then you'll end up with a mess.