passenger 5.0.28 → 5.0.29
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of passenger might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.editorconfig +5 -0
- data/CHANGELOG +13 -0
- data/build/apache2.rb +3 -3
- data/build/common_library.rb +3 -3
- data/build/nginx.rb +4 -4
- data/build/packaging.rb +9 -8
- data/build/support/cxx_dependency_map.rb +9 -7
- data/build/support/general.rb +39 -0
- data/build/support/vendor/cxxcodebuilder/CxxCodeBuilder.sublime-project +8 -0
- data/build/support/vendor/cxxcodebuilder/Gemfile +4 -0
- data/build/support/vendor/cxxcodebuilder/Gemfile.lock +28 -0
- data/build/support/vendor/cxxcodebuilder/LICENSE.md +19 -0
- data/build/support/vendor/cxxcodebuilder/README.md +98 -0
- data/build/support/vendor/cxxcodebuilder/Rakefile +4 -0
- data/build/support/vendor/cxxcodebuilder/lib/cxxcodebuilder.rb +23 -0
- data/build/support/vendor/cxxcodebuilder/lib/cxxcodebuilder/builder.rb +574 -0
- data/build/support/vendor/cxxcodebuilder/lib/cxxcodebuilder/initializer_builder.rb +166 -0
- data/build/test_basics.rb +2 -1
- data/resources/templates/standalone/server.erb +6 -4
- data/src/agent/Core/Controller/ForwardResponse.cpp +5 -5
- data/src/agent/Watchdog/WatchdogMain.cpp +0 -10
- data/src/apache2_module/ConfigurationCommands.cpp +181 -248
- data/src/apache2_module/ConfigurationCommands.cpp.cxxcodebuilder +127 -0
- data/src/apache2_module/ConfigurationFields.hpp +135 -51
- data/src/apache2_module/ConfigurationFields.hpp.cxxcodebuilder +113 -0
- data/src/apache2_module/ConfigurationSetters.cpp +414 -459
- data/src/apache2_module/ConfigurationSetters.cpp.cxxcodebuilder +144 -0
- data/src/apache2_module/CreateDirConfig.cpp +49 -52
- data/src/apache2_module/CreateDirConfig.cpp.cxxcodebuilder +81 -0
- data/src/apache2_module/Hooks.cpp +0 -14
- data/src/apache2_module/MergeDirConfig.cpp +136 -226
- data/src/apache2_module/MergeDirConfig.cpp.cxxcodebuilder +97 -0
- data/src/apache2_module/SetHeaders.cpp +92 -143
- data/src/apache2_module/SetHeaders.cpp.cxxcodebuilder +106 -0
- data/src/cxx_supportlib/Constants.h +86 -146
- data/src/cxx_supportlib/Constants.h.cxxcodebuilder +43 -0
- data/src/cxx_supportlib/DataStructures/LString.h +40 -23
- data/src/cxx_supportlib/MemoryKit/mbuf.cpp +60 -25
- data/src/cxx_supportlib/MemoryKit/mbuf.h +50 -25
- data/src/cxx_supportlib/ServerKit/CookieUtils.h +36 -3
- data/src/cxx_supportlib/ServerKit/HeaderTable.h +2 -8
- data/src/cxx_supportlib/ServerKit/HttpServer.h +6 -15
- data/src/cxx_supportlib/WatchdogLauncher.cpp +4 -4
- data/src/cxx_supportlib/WatchdogLauncher.h +2 -3
- data/src/nginx_module/CacheLocationConfig.c +623 -780
- data/src/nginx_module/CacheLocationConfig.c.cxxcodebuilder +214 -0
- data/src/nginx_module/Configuration.h +1 -1
- data/src/nginx_module/ConfigurationCommands.c +404 -535
- data/src/nginx_module/ConfigurationCommands.c.cxxcodebuilder +157 -0
- data/src/nginx_module/CreateLocationConfig.c +82 -206
- data/src/nginx_module/CreateLocationConfig.c.cxxcodebuilder +98 -0
- data/src/nginx_module/LocationConfig.h +97 -0
- data/src/nginx_module/LocationConfig.h.cxxcodebuilder +131 -0
- data/src/nginx_module/MergeLocationConfig.c +157 -278
- data/src/nginx_module/MergeLocationConfig.c.cxxcodebuilder +144 -0
- data/src/nginx_module/ngx_http_passenger_module.c +4 -10
- data/src/ruby_supportlib/phusion_passenger.rb +4 -4
- data/src/ruby_supportlib/phusion_passenger/config/validate_install_command.rb +2 -2
- data/src/ruby_supportlib/phusion_passenger/packaging.rb +2 -0
- data/src/ruby_supportlib/phusion_passenger/platform_info/compiler.rb +6 -0
- data/src/ruby_supportlib/phusion_passenger/platform_info/cxx_portability.rb +1 -1
- data/src/ruby_supportlib/phusion_passenger/standalone/start_command.rb +27 -8
- data/src/ruby_supportlib/phusion_passenger/vendor/daemon_controller.rb +120 -2
- data/src/ruby_supportlib/phusion_passenger/vendor/daemon_controller/lock_file.rb +1 -1
- data/src/ruby_supportlib/phusion_passenger/vendor/daemon_controller/spawn.rb +4 -4
- data/src/ruby_supportlib/phusion_passenger/vendor/daemon_controller/version.rb +1 -1
- data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/api.rb +5 -5
- metadata +24 -15
- data/src/apache2_module/ConfigurationCommands.cpp.erb +0 -109
- data/src/apache2_module/ConfigurationFields.hpp.erb +0 -98
- data/src/apache2_module/ConfigurationSetters.cpp.erb +0 -128
- data/src/apache2_module/CreateDirConfig.cpp.erb +0 -72
- data/src/apache2_module/MergeDirConfig.cpp.erb +0 -82
- data/src/apache2_module/SetHeaders.cpp.erb +0 -91
- data/src/cxx_supportlib/Constants.h.erb +0 -41
- data/src/nginx_module/CacheLocationConfig.c.erb +0 -171
- data/src/nginx_module/ConfigurationCommands.c.erb +0 -144
- data/src/nginx_module/ConfigurationFields.h +0 -145
- data/src/nginx_module/ConfigurationFields.h.erb +0 -112
- data/src/nginx_module/CreateLocationConfig.c.erb +0 -78
- data/src/nginx_module/MergeLocationConfig.c.erb +0 -118
@@ -0,0 +1,144 @@
|
|
1
|
+
# Phusion Passenger - https://www.phusionpassenger.com/
|
2
|
+
# Copyright (c) 2010-2016 Phusion Holding B.V.
|
3
|
+
#
|
4
|
+
# "Passenger", "Phusion Passenger" and "Union Station" are registered
|
5
|
+
# trademarks of Phusion Holding B.V.
|
6
|
+
#
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
12
|
+
# furnished to do so, subject to the following conditions:
|
13
|
+
#
|
14
|
+
# The above copyright notice and this permission notice shall be included in
|
15
|
+
# all copies or substantial portions of the Software.
|
16
|
+
#
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23
|
+
# THE SOFTWARE.
|
24
|
+
|
25
|
+
# This file uses the cxxcodebuilder API. Learn more at:
|
26
|
+
# https://github.com/phusion/passenger/cxxcodebuilder
|
27
|
+
|
28
|
+
require 'phusion_passenger/nginx/config_options'
|
29
|
+
|
30
|
+
def main
|
31
|
+
set_indent_string ' '
|
32
|
+
comment copyright_header_for(__FILE__)
|
33
|
+
|
34
|
+
separator
|
35
|
+
|
36
|
+
comment %q{
|
37
|
+
MergeLocationConfig.c is automatically generated from MergeLocationConfig.c.cxxcodebuilder,
|
38
|
+
using definitions from src/ruby_supportlib/phusion_passenger/nginx/config_options.rb.
|
39
|
+
Edits to MergeLocationConfig.c will be lost.
|
40
|
+
|
41
|
+
To update MergeLocationConfig.c:
|
42
|
+
rake nginx
|
43
|
+
|
44
|
+
To force regeneration of MergeLocationConfig.c:
|
45
|
+
rm -f src/nginx_module/MergeLocationConfig.c
|
46
|
+
rake src/nginx_module/MergeLocationConfig.c
|
47
|
+
}
|
48
|
+
|
49
|
+
separator
|
50
|
+
|
51
|
+
comment %q{
|
52
|
+
0: NGX_CONF_ERROR, 1: OK
|
53
|
+
}
|
54
|
+
function('int generated_merge_part(passenger_loc_conf_t *conf, passenger_loc_conf_t *prev, ngx_conf_t *cf)') do
|
55
|
+
filter_eligible_options(LOCATION_CONFIGURATION_OPTIONS).each do |option|
|
56
|
+
if option[:type] == :string
|
57
|
+
add_code %Q{
|
58
|
+
ngx_conf_merge_str_value(conf->#{struct_field_for(option)},
|
59
|
+
prev->#{struct_field_for(option)},
|
60
|
+
NULL);
|
61
|
+
}
|
62
|
+
elsif option[:type] == :integer || option[:type] == :flag
|
63
|
+
add_code %Q{
|
64
|
+
ngx_conf_merge_value(conf->#{struct_field_for(option)},
|
65
|
+
prev->#{struct_field_for(option)},
|
66
|
+
NGX_CONF_UNSET);
|
67
|
+
}
|
68
|
+
elsif option[:type] == :uinteger
|
69
|
+
add_code %Q{
|
70
|
+
ngx_conf_merge_uint_value(conf->#{struct_field_for(option)},
|
71
|
+
prev->#{struct_field_for(option)},
|
72
|
+
#{default_value_for(option) || "NGX_CONF_UNSET_UINT"});
|
73
|
+
}
|
74
|
+
elsif option[:type] == :string_array
|
75
|
+
add_code %Q{
|
76
|
+
if (merge_string_array(cf, &prev->#{struct_field_for(option)}, &conf->#{struct_field_for(option)}) != NGX_OK) {
|
77
|
+
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
78
|
+
"cannot merge \\"#{option[:name]}\\" configurations");
|
79
|
+
return 0;
|
80
|
+
}
|
81
|
+
}
|
82
|
+
elsif option[:type] == :string_keyval
|
83
|
+
add_code %Q{
|
84
|
+
if (merge_string_keyval_table(cf, &prev->#{struct_field_for(option)}, &conf->#{struct_field_for(option)}) != NGX_OK) {
|
85
|
+
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
86
|
+
"cannot merge \\"#{option[:name]}\\" configurations");
|
87
|
+
return 0;
|
88
|
+
}
|
89
|
+
}
|
90
|
+
else
|
91
|
+
raise "Unknown option type #{option[:type].inspect} for option #{option[:name]}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
separator
|
96
|
+
add_code %q{
|
97
|
+
return 1;
|
98
|
+
}
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def filter_eligible_options(options)
|
103
|
+
options.reject do |option|
|
104
|
+
option[:alias_for] ||
|
105
|
+
option.fetch(:field, true).nil? ||
|
106
|
+
option[:field].to_s =~ /\./ ||
|
107
|
+
!option.fetch(:auto_generate_nginx_merge_code, true)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def struct_field_for(option)
|
112
|
+
if option.has_key?(:field)
|
113
|
+
option[:field]
|
114
|
+
else
|
115
|
+
option[:name].sub(/^passenger_/, '')
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def default_value_for(option)
|
120
|
+
case option[:type]
|
121
|
+
when :string
|
122
|
+
if option[:default]
|
123
|
+
option[:default].inspect
|
124
|
+
else
|
125
|
+
"NULL"
|
126
|
+
end
|
127
|
+
when :integer, :flag
|
128
|
+
if option[:default]
|
129
|
+
option[:default]
|
130
|
+
else
|
131
|
+
"NGX_CONF_UNSET"
|
132
|
+
end
|
133
|
+
when :uinteger
|
134
|
+
if option[:default]
|
135
|
+
option[:default]
|
136
|
+
else
|
137
|
+
"NGX_CONF_UNSET_UINT"
|
138
|
+
end
|
139
|
+
else
|
140
|
+
raise "Unknown type #{option[:type].inspect} for option #{option[:name]}"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
main
|
@@ -131,7 +131,7 @@ starting_watchdog_after_fork(void *paramCycle, void *paramParams) {
|
|
131
131
|
ngx_cycle_t *cycle = (void *) paramCycle;
|
132
132
|
PsgVariantMap *params = (void *) paramParams;
|
133
133
|
|
134
|
-
|
134
|
+
char *log_filename;
|
135
135
|
FILE *log_file;
|
136
136
|
ngx_core_conf_t *ccf;
|
137
137
|
ngx_uint_t i;
|
@@ -142,7 +142,7 @@ starting_watchdog_after_fork(void *paramCycle, void *paramParams) {
|
|
142
142
|
* Make sure that they're both redirected to the log file.
|
143
143
|
*/
|
144
144
|
log_file = NULL;
|
145
|
-
log_filename =
|
145
|
+
log_filename = psg_variant_map_get_optional(params, "log_file");
|
146
146
|
if (log_filename == NULL) {
|
147
147
|
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
|
148
148
|
"no passenger log file configured, discarding log output");
|
@@ -152,6 +152,8 @@ starting_watchdog_after_fork(void *paramCycle, void *paramParams) {
|
|
152
152
|
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
|
153
153
|
"could not open the passenger log file for writing during Nginx startup, some log lines might be lost (will retry from Passenger core)");
|
154
154
|
}
|
155
|
+
free(log_filename);
|
156
|
+
log_filename = NULL;
|
155
157
|
}
|
156
158
|
|
157
159
|
if (log_file == NULL) {
|
@@ -223,7 +225,6 @@ start_watchdog(ngx_cycle_t *cycle) {
|
|
223
225
|
ngx_core_conf_t *core_conf;
|
224
226
|
ngx_int_t ret, result;
|
225
227
|
ngx_uint_t i;
|
226
|
-
char *config_file = NULL;
|
227
228
|
ngx_str_t *prestart_uris;
|
228
229
|
char **prestart_uris_ary = NULL;
|
229
230
|
ngx_keyval_t *ctl = NULL;
|
@@ -243,11 +244,6 @@ start_watchdog(ngx_cycle_t *cycle) {
|
|
243
244
|
pp_app_type_detector_set_throttle_rate(pp_app_type_detector,
|
244
245
|
passenger_main_conf.stat_throttle_rate);
|
245
246
|
|
246
|
-
config_file = ngx_str_null_terminate(&cycle->conf_file);
|
247
|
-
if (config_file == NULL) {
|
248
|
-
goto error_enomem;
|
249
|
-
}
|
250
|
-
|
251
247
|
prestart_uris = (ngx_str_t *) passenger_main_conf.prestart_uris->elts;
|
252
248
|
prestart_uris_ary = calloc(sizeof(char *), passenger_main_conf.prestart_uris->nelts);
|
253
249
|
for (i = 0; i < passenger_main_conf.prestart_uris->nelts; i++) {
|
@@ -258,7 +254,6 @@ start_watchdog(ngx_cycle_t *cycle) {
|
|
258
254
|
}
|
259
255
|
|
260
256
|
psg_variant_map_set_int (params, "web_server_control_process_pid", getpid());
|
261
|
-
psg_variant_map_set_strset (params, "web_server_config_files", (const char **) &config_file, 1);
|
262
257
|
psg_variant_map_set (params, "server_software", NGINX_VER, strlen(NGINX_VER));
|
263
258
|
psg_variant_map_set_bool (params, "multi_app", 1);
|
264
259
|
psg_variant_map_set_bool (params, "load_shell_envvars", 1);
|
@@ -348,7 +343,6 @@ cleanup:
|
|
348
343
|
psg_variant_map_free(params);
|
349
344
|
free(passenger_root);
|
350
345
|
free(error_message);
|
351
|
-
free(config_file);
|
352
346
|
if (prestart_uris_ary != NULL) {
|
353
347
|
for (i = 0; i < passenger_main_conf.prestart_uris->nelts; i++) {
|
354
348
|
free(prestart_uris_ary[i]);
|
@@ -31,12 +31,12 @@ module PhusionPassenger
|
|
31
31
|
|
32
32
|
PACKAGE_NAME = 'passenger'
|
33
33
|
# Run 'rake src/cxx_supportlib/Constants.h' after changing this number.
|
34
|
-
VERSION_STRING = '5.0.
|
34
|
+
VERSION_STRING = '5.0.29'
|
35
35
|
|
36
|
-
PREFERRED_NGINX_VERSION = '1.10.
|
37
|
-
NGINX_SHA256_CHECKSUM = '
|
36
|
+
PREFERRED_NGINX_VERSION = '1.10.1'
|
37
|
+
NGINX_SHA256_CHECKSUM = '1fd35846566485e03c0e318989561c135c598323ff349c503a6c14826487a801'
|
38
38
|
|
39
|
-
PREFERRED_PCRE_VERSION = '8.
|
39
|
+
PREFERRED_PCRE_VERSION = '8.39'
|
40
40
|
PCRE_SHA256_CHECKSUM = '1dd78994c81e44ac41cf30b2a21d4b4cc6d76ccde7fc6e77713ed51d7bddca47'
|
41
41
|
|
42
42
|
STANDALONE_INTERFACE_VERSION = 1
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
# Phusion Passenger - https://www.phusionpassenger.com/
|
3
|
-
# Copyright (c) 2014-
|
3
|
+
# Copyright (c) 2014-2016 Phusion Holding B.V.
|
4
4
|
#
|
5
5
|
# "Passenger", "Phusion Passenger" and "Union Station" are registered
|
6
6
|
# trademarks of Phusion Holding B.V.
|
@@ -100,7 +100,7 @@ module PhusionPassenger
|
|
100
100
|
opts.separator " The exit codes are as follows:"
|
101
101
|
opts.separator " 0 - All checks passed. No errors, no warnings."
|
102
102
|
opts.separator " #{FAIL_EXIT_CODE} - Some checks failed with an error."
|
103
|
-
opts.separator " #{WARN_EXIT_CODE} - No checks failed with an error, but some
|
103
|
+
opts.separator " #{WARN_EXIT_CODE} - No checks failed with an error, but some produced warnings."
|
104
104
|
opts.separator " #{INTERNAL_ERROR_CODE} - Some internal error occurred."
|
105
105
|
opts.separator ""
|
106
106
|
|
@@ -108,6 +108,8 @@ module PhusionPassenger
|
|
108
108
|
'Vagrantfile',
|
109
109
|
'Passenger.sublime-project',
|
110
110
|
'Passenger.xcodeproj/**/*',
|
111
|
+
'build/support/vendor/*/.*',
|
112
|
+
'build/support/vendor/*/spec/**/*',
|
111
113
|
'src/ruby_supportlib/phusion_passenger/vendor/*/.*',
|
112
114
|
'src/ruby_supportlib/phusion_passenger/vendor/*/hacking/**/*',
|
113
115
|
'src/ruby_supportlib/phusion_passenger/vendor/*/spec/**/*',
|
@@ -484,6 +484,12 @@ module PhusionPassenger
|
|
484
484
|
end
|
485
485
|
memoize :has_math_library?, true
|
486
486
|
|
487
|
+
def self.has_dl_library?
|
488
|
+
return try_link("Checking for -ldl support",
|
489
|
+
:c, "int main() { return 0; }\n", '-ldl')
|
490
|
+
end
|
491
|
+
memoize :has_dl_library?, true
|
492
|
+
|
487
493
|
def self.has_alloca_h?
|
488
494
|
return try_compile("Checking for alloca.h",
|
489
495
|
:c, '#include <alloca.h>')
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# Phusion Passenger - https://www.phusionpassenger.com/
|
2
|
-
# Copyright (c) 2010-
|
2
|
+
# Copyright (c) 2010-2016 Phusion Holding B.V.
|
3
3
|
#
|
4
4
|
# "Passenger", "Phusion Passenger" and "Union Station" are registered
|
5
5
|
# trademarks of Phusion Holding B.V.
|
@@ -67,7 +67,7 @@ module PhusionPassenger
|
|
67
67
|
touch_temp_dir_in_background
|
68
68
|
########################
|
69
69
|
########################
|
70
|
-
watch_log_files_in_background if
|
70
|
+
watch_log_files_in_background if should_watch_one_or_more_log_files?
|
71
71
|
wait_until_engine_has_exited if should_wait_until_engine_has_exited?
|
72
72
|
rescue Interrupt
|
73
73
|
trapsafe_shutdown_and_cleanup(true)
|
@@ -456,15 +456,34 @@ module PhusionPassenger
|
|
456
456
|
@threads << thread
|
457
457
|
@interruptable_threads << thread
|
458
458
|
end
|
459
|
-
|
460
|
-
|
459
|
+
if should_watch_main_log_file?
|
460
|
+
thread = Utils.create_thread_and_abort_on_exception do
|
461
|
+
watch_log_file(@options[:log_file])
|
462
|
+
end
|
463
|
+
@threads << thread
|
464
|
+
@interruptable_threads << thread
|
461
465
|
end
|
462
|
-
@threads << thread
|
463
|
-
@interruptable_threads << thread
|
464
466
|
end
|
465
467
|
|
466
|
-
def
|
467
|
-
|
468
|
+
def should_watch_one_or_more_log_files?
|
469
|
+
!@options[:daemonize]
|
470
|
+
end
|
471
|
+
|
472
|
+
def should_watch_main_log_file?
|
473
|
+
if @options[:daemonize]
|
474
|
+
false
|
475
|
+
else
|
476
|
+
begin
|
477
|
+
stat = File.stat(@options[:log_file])
|
478
|
+
rescue Errno::ENOENT
|
479
|
+
stat = nil
|
480
|
+
end
|
481
|
+
if stat
|
482
|
+
stat.file?
|
483
|
+
else
|
484
|
+
true
|
485
|
+
end
|
486
|
+
end
|
468
487
|
end
|
469
488
|
|
470
489
|
def should_wait_until_engine_has_exited?
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# daemon_controller, library for robust daemon management
|
2
|
-
# Copyright (c) 2010-
|
2
|
+
# Copyright (c) 2010-2016 Phusion Holding B.V.
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
5
|
# of this software and associated documentation files (the "Software"), to deal
|
@@ -22,6 +22,7 @@
|
|
22
22
|
require 'tempfile'
|
23
23
|
require 'fcntl'
|
24
24
|
require 'socket'
|
25
|
+
require 'pathname'
|
25
26
|
require 'timeout'
|
26
27
|
if Process.respond_to?(:spawn)
|
27
28
|
require 'rbconfig'
|
@@ -560,7 +561,7 @@ private
|
|
560
561
|
end
|
561
562
|
|
562
563
|
def differences_in_log_file
|
563
|
-
if @original_log_file_stat
|
564
|
+
if @original_log_file_stat && @original_log_file_stat.file?
|
564
565
|
File.open(@log_file, 'r') do |f|
|
565
566
|
f.seek(@original_log_file_stat.size, IO::SEEK_SET)
|
566
567
|
diff = f.read.strip
|
@@ -596,6 +597,39 @@ private
|
|
596
597
|
end
|
597
598
|
|
598
599
|
def run_command(command)
|
600
|
+
if should_capture_output_while_running_command?
|
601
|
+
run_command_while_capturing_output(command)
|
602
|
+
else
|
603
|
+
run_command_without_capturing_output(command)
|
604
|
+
end
|
605
|
+
end
|
606
|
+
|
607
|
+
def should_capture_output_while_running_command?
|
608
|
+
if is_std_channel_chardev?(@log_file)
|
609
|
+
false
|
610
|
+
else
|
611
|
+
begin
|
612
|
+
real_log_file = Pathname.new(@log_file).realpath.to_s
|
613
|
+
rescue SystemCallError
|
614
|
+
real_log_file = nil
|
615
|
+
end
|
616
|
+
if real_log_file
|
617
|
+
!is_std_channel_chardev?(real_log_file)
|
618
|
+
else
|
619
|
+
true
|
620
|
+
end
|
621
|
+
end
|
622
|
+
end
|
623
|
+
|
624
|
+
def is_std_channel_chardev?(path)
|
625
|
+
path == "/dev/stdout" ||
|
626
|
+
path == "/dev/stderr" ||
|
627
|
+
path == "/dev/fd/1" ||
|
628
|
+
path == "/dev/fd/2" ||
|
629
|
+
path =~ %r(\A/proc/([0-9]+|self)/fd/[12]\Z)
|
630
|
+
end
|
631
|
+
|
632
|
+
def run_command_while_capturing_output(command)
|
599
633
|
# Create tempfile for storing the command's output.
|
600
634
|
tempfile = Tempfile.new('daemon-output')
|
601
635
|
tempfile_path = tempfile.path
|
@@ -691,6 +725,90 @@ private
|
|
691
725
|
File.unlink(tempfile_path) rescue nil
|
692
726
|
end
|
693
727
|
|
728
|
+
def run_command_without_capturing_output(command)
|
729
|
+
if self.class.fork_supported? || self.class.spawn_supported?
|
730
|
+
if Process.respond_to?(:spawn)
|
731
|
+
options = {
|
732
|
+
:in => "/dev/null",
|
733
|
+
:out => :out,
|
734
|
+
:err => :err,
|
735
|
+
:close_others => true
|
736
|
+
}
|
737
|
+
@keep_ios.each do |io|
|
738
|
+
options[io] = io
|
739
|
+
end
|
740
|
+
if @daemonize_for_me
|
741
|
+
pid = Process.spawn(@env, ruby_interpreter, SPAWNER_FILE,
|
742
|
+
command, options)
|
743
|
+
else
|
744
|
+
pid = Process.spawn(@env, command, options)
|
745
|
+
end
|
746
|
+
else
|
747
|
+
pid = safe_fork(@daemonize_for_me) do
|
748
|
+
ObjectSpace.each_object(IO) do |obj|
|
749
|
+
if !@keep_ios.include?(obj)
|
750
|
+
obj.close rescue nil
|
751
|
+
end
|
752
|
+
end
|
753
|
+
STDIN.reopen("/dev/null", "r")
|
754
|
+
ENV.update(@env)
|
755
|
+
exec(command)
|
756
|
+
end
|
757
|
+
end
|
758
|
+
|
759
|
+
# run_command might be running in a timeout block (like
|
760
|
+
# in #start_without_locking).
|
761
|
+
begin
|
762
|
+
interruptable_waitpid(pid)
|
763
|
+
rescue Errno::ECHILD
|
764
|
+
# Maybe a background thread or whatever waitpid()'ed
|
765
|
+
# this child process before we had the chance. There's
|
766
|
+
# no way to obtain the exit status now. Assume that
|
767
|
+
# it started successfully; if it didn't we'll know
|
768
|
+
# that later by checking the PID file and by pinging
|
769
|
+
# it.
|
770
|
+
return
|
771
|
+
rescue Timeout::Error
|
772
|
+
daemonization_timed_out
|
773
|
+
|
774
|
+
# If the daemon doesn't fork into the background
|
775
|
+
# in time, then kill it.
|
776
|
+
begin
|
777
|
+
Process.kill('SIGTERM', pid)
|
778
|
+
rescue SystemCallError
|
779
|
+
end
|
780
|
+
begin
|
781
|
+
Timeout.timeout(5, Timeout::Error) do
|
782
|
+
begin
|
783
|
+
interruptable_waitpid(pid)
|
784
|
+
rescue SystemCallError
|
785
|
+
end
|
786
|
+
end
|
787
|
+
rescue Timeout::Error
|
788
|
+
begin
|
789
|
+
Process.kill('SIGKILL', pid)
|
790
|
+
interruptable_waitpid(pid)
|
791
|
+
rescue SystemCallError
|
792
|
+
end
|
793
|
+
end
|
794
|
+
raise DaemonizationTimeout
|
795
|
+
end
|
796
|
+
if $?.exitstatus != 0
|
797
|
+
raise StartError, "Daemon '#{@identifier}' failed to start."
|
798
|
+
end
|
799
|
+
else
|
800
|
+
if @env && !@env.empty?
|
801
|
+
raise "Setting the :env option is not supported on this Ruby implementation."
|
802
|
+
elsif @daemonize_for_me
|
803
|
+
raise "Setting the :daemonize_for_me option is not supported on this Ruby implementation."
|
804
|
+
end
|
805
|
+
|
806
|
+
if !system(command)
|
807
|
+
raise StartError, "Daemon '#{@identifier}' failed to start."
|
808
|
+
end
|
809
|
+
end
|
810
|
+
end
|
811
|
+
|
694
812
|
def run_ping_command
|
695
813
|
if @ping_command.respond_to?(:call)
|
696
814
|
begin
|