Subject: understanding /etc/rc.subr
To: None <netbsd-help@netbsd.org>
From: Marshall Rose <mrose+mtr.netnews@dbc.mtview.ca.us>
List: netbsd-help
Date: 02/28/2003 22:08:44
i have this tcl script that gets invoked by a file under /etc/rc.d/.
like most tcl scripts, it starts like this:
#!/bin/sh
# the following restarts using tclsh \
PATH=/usr/bin:/bin:/usr/pkg/bin:/usr/local/bin:/sbin:/usr/sbin \
LD_LIBRARY_PATH=/usr/pkg/lib:/usr/lib:/usr/local/lib \
export PATH LD_LIBRARY_PATH; exec tclsh "$0" "$@"
..tcl script starts here...
(for those not familiar with this idiom, skip to the postscript at the
bottom of this email; otherwise, let's just assume there are good reason
for doing things this way...)
anyway, the problem arises in /etc/rc.subr's procedure _find_processes,
whose job it is see if a particular process is running. there are two
variables that are key to this job:
pidfile, which tells you the path of the file containing a pid
command_interpreter, which tells you what argv[0] should be
in my /etc/rc.d/foo file, i have:
command_interpreter=tclsh
pidfile="/var/run/${name}.pid"
unfortunately, _find_processes() is too clever for its own good, because
it actually opens the script and reads the first line. if the value
doesn't match $command_interpreter it prints a warning and then uses the
value it reads from the file instead of what was in the rc file.
would someone explain to me "why?" certainly, i can see printing the
warning, but why does rc.subr override what's in the rc file? i'd like
to think that i'm a bit more clueful than the script, eh?
thanks!
/mtr
ps: the idiom explained:
1. some shells/kernels/whatever refuse to "do the right" thing with
a script unless the interpreter comes from an approved list.
2. the location of the tcl shell varies on different systems.
the bourne and tcl shells have different continuation conventions for
comment lines, i.e., the bourne shell doesn't allow comment lines to
continue more than one line, whilst the tcl shell does.
hence, the bourne shell sees these lines
PATH=/usr/bin:/bin:/usr/pkg/bin:/usr/local/bin:/sbin:/usr/sbin \
LD_LIBRARY_PATH=/usr/pkg/lib:/usr/lib:/usr/local/lib \
export PATH LD_LIBRARY_PATH; exec tclsh "$0" "$@"
and no others, because of the exec; in contrast, the tcl shell ignores
all these lines...
/mtr