DragonFly On-Line Manual Pages
tcllauncher(n) Tcl application launcher for servers tcllauncher(n)
______________________________________________________________________________
NAME
tcllauncher - Tcl application launcher
SYNOPSIS
::tcllauncher::pidfile_open ?filename? ?mode?
::tcllauncher::pidfile_write
::tcllauncher::pidfile_mtime
::tcllauncher::pidfile_close
::tcllauncher::pidfile_remove
::tcllauncher::daemonize ?-noclose? ?-nochdir?
::tcllauncher::require_user userName
::tcllauncher::require_group groupName
::tcllauncher::require_user_and_group userName groupName
______________________________________________________________________________
DESCRIPTION
tcllauncher is a way to have Tcl programs run out of /usr/local/bin
under their own name, be installed in one place with their support
files, and provides commands to facilitate server-oriented application
execution.
Now you might think, why bother? I'll just put my script in there and
do a #! thing to invoke Tcl.
Well, OK, but this has certain problems:
o All your Tcl programs will show in "ps" as tclsh
o All your Tcl programs will show in "top" as tclsh
o if there are any files you want to pull in that aren't in a
package, you have to invent your own place to install and locate
them.
You'd like to be able to have stuff show up as its script name.
You could just copy or even link tclsh to the name of your program.
Say, for instance, trackserver.
But then you have to invoke trackserver with arguments and do stuff to
prep it, like:
cd ...somewhere...
/usr/local/bin/trackserver main.tcl
That's the original purpose for tcllauncher, just to make that
reasonable.
cp /usr/local/bin/tcllauncher /usr/local/bin/trackserver
trackserver
How does it find its files? It cd's to the corresponding lib directory
and a directory underneath that of the same name as the application,
and sources "main.tcl" with tcl_interactive set to 0.
So when "tcllauncher" is installed as "trackserver" and you run
trackserver, what happens "/usr/local/bin/trackserver" starts up like
the Tcl shell, except that it sources in
"/usr/local/lib/trackserver/main.tcl". Also, a global variable called
launchdir is set containing the "launch directory," i.e. the directory
where main.tcl was loaded from. ( In the above example,
"/usr/local/lib/trackserver.")
WHAT DIRECTORY
Tcllauncher doesn't change your directory behind your back, so wherever
you are at when you run it, you're still in that directory.
But a lot of times you want to go to your application directory, so you
can just
cd $::launchdir
Then you can source in all of your various files and stuff like that.
PROCESS GROUP
If you are going to fork off children, exec them, or whatever, you
should probably become your own process group so hopefully your
children might inherit your signals and Do The Right Thing.
id process group set
The id command is from the TclX extension.
PID FILE
Lots of apps write a file with the server's process ID in it. Upon
relaunch, the program can come along and look in its own pid file to
see if it's already alive or not, and also to potentially kill it.
Our pidfile support is a studied Tcl-based copy of BSD's pidfile C
library.
::tcllauncher::pidfile_open ?filename? ?mode?
Given an optional path to a pid filename and optional
permissions, pidfile_open opens (or creates) a file specified by
the path and locks it with TclX's interface to the flock system
call.
If the file cannot be locked, the PID of an already running
daemon is returned. Otherwise zero is returned and you've got
the lock. You can now call pidfile_write to get your pid into
the lock file.
This function does not write your process' PID into the file, so
it can be used before forking if needed.
If path is not specified (empty string), "/var/run/$::argv0.pid"
is used, and if mode is not specified, 0600 is used.
::tcllauncher::pidfile_write
Writes your pid into the pid file previously opened by
pidfile_open.
::tcllauncher::pidfile_mtime
Return the mtime of the pidfile.
Can be used after a successful or unsuccessful call to
pidfile_open. Considered useful after pidfile_open fails due to
another process holding the lock to examine when the owner
process got the lock.
::tcllauncher::pidfile_close
Close a pidfile. It should be used after your daemon forks to
start a child process.
::tcllauncher::pidfile_remove
Close and remove a pidfile.
EXAMPLE
set pid [::tcllauncher::pidfile_open "/var/run/daemon.pid" 0600]
if {$pid > 0} {
puts stderr "pid $pid already has the lock"
exit 1
}
::tcllauncher::daemonize
::tcllauncher::pidfile_write
...do work...
::tcllauncher::pidfile_remove
exit
DAEMONIZE
Sometimes you want your program to spawn itself off into the background
in a way that when you logout it doesn't kill the process, etc. To
daemonize a tcllauncher app,
::tcllauncher::daemonize ?-noclose? ?-nochdir?
By default this forks off a child and exits the parent. In the
child, it changes the current directory to "/", and redirects
stdin, stdout and stderr to/from "/dev/null".
Specifying -noclose prevents the closing and redirecting of
stdin, stdout and stderr, while -nochdir prevents the changing
of the working dir to "/"
This is a rough copy of BSD 4.4's daemon library routine.
USER AND GROUP ID MANAGEMENT
If a program needs to be run as a certain use, it can invoke
::tcllauncher::require_user userName
This requires the program to either be run as fred or as root or
something like that, by a user that has permissions to become
fred.
If the program is running as user fred or can change the user id
(suid) to fred, it continues, else it aborts.
This means if the superuser invokes the program, it will change
user to the correct user. If the correct user invokes the
program, it will correctly do nothing and proceed. Handy.
::tcllauncher::require_group groupName
does for groups what require_user does for users.
::tcllauncher::require_user_and_group userName groupName
combines changing the group and user into a single procedure.
Note that if you require user first then require group, the process may
have lost the privileges necessary to change groups after changing
users. Either require the group ID first or use
::tcllauncher::require_user_and_group to do both.
KEYWORDS
background, daemon, daemonize, tcllauncher
COPYRIGHT
Copyright (c) 2007-2014 FlightAware LLC (BSD Liscense)
tcllauncher 1.1 tcllauncher(n)