Once a network server has been written, tested , and debugged , you may want it to start up automatically each time the machine is booted . On UNIX systems this is relatively simple once you learn the specifics of your operating system. At boot time, UNIX (and Linux) systems run a series of shell scripts. Each shell script performs an aspect of system initialization, such as checking file systems, checking user quotas, mounting remote directories, and starting network services. You need only find a suitable shell script, add the command needed to start your Perl-based server, and you're done. The only catch is that the location and organization of these shell scripts varies considerably among UNIX dialects. There are two general organizational styles in use. One style, derived from the BSD lineage, uses a series of scripts beginning with the characters rc , for example, rc.boot and rc.single . These files are usually located in either /etc or /etc/rc.d . On such systems, there is generally a boot script reserved for local customizations named rc.local . If you have such a system, then the easiest way to start a Perl script at boot time is to add a section to the bottom of rc.local , using as your example other sections in the script. For example, on the BSD-based system that I use at home, the end of my rc.local script has several sections like this one: # start time server if [ -x /usr/sbin/xntpd ]; then echo "Starting time server..." /usr/sbin/xntpd fi This is a bit of Bourne shell-scripting language which says that if the file /usr/sbin/xntpd exists and is executable, then echo a message to the console and run the program. To start our eliza_daemon.pl script at boot time, we would add a section like this one: # start psychotherapist server if [ -x /usr/local/bin/eliza_daemon.pl ]; then echo "Starting psychotherapist server..." /usr/local/bin/eliza_daemon.pl fi This assumes that eliza_daemon.pl has been installed into the /usr/local/bin directory. Before you reboot your system, you should try executing this fragment of the shell script a few times to make sure you've got it right. The other boot script organizational style found on UNIX systems is derived from the AT&T family of UNIX. In this style, startup scripts are sorted into subdirectories with names like rc0.d , rc1.d , and so on. Depending on the operating system, these directories may be located in /etc , /etc/rc.d , or /sbin. Each subdirectory is named after a runlevel, which controls the level of service the system will provide. For example, in runlevel 1 (corresponding to directory rc1.d ) the system may provide single-user services only, blocking all network logins, and in runlevel 3 ( rc3.d ) it may allow full network login, filesharing, and a host of other multiuser services. You will need to determine what runlevel your system commonly runs at. This can be done by examining /etc/inittab for the initdefault entry, or by running the runlevel command if your system provides one. The next step is to enter the rc*.d directory that corresponds to this runlevel. You will see a host of scripts with names that begin with either "S" or "K" ” for example, S15nfs.server and K20lp . The scripts that begin with "S" correspond to services that are started when the system enters that runlevel; those that begin with "K" are services that the system kills when it leaves the runlevel. On Solaris systems, S15nfs.server starts up NFS filesharing services, and K20lp shuts down line printing. The numbers in the script name are used to control the order in which the startup scripts are executed, since the boot system sorts the scripts alphabetically before invoking them. Frequently, the scripts are just symbolic links to general-purpose shell scripts that can start and stop the service. The real script is located in a directory named init.d , located variously in /etc/init.d , /etc/rc.d/init.d , or /sbin/init.d . When the boot system wants to launch or kill the service, it follows the link to its location, and then invokes the script with the arguments 'start' or 'stop' . On systems with AT&T-style boot scripts, the strategy again is to see how another service already does it, clone and rename its startup script, and then modify it to invoke your script at startup time. Here is an extremely simple script that can be used on many systems to start and stop the psychotherapist daemon. Name it eliza , make it executable, and store it in /etc/init.d (or whatever is the proper location for such scripts on your system). Then create a link from /etc/r3.d/S20eliza to this script, again modifying the exact path as appropriate for your operating system. #!/bin/sh # psychotherapist startup script case "" in 'start') if [ -x /usr/local/bin/eliza_daemon.pl ]; then echo -n "Starting psychotherapist: " /usr/local/bin/eliza_daemon.pl fi ;; 'stop') if [ -e /var/tmp/eliza.pid ]; then echo -n "Shutting down psychotherapist" kill -TERM `cat /var/tmp/eliza.pid` fi ;; *) echo "usage: #!/bin/sh # psychotherapist startup script case "$1" in 'start') if [ -x /usr/local/bin/eliza_daemon.pl ]; then echo -n "Starting psychotherapist: " /usr/local/bin/eliza_daemon.pl fi ;; 'stop') if [ -e /var/tmp/eliza.pid ]; then echo -n "Shutting down psychotherapist" kill - TERM `cat /var/tmp/eliza.pid` fi ;; *) echo "usage: $0 {startstop}" ;; esac {startstop}" ;; esac Again, it's a good idea to test this script from the command line before committing it to your boot scripts directory. One thing to watch for is that the boot scripts run as the superuser, so your network application also runs with superuser privileges. This is generally an undesirable feature. Chapter 14 describes how scripts started with superuser privileges can relinquish those privileges to become an ordinary user. Alternatively, you can use the su command to launch the script using the privileges of an ordinary user. In the two shell scripts mentioned, replace the calls to /usr/local/bin/eliza_daemon.pl with: su nobody -c /usr/local/bin/eliza_daemon.pl This will run the server under the nobody account. Nemeth [1995] has an excellent discussion of the boot process on a variety of popular UNIX systems. The inetd daemon, discussed at length later in this chapter in the section Using the inetd Super Daemon, provides a convenient way to automatically launch servers that are used only occasionally. Backgrounding on Windows and Macintosh Systems Neither the Macintosh nor the Microsoft Windows have the same concept of background processes as UNIX. This section explains how to achieve daemonlike behavior for long-running network applications on these platforms. On the Macintosh, the best that you can currently do is to have a network script started automatically at boot time by placing the Perl script file into the Startup Items folder in the System folder. At boot time, MacPerl will be launched and run the script. However, as soon as you exit MacPerl, the server will be terminated , along with any other Perl scripts that are running. You can improve this situation esthetically by loading the Mac::Apps::Launch module within the script and immediately calling the Hide() function, using "MacPerl" as the name of the application to hide. This code fragment illustrates the idiom: use Mac::Apps::Launch; Hide(MacPerl => 1) or warn $^E; (Under MacPerl, the $^E global returns Macintosh-specific error information.) To show the application again, launch MacPerl, bringing it to the foreground. Microsoft Windows offers a more generic way to turn applications into background daemons, using its system of "services." Services are available only on Windows NT and 2000 systems. To do this, you need two utilities: instsrv.exe and srvany.exe . These utilities are not part of the standard Windows NT/2000 distributions, but are add-ons provided by the Windows NT/2000 Resource Kits. There are two steps to the process. In the first step, you use instsrv.exe to define the name of the new service. In the second step, you use the registry editor to associate the newly defined service with the name and command-line arguments of the Perl script. The first step is to define the new service using instsrv.exe. From the DOS command window, type the following: % C:\rkit\instsrv.exe PSYCHOTHERAPIST C:\rkit\srvany.exe Replace C:\rkit with the path of the actual instsrv.exe and srvany.exe files, and PSYCHOTHERAPIST with the name that you wish to use when referring to the network service. The next step is to edit the registry using the Registry Editor. The usual caveats and dire warnings apply to this process. Launch regedt32.exe and locate the following key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PSYCHOTHERAPIST Modify this as appropriate for the service name you selected earlier. Now you add a key named Parameters , and two subkeys named Application and AppParameters. Application contains the path to the Perl executable, and AppParameters contains the arguments passed to Perl, including the script name and any script arguments. Click on the PSYCHOTHERAPIST key and choose Add Key from the Edit menu. When prompted, enter a key name of Parameters and leave the class field blank. Now select the newly created Parameters key and invoke Add Value from the Edit menu. When prompted, enter a value name of Application , a data type of REG_SZ (a null-terminated string), and a string containing the correct path to the Perl executable, such as C:\Perl\bin\perl5.6.0.exe . Select the Parameters key once again and invoke Add Value . This time enter a value name of AppParameters , a data type of REG_SZ , and a value containing the complete path of the script and any arguments you wish to pass to it, for example C:\scripts\eliza_server.pl . [3] [3] Don't use the version of the server that autobackgrounds itself and dissociates from the session group , because these tricks are UNIX specific. Use the forking server from Figure 10.3 with the interact () subroutine modified for Windows systems. Close the Registry Editor. You should now be able to go to the Services control panel and set it to start automatically at system startup time. From the list of NT/2000 services, select the psychotherapist server, and press the button labeled Startup . When prompted, change the startup type to Automatic , and set the LogOnAs field to the name of the user you wish the server to run as. A common choice is "System Acount." Also clear the checkbox labeled "Allow service to interact with users." The Services control panel allows you to manually start and stop the server. If you prefer, you can use the DOS commands NET START PSYCHOTHERAPIST and NET STOP PSYCHOTHERAPIST to the same effect. |