fire_and_forget 0.3.2 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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.