fire_and_forget 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,7 +1,5 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- gem "daemons", "~>1.1.0"
4
-
5
3
  group :development do
6
4
  gem "shoulda", ">= 0"
7
5
  gem 'jnunemaker-matchy', '~>0.4'
data/Gemfile.lock CHANGED
@@ -1,7 +1,6 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- daemons (1.1.0)
5
4
  git (1.2.5)
6
5
  jeweler (1.5.1)
7
6
  bundler (~> 1.0.0)
@@ -17,7 +16,6 @@ PLATFORMS
17
16
 
18
17
  DEPENDENCIES
19
18
  bundler (~> 1.0.0)
20
- daemons (~> 1.1.0)
21
19
  jeweler (~> 1.5.1)
22
20
  jnunemaker-matchy (~> 0.4)
23
21
  rr (~> 1.0.2)
data/bin/fire_forget CHANGED
@@ -6,10 +6,6 @@ Dir.chdir(File.join(File.dirname(__FILE__), '..'))
6
6
  faf_lib_path = File.expand_path(File.dirname(__FILE__) + "/../lib")
7
7
  $:.unshift(faf_lib_path) unless $:.include?(faf_lib_path)
8
8
 
9
- # include dependencies without using rubygems (to save memory)
10
- $:.unshift('vendor/daemons-1.1.0/lib')
11
-
12
- require 'vendor/daemons-1.1.0/lib/daemons'
13
9
 
14
10
  require 'ostruct'
15
11
  require 'optparse'
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{fire_and_forget}
8
- s.version = "0.3.2"
8
+ s.version = "0.3.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Garry Hill"]
12
- s.date = %q{2011-01-21}
12
+ s.date = %q{2011-01-28}
13
13
  s.default_executable = %q{fire_forget}
14
14
  s.email = %q{garry@magnetised.info}
15
15
  s.executables = ["fire_forget"]
@@ -45,26 +45,7 @@ Gem::Specification.new do |s|
45
45
  "lib/fire_and_forget/utilities.rb",
46
46
  "lib/fire_and_forget/version.rb",
47
47
  "test/helper.rb",
48
- "test/test_fire_and_forget.rb",
49
- "vendor/daemons-1.1.0/LICENSE",
50
- "vendor/daemons-1.1.0/README",
51
- "vendor/daemons-1.1.0/Rakefile",
52
- "vendor/daemons-1.1.0/Releases",
53
- "vendor/daemons-1.1.0/TODO",
54
- "vendor/daemons-1.1.0/lib/daemons.rb",
55
- "vendor/daemons-1.1.0/lib/daemons/application.rb",
56
- "vendor/daemons-1.1.0/lib/daemons/application_group.rb",
57
- "vendor/daemons-1.1.0/lib/daemons/change_privilege.rb",
58
- "vendor/daemons-1.1.0/lib/daemons/cmdline.rb",
59
- "vendor/daemons-1.1.0/lib/daemons/controller.rb",
60
- "vendor/daemons-1.1.0/lib/daemons/daemonize.rb",
61
- "vendor/daemons-1.1.0/lib/daemons/etc_extension.rb",
62
- "vendor/daemons-1.1.0/lib/daemons/exceptions.rb",
63
- "vendor/daemons-1.1.0/lib/daemons/monitor.rb",
64
- "vendor/daemons-1.1.0/lib/daemons/pid.rb",
65
- "vendor/daemons-1.1.0/lib/daemons/pidfile.rb",
66
- "vendor/daemons-1.1.0/lib/daemons/pidmem.rb",
67
- "vendor/daemons-1.1.0/setup.rb"
48
+ "test/test_fire_and_forget.rb"
68
49
  ]
69
50
  s.homepage = %q{http://github.com/magnetised/fire_and_forget}
70
51
  s.licenses = ["MIT"]
@@ -81,14 +62,12 @@ Gem::Specification.new do |s|
81
62
  s.specification_version = 3
82
63
 
83
64
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
84
- s.add_runtime_dependency(%q<daemons>, ["~> 1.1.0"])
85
65
  s.add_development_dependency(%q<shoulda>, [">= 0"])
86
66
  s.add_development_dependency(%q<jnunemaker-matchy>, ["~> 0.4"])
87
67
  s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
88
68
  s.add_development_dependency(%q<jeweler>, ["~> 1.5.1"])
89
69
  s.add_development_dependency(%q<rr>, ["~> 1.0.2"])
90
70
  else
91
- s.add_dependency(%q<daemons>, ["~> 1.1.0"])
92
71
  s.add_dependency(%q<shoulda>, [">= 0"])
93
72
  s.add_dependency(%q<jnunemaker-matchy>, ["~> 0.4"])
94
73
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
@@ -96,7 +75,6 @@ Gem::Specification.new do |s|
96
75
  s.add_dependency(%q<rr>, ["~> 1.0.2"])
97
76
  end
98
77
  else
99
- s.add_dependency(%q<daemons>, ["~> 1.1.0"])
100
78
  s.add_dependency(%q<shoulda>, [">= 0"])
101
79
  s.add_dependency(%q<jnunemaker-matchy>, ["~> 0.4"])
102
80
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
@@ -44,7 +44,7 @@ module FireAndForget
44
44
  end
45
45
 
46
46
  def debug()
47
- "#{self.class.name.split("::").last} #{@task_name}\n"
47
+ "#{self.class.name.split("::").last} :#{@task_name}\n"
48
48
  end
49
49
  end
50
50
 
@@ -1,5 +1,4 @@
1
1
 
2
- require 'daemons' unless defined?(Daemons)
3
2
 
4
3
  module FireAndForget
5
4
  module Command
@@ -54,11 +53,12 @@ module FireAndForget
54
53
  pid = fork do
55
54
  # set up the environment so that the task can access the F&F server
56
55
  env.each { | k, v | ENV[k] = v }
57
- Daemons.daemonize(:backtrace => true)
56
+ # TODO: figure out how to pass a logfile path to this
57
+ daemonize
58
58
  Process.setpriority(Process::PRIO_PROCESS, 0, niceness) if niceness > 0
59
59
  # change to the UID of the originating thread if necessary
60
60
  Process::UID.change_privilege(task_uid) unless Process.euid == task_uid
61
- File.umask(022)
61
+ File.umask(0022)
62
62
  exec(cmd)
63
63
  end
64
64
  Process.detach(pid) if pid
@@ -71,6 +71,80 @@ module FireAndForget
71
71
  def debug
72
72
  "Fire :#{@task.name}: #{cmd}\n"
73
73
  end
74
+
75
+ private
76
+
77
+ # The following adapted from Daemons.daemonize
78
+ def daemonize(logfile_name = nil, app_name = nil)
79
+ srand # Split rand streams between spawning and daemonized process
80
+ safefork and exit # Fork and exit from the parent
81
+
82
+ # Detach from the controlling terminal
83
+ unless sess_id = Process.setsid
84
+ raise RuntimeException.new('cannot detach from controlling terminal')
85
+ end
86
+
87
+ # Prevent the possibility of acquiring a controlling terminal
88
+ trap 'SIGHUP', 'IGNORE'
89
+ exit if pid = safefork
90
+
91
+ $0 = app_name if app_name
92
+
93
+ Dir.chdir "/" # Release old working directory
94
+ File.umask 0000 # Ensure sensible umask
95
+
96
+ # Make sure all file descriptors are closed
97
+ ObjectSpace.each_object(IO) do |io|
98
+ unless [STDIN, STDOUT, STDERR].include?(io)
99
+ begin
100
+ unless io.closed?
101
+ io.close
102
+ end
103
+ rescue ::Exception
104
+ end
105
+ end
106
+ end
107
+
108
+ redirect_io(logfile_name)
109
+
110
+ return sess_id
111
+ end
112
+
113
+ def redirect_io(logfile_name)
114
+ begin; STDIN.reopen "/dev/null"; rescue ::Exception; end
115
+
116
+ if logfile_name
117
+ begin
118
+ STDOUT.reopen logfile_name, "a"
119
+ File.chmod(0644, logfile_name)
120
+ STDOUT.sync = true
121
+ rescue ::Exception
122
+ begin; STDOUT.reopen "/dev/null"; rescue ::Exception; end
123
+ end
124
+ else
125
+ begin; STDOUT.reopen "/dev/null"; rescue ::Exception; end
126
+ end
127
+
128
+ begin; STDERR.reopen STDOUT; rescue ::Exception; end
129
+ STDERR.sync = true
130
+ end
131
+
132
+ def safefork
133
+ tryagain = true
134
+
135
+ while tryagain
136
+ tryagain = false
137
+ begin
138
+ if pid = fork
139
+ return pid
140
+ end
141
+ rescue Errno::EWOULDBLOCK
142
+ sleep 5
143
+ tryagain = true
144
+ end
145
+ end
146
+ end
147
+
74
148
  end
75
149
  end
76
150
  end
@@ -11,6 +11,10 @@ module FireAndForget
11
11
  def run
12
12
  FireAndForget::Server.pids[@task_name] = @pid
13
13
  end
14
+
15
+ def debug
16
+ "SetPid :#{@task_name}: #{@pid}\n"
17
+ end
14
18
  end
15
19
  end
16
20
  end
@@ -11,6 +11,10 @@ module FireAndForget
11
11
  FireAndForget::Server.set_pid(@task_name, @pid)
12
12
  FireAndForget::Server.status[@task_name] = @status_value.to_s
13
13
  end
14
+
15
+ def debug
16
+ "SetStatus :#{@task_name}: #{@status_value}\n"
17
+ end
14
18
  end
15
19
  end
16
20
  end
@@ -3,12 +3,12 @@ module FireAndForget
3
3
  class Server
4
4
  def self.parse(command_string)
5
5
  command = Command.load(command_string)
6
- run(command)
6
+ [command, run(command)]
7
7
  end
8
8
 
9
9
  def self.run(cmd)
10
10
  if Command.allowed?(cmd)
11
- [cmd, cmd.run]
11
+ cmd.run
12
12
  else
13
13
  raise PermissionsError, "'#{cmd.class}' is not an approved command"
14
14
  end
@@ -1,4 +1,4 @@
1
1
 
2
2
  module FireAndForget
3
- VERSION = "0.3.2"
3
+ VERSION = "0.3.3"
4
4
  end
@@ -154,7 +154,7 @@ class TestFireAndForget < Test::Unit::TestCase
154
154
  mock(FAF::Command).load(is_a(String)) { command }
155
155
  mock(command).run { "666" }
156
156
  result = FAF::Server.parse("object")
157
- result.should == "666"
157
+ result.should == [command, "666"]
158
158
  end
159
159
  end
160
160
  context "daemon methods" do
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 3
8
- - 2
9
- version: 0.3.2
8
+ - 3
9
+ version: 0.3.3
10
10
  platform: ruby
11
11
  authors:
12
12
  - Garry Hill
@@ -14,25 +14,11 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-01-21 00:00:00 +00:00
17
+ date: 2011-01-28 00:00:00 +00:00
18
18
  default_executable: fire_forget
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  version_requirements: &id001 !ruby/object:Gem::Requirement
22
- requirements:
23
- - - ~>
24
- - !ruby/object:Gem::Version
25
- segments:
26
- - 1
27
- - 1
28
- - 0
29
- version: 1.1.0
30
- name: daemons
31
- requirement: *id001
32
- prerelease: false
33
- type: :runtime
34
- - !ruby/object:Gem::Dependency
35
- version_requirements: &id002 !ruby/object:Gem::Requirement
36
22
  requirements:
37
23
  - - ">="
38
24
  - !ruby/object:Gem::Version
@@ -40,11 +26,11 @@ dependencies:
40
26
  - 0
41
27
  version: "0"
42
28
  name: shoulda
43
- requirement: *id002
29
+ requirement: *id001
44
30
  prerelease: false
45
31
  type: :development
46
32
  - !ruby/object:Gem::Dependency
47
- version_requirements: &id003 !ruby/object:Gem::Requirement
33
+ version_requirements: &id002 !ruby/object:Gem::Requirement
48
34
  requirements:
49
35
  - - ~>
50
36
  - !ruby/object:Gem::Version
@@ -53,11 +39,11 @@ dependencies:
53
39
  - 4
54
40
  version: "0.4"
55
41
  name: jnunemaker-matchy
56
- requirement: *id003
42
+ requirement: *id002
57
43
  prerelease: false
58
44
  type: :development
59
45
  - !ruby/object:Gem::Dependency
60
- version_requirements: &id004 !ruby/object:Gem::Requirement
46
+ version_requirements: &id003 !ruby/object:Gem::Requirement
61
47
  requirements:
62
48
  - - ~>
63
49
  - !ruby/object:Gem::Version
@@ -67,11 +53,11 @@ dependencies:
67
53
  - 0
68
54
  version: 1.0.0
69
55
  name: bundler
70
- requirement: *id004
56
+ requirement: *id003
71
57
  prerelease: false
72
58
  type: :development
73
59
  - !ruby/object:Gem::Dependency
74
- version_requirements: &id005 !ruby/object:Gem::Requirement
60
+ version_requirements: &id004 !ruby/object:Gem::Requirement
75
61
  requirements:
76
62
  - - ~>
77
63
  - !ruby/object:Gem::Version
@@ -81,11 +67,11 @@ dependencies:
81
67
  - 1
82
68
  version: 1.5.1
83
69
  name: jeweler
84
- requirement: *id005
70
+ requirement: *id004
85
71
  prerelease: false
86
72
  type: :development
87
73
  - !ruby/object:Gem::Dependency
88
- version_requirements: &id006 !ruby/object:Gem::Requirement
74
+ version_requirements: &id005 !ruby/object:Gem::Requirement
89
75
  requirements:
90
76
  - - ~>
91
77
  - !ruby/object:Gem::Version
@@ -95,7 +81,7 @@ dependencies:
95
81
  - 2
96
82
  version: 1.0.2
97
83
  name: rr
98
- requirement: *id006
84
+ requirement: *id005
99
85
  prerelease: false
100
86
  type: :development
101
87
  description:
@@ -136,25 +122,6 @@ files:
136
122
  - lib/fire_and_forget/version.rb
137
123
  - test/helper.rb
138
124
  - test/test_fire_and_forget.rb
139
- - vendor/daemons-1.1.0/LICENSE
140
- - vendor/daemons-1.1.0/README
141
- - vendor/daemons-1.1.0/Rakefile
142
- - vendor/daemons-1.1.0/Releases
143
- - vendor/daemons-1.1.0/TODO
144
- - vendor/daemons-1.1.0/lib/daemons.rb
145
- - vendor/daemons-1.1.0/lib/daemons/application.rb
146
- - vendor/daemons-1.1.0/lib/daemons/application_group.rb
147
- - vendor/daemons-1.1.0/lib/daemons/change_privilege.rb
148
- - vendor/daemons-1.1.0/lib/daemons/cmdline.rb
149
- - vendor/daemons-1.1.0/lib/daemons/controller.rb
150
- - vendor/daemons-1.1.0/lib/daemons/daemonize.rb
151
- - vendor/daemons-1.1.0/lib/daemons/etc_extension.rb
152
- - vendor/daemons-1.1.0/lib/daemons/exceptions.rb
153
- - vendor/daemons-1.1.0/lib/daemons/monitor.rb
154
- - vendor/daemons-1.1.0/lib/daemons/pid.rb
155
- - vendor/daemons-1.1.0/lib/daemons/pidfile.rb
156
- - vendor/daemons-1.1.0/lib/daemons/pidmem.rb
157
- - vendor/daemons-1.1.0/setup.rb
158
125
  has_rdoc: true
159
126
  homepage: http://github.com/magnetised/fire_and_forget
160
127
  licenses:
@@ -1,29 +0,0 @@
1
- Copyright (c) 2005-2007 Thomas Uehlinger
2
-
3
- Permission is hereby granted, free of charge, to any person
4
- obtaining a copy of this software and associated documentation
5
- files (the "Software"), to deal in the Software without
6
- restriction, including without limitation the rights to use,
7
- copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- copies of the Software, and to permit persons to whom the
9
- Software is furnished to do so, subject to the following
10
- conditions:
11
-
12
- The above copyright notice and this permission notice shall be
13
- included in all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
- OTHER DEALINGS IN THE SOFTWARE.
23
-
24
- This license does not apply to daemonize.rb, which is was written by
25
- Travis Whitton und published under the following license:
26
-
27
- The Daemonize extension module is copywrited free software by Travis Whitton
28
- <whitton@atlantic.net>. You can redistribute it under the terms specified in
29
- the COPYING file of the Ruby distribution.
@@ -1,224 +0,0 @@
1
- = Daemons Version 1.1.0
2
-
3
- (See Releases for release-specific information)
4
-
5
- == What is Daemons?
6
-
7
- Daemons provides an easy way to wrap existing ruby scripts (for example a self-written server)
8
- to be <i>run as a daemon</i> and to be <i>controlled by simple start/stop/restart commands</i>.
9
-
10
- If you want, you can also use daemons to <i>run blocks of ruby code in a daemon process</i> and to control
11
- these processes from the main application.
12
-
13
- Besides this basic functionality, daemons offers many advanced features like <i>exception backtracing</i>
14
- and logging (in case your ruby script crashes) and <i>monitoring</i> and automatic restarting of your processes
15
- if they crash.
16
-
17
- Daemons includes the <tt>daemonize.rb</tt> script written by <i>Travis Whitton</i> to do the daemonization
18
- process.
19
-
20
- == Basic Usage
21
-
22
- You can use Daemons in four different ways:
23
-
24
- === 1. Create wrapper scripts for your server scripts or applications
25
-
26
- Layout: suppose you have your self-written server <tt>myserver.rb</tt>:
27
-
28
- # this is myserver.rb
29
- # it does nothing really useful at the moment
30
-
31
- loop do
32
- sleep(5)
33
- end
34
-
35
- To use <tt>myserver.rb</tt> in a production environment, you need to be able to
36
- run <tt>myserver.rb</tt> in the _background_ (this means detach it from the console, fork it
37
- in the background, release all directories and file descriptors).
38
-
39
- Just create <tt>myserver_control.rb</tt> like this:
40
-
41
- # this is myserver_control.rb
42
-
43
- require 'rubygems' # if you use RubyGems
44
- require 'daemons'
45
-
46
- Daemons.run('myserver.rb')
47
-
48
- And use it like this from the console:
49
-
50
- $ ruby myserver_control.rb start
51
- (myserver.rb is now running in the background)
52
- $ ruby myserver_control.rb restart
53
- (...)
54
- $ ruby myserver_control.rb stop
55
-
56
- For testing purposes you can even run <tt>myserver.rb</tt> <i>without forking</i> in the background:
57
-
58
- $ ruby myserver_control.rb run
59
-
60
- An additional nice feature of Daemons is that you can pass <i>additional arguments</i> to the script that
61
- should be daemonized by seperating them by two _hyphens_:
62
-
63
- $ ruby myserver_control.rb start -- --file=anyfile --a_switch another_argument
64
-
65
-
66
- === 2. Create wrapper scripts that include your server procs
67
-
68
- Layout: suppose you have some code you want to run in the background and control that background process
69
- from a script:
70
-
71
- # this is your code
72
- # it does nothing really useful at the moment
73
-
74
- loop do
75
- sleep(5)
76
- end
77
-
78
- To run this code as a daemon create <tt>myproc_control.rb</tt> like this and include your code:
79
-
80
- # this is myproc_control.rb
81
-
82
- require 'rubygems' # if you use RubyGems
83
- require 'daemons'
84
-
85
- Daemons.run_proc('myproc.rb') do
86
- loop do
87
- sleep(5)
88
- end
89
- end
90
-
91
- And use it like this from the console:
92
-
93
- $ ruby myproc_control.rb start
94
- (myproc.rb is now running in the background)
95
- $ ruby myproc_control.rb restart
96
- (...)
97
- $ ruby myproc_control.rb stop
98
-
99
- For testing purposes you can even run <tt>myproc.rb</tt> <i>without forking</i> in the background:
100
-
101
- $ ruby myproc_control.rb run
102
-
103
- === 3. Control a bunch of daemons from another application
104
-
105
- Layout: you have an application <tt>my_app.rb</tt> that wants to run a bunch of
106
- server tasks as daemon processes.
107
-
108
- # this is my_app.rb
109
-
110
- require 'rubygems' # if you use RubyGems
111
- require 'daemons'
112
-
113
- task1 = Daemons.call(:multiple => true) do
114
- # first server task
115
-
116
- loop {
117
- conn = accept_conn()
118
- serve(conn)
119
- }
120
- end
121
-
122
- task2 = Daemons.call do
123
- # second server task
124
-
125
- loop {
126
- something_different()
127
- }
128
- end
129
-
130
- # the parent process continues to run
131
-
132
- # we can even control our tasks, for example stop them
133
- task1.stop
134
- task2.stop
135
-
136
- exit
137
-
138
- === 4. Daemonize the currently running process
139
-
140
- Layout: you have an application <tt>my_daemon.rb</tt> that wants to run as a daemon
141
- (but without the ability to be controlled by daemons via start/stop commands)
142
-
143
- # this is my_daemons.rb
144
-
145
- require 'rubygems' # if you use RubyGems
146
- require 'daemons'
147
-
148
- # Initialize the app while we're not a daemon
149
- init()
150
-
151
- # Become a daemon
152
- Daemons.daemonize
153
-
154
- # The server loop
155
- loop {
156
- conn = accept_conn()
157
- serve(conn)
158
- }
159
-
160
-
161
- <b>For further documentation, refer to the module documentation of Daemons.</b>
162
-
163
-
164
- == Download and Installation
165
-
166
- *Download*: just go to http://rubyforge.org/projects/daemons/
167
-
168
- Installation *with* RubyGems:
169
- $ su
170
- # gem install daemons
171
-
172
- Installation *without* RubyGems:
173
- $ tar xfz daemons-x.x.x.tar.gz
174
- $ cd daemons-x.x.x
175
- $ su
176
- # ruby setup.rb
177
-
178
- == Documentation
179
-
180
- For further documentation, refer to the module documentation of Daemons (click on Daemons).
181
-
182
- The RDoc documentation is also online at http://daemons.rubyforge.org
183
-
184
-
185
- == Author
186
-
187
- Written 2005-2010 by Thomas Uehlinger <mailto:th.uehlinger@gmx.ch>.
188
- Anonymous SVN checkout is available with "svn checkout http://daemons.rubyforge.org/svn/".
189
-
190
- == License
191
-
192
- Copyright (c) 2005-2010 Thomas Uehlinger
193
-
194
- Permission is hereby granted, free of charge, to any person
195
- obtaining a copy of this software and associated documentation
196
- files (the "Software"), to deal in the Software without
197
- restriction, including without limitation the rights to use,
198
- copy, modify, merge, publish, distribute, sublicense, and/or sell
199
- copies of the Software, and to permit persons to whom the
200
- Software is furnished to do so, subject to the following
201
- conditions:
202
-
203
- The above copyright notice and this permission notice shall be
204
- included in all copies or substantial portions of the Software.
205
-
206
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
207
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
208
- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
209
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
210
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
211
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
212
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
213
- OTHER DEALINGS IN THE SOFTWARE.
214
-
215
- This license does not apply to daemonize.rb, which is was written by
216
- Travis Whitton und published under the following license:
217
-
218
- The Daemonize extension module is copywrited free software by Travis Whitton
219
- <whitton@atlantic.net>. You can redistribute it under the terms specified in
220
- the COPYING file of the Ruby distribution.
221
-
222
- == Feedback and other resources
223
-
224
- At http://rubyforge.org/projects/daemons.