mlanett-daemons 1.0.13 → 1.1.10.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +12 -2
- data/LICENSE +1 -8
- data/README-mlanett.rdoc +8 -0
- data/{README → README.rdoc} +6 -15
- data/Releases +84 -9
- data/TODO +1 -5
- data/daemons.gemspec +1 -0
- data/examples/call/call.rb +1 -0
- data/examples/daemonize/daemonize.rb +10 -3
- data/examples/run/ctrl_hanging.rb +19 -0
- data/examples/run/ctrl_monitor_multiple.rb +18 -0
- data/examples/run/ctrl_normal.rb +0 -1
- data/examples/run/ctrl_proc.rb.output +20 -0
- data/examples/run/ctrl_proc_rand.rb +23 -0
- data/examples/run/ctrl_slowstop.rb +16 -0
- data/examples/run/myserver_crashing.rb +2 -2
- data/examples/run/myserver_hanging.rb +21 -0
- data/examples/run/myserver_slowstop.rb +21 -0
- data/lib/daemons.rb +38 -10
- data/lib/daemons/application.rb +131 -26
- data/lib/daemons/application_group.rb +58 -10
- data/lib/daemons/change_privilege.rb +19 -0
- data/lib/daemons/cmdline.rb +10 -6
- data/lib/daemons/controller.rb +5 -2
- data/lib/daemons/daemonize.rb +64 -150
- data/lib/daemons/etc_extension.rb +12 -0
- data/lib/daemons/exceptions.rb +3 -0
- data/lib/daemons/monitor.rb +27 -19
- data/lib/daemons/pid.rb +13 -14
- data/lib/daemons/pidfile.rb +14 -7
- data/lib/daemons/pidmem.rb +9 -0
- data/lib/daemons/version.rb +1 -1
- data/spec/pidfile_spec.rb +12 -0
- data/spec/spec_helper.rb +1 -0
- metadata +31 -47
- data/daemons.tmproj +0 -56
- data/examples/run/myserver_crashing.rb.output +0 -30
- data/html/classes/Daemonize.html +0 -497
- data/html/classes/Daemons.html +0 -683
- data/html/classes/Daemons/Application.html +0 -836
- data/html/classes/Daemons/ApplicationGroup.html +0 -508
- data/html/classes/Daemons/CmdException.html +0 -113
- data/html/classes/Daemons/Controller.html +0 -429
- data/html/classes/Daemons/Error.html +0 -113
- data/html/classes/Daemons/Exception.html +0 -111
- data/html/classes/Daemons/Monitor.html +0 -263
- data/html/classes/Daemons/Optparse.html +0 -244
- data/html/classes/Daemons/Pid.html +0 -339
- data/html/classes/Daemons/PidFile.html +0 -441
- data/html/classes/Daemons/PidMem.html +0 -126
- data/html/classes/Daemons/RuntimeException.html +0 -113
- data/html/classes/Daemons/SystemError.html +0 -163
- data/html/created.rid +0 -1
- data/html/files/README.html +0 -377
- data/html/files/Releases.html +0 -342
- data/html/files/TODO.html +0 -121
- data/html/files/lib/daemons/application_group_rb.html +0 -101
- data/html/files/lib/daemons/application_rb.html +0 -110
- data/html/files/lib/daemons/cmdline_rb.html +0 -101
- data/html/files/lib/daemons/controller_rb.html +0 -101
- data/html/files/lib/daemons/daemonize_rb.html +0 -207
- data/html/files/lib/daemons/exceptions_rb.html +0 -101
- data/html/files/lib/daemons/monitor_rb.html +0 -108
- data/html/files/lib/daemons/pid_rb.html +0 -108
- data/html/files/lib/daemons/pidfile_rb.html +0 -108
- data/html/files/lib/daemons/pidmem_rb.html +0 -108
- data/html/files/lib/daemons_rb.html +0 -117
- data/html/fr_class_index.html +0 -41
- data/html/fr_file_index.html +0 -40
- data/html/fr_method_index.html +0 -91
- data/html/index.html +0 -24
- data/html/rdoc-style.css +0 -208
- data/test/call_as_daemon.rb +0 -12
- data/test/tc_main.rb +0 -24
- data/test/test1.rb +0 -19
- data/test/testapp.rb +0 -11
@@ -42,6 +42,7 @@ module Daemons
|
|
42
42
|
@dir = options[:dir] || ''
|
43
43
|
|
44
44
|
@keep_pid_files = options[:keep_pid_files] || false
|
45
|
+
@no_pidfiles = options[:no_pidfiles] || false
|
45
46
|
|
46
47
|
#@applications = find_applications(pidfile_dir())
|
47
48
|
@applications = []
|
@@ -60,6 +61,41 @@ module Daemons
|
|
60
61
|
end
|
61
62
|
|
62
63
|
def find_applications(dir)
|
64
|
+
if @no_pidfiles
|
65
|
+
return find_applications_by_app_name(app_name)
|
66
|
+
else
|
67
|
+
return find_applications_by_pidfiles(dir)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# TODO: identifiy the monitor process
|
72
|
+
def find_applications_by_app_name(app_name)
|
73
|
+
pids = []
|
74
|
+
|
75
|
+
begin
|
76
|
+
x = `ps auxw | grep -v grep | awk '{print $2, $11, $12}' | grep #{app_name}`
|
77
|
+
if x && x.chomp!
|
78
|
+
processes = x.split(/\n/).compact
|
79
|
+
processes = processes.delete_if do |p|
|
80
|
+
pid, name, add = p.split(/\s/)
|
81
|
+
# We want to make sure that the first part of the process name matches
|
82
|
+
# so that app_name matches app_name_22
|
83
|
+
|
84
|
+
app_name != name[0..(app_name.length - 1)] and not add.include?(app_name)
|
85
|
+
end
|
86
|
+
pids = processes.map {|p| p.split(/\s/)[0].to_i}
|
87
|
+
end
|
88
|
+
rescue ::Exception
|
89
|
+
end
|
90
|
+
|
91
|
+
return pids.map {|f|
|
92
|
+
app = Application.new(self, {}, PidMem.existing(f))
|
93
|
+
setup_app(app)
|
94
|
+
app
|
95
|
+
}
|
96
|
+
end
|
97
|
+
|
98
|
+
def find_applications_by_pidfiles(dir)
|
63
99
|
pid_files = PidFile.find_files(dir, app_name, ! @keep_pid_files)
|
64
100
|
|
65
101
|
#pp pid_files
|
@@ -105,12 +141,14 @@ module Daemons
|
|
105
141
|
private :setup_app
|
106
142
|
|
107
143
|
def create_monitor(an_app)
|
108
|
-
|
144
|
+
if @monitor and options[:monitor]
|
145
|
+
@monitor.stop
|
146
|
+
@monitor = nil
|
147
|
+
end
|
109
148
|
|
110
149
|
if options[:monitor]
|
111
150
|
@monitor = Monitor.new(an_app)
|
112
|
-
|
113
|
-
@monitor.start(@applications)
|
151
|
+
@monitor.start(self)
|
114
152
|
end
|
115
153
|
end
|
116
154
|
|
@@ -125,18 +163,28 @@ module Daemons
|
|
125
163
|
}
|
126
164
|
end
|
127
165
|
|
128
|
-
def stop_all(
|
129
|
-
|
166
|
+
def stop_all(no_wait = false)
|
167
|
+
if @monitor
|
168
|
+
@monitor.stop
|
169
|
+
@monitor = nil
|
170
|
+
setup
|
171
|
+
end
|
172
|
+
|
173
|
+
threads = []
|
130
174
|
|
131
175
|
@applications.each {|a|
|
132
|
-
|
133
|
-
|
134
|
-
else
|
135
|
-
a.stop
|
176
|
+
threads << Thread.new do
|
177
|
+
a.stop(no_wait)
|
136
178
|
end
|
137
179
|
}
|
180
|
+
|
181
|
+
threads.each {|t| t.join}
|
138
182
|
end
|
139
183
|
|
184
|
+
def reload_all
|
185
|
+
@applications.each {|a| a.reload}
|
186
|
+
end
|
187
|
+
|
140
188
|
def zap_all
|
141
189
|
@monitor.stop if @monitor
|
142
190
|
|
@@ -149,4 +197,4 @@ module Daemons
|
|
149
197
|
|
150
198
|
end
|
151
199
|
|
152
|
-
end
|
200
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'daemons/etc_extension'
|
2
|
+
|
3
|
+
class CurrentProcess
|
4
|
+
def self.change_privilege(user, group=user)
|
5
|
+
puts "Changing process privilege to #{user}:#{group}"
|
6
|
+
|
7
|
+
uid, gid = Process.euid, Process.egid
|
8
|
+
target_uid = Etc.getpwnam(user).uid
|
9
|
+
target_gid = Etc.getgrnam(group).gid
|
10
|
+
|
11
|
+
if uid != target_uid || gid != target_gid
|
12
|
+
Process.initgroups(user, target_gid)
|
13
|
+
Process::GID.change_privilege(target_gid)
|
14
|
+
Process::UID.change_privilege(target_uid)
|
15
|
+
end
|
16
|
+
rescue Errno::EPERM => e
|
17
|
+
raise "Couldn't change user and group to #{user}:#{group}: #{e}"
|
18
|
+
end
|
19
|
+
end
|
data/lib/daemons/cmdline.rb
CHANGED
@@ -10,10 +10,8 @@ module Daemons
|
|
10
10
|
@options = {}
|
11
11
|
|
12
12
|
@opts = OptionParser.new do |opts|
|
13
|
-
#opts.banner = "Usage: example.rb [options]"
|
14
13
|
opts.banner = ""
|
15
14
|
|
16
|
-
# Boolean switch.
|
17
15
|
# opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
|
18
16
|
# @options[:verbose] = v
|
19
17
|
# end
|
@@ -26,6 +24,10 @@ module Daemons
|
|
26
24
|
@options[:force] = t
|
27
25
|
end
|
28
26
|
|
27
|
+
opts.on("-n", "--no_wait", "Do not wait for processes to stop") do |t|
|
28
|
+
@options[:no_wait] = t
|
29
|
+
end
|
30
|
+
|
29
31
|
#opts.separator ""
|
30
32
|
#opts.separator "Specific options:"
|
31
33
|
|
@@ -33,8 +35,7 @@ module Daemons
|
|
33
35
|
opts.separator ""
|
34
36
|
opts.separator "Common options:"
|
35
37
|
|
36
|
-
# No argument, shows at tail. This will print an options summary
|
37
|
-
# Try it and see!
|
38
|
+
# No argument, shows at tail. This will print an options summary
|
38
39
|
opts.on_tail("-h", "--help", "Show this message") do
|
39
40
|
#puts opts
|
40
41
|
#@usage =
|
@@ -43,7 +44,7 @@ module Daemons
|
|
43
44
|
exit
|
44
45
|
end
|
45
46
|
|
46
|
-
#
|
47
|
+
# Switch to print the version.
|
47
48
|
opts.on_tail("--version", "Show version") do
|
48
49
|
puts "daemons version #{Daemons::VERSION}"
|
49
50
|
exit
|
@@ -56,6 +57,7 @@ module Daemons
|
|
56
57
|
@usage = <<END
|
57
58
|
-t, --ontop Stay on top (does not daemonize)
|
58
59
|
-f, --force Force operation
|
60
|
+
-n, --no_wait Do not wait for processes to stop
|
59
61
|
|
60
62
|
Common options:
|
61
63
|
-h, --help Show this message
|
@@ -92,8 +94,10 @@ END
|
|
92
94
|
puts " start start an instance of the application"
|
93
95
|
puts " stop stop all instances of the application"
|
94
96
|
puts " restart stop all instances and restart them afterwards"
|
97
|
+
puts " reload send a SIGHUP to all instances of the application"
|
95
98
|
puts " run start the application and stay on top"
|
96
99
|
puts " zap set the application to a stopped state"
|
100
|
+
puts " status show status (PID) of application instances"
|
97
101
|
puts
|
98
102
|
puts "* and where <options> may contain several of the following:"
|
99
103
|
|
@@ -114,4 +118,4 @@ END
|
|
114
118
|
|
115
119
|
end
|
116
120
|
|
117
|
-
end
|
121
|
+
end
|
data/lib/daemons/controller.rb
CHANGED
@@ -15,6 +15,7 @@ module Daemons
|
|
15
15
|
'restart',
|
16
16
|
'run',
|
17
17
|
'zap',
|
18
|
+
'reload',
|
18
19
|
'status'
|
19
20
|
]
|
20
21
|
|
@@ -71,16 +72,18 @@ module Daemons
|
|
71
72
|
@options[:ontop] ||= true
|
72
73
|
@group.new_application.start
|
73
74
|
when 'stop'
|
74
|
-
@group.stop_all
|
75
|
+
@group.stop_all(@options[:no_wait])
|
75
76
|
when 'restart'
|
76
77
|
unless @group.applications.empty?
|
77
78
|
@group.stop_all
|
78
|
-
sleep
|
79
|
+
sleep(1)
|
79
80
|
@group.start_all
|
80
81
|
else
|
81
82
|
puts "Warning: no instances running. Starting..."
|
82
83
|
@group.new_application.start
|
83
84
|
end
|
85
|
+
when 'reload'
|
86
|
+
@group.reload_all
|
84
87
|
when 'zap'
|
85
88
|
@group.zap_all
|
86
89
|
when 'status'
|
data/lib/daemons/daemonize.rb
CHANGED
@@ -1,97 +1,5 @@
|
|
1
|
-
#--
|
2
|
-
###############################################################################
|
3
|
-
# daemonize.rb is a slightly modified version of daemonize.rb was #
|
4
|
-
# from the Daemonize Library written by Travis Whitton #
|
5
|
-
# for details, read the notice below #
|
6
|
-
###############################################################################
|
7
|
-
#++
|
8
|
-
#
|
9
|
-
#
|
10
|
-
# =Daemonize Library
|
11
|
-
#
|
12
|
-
# February. 4, 2005 Travis Whitton <whitton@atlantic.net>
|
13
|
-
#
|
14
|
-
# Daemonize allows you to easily modify any existing Ruby program to run
|
15
|
-
# as a daemon. See README.rdoc for more details.
|
16
|
-
#
|
17
|
-
# == How to install
|
18
|
-
# 1. su to root
|
19
|
-
# 2. ruby install.rb
|
20
|
-
# build the docs if you want to
|
21
|
-
# 3. rdoc --main README.rdoc daemonize.rb README.rdoc
|
22
|
-
#
|
23
|
-
# == Copying
|
24
|
-
# The Daemonize extension module is copywrited free software by Travis Whitton
|
25
|
-
# <whitton@atlantic.net>. You can redistribute it under the terms specified in
|
26
|
-
# the COPYING file of the Ruby distribution.
|
27
|
-
#
|
28
|
-
# == WARRANTY
|
29
|
-
# THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
|
30
|
-
# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
31
|
-
# WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
32
|
-
# PURPOSE.
|
33
|
-
#
|
34
|
-
#
|
35
|
-
# ----
|
36
|
-
#
|
37
|
-
# == Purpose
|
38
|
-
#
|
39
|
-
# Daemonize is a module derived from Perl's Proc::Daemon module. This module
|
40
|
-
# allows you to easily modify any existing Ruby program to run as a daemon.
|
41
|
-
# A daemon is a process that runs in the background with no controlling terminal.
|
42
|
-
# Generally servers (like FTP and HTTP servers) run as daemon processes.
|
43
|
-
# Note, do not make the mistake that a daemon == server. Converting a program
|
44
|
-
# to a daemon by hand is a relatively simple process; however, this module will
|
45
|
-
# save you the effort of repeatedly looking up the procedure, and it will also
|
46
|
-
# insure that your programs are daemonized in the safest and most corrects
|
47
|
-
# fashion possible.
|
48
|
-
#
|
49
|
-
# == Procedure
|
50
|
-
#
|
51
|
-
# The Daemonize module does the following:
|
52
|
-
#
|
53
|
-
# Forks a child and exits the parent process.
|
54
|
-
#
|
55
|
-
# Becomes a session leader (which detaches the program from
|
56
|
-
# the controlling terminal).
|
57
|
-
#
|
58
|
-
# Forks another child process and exits first child. This prevents
|
59
|
-
# the potential of acquiring a controlling terminal.
|
60
|
-
#
|
61
|
-
# Changes the current working directory to "/".
|
62
|
-
#
|
63
|
-
# Clears the file creation mask.
|
64
|
-
#
|
65
|
-
# Closes file descriptors.
|
66
|
-
#
|
67
|
-
# == Example usage
|
68
|
-
#
|
69
|
-
# Using the Daemonize module is extremely simple:
|
70
|
-
#
|
71
|
-
# require 'daemonize'
|
72
|
-
#
|
73
|
-
# class TestDaemon
|
74
|
-
# include Daemonize
|
75
|
-
#
|
76
|
-
# def initialize
|
77
|
-
# daemonize()
|
78
|
-
# loop do
|
79
|
-
# # do some work here
|
80
|
-
# end
|
81
|
-
# end
|
82
|
-
# end
|
83
|
-
#
|
84
|
-
# == Credits
|
85
|
-
#
|
86
|
-
# Daemonize was written by Travis Whitton and is based on Perl's
|
87
|
-
# Proc::Daemonize, which was written by Earl Hood. The above documentation
|
88
|
-
# is also partially borrowed from the Proc::Daemonize POD documentation.
|
89
|
-
|
90
|
-
|
91
|
-
|
92
1
|
module Daemonize
|
93
|
-
|
94
|
-
|
2
|
+
|
95
3
|
# Try to fork if at all possible retrying every 5 sec if the
|
96
4
|
# maximum process limit for the system has been reached
|
97
5
|
def safefork
|
@@ -112,38 +20,37 @@ module Daemonize
|
|
112
20
|
module_function :safefork
|
113
21
|
|
114
22
|
|
115
|
-
|
116
|
-
|
23
|
+
# Simulate the daemonization process (:ontop mode)
|
24
|
+
# NOTE: STDOUT and STDERR will not be redirected to the logfile,
|
25
|
+
# because in :ontop mode, we normally want to see the output
|
26
|
+
def simulate(logfile_name = nil, app_name = nil)
|
27
|
+
$0 = app_name if app_name
|
117
28
|
|
118
|
-
|
119
|
-
|
29
|
+
# Release old working directory
|
30
|
+
Dir.chdir "/"
|
31
|
+
|
32
|
+
# Release old working directory
|
33
|
+
Dir.chdir "/"
|
120
34
|
|
121
|
-
|
122
|
-
ObjectSpace.each_object(IO) do |io|
|
123
|
-
unless [STDIN, STDOUT, STDERR].include?(io)
|
124
|
-
begin
|
125
|
-
unless io.closed?
|
126
|
-
io.close
|
127
|
-
end
|
128
|
-
rescue ::Exception
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
35
|
+
close_io()
|
132
36
|
|
133
|
-
# Free
|
134
|
-
|
135
|
-
# STDOUT/STDERR should go to a logfile
|
37
|
+
# Free STDIN and point it to somewhere sensible
|
38
|
+
begin; STDIN.reopen "/dev/null"; rescue ::Exception; end
|
136
39
|
|
137
|
-
|
40
|
+
# Split rand streams between spawning and daemonized process
|
41
|
+
srand
|
138
42
|
end
|
139
43
|
module_function :simulate
|
140
44
|
|
141
45
|
|
46
|
+
# Call a given block as a daemon
|
142
47
|
def call_as_daemon(block, logfile_name = nil, app_name = nil)
|
48
|
+
# we use a pipe to return the PID of the daemon
|
143
49
|
rd, wr = IO.pipe
|
144
50
|
|
145
51
|
if tmppid = safefork
|
146
|
-
# parent
|
52
|
+
# in the parent
|
53
|
+
|
147
54
|
wr.close
|
148
55
|
pid = rd.read.to_i
|
149
56
|
rd.close
|
@@ -152,7 +59,7 @@ module Daemonize
|
|
152
59
|
|
153
60
|
return pid
|
154
61
|
else
|
155
|
-
# child
|
62
|
+
# in the child
|
156
63
|
|
157
64
|
rd.close
|
158
65
|
|
@@ -162,33 +69,24 @@ module Daemonize
|
|
162
69
|
end
|
163
70
|
|
164
71
|
# Prevent the possibility of acquiring a controlling terminal
|
165
|
-
|
166
|
-
|
167
|
-
exit if pid = safefork
|
168
|
-
#end
|
72
|
+
trap 'SIGHUP', 'IGNORE'
|
73
|
+
exit if pid = safefork
|
169
74
|
|
170
75
|
wr.write Process.pid
|
171
76
|
wr.close
|
172
77
|
|
173
78
|
$0 = app_name if app_name
|
174
79
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
# Make sure all file descriptors are closed
|
179
|
-
ObjectSpace.each_object(IO) do |io|
|
180
|
-
unless [STDIN, STDOUT, STDERR].include?(io)
|
181
|
-
begin
|
182
|
-
unless io.closed?
|
183
|
-
io.close
|
184
|
-
end
|
185
|
-
rescue ::Exception
|
186
|
-
end
|
187
|
-
end
|
188
|
-
end
|
80
|
+
# Release old working directory
|
81
|
+
Dir.chdir "/"
|
189
82
|
|
83
|
+
close_io()
|
84
|
+
|
190
85
|
redirect_io(logfile_name)
|
191
86
|
|
87
|
+
# Split rand streams between spawning and daemonized process
|
88
|
+
srand
|
89
|
+
|
192
90
|
block.call
|
193
91
|
|
194
92
|
exit
|
@@ -197,10 +95,10 @@ module Daemonize
|
|
197
95
|
module_function :call_as_daemon
|
198
96
|
|
199
97
|
|
200
|
-
#
|
98
|
+
# Transform the current process into a daemon
|
201
99
|
def daemonize(logfile_name = nil, app_name = nil)
|
202
|
-
|
203
|
-
safefork and exit
|
100
|
+
# Fork and exit from the parent
|
101
|
+
safefork and exit
|
204
102
|
|
205
103
|
# Detach from the controlling terminal
|
206
104
|
unless sess_id = Process.setsid
|
@@ -208,17 +106,29 @@ module Daemonize
|
|
208
106
|
end
|
209
107
|
|
210
108
|
# Prevent the possibility of acquiring a controlling terminal
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
#end
|
215
|
-
|
109
|
+
trap 'SIGHUP', 'IGNORE'
|
110
|
+
exit if pid = safefork
|
111
|
+
|
216
112
|
$0 = app_name if app_name
|
217
113
|
|
218
|
-
|
219
|
-
|
114
|
+
# Release old working directory
|
115
|
+
Dir.chdir "/"
|
116
|
+
|
117
|
+
close_io()
|
220
118
|
|
221
|
-
|
119
|
+
redirect_io(logfile_name)
|
120
|
+
|
121
|
+
# Split rand streams between spawning and daemonized process
|
122
|
+
srand
|
123
|
+
|
124
|
+
return sess_id
|
125
|
+
end
|
126
|
+
module_function :daemonize
|
127
|
+
|
128
|
+
|
129
|
+
def close_io()
|
130
|
+
# Make sure all input/output streams are closed
|
131
|
+
# Part I: close all IO objects (except for STDIN/STDOUT/STDERR)
|
222
132
|
ObjectSpace.each_object(IO) do |io|
|
223
133
|
unless [STDIN, STDOUT, STDERR].include?(io)
|
224
134
|
begin
|
@@ -229,24 +139,27 @@ module Daemonize
|
|
229
139
|
end
|
230
140
|
end
|
231
141
|
end
|
232
|
-
|
233
|
-
redirect_io(logfile_name)
|
234
142
|
|
235
|
-
#
|
236
|
-
|
143
|
+
# Make sure all input/output streams are closed
|
144
|
+
# Part II: close all file decriptors (except for STDIN/STDOUT/STDERR)
|
145
|
+
ios = Array.new(8192) {|i| IO.for_fd(i) rescue nil}.compact
|
146
|
+
ios.each do |io|
|
147
|
+
next if io.fileno < 3
|
148
|
+
io.close
|
149
|
+
end
|
237
150
|
end
|
238
|
-
module_function :
|
151
|
+
module_function :close_io
|
239
152
|
|
240
153
|
|
241
|
-
# Free file descriptors and
|
154
|
+
# Free STDIN/STDOUT/STDERR file descriptors and
|
242
155
|
# point them somewhere sensible
|
243
|
-
# STDOUT/STDERR should go to a logfile
|
244
156
|
def redirect_io(logfile_name)
|
245
157
|
begin; STDIN.reopen "/dev/null"; rescue ::Exception; end
|
246
158
|
|
247
159
|
if logfile_name
|
248
160
|
begin
|
249
161
|
STDOUT.reopen logfile_name, "a"
|
162
|
+
File.chmod(0644, logfile_name)
|
250
163
|
STDOUT.sync = true
|
251
164
|
rescue ::Exception
|
252
165
|
begin; STDOUT.reopen "/dev/null"; rescue ::Exception; end
|
@@ -260,4 +173,5 @@ module Daemonize
|
|
260
173
|
end
|
261
174
|
module_function :redirect_io
|
262
175
|
|
176
|
+
|
263
177
|
end
|