[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

trap HUP not working

wmwilson01

6/1/2005 7:49:00 PM

I know I must be doing something dumb here, but I can't figure out
what, and I'm about to give up. I'm setting a trap("HUP") to call a
couple of functions (basically to re-read a config). The first time
running a "kill -HUP" on the process works fine, but the second time it
exits with a "hangup". If I modify the trap to look like:

trap("HUP") {
trap("HUP", "IGNORE")
fun1
fun2
}

It doesn't hangup, but only the first "kill -HUP" actually re-reads the
configuration.

This is ruby 1.8.1
Code follows:
<code>
require "yaml"
require "socket"
require "net/smtp"
require "file/tail"
require "getoptlong"

$config = {}
$reread = false
thishost = Socket.gethostname
tivenv = "/etc/Tivoli/setup_env.sh"
usetiv = false
daemon = false
logfile = nil
config_file = nil

opts = GetoptLong.new(
["--config-file", "-c", GetoptLong::REQUIRED_ARGUMENT],
["--daemon", "-d", GetoptLong::NO_ARGUMENT],
["--logfile", "-l", GetoptLong::REQUIRED_ARGUMENT]
)

logan_struct = Struct::new("LoganStruct",
:pattern, :tmout, :mailhost, :email, :post, :expire)


def daemonize()
fork and exit
Process.setsid
fork and exit
File.open("/dev/null", "r+") do |devnull|
$stdin.reopen(devnull)
$stdout.reopen(devnull)
$stderr.reopen(devnull)
end

Dir.chdir("/")
end

def source(file)
response_match = Regexp.new(/^([^=]*)=(.*)/)

`#{ENV['SHELL']} -c ". #{file}; set"`.each_line do |line|
if response_match.match(line)
k, v = line.gsub(/^([^=]*)=(.*)/, '\1 \2').split
ENV[k] = v
end
end
end

def parseYamlConfig(file)
if File.exists?(file) and File.stat(file).readable?
$config = YAML::load(File.open(file))
else
raise "Unusable file #{file}"
end

$config
end

def setDefaultConfigVals(tmout = 3600)
$config["patterns"].each do |pat|
pat.expire = 0

case pat.pattern
when String
pat.pattern = Regexp.new(pat.pattern)
end

if not pat.mailhost
if $config["mailhost"]
pat.mailhost = $config["mailhost"]
end
end

if not pat.tmout
if $config["tmout"]
pat.tmout = $config["tmout"]
else
pat.tmout = tmout
end
end
end
end

def lookForPatternsInLogfile(file)
if File.exists?(file) and File.stat(file).readable?
File::Tail::Logfile.open(file, :rewind=>0) do |log|
log.tail do |line|
$config["patterns"].each do |pat|
if pat.pattern.match(line)
yield pat, line
end
end
end
end
end
end

def sendMail(email, alert, host, mailhost = "mailhost")
message = <<EndOfMsg
Subject: Log Analyzer Alert for #{host}
To: #{email}
From: LOGAN

The following pattern match was made on #{host} at #{Time.now}
#{alert}

EndOfMsg

Net::SMTP.start(mailhost, 25) do |smtp|
smtp.send_mail(message, '"LOGAN"', email)
end
end

def postMessage(msg)
system("postemsg #{msg} > /dev/null 2>&1")
end


opts.each do |opt, arg|
case opt
when "--daemon"
daemon = true
when "--logfile"
logfile = File.expand_path(arg)
when "--config-file"
config_file = File.expand_path(arg)
end
end

if not logfile or not config_file
fail "Usage: #$0 [-d] -c config_file -l logfile"
end

trap("HUP") do
trap("HUP", "IGNORE")
parseYamlConfig(config_file) or fail $!
setDefaultConfigVals
end

parseYamlConfig(config_file) or fail $!
setDefaultConfigVals
daemonize if daemon

if File.exists?(tivenv)
source(tivenv)
usetiv = true
end

lookForPatternsInLogfile(logfile) do |pat, msg|
if pat.expire <= Time.now.to_i
pat.expire = 0
end

if pat.expire == 0
pat.expire = Time.now.to_i + pat.tmout
if pat.email
sendMail(pat.email, msg, thishost, pat.mailhost)
end

if pat.post
postMessage(pat.post) if usetiv
end
end
end
</code>

2 Answers

Ara.T.Howard

6/1/2005 9:06:00 PM

0

Robert Klemme

6/2/2005 10:19:00 AM

0

wmwilson01@gmail.com wrote:
> I know I must be doing something dumb here, but I can't figure out
> what, and I'm about to give up. I'm setting a trap("HUP") to call a
> couple of functions (basically to re-read a config). The first time
> running a "kill -HUP" on the process works fine, but the second time
> it exits with a "hangup". If I modify the trap to look like:
>
> trap("HUP") {
> trap("HUP", "IGNORE")
> fun1
> fun2
> }
>
> It doesn't hangup, but only the first "kill -HUP" actually re-reads
> the configuration.

You surprise me: you are really surprised that only the first signal is
processed? I mean, you set the signal handler to IGNORE on first run and
apparently you never reset it.

As far as I can see signal handlers are never executed concurrently but if
you want to be sure, I'd use standard thread synchronization:

require 'thread'

$HUP_LOCK = Mutex.new

trap "HUP" do
$HUP_LOCK.synchronize do
puts "your code here (queued up)"
end

if $HUP_LOCK.try_lock
puts "your code here (ingore duplicate invocations)"
$HUP_LOCK.unlock
end
end


Kind regards

robert