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

Hello, i'm new here (and to Perl), and this is my question: I want to get a variable directly from an on-running UNIX daemon on my system. How do I do that? The daemon is a simple, self-created one that continuously calculates some system information. Then, I have another script that accepts user input and chooses the correct variable to retrieve from the daemon. I have done this by making the daemon print to a file and read it from there. However, how do I read it directly without using files? I've tried turning the daemon into a package and trying to use the 'require' and 'use' function but this doesn't work. I think its because the daemon is already running and the require would try to execute it again. How can I get round this? Or is there another better way? Hope someone out there can help me with this. Wish you thanks first.

Replies are listed 'Best First'.
Re: Reading from a UNIX daemon
by Zaxo (Archbishop) on Sep 12, 2002 at 07:36 UTC

    Commonly, a daemon accepts connections over a socket. The client should connect to the port the daemon is listening on, and write the identifier of the information it wants, then read the response over the socket and disconnect.

    I'd like to see your code, to check the goodness of your daemon. There are things you should do to make it a good citizen.

    After Compline,
    Zaxo

Re: Reading from a UNIX daemon
by dws (Chancellor) on Sep 12, 2002 at 08:04 UTC
    Hello, i'm new here (and to Perl), and this is my question: I want to get a variable directly from an on-running UNIX daemon on my system. How do I do that?

    Buy or borrow a copy of The Perl Cookbook. The Cookbook has recipes for writing simple network clients and servers, one of which you could adapt for your purposes.

Re: Reading from a UNIX daemon
by tadman (Prior) on Sep 12, 2002 at 07:48 UTC
    You can run your daemon as a service under something like xinetd, or more preferably, using tcpserver. Either way, these tend to remap STDIN and STDOUT to a socket for you, saving the hassle of writing your own stand-alone server.

    If you really do need a server, though, because it has to persist, look in to IO::Socket and IO::Select which can provide a solid framework for implementing something fairly robust.

    I'd try to explain how to write a client/server application here, but there's a plethora of examples in many of the O'Reilly books on Perl.
Re: Reading from a UNIX daemon
by mint1981 (Initiate) on Sep 12, 2002 at 08:26 UTC
    Thanks for the prompt replies: This is my daemon code.
    use strict; use POSIX qw(setsid); chdir '/' or die "Can't chdir to /:$!"; open STDIN, '/dev/null' or die "Can't read /dev/null:$!"; open STDOUT, '>>/dev/null' or die "Can't write to /dev/null:$!"; open STDERR, '>>/dev/null' or die "Can't write to /dev/null:$!"; defined(my $pid = fork) or die "Can't fork:$!"; setsid or die "Can't start a new session:$!"; umask 0; # this point on its a polling program. Didn't copy it entirely. while (1) { my (@lines, @fields, @bytes, $mysecond1, $mysecond2, @throughput, @ban +dwidth); @lines = `/sbin/ifconfig eth0` or die("$!\n"); @fields = split(/\s+/, $lines[6]); $fields[6] =~ /(([^:]*):?){2}/; $bytes[0] = $2; $fields[2] =~ /(([^:]*):?){2}/; $bytes[2] = $2; $mysecond1 = time; sleep 15; @lines = `/sbin/ifconfig eth0` or die("$!\n"); @fields = split(/\s+/, $lines[6]); $fields[6] =~ /(([^:]*):?){2}/; $bytes[1] = $2; $fields[2] =~ /(([^:]*):?){2}/; $bytes[3] = $2; $mysecond2 = time;
    I did try to turn my daemon to a socket just now but I hit a snag. The server code used the accept(COMM_SOCKET,SOCKET) function in a continuous while loop. This function causes the server to wait for a connection and stops the script at this point.

    But at the same time, I want the daemon to continue to do the polling routine. Note also that the routine has a sleep function inside. It works like this. The program polls the number of bytes at a certain time. Then, I sleep it for lets say 15 seconds. Then, I poll the number of bytes again. Then, I compute the difference. This is supposed to run continuously in the background. When I want to retrieve the data, my main script will ask for the data. So, the idea would be to send it over a socket connection with the daemon being the server and the main script the client.

    But, how do I get the daemon to continuously listen for a connection and at the same time run the polling routine that has a sleep function? Do I alter the server code or the polling routine code?

    Thanks.

    Edit by dws to rescue the formatting

Re: Reading from a UNIX daemon
by sauoq (Abbot) on Sep 12, 2002 at 18:07 UTC

    At this point, your "daemon" might better be described as a simple background process because all it does is collect data. It sounds to me like you are actually looking for advice on how to turn it into a daemon.

    In general, a daemon is a program that monitors something and acts when there is a change. A server is a special kind of daemon that waits for a connection on a port. Some daemons monitor a spool directory and go into action when a file is placed in the spool. There are, of course, many other variations on the same idea.

    It might make sense for your program to analyze the data as it collects it and then do something when it detects one or more conditions. (At which point your program would accurately be described as a daemon.) On the other hand, it might make sense for your program to simply collect the information and then hand it out to clients that connect to a port and request it. (At which point your program would accurately be called a daemon and just as accurately be called a server.)

    Before we can adequately help, it would help us to know what you want to do with the data that you collect. If it is something simple, then building a server might be overkill. If, however, the data might be used for a variety of things or from a variety of places a server could be the way to go.

    What exactly are you trying to accomplish?

    -sauoq
    "My two cents aren't worth a dime.";
    
Re: Reading from a UNIX daemon
by mint1981 (Initiate) on Sep 13, 2002 at 01:57 UTC
    Actually I just want to accomplish something very simple. The background program samples values every 15 seconds. Takes the difference between two most recent samples and returns a value call it X. Thus, the value X is refreshed every 15 seconds.

    Then, when another program is activated with certain command line arguments, it is supposed to immediately take the current value of X and print it.

    I got it implemented already by making the background program write X to a file and later getting the second program to read from the file.

    But I was thinking of modifying it so that I wouldn't need to use a file since a file may be externally altered. I was thinking of using packages or modules but somehow the 'use' function didn't go quite well.