Permalink
Browse files

* Deploy pidfile_* and daemonize functions.

* Document pidfile functions.

* Version bump to 1.1
  • Loading branch information...
1 parent 37e633b commit 2945ebd14dfd6ac3b528d0b3f09bdd2e5f74ae3f karllehenbauer committed Jun 11, 2009
Showing with 243 additions and 201 deletions.
  1. +9 −0 .gitignore
  2. +7 −0 ChangeLog
  3. +2 −2 configure.in
  4. +0 −50 daemon.tcl
  5. +48 −9 doc/tcllauncher.txt
  6. +0 −136 pidfile.tcl
  7. +177 −4 tcllauncher.tcl
View
@@ -0,0 +1,9 @@
+Makefile
+autom4te.cache/
+config.log
+config.status
+configure
+pkgIndex.tcl
+*.o
+*.so
+tcllauncher
View
@@ -1,5 +1,12 @@
$Id: ChangeLog,v 1.7 2008-11-18 21:48:24 karl Exp $
+2009-06-11 karl
+ * Deploy pidfile_* and daemonize functions.
+
+ * Document pidfile functions.
+
+ * Version bump to 1.1
+
2009-03-31 karl
* Builds cleanly on Debian. Added README.Debin with configure instructions.
View
@@ -19,7 +19,7 @@ dnl to configure the system for the local environment.
# so you can encode the package version directly into the source files.
#-----------------------------------------------------------------------
-AC_INIT([tcllauncher], [1.0])
+AC_INIT([tcllauncher], [1.1])
#--------------------------------------------------------------------
# Call TEA_INIT as the first TEA_ macro to set up initial vars.
@@ -77,7 +77,7 @@ TEA_ADD_INCLUDES([])
TEA_ADD_LIBS([])
TEA_ADD_CFLAGS([])
TEA_ADD_STUB_SOURCES([])
-TEA_ADD_TCL_SOURCES([tcllauncher.tcl])
+TEA_ADD_TCL_SOURCES([tcllauncher.tcl daemonize.tcl pidfile.tcl])
#--------------------------------------------------------------------
# __CHANGE__
View
@@ -1,50 +0,0 @@
-#
-# tcllauncher
-#
-# rough tclx-based copy of BSD 4.4's daemon library routine
-#
-# $Id: daemon.tcl,v 1.1 2008-03-31 06:51:07 karl Exp $
-#
-
-proc daemon {args} {
- set doClose 1
- set doChdir 1
-
- foreach arg $args {
- switch $arg {
- "-noclose" {
- set doClose 0
- }
-
- "-nochdir" {
- set doChdir 0
- }
-
- default {
- error "unrecognized option: $arg"
- }
- }
- }
-
- set pid [fork]
-
- if {$pid != 0} {
- exit 0
- }
-
- id process group set
-
- if {$doChdir} {
- cd "/"
- }
-
- if {$doClose} {
- set fp [open /dev/null RDWR]
- dup $fp stdin
- dup $fp stdout
- dup $fp stderr
- close $fp
- }
-
- return
-}
View
@@ -16,6 +16,9 @@ Well, OK, but this has certain problems:
o everything 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.
@@ -30,7 +33,7 @@ prep it, like:
That's the original purpose for tcllauncher, just to make that reasonable.
- ln /usr/local/bin/tcllauncher /usr/local/bin/trackserver
+ cp /usr/local/bin/tcllauncher /usr/local/bin/trackserver
trackserver
@@ -78,18 +81,52 @@ 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.
-We need this functionality.
+Our pidfile support is a studied Tcl-based copy of BSD's pidfile C library.
+
+::tcllauncher::pidfile_open
+
+ Given an optional path to a directory 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.
+
+::tcllauncher::pidfile_write
-Something like
+ Writes your pid into the pid file previously opened by pidfile_open.
- pidfile
+::tcllauncher::pidfile_close
- pidfile app.pid
+ Close a pidfile. It should be used after your daemon forks to start
+ a child process.
- pidfile -kill app.pid
+::tcllauncher::pidfile_remove
-Should tcllauncher have standard semantics for killing, like
- apachectl graceful
+ 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
@@ -99,7 +136,7 @@ a way that when you logout it doesn't kill the process, etc.
To daemonize a tcllauncher app,
- daemon
+ ::tcllauncher::daemonize
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
@@ -109,6 +146,8 @@ Optional arguments are -noclose, which prevents the closing and redirecting
of stdin, stdout and stderr, and -nochdir, which prevents the changing of
the working dir to /.
+ ::tcllauncher::daemonize -nochdir
+
This is a rough copy of BSD 4.4's daemon library routine.
USER AND GROUP ID MANAGEMENT
View
@@ -1,136 +0,0 @@
-#
-# pidfile actions
-#
-# Tcl-ized, TclX-ized, studied copy of FreeBSD's pidfile library
-#
-# $Id: pidfile.tcl,v 1.2 2008-03-25 06:16:53 karl Exp $
-#
-
-package require Tclx
-
-#
-# pidfile_verify - insane checks of pid file
-#
-proc pidfile_verify {} {
- variable pfh
-
- if {[catch {fstat $pfh(fp)} stat] == 1} {
- error "programming error"
- }
-
- set dev [keylget stat dev]
- set ino [keylget stat ino]
-
- if {$dev != $pfh(dev) || $ino != $pfh(ino)} {
- error "programming error"
- }
-
- return 0
-}
-
-#
-# pidfile_read - given a path and the name of a pid variable, set the
-# PID into the variable
-#
-proc pidfile_read {path _pid} {
- variable pfh
-
- upvar $_pid pid
-
- set fp [open $path "RDONLY"]
- set pid [read -nonewline $fp]
- close $fp
-
- set pfh(path) $path
-}
-
-#
-# pidfile_open - given an optional path to a directory and optional permissions,
-# open the file, try to lock it, get its contents. Return the pid contained
-# therein if there is one and the lock failed. (Somebody's already got the
-# pid.)
-#
-# else you've got the lock and call pidfile_write to get your pid in there
-#
-proc pidfile_open {{path "/var/run"} {mode 0600}} {
- variable pfh
-
- set pidfile $path/$::argv0.pid
- set pfh(path) $pidfile
-
- # Open the PID file and obtain exclusive lock.
- # We truncate PID file here only to remove old PID immediately,
- # PID file will be truncated again in pidfile_write(), so
- # pidfile_write() can be called multiple times.
-
- set fp [open $pidfile "RDWR CREAT"]
-
- # try to lock the file
-
- if {![flock -write -nowait $fp]} {
- # failed to lock the file, read it for the pid of the owner
- set pid [read -nonewline $fp]
-
- # if we can get an integer out of it, return that
- if {[scan $pid %d pid] > 0} {
- close $fp
- return $pid
- }
- }
-
- # i got the lock
-
- # can fstat really fail on a file i have open?
- set stat [fstat $fp]
-
- set pfh(fp) $fp
- set pfh(dev) [keylget stat dev]
- set pfh(ino) [keylget stat ino]
-
- return 0
-}
-
-#
-# pidfile_write - write my pid into the pid file
-#
-proc pidfile_write {} {
- variable pfh
-
- pidfile_verify
-
- set fp $pfh(fp)
-
- ftruncate -fileid $fp 0
-
- puts $fp [pid]
- flush $fp
-}
-
-#
-# pidfile_close - close the pid file
-#
-proc pidfile_close {} {
- variable pfh
-
- pidfile_verify
-
- close $pfh(fp)
-}
-
-#
-# pidfile_remove - remove the pidfile, unlock the lock, and close it
-#
-proc pidfile_remove {} {
- variable pfh
-
- pidfile_verify
-
- file delete $pfh(path)
- funlock $pfh(fp)
-
- close $pfh(fp)
-}
-
-
-
-
Oops, something went wrong.

0 comments on commit 2945ebd

Please sign in to comment.