passenger 3.0.21 → 3.9.1.beta

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.

Files changed (835) hide show
  1. data/DEVELOPERS.TXT +4 -10
  2. data/NEWS +19 -27
  3. data/Rakefile +20 -19
  4. data/bin/passenger +3 -2
  5. data/bin/passenger-config +35 -5
  6. data/bin/passenger-install-apache2-module +12 -12
  7. data/bin/passenger-install-nginx-module +55 -38
  8. data/bin/passenger-memory-stats +3 -1
  9. data/bin/passenger-status +7 -35
  10. data/build/agents.rb +107 -21
  11. data/build/apache2.rb +11 -46
  12. data/build/basics.rb +61 -9
  13. data/build/common_library.rb +59 -142
  14. data/build/cxx_tests.rb +111 -110
  15. data/build/documentation.rb +33 -0
  16. data/build/misc.rb +30 -12
  17. data/build/nginx.rb +10 -39
  18. data/build/oxt_tests.rb +1 -0
  19. data/build/ruby_extension.rb +1 -5
  20. data/build/test_basics.rb +3 -2
  21. data/dev/copy_boost_headers.rb +2 -1
  22. data/doc/Architectural overview.html +49 -90
  23. data/doc/DebuggingAndStressTesting.txt.md +49 -0
  24. data/doc/Packaging.txt.md +254 -0
  25. data/doc/Security of user switching support.html +35 -66
  26. data/doc/Users guide Apache.html +588 -758
  27. data/doc/Users guide Apache.idmap.txt +253 -136
  28. data/doc/Users guide Apache.txt +154 -109
  29. data/doc/Users guide Nginx.html +544 -660
  30. data/doc/Users guide Nginx.idmap.txt +179 -91
  31. data/doc/Users guide Nginx.txt +192 -118
  32. data/doc/Users guide Standalone.html +65 -48
  33. data/doc/Users guide Standalone.idmap.txt +10 -2
  34. data/doc/Users guide Standalone.txt +4 -0
  35. data/doc/images/glyphicons-halflings-white.png +0 -0
  36. data/doc/images/glyphicons-halflings.png +0 -0
  37. data/doc/images/phusion_banner_small.png +0 -0
  38. data/doc/images/{smart-lv2.png → smart.png} +0 -0
  39. data/doc/images/{smart-lv2.svg → smart.svg} +0 -0
  40. data/doc/templates/bootstrap.min.css +397 -0
  41. data/doc/templates/markdown.html.erb +117 -0
  42. data/doc/users_guide_snippets/analysis_and_system_maintenance.txt +2 -1
  43. data/doc/users_guide_snippets/appendix_c_spawning_methods.txt +26 -48
  44. data/doc/users_guide_snippets/passenger_spawn_method.txt +18 -30
  45. data/doc/users_guide_snippets/support_information.txt +30 -0
  46. data/ext/apache2/Bucket.cpp +9 -26
  47. data/ext/apache2/Bucket.h +13 -10
  48. data/ext/apache2/Configuration.cpp +70 -58
  49. data/ext/apache2/Configuration.hpp +19 -47
  50. data/ext/apache2/DirectoryMapper.h +7 -7
  51. data/ext/apache2/Hooks.cpp +150 -313
  52. data/ext/boost/algorithm/string/detail/case_conv.hpp +4 -2
  53. data/ext/boost/algorithm/string/detail/find_format.hpp +20 -20
  54. data/ext/boost/algorithm/string/detail/find_format_all.hpp +23 -23
  55. data/ext/boost/algorithm/string/detail/find_format_store.hpp +2 -2
  56. data/ext/boost/algorithm/string/detail/formatter.hpp +25 -0
  57. data/ext/boost/algorithm/string/formatter.hpp +20 -3
  58. data/ext/boost/assert.hpp +85 -4
  59. data/ext/boost/bind/bind.hpp +1 -1
  60. data/ext/boost/concept/detail/backward_compatibility.hpp +1 -1
  61. data/ext/boost/concept_check.hpp +140 -64
  62. data/ext/boost/config.hpp +1 -1
  63. data/ext/boost/config/auto_link.hpp +8 -6
  64. data/ext/boost/config/compiler/borland.hpp +12 -2
  65. data/ext/boost/config/compiler/clang.hpp +89 -30
  66. data/ext/boost/config/compiler/codegear.hpp +3 -2
  67. data/ext/boost/config/compiler/common_edg.hpp +7 -5
  68. data/ext/boost/config/compiler/cray.hpp +61 -0
  69. data/ext/boost/config/compiler/digitalmars.hpp +9 -1
  70. data/ext/boost/config/compiler/gcc.hpp +33 -24
  71. data/ext/boost/config/compiler/gcc_xml.hpp +4 -0
  72. data/ext/boost/config/compiler/hp_acc.hpp +12 -1
  73. data/ext/boost/config/compiler/intel.hpp +78 -4
  74. data/ext/boost/config/compiler/metrowerks.hpp +4 -1
  75. data/ext/boost/config/compiler/mpw.hpp +4 -1
  76. data/ext/boost/config/compiler/nvcc.hpp +8 -66
  77. data/ext/boost/config/compiler/pathscale.hpp +80 -0
  78. data/ext/boost/config/compiler/pgi.hpp +5 -5
  79. data/ext/boost/config/compiler/sunpro_cc.hpp +4 -1
  80. data/ext/boost/config/compiler/vacpp.hpp +37 -13
  81. data/ext/boost/config/compiler/visualc.hpp +24 -11
  82. data/ext/boost/config/platform/bsd.hpp +1 -1
  83. data/ext/boost/config/platform/cray.hpp +18 -0
  84. data/ext/boost/config/platform/cygwin.hpp +10 -0
  85. data/ext/boost/config/platform/linux.hpp +5 -0
  86. data/ext/boost/config/platform/macos.hpp +5 -4
  87. data/ext/boost/config/platform/symbian.hpp +5 -2
  88. data/ext/boost/config/platform/vms.hpp +25 -0
  89. data/ext/boost/config/platform/win32.hpp +7 -1
  90. data/ext/boost/config/select_compiler_config.hpp +8 -25
  91. data/ext/boost/config/select_platform_config.hpp +8 -1
  92. data/ext/boost/config/select_stdlib_config.hpp +9 -1
  93. data/ext/boost/config/stdlib/dinkumware.hpp +6 -9
  94. data/ext/boost/config/stdlib/libcomo.hpp +1 -4
  95. data/ext/boost/config/stdlib/libcpp.hpp +36 -0
  96. data/ext/boost/config/stdlib/libstdcpp3.hpp +37 -11
  97. data/ext/boost/config/stdlib/modena.hpp +1 -4
  98. data/ext/boost/config/stdlib/msl.hpp +1 -4
  99. data/ext/boost/config/stdlib/roguewave.hpp +9 -6
  100. data/ext/boost/config/stdlib/sgi.hpp +12 -4
  101. data/ext/boost/config/stdlib/stlport.hpp +11 -4
  102. data/ext/boost/config/stdlib/vacpp.hpp +11 -4
  103. data/ext/boost/config/suffix.hpp +71 -6
  104. data/ext/boost/config/warning_disable.hpp +1 -1
  105. data/ext/boost/container/container_fwd.hpp +177 -0
  106. data/ext/boost/cstdint.hpp +17 -12
  107. data/ext/boost/current_function.hpp +2 -1
  108. data/ext/boost/date_time/c_time.hpp +17 -1
  109. data/ext/boost/date_time/compiler_config.hpp +13 -15
  110. data/ext/boost/date_time/date_formatting.hpp +7 -1
  111. data/ext/boost/date_time/filetime_functions.hpp +4 -4
  112. data/ext/boost/date_time/gregorian_calendar.ipp +2 -2
  113. data/ext/boost/date_time/strings_from_facet.hpp +3 -3
  114. data/ext/boost/date_time/time_facet.hpp +101 -101
  115. data/ext/boost/detail/endian.hpp +4 -2
  116. data/ext/boost/detail/fenv.hpp +74 -0
  117. data/ext/boost/detail/sp_typeinfo.hpp +6 -0
  118. data/ext/boost/exception/detail/clone_current_exception.hpp +47 -0
  119. data/ext/boost/exception/detail/exception_ptr.hpp +194 -122
  120. data/ext/boost/exception/detail/type_info.hpp +3 -3
  121. data/ext/boost/exception/diagnostic_information.hpp +37 -21
  122. data/ext/boost/exception/exception.hpp +21 -1
  123. data/ext/boost/exception/info.hpp +0 -1
  124. data/ext/boost/function.hpp +2 -2
  125. data/ext/boost/function/function_base.hpp +15 -9
  126. data/ext/boost/function/function_template.hpp +26 -48
  127. data/ext/boost/integer_fwd.hpp +0 -16
  128. data/ext/boost/integer_traits.hpp +2 -2
  129. data/ext/boost/iterator.hpp +1 -1
  130. data/ext/boost/iterator/iterator_adaptor.hpp +1 -7
  131. data/ext/boost/iterator/iterator_facade.hpp +13 -13
  132. data/ext/boost/iterator/transform_iterator.hpp +5 -20
  133. data/ext/boost/lexical_cast.hpp +1655 -673
  134. data/ext/boost/math/policies/policy.hpp +982 -0
  135. data/ext/boost/math/special_functions/detail/fp_traits.hpp +570 -0
  136. data/ext/boost/math/special_functions/detail/round_fwd.hpp +80 -0
  137. data/ext/boost/math/special_functions/fpclassify.hpp +533 -0
  138. data/ext/boost/math/special_functions/math_fwd.hpp +1070 -0
  139. data/ext/boost/math/special_functions/sign.hpp +145 -0
  140. data/ext/boost/math/tools/config.hpp +321 -0
  141. data/ext/boost/math/tools/promotion.hpp +150 -0
  142. data/ext/boost/math/tools/real_cast.hpp +29 -0
  143. data/ext/boost/math/tools/user.hpp +97 -0
  144. data/ext/boost/move/move.hpp +1222 -0
  145. data/ext/boost/mpl/O1_size.hpp +40 -0
  146. data/ext/boost/mpl/O1_size_fwd.hpp +24 -0
  147. data/ext/boost/mpl/advance.hpp +76 -0
  148. data/ext/boost/mpl/advance_fwd.hpp +28 -0
  149. data/ext/boost/mpl/at.hpp +52 -0
  150. data/ext/boost/mpl/at_fwd.hpp +24 -0
  151. data/ext/boost/mpl/aux_/O1_size_impl.hpp +87 -0
  152. data/ext/boost/mpl/aux_/advance_backward.hpp +128 -0
  153. data/ext/boost/mpl/aux_/advance_forward.hpp +127 -0
  154. data/ext/boost/mpl/aux_/arithmetic_op.hpp +92 -0
  155. data/ext/boost/mpl/aux_/at_impl.hpp +45 -0
  156. data/ext/boost/mpl/aux_/begin_end_impl.hpp +101 -0
  157. data/ext/boost/mpl/aux_/clear_impl.hpp +35 -0
  158. data/ext/boost/mpl/aux_/comparison_op.hpp +83 -0
  159. data/ext/boost/mpl/aux_/config/forwarding.hpp +27 -0
  160. data/ext/boost/mpl/aux_/config/typeof.hpp +38 -0
  161. data/ext/boost/mpl/aux_/contains_impl.hpp +61 -0
  162. data/ext/boost/mpl/aux_/find_if_pred.hpp +31 -0
  163. data/ext/boost/mpl/aux_/fold_impl.hpp +43 -0
  164. data/ext/boost/mpl/aux_/has_begin.hpp +23 -0
  165. data/ext/boost/mpl/aux_/has_size.hpp +23 -0
  166. data/ext/boost/mpl/aux_/has_tag.hpp +23 -0
  167. data/ext/boost/mpl/aux_/inserter_algorithm.hpp +159 -0
  168. data/ext/boost/mpl/aux_/is_msvc_eti_arg.hpp +64 -0
  169. data/ext/boost/mpl/aux_/iter_apply.hpp +47 -0
  170. data/ext/boost/mpl/aux_/iter_fold_if_impl.hpp +210 -0
  171. data/ext/boost/mpl/aux_/iter_fold_impl.hpp +42 -0
  172. data/ext/boost/mpl/aux_/lambda_spec.hpp +49 -0
  173. data/ext/boost/mpl/aux_/largest_int.hpp +63 -0
  174. data/ext/boost/mpl/aux_/msvc_eti_base.hpp +77 -0
  175. data/ext/boost/mpl/aux_/msvc_type.hpp +62 -0
  176. data/ext/boost/mpl/aux_/numeric_cast_utils.hpp +77 -0
  177. data/ext/boost/mpl/aux_/numeric_op.hpp +315 -0
  178. data/ext/boost/mpl/aux_/preprocessed/gcc/advance_backward.hpp +97 -0
  179. data/ext/boost/mpl/aux_/preprocessed/gcc/advance_forward.hpp +97 -0
  180. data/ext/boost/mpl/aux_/preprocessed/gcc/equal_to.hpp +94 -0
  181. data/ext/boost/mpl/aux_/preprocessed/gcc/fold_impl.hpp +180 -0
  182. data/ext/boost/mpl/aux_/preprocessed/gcc/greater.hpp +94 -0
  183. data/ext/boost/mpl/aux_/preprocessed/gcc/greater_equal.hpp +94 -0
  184. data/ext/boost/mpl/aux_/preprocessed/gcc/iter_fold_if_impl.hpp +133 -0
  185. data/ext/boost/mpl/aux_/preprocessed/gcc/iter_fold_impl.hpp +180 -0
  186. data/ext/boost/mpl/aux_/preprocessed/gcc/less.hpp +94 -0
  187. data/ext/boost/mpl/aux_/preprocessed/gcc/less_equal.hpp +94 -0
  188. data/ext/boost/mpl/aux_/preprocessed/gcc/list.hpp +323 -0
  189. data/ext/boost/mpl/aux_/preprocessed/gcc/minus.hpp +146 -0
  190. data/ext/boost/mpl/aux_/preprocessed/gcc/not_equal_to.hpp +94 -0
  191. data/ext/boost/mpl/aux_/preprocessed/gcc/plus.hpp +146 -0
  192. data/ext/boost/mpl/aux_/preprocessed/gcc/reverse_fold_impl.hpp +231 -0
  193. data/ext/boost/mpl/aux_/preprocessed/gcc/times.hpp +146 -0
  194. data/ext/boost/mpl/aux_/preprocessed/gcc/vector.hpp +323 -0
  195. data/ext/boost/mpl/aux_/preprocessor/default_params.hpp +67 -0
  196. data/ext/boost/mpl/aux_/push_back_impl.hpp +70 -0
  197. data/ext/boost/mpl/aux_/push_front_impl.hpp +71 -0
  198. data/ext/boost/mpl/aux_/reverse_fold_impl.hpp +44 -0
  199. data/ext/boost/mpl/aux_/size_impl.hpp +52 -0
  200. data/ext/boost/mpl/aux_/traits_lambda_spec.hpp +63 -0
  201. data/ext/boost/mpl/back_fwd.hpp +24 -0
  202. data/ext/boost/mpl/back_inserter.hpp +34 -0
  203. data/ext/boost/mpl/begin_end.hpp +57 -0
  204. data/ext/boost/mpl/begin_end_fwd.hpp +27 -0
  205. data/ext/boost/mpl/clear.hpp +39 -0
  206. data/ext/boost/mpl/clear_fwd.hpp +24 -0
  207. data/ext/boost/mpl/comparison.hpp +24 -0
  208. data/ext/boost/mpl/contains.hpp +41 -0
  209. data/ext/boost/mpl/contains_fwd.hpp +25 -0
  210. data/ext/boost/mpl/deref.hpp +41 -0
  211. data/ext/boost/mpl/distance.hpp +78 -0
  212. data/ext/boost/mpl/distance_fwd.hpp +28 -0
  213. data/ext/boost/mpl/empty_fwd.hpp +24 -0
  214. data/ext/boost/mpl/equal_to.hpp +21 -0
  215. data/ext/boost/mpl/find.hpp +38 -0
  216. data/ext/boost/mpl/find_if.hpp +50 -0
  217. data/ext/boost/mpl/fold.hpp +48 -0
  218. data/ext/boost/mpl/front_fwd.hpp +24 -0
  219. data/ext/boost/mpl/front_inserter.hpp +33 -0
  220. data/ext/boost/mpl/greater.hpp +21 -0
  221. data/ext/boost/mpl/greater_equal.hpp +21 -0
  222. data/ext/boost/mpl/inserter.hpp +32 -0
  223. data/ext/boost/mpl/iter_fold.hpp +49 -0
  224. data/ext/boost/mpl/iter_fold_if.hpp +117 -0
  225. data/ext/boost/mpl/iterator_range.hpp +42 -0
  226. data/ext/boost/mpl/iterator_tags.hpp +27 -0
  227. data/ext/boost/mpl/less.hpp +21 -0
  228. data/ext/boost/mpl/less_equal.hpp +21 -0
  229. data/ext/boost/mpl/limits/list.hpp +21 -0
  230. data/ext/boost/mpl/limits/vector.hpp +21 -0
  231. data/ext/boost/mpl/list.hpp +57 -0
  232. data/ext/boost/mpl/list/aux_/O1_size.hpp +33 -0
  233. data/ext/boost/mpl/list/aux_/begin_end.hpp +44 -0
  234. data/ext/boost/mpl/list/aux_/clear.hpp +34 -0
  235. data/ext/boost/mpl/list/aux_/empty.hpp +34 -0
  236. data/ext/boost/mpl/list/aux_/front.hpp +33 -0
  237. data/ext/boost/mpl/list/aux_/include_preprocessed.hpp +35 -0
  238. data/ext/boost/mpl/list/aux_/item.hpp +55 -0
  239. data/ext/boost/mpl/list/aux_/iterator.hpp +76 -0
  240. data/ext/boost/mpl/list/aux_/pop_front.hpp +34 -0
  241. data/ext/boost/mpl/list/aux_/preprocessed/plain/list10.hpp +149 -0
  242. data/ext/boost/mpl/list/aux_/preprocessed/plain/list20.hpp +169 -0
  243. data/ext/boost/mpl/list/aux_/push_back.hpp +36 -0
  244. data/ext/boost/mpl/list/aux_/push_front.hpp +39 -0
  245. data/ext/boost/mpl/list/aux_/size.hpp +33 -0
  246. data/ext/boost/mpl/list/aux_/tag.hpp +24 -0
  247. data/ext/boost/mpl/list/list0.hpp +42 -0
  248. data/ext/boost/mpl/list/list10.hpp +43 -0
  249. data/ext/boost/mpl/list/list20.hpp +43 -0
  250. data/ext/boost/mpl/long.hpp +22 -0
  251. data/ext/boost/mpl/long_fwd.hpp +27 -0
  252. data/ext/boost/mpl/minus.hpp +21 -0
  253. data/ext/boost/mpl/multiplies.hpp +53 -0
  254. data/ext/boost/mpl/negate.hpp +81 -0
  255. data/ext/boost/mpl/not_equal_to.hpp +21 -0
  256. data/ext/boost/mpl/numeric_cast.hpp +41 -0
  257. data/ext/boost/mpl/pair.hpp +70 -0
  258. data/ext/boost/mpl/plus.hpp +21 -0
  259. data/ext/boost/mpl/pop_back_fwd.hpp +24 -0
  260. data/ext/boost/mpl/pop_front_fwd.hpp +24 -0
  261. data/ext/boost/mpl/prior.hpp +19 -0
  262. data/ext/boost/mpl/push_back.hpp +53 -0
  263. data/ext/boost/mpl/push_back_fwd.hpp +24 -0
  264. data/ext/boost/mpl/push_front.hpp +52 -0
  265. data/ext/boost/mpl/push_front_fwd.hpp +24 -0
  266. data/ext/boost/mpl/remove_if.hpp +83 -0
  267. data/ext/boost/mpl/reverse_fold.hpp +50 -0
  268. data/ext/boost/mpl/same_as.hpp +55 -0
  269. data/ext/boost/mpl/sequence_tag.hpp +124 -0
  270. data/ext/boost/mpl/sequence_tag_fwd.hpp +26 -0
  271. data/ext/boost/mpl/size.hpp +42 -0
  272. data/ext/boost/mpl/size_fwd.hpp +24 -0
  273. data/ext/boost/mpl/tag.hpp +52 -0
  274. data/ext/boost/mpl/times.hpp +21 -0
  275. data/ext/boost/mpl/vector.hpp +57 -0
  276. data/ext/boost/mpl/vector/aux_/O1_size.hpp +56 -0
  277. data/ext/boost/mpl/vector/aux_/at.hpp +116 -0
  278. data/ext/boost/mpl/vector/aux_/back.hpp +59 -0
  279. data/ext/boost/mpl/vector/aux_/begin_end.hpp +49 -0
  280. data/ext/boost/mpl/vector/aux_/clear.hpp +55 -0
  281. data/ext/boost/mpl/vector/aux_/empty.hpp +68 -0
  282. data/ext/boost/mpl/vector/aux_/front.hpp +56 -0
  283. data/ext/boost/mpl/vector/aux_/include_preprocessed.hpp +55 -0
  284. data/ext/boost/mpl/vector/aux_/item.hpp +103 -0
  285. data/ext/boost/mpl/vector/aux_/iterator.hpp +130 -0
  286. data/ext/boost/mpl/vector/aux_/pop_back.hpp +40 -0
  287. data/ext/boost/mpl/vector/aux_/pop_front.hpp +40 -0
  288. data/ext/boost/mpl/vector/aux_/preprocessed/plain/vector10.hpp +829 -0
  289. data/ext/boost/mpl/vector/aux_/preprocessed/plain/vector20.hpp +1144 -0
  290. data/ext/boost/mpl/vector/aux_/preprocessed/typeof_based/vector10.hpp +139 -0
  291. data/ext/boost/mpl/vector/aux_/preprocessed/typeof_based/vector20.hpp +159 -0
  292. data/ext/boost/mpl/vector/aux_/push_back.hpp +40 -0
  293. data/ext/boost/mpl/vector/aux_/push_front.hpp +40 -0
  294. data/ext/boost/mpl/vector/aux_/size.hpp +49 -0
  295. data/ext/boost/mpl/vector/aux_/tag.hpp +32 -0
  296. data/ext/boost/mpl/vector/aux_/vector0.hpp +52 -0
  297. data/ext/boost/mpl/vector/vector0.hpp +34 -0
  298. data/ext/boost/mpl/vector/vector10.hpp +45 -0
  299. data/ext/boost/mpl/vector/vector20.hpp +45 -0
  300. data/ext/boost/none.hpp +1 -1
  301. data/ext/boost/numeric/conversion/bounds.hpp +24 -0
  302. data/ext/boost/numeric/conversion/cast.hpp +61 -0
  303. data/ext/boost/numeric/conversion/conversion_traits.hpp +39 -0
  304. data/ext/boost/numeric/conversion/converter.hpp +68 -0
  305. data/ext/boost/numeric/conversion/converter_policies.hpp +186 -0
  306. data/ext/boost/numeric/conversion/detail/bounds.hpp +58 -0
  307. data/ext/boost/numeric/conversion/detail/conversion_traits.hpp +97 -0
  308. data/ext/boost/numeric/conversion/detail/converter.hpp +602 -0
  309. data/ext/boost/numeric/conversion/detail/int_float_mixture.hpp +72 -0
  310. data/ext/boost/numeric/conversion/detail/is_subranged.hpp +234 -0
  311. data/ext/boost/numeric/conversion/detail/meta.hpp +120 -0
  312. data/ext/boost/numeric/conversion/detail/numeric_cast_traits.hpp +138 -0
  313. data/ext/boost/numeric/conversion/detail/preprocessed/numeric_cast_traits_common.hpp +1741 -0
  314. data/ext/boost/numeric/conversion/detail/preprocessed/numeric_cast_traits_long_long.hpp +347 -0
  315. data/ext/boost/numeric/conversion/detail/sign_mixture.hpp +72 -0
  316. data/ext/boost/numeric/conversion/detail/udt_builtin_mixture.hpp +69 -0
  317. data/ext/boost/numeric/conversion/int_float_mixture_enum.hpp +29 -0
  318. data/ext/boost/numeric/conversion/numeric_cast_traits.hpp +31 -0
  319. data/ext/boost/numeric/conversion/sign_mixture_enum.hpp +29 -0
  320. data/ext/boost/numeric/conversion/udt_builtin_mixture_enum.hpp +26 -0
  321. data/ext/boost/operators.hpp +3 -1
  322. data/ext/boost/optional/optional.hpp +146 -79
  323. data/ext/boost/optional/optional_fwd.hpp +8 -1
  324. data/ext/boost/preprocessor/cat.hpp +2 -2
  325. data/ext/boost/preprocessor/config/config.hpp +39 -4
  326. data/ext/boost/preprocessor/facilities/intercept.hpp +277 -0
  327. data/ext/boost/preprocessor/facilities/overload.hpp +25 -0
  328. data/ext/boost/preprocessor/iteration/detail/iter/forward1.hpp +3 -3
  329. data/ext/boost/preprocessor/iteration/iterate.hpp +3 -3
  330. data/ext/boost/preprocessor/punctuation/paren.hpp +23 -0
  331. data/ext/boost/preprocessor/repetition/enum_shifted_params.hpp +44 -0
  332. data/ext/boost/preprocessor/seq/cat.hpp +5 -4
  333. data/ext/boost/preprocessor/seq/size.hpp +0 -1
  334. data/ext/boost/preprocessor/tuple/eat.hpp +83 -34
  335. data/ext/boost/preprocessor/tuple/elem.hpp +161 -355
  336. data/ext/boost/preprocessor/tuple/rem.hpp +110 -48
  337. data/ext/boost/preprocessor/tuple/to_list.hpp +90 -36
  338. data/ext/boost/preprocessor/variadic/elem.hpp +94 -0
  339. data/ext/boost/preprocessor/variadic/size.hpp +30 -0
  340. data/ext/boost/range/begin.hpp +17 -6
  341. data/ext/boost/range/concepts.hpp +37 -2
  342. data/ext/boost/range/detail/safe_bool.hpp +72 -0
  343. data/ext/boost/range/end.hpp +14 -9
  344. data/ext/boost/range/iterator_range_core.hpp +120 -12
  345. data/ext/boost/range/size.hpp +21 -5
  346. data/ext/boost/smart_ptr/detail/shared_count.hpp +88 -0
  347. data/ext/boost/smart_ptr/detail/sp_counted_base.hpp +3 -0
  348. data/ext/boost/smart_ptr/detail/sp_counted_base_aix.hpp +142 -0
  349. data/ext/boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp +9 -0
  350. data/ext/boost/smart_ptr/detail/sp_counted_impl.hpp +10 -2
  351. data/ext/boost/smart_ptr/detail/sp_has_sync.hpp +5 -1
  352. data/ext/boost/smart_ptr/detail/spinlock.hpp +4 -1
  353. data/ext/boost/smart_ptr/detail/spinlock_gcc_arm.hpp +20 -3
  354. data/ext/boost/smart_ptr/detail/spinlock_pool.hpp +4 -0
  355. data/ext/boost/smart_ptr/make_shared.hpp +591 -22
  356. data/ext/boost/smart_ptr/shared_array.hpp +29 -1
  357. data/ext/boost/smart_ptr/shared_ptr.hpp +29 -13
  358. data/ext/boost/smart_ptr/weak_ptr.hpp +24 -12
  359. data/ext/boost/src/pthread/once.cpp +9 -7
  360. data/ext/boost/src/pthread/thread.cpp +32 -28
  361. data/ext/boost/src/pthread/timeconv.inl +4 -5
  362. data/ext/boost/src/tss_null.cpp +5 -1
  363. data/ext/boost/static_assert.hpp +8 -2
  364. data/ext/boost/thread/detail/config.hpp +19 -4
  365. data/ext/boost/thread/detail/move.hpp +11 -5
  366. data/ext/boost/thread/detail/thread.hpp +59 -43
  367. data/ext/boost/thread/exceptions.hpp +9 -9
  368. data/ext/boost/thread/future.hpp +150 -82
  369. data/ext/boost/thread/locks.hpp +101 -60
  370. data/ext/boost/thread/pthread/condition_variable.hpp +79 -32
  371. data/ext/boost/thread/pthread/condition_variable_fwd.hpp +12 -3
  372. data/ext/boost/thread/pthread/mutex.hpp +17 -14
  373. data/ext/boost/thread/pthread/once.hpp +3 -4
  374. data/ext/boost/thread/pthread/pthread_mutex_scoped_lock.hpp +12 -2
  375. data/ext/boost/thread/pthread/recursive_mutex.hpp +19 -19
  376. data/ext/boost/thread/pthread/shared_mutex.hpp +13 -13
  377. data/ext/boost/thread/pthread/thread_data.hpp +40 -12
  378. data/ext/boost/thread/thread_time.hpp +5 -0
  379. data/ext/boost/throw_exception.hpp +1 -1
  380. data/ext/boost/token_functions.hpp +34 -10
  381. data/ext/boost/type_traits/add_rvalue_reference.hpp +66 -0
  382. data/ext/boost/type_traits/alignment_of.hpp +1 -1
  383. data/ext/boost/type_traits/detail/bool_trait_def.hpp +26 -3
  384. data/ext/boost/type_traits/detail/bool_trait_undef.hpp +3 -2
  385. data/ext/boost/type_traits/detail/cv_traits_impl.hpp +1 -1
  386. data/ext/boost/type_traits/detail/size_t_trait_def.hpp +6 -4
  387. data/ext/boost/type_traits/detail/type_trait_def.hpp +8 -2
  388. data/ext/boost/type_traits/function_traits.hpp +1 -1
  389. data/ext/boost/type_traits/has_nothrow_constructor.hpp +53 -0
  390. data/ext/boost/type_traits/has_nothrow_copy.hpp +19 -5
  391. data/ext/boost/type_traits/has_trivial_constructor.hpp +51 -0
  392. data/ext/boost/type_traits/has_trivial_copy.hpp +20 -5
  393. data/ext/boost/type_traits/has_trivial_destructor.hpp +12 -5
  394. data/ext/boost/type_traits/intrinsics.hpp +119 -71
  395. data/ext/boost/type_traits/is_const.hpp +5 -5
  396. data/ext/boost/type_traits/is_convertible.hpp +14 -13
  397. data/ext/boost/type_traits/is_enum.hpp +1 -1
  398. data/ext/boost/type_traits/is_floating_point.hpp +27 -0
  399. data/ext/boost/type_traits/is_function.hpp +3 -3
  400. data/ext/boost/type_traits/is_fundamental.hpp +1 -1
  401. data/ext/boost/type_traits/is_member_function_pointer.hpp +2 -2
  402. data/ext/boost/type_traits/is_member_pointer.hpp +2 -2
  403. data/ext/boost/type_traits/is_pod.hpp +11 -3
  404. data/ext/boost/type_traits/is_pointer.hpp +2 -2
  405. data/ext/boost/type_traits/is_signed.hpp +8 -3
  406. data/ext/boost/type_traits/is_union.hpp +8 -0
  407. data/ext/boost/type_traits/is_unsigned.hpp +9 -4
  408. data/ext/boost/type_traits/is_volatile.hpp +5 -5
  409. data/ext/boost/type_traits/remove_cv.hpp +4 -3
  410. data/ext/boost/type_traits/remove_pointer.hpp +51 -2
  411. data/ext/boost/type_traits/remove_reference.hpp +2 -2
  412. data/ext/boost/type_traits/type_with_alignment.hpp +8 -2
  413. data/ext/boost/utility/declval.hpp +44 -0
  414. data/ext/boost/utility/detail/in_place_factory_prefix.hpp +36 -0
  415. data/ext/boost/utility/detail/in_place_factory_suffix.hpp +23 -0
  416. data/ext/boost/utility/detail/result_of_iterate.hpp +142 -0
  417. data/ext/boost/utility/in_place_factory.hpp +88 -0
  418. data/ext/boost/utility/result_of.hpp +103 -0
  419. data/ext/boost/utility/swap.hpp +55 -0
  420. data/ext/common/AnsiColorConstants.h +36 -0
  421. data/ext/common/ApplicationPool2/Common.h +87 -0
  422. data/ext/common/ApplicationPool2/ComponentInfo.h +53 -0
  423. data/ext/common/ApplicationPool2/Group.h +648 -0
  424. data/ext/common/ApplicationPool2/Implementation.cpp +580 -0
  425. data/ext/common/ApplicationPool2/Options.h +576 -0
  426. data/ext/common/ApplicationPool2/PipeWatcher.h +61 -0
  427. data/ext/common/ApplicationPool2/Pool.h +1181 -0
  428. data/ext/common/ApplicationPool2/Process.h +425 -0
  429. data/ext/common/ApplicationPool2/README.md +96 -0
  430. data/ext/common/ApplicationPool2/Session.h +158 -0
  431. data/ext/common/ApplicationPool2/Socket.h +246 -0
  432. data/ext/common/ApplicationPool2/Spawner.h +2212 -0
  433. data/ext/common/ApplicationPool2/SuperGroup.h +749 -0
  434. data/ext/common/BackgroundEventLoop.cpp +129 -0
  435. data/ext/common/BackgroundEventLoop.h +61 -0
  436. data/ext/common/Constants.h +3 -1
  437. data/ext/common/EventedBufferedInput.h +331 -0
  438. data/ext/common/EventedMessageServer.h +17 -34
  439. data/ext/common/EventedServer.h +2 -2
  440. data/ext/common/Exceptions.h +71 -19
  441. data/ext/common/FileDescriptor.h +8 -6
  442. data/ext/common/HttpConstants.h +167 -0
  443. data/ext/common/IniFile.h +24 -0
  444. data/ext/common/Logging.h +62 -849
  445. data/ext/common/MessageReadersWriters.h +19 -0
  446. data/ext/common/MessageServer.h +11 -14
  447. data/ext/common/MultiLibeio.cpp +198 -0
  448. data/ext/common/MultiLibeio.h +67 -0
  449. data/ext/common/ResourceLocator.h +24 -41
  450. data/ext/common/SafeLibev.h +186 -14
  451. data/ext/common/StaticString.h +23 -3
  452. data/ext/common/UnionStation.h +972 -0
  453. data/ext/common/Utils.cpp +168 -24
  454. data/ext/common/Utils.h +25 -3
  455. data/ext/common/Utils/CachedFileStat.hpp +4 -3
  456. data/ext/common/Utils/FileChangeChecker.h +2 -2
  457. data/ext/common/Utils/HashMap.h +50 -0
  458. data/ext/common/Utils/IOUtils.cpp +229 -68
  459. data/ext/common/Utils/IOUtils.h +134 -3
  460. data/ext/common/Utils/Lock.h +28 -0
  461. data/ext/common/Utils/MemoryBarrier.h +52 -0
  462. data/ext/common/Utils/PriorityQueue.h +54 -0
  463. data/ext/common/Utils/ProcessMetricsCollector.h +9 -11
  464. data/ext/common/Utils/ScopeGuard.h +50 -1
  465. data/ext/common/Utils/SmallVector.h +653 -0
  466. data/ext/common/Utils/StrIntUtils.cpp +26 -2
  467. data/ext/common/Utils/StrIntUtils.h +18 -2
  468. data/ext/common/Utils/StringMap.h +125 -8
  469. data/ext/common/Utils/Template.h +212 -0
  470. data/ext/common/Utils/fib.c +699 -0
  471. data/ext/common/Utils/fib.h +101 -0
  472. data/ext/common/Utils/fibpriv.h +67 -0
  473. data/ext/common/Utils/json-forwards.h +249 -0
  474. data/ext/common/Utils/json.h +1855 -0
  475. data/ext/common/Utils/jsoncpp.cpp +4230 -0
  476. data/ext/common/agents/Base.cpp +1126 -0
  477. data/ext/common/{AgentBase.h → agents/Base.h} +5 -1
  478. data/ext/common/agents/EnvPrinter.c +16 -0
  479. data/ext/common/agents/HelperAgent/AgentOptions.h +81 -0
  480. data/ext/common/{HelperAgent → agents/HelperAgent}/BacktracesServer.h +3 -2
  481. data/ext/common/agents/HelperAgent/FileBackedPipe.h +732 -0
  482. data/ext/common/agents/HelperAgent/Main.cpp +497 -0
  483. data/ext/common/agents/HelperAgent/RequestHandler.cpp +283 -0
  484. data/ext/common/agents/HelperAgent/RequestHandler.h +2139 -0
  485. data/ext/common/agents/HelperAgent/ScgiRequestParser.h +451 -0
  486. data/ext/common/{LoggingAgent → agents/LoggingAgent}/DataStoreId.h +1 -1
  487. data/ext/common/{LoggingAgent → agents/LoggingAgent}/FilterSupport.cpp +1 -1
  488. data/ext/common/{LoggingAgent → agents/LoggingAgent}/FilterSupport.h +0 -0
  489. data/ext/common/{LoggingAgent → agents/LoggingAgent}/LoggingServer.h +18 -16
  490. data/ext/common/{LoggingAgent → agents/LoggingAgent}/Main.cpp +15 -13
  491. data/ext/common/{LoggingAgent → agents/LoggingAgent}/RemoteSender.h +6 -6
  492. data/ext/common/agents/SpawnPreparer.cpp +127 -0
  493. data/ext/common/{Watchdog.cpp → agents/Watchdog/Main.cpp} +63 -25
  494. data/ext/libeio/Changes +72 -0
  495. data/ext/{google/COPYING → libeio/LICENSE} +17 -9
  496. data/ext/libeio/Makefile.am +15 -0
  497. data/ext/libeio/Makefile.in +694 -0
  498. data/ext/libeio/aclocal.m4 +9418 -0
  499. data/ext/libeio/autogen.sh +3 -0
  500. data/ext/libeio/config.guess +1501 -0
  501. data/ext/libeio/config.h.in +136 -0
  502. data/ext/libeio/config.sub +1705 -0
  503. data/ext/libeio/configure +14822 -0
  504. data/ext/libeio/configure.ac +22 -0
  505. data/ext/libeio/demo.c +194 -0
  506. data/ext/libeio/ecb.h +457 -0
  507. data/ext/libeio/eio.c +2816 -0
  508. data/ext/libeio/eio.h +411 -0
  509. data/ext/libeio/install-sh +520 -0
  510. data/ext/libeio/libeio.m4 +211 -0
  511. data/ext/libeio/ltmain.sh +9636 -0
  512. data/ext/libeio/missing +376 -0
  513. data/ext/libeio/xthread.h +166 -0
  514. data/ext/libev/Changes +125 -7
  515. data/ext/libev/Makefile.am +5 -3
  516. data/ext/libev/Makefile.in +209 -120
  517. data/ext/libev/aclocal.m4 +6027 -4619
  518. data/ext/libev/autogen.sh +1 -4
  519. data/ext/libev/config.h.in +11 -7
  520. data/ext/libev/configure +7312 -14993
  521. data/ext/libev/configure.ac +12 -5
  522. data/ext/libev/depcomp +630 -0
  523. data/ext/libev/ev++.h +48 -32
  524. data/ext/libev/ev.c +1173 -391
  525. data/ext/libev/ev.h +315 -181
  526. data/ext/libev/ev_epoll.c +66 -15
  527. data/ext/libev/ev_kqueue.c +20 -18
  528. data/ext/libev/ev_poll.c +27 -23
  529. data/ext/libev/ev_port.c +39 -19
  530. data/ext/libev/ev_select.c +23 -17
  531. data/ext/libev/ev_vars.h +25 -8
  532. data/ext/libev/ev_win32.c +6 -6
  533. data/ext/libev/ev_wrap.h +22 -2
  534. data/ext/libev/event.c +18 -17
  535. data/ext/libev/event.h +16 -4
  536. data/ext/libev/libev.m4 +10 -6
  537. data/ext/libev/ltmain.sh +7353 -5811
  538. data/ext/nginx/Configuration.c +74 -42
  539. data/ext/nginx/Configuration.h +3 -5
  540. data/ext/nginx/ContentHandler.c +26 -83
  541. data/ext/nginx/ContentHandler.h +1 -1
  542. data/ext/nginx/config +13 -9
  543. data/ext/nginx/ngx_http_passenger_module.c +3 -7
  544. data/ext/oxt/detail/backtrace_enabled.hpp +5 -102
  545. data/ext/oxt/detail/context.hpp +90 -0
  546. data/ext/oxt/detail/spin_lock_darwin.hpp +4 -0
  547. data/ext/oxt/detail/spin_lock_gcc_x86.hpp +4 -0
  548. data/ext/oxt/detail/spin_lock_pthreads.hpp +14 -0
  549. data/ext/oxt/detail/tracable_exception_enabled.hpp +2 -2
  550. data/ext/oxt/dynamic_thread_group.hpp +27 -1
  551. data/ext/oxt/implementation.cpp +415 -0
  552. data/ext/oxt/{thread.cpp → initialize.hpp} +13 -6
  553. data/ext/oxt/macros.hpp +32 -1
  554. data/ext/oxt/spin_lock.hpp +6 -11
  555. data/ext/oxt/system_calls.cpp +204 -16
  556. data/ext/oxt/system_calls.hpp +85 -45
  557. data/ext/oxt/thread.hpp +13 -117
  558. data/ext/ruby/passenger_native_support.c +82 -237
  559. data/helper-scripts/backtrace-sanitizer.rb +114 -0
  560. data/helper-scripts/classic-rails-loader.rb +135 -0
  561. data/helper-scripts/classic-rails-preloader.rb +161 -0
  562. data/helper-scripts/node-loader.js +314 -0
  563. data/helper-scripts/rack-loader.rb +104 -0
  564. data/helper-scripts/rack-preloader.rb +132 -0
  565. data/helper-scripts/wsgi-loader.py +231 -0
  566. data/helper-scripts/wsgi-preloader.py +1 -0
  567. data/lib/phusion_passenger.rb +159 -61
  568. data/lib/phusion_passenger/abstract_installer.rb +182 -87
  569. data/lib/phusion_passenger/admin_tools/server_instance.rb +25 -19
  570. data/lib/phusion_passenger/analytics_logger.rb +5 -4
  571. data/lib/phusion_passenger/classic_rails/{request_handler.rb → thread_handler_extension.rb} +4 -40
  572. data/lib/phusion_passenger/classic_rails_extensions/init.rb +5 -3
  573. data/lib/phusion_passenger/common_library.rb +441 -0
  574. data/lib/phusion_passenger/console_text_template.rb +4 -16
  575. data/lib/phusion_passenger/constants.rb +1 -8
  576. data/lib/phusion_passenger/debug_logging.rb +5 -2
  577. data/lib/phusion_passenger/dependencies.rb +51 -13
  578. data/lib/phusion_passenger/loader_shared_helpers.rb +318 -0
  579. data/lib/phusion_passenger/message_channel.rb +3 -47
  580. data/lib/phusion_passenger/message_client.rb +2 -2
  581. data/lib/phusion_passenger/native_support.rb +36 -15
  582. data/lib/phusion_passenger/packaging.rb +8 -11
  583. data/lib/phusion_passenger/platform_info.rb +25 -17
  584. data/lib/phusion_passenger/platform_info/apache.rb +10 -7
  585. data/lib/phusion_passenger/platform_info/binary_compatibility.rb +10 -30
  586. data/lib/phusion_passenger/platform_info/compiler.rb +93 -34
  587. data/lib/phusion_passenger/platform_info/ruby.rb +37 -97
  588. data/lib/phusion_passenger/preloader_shared_helpers.rb +121 -0
  589. data/lib/phusion_passenger/public_api.rb +1 -4
  590. data/lib/phusion_passenger/rack/{request_handler.rb → thread_handler_extension.rb} +14 -63
  591. data/lib/phusion_passenger/rails3_extensions/init.rb +9 -8
  592. data/lib/phusion_passenger/request_handler.rb +500 -0
  593. data/lib/phusion_passenger/request_handler/thread_handler.rb +360 -0
  594. data/lib/phusion_passenger/ruby_core_enhancements.rb +142 -0
  595. data/lib/phusion_passenger/standalone/command.rb +36 -15
  596. data/lib/phusion_passenger/standalone/package_runtime_command.rb +16 -8
  597. data/lib/phusion_passenger/standalone/runtime_installer.rb +169 -72
  598. data/lib/phusion_passenger/standalone/start_command.rb +44 -39
  599. data/lib/phusion_passenger/standalone/utils.rb +5 -5
  600. data/lib/phusion_passenger/utils.rb +35 -914
  601. data/lib/phusion_passenger/utils/ansi_colors.rb +59 -0
  602. data/lib/phusion_passenger/utils/file_system_watcher.rb +1 -1
  603. data/lib/phusion_passenger/utils/robust_interruption.rb +134 -0
  604. data/lib/phusion_passenger/utils/tee_input.rb +174 -0
  605. data/lib/phusion_passenger/utils/tmpio.rb +33 -0
  606. data/lib/phusion_passenger/utils/unseekable_socket.rb +6 -0
  607. data/resources/mime.types +5 -1
  608. data/{lib/phusion_passenger/templates → resources}/standalone_default_root/index.html +0 -0
  609. data/{lib/phusion_passenger → resources}/templates/apache2/apache_must_be_compiled_with_compatible_mpm.txt.erb +0 -0
  610. data/{lib/phusion_passenger → resources}/templates/apache2/config_snippets.txt.erb +0 -0
  611. data/{lib/phusion_passenger → resources}/templates/apache2/deployment_example.txt.erb +0 -0
  612. data/{lib/phusion_passenger → resources}/templates/apache2/no_write_permission_to_passenger_root.txt.erb +0 -0
  613. data/{lib/phusion_passenger → resources}/templates/apache2/possible_solutions_for_compilation_and_installation_problems.txt.erb +0 -0
  614. data/{lib/phusion_passenger → resources}/templates/apache2/run_installer_as_root.txt.erb +0 -0
  615. data/{lib/phusion_passenger → resources}/templates/apache2/welcome.txt.erb +0 -0
  616. data/{lib/phusion_passenger → resources}/templates/error_layout.css +6 -0
  617. data/resources/templates/error_layout.html.template +89 -0
  618. data/resources/templates/general_error.html.template +1 -0
  619. data/resources/templates/general_error_with_html.html.template +1 -0
  620. data/{lib/phusion_passenger → resources}/templates/nginx/ask_for_extra_configure_flags.txt.erb +0 -0
  621. data/{lib/phusion_passenger → resources}/templates/nginx/cannot_write_to_dir.txt.erb +0 -0
  622. data/{lib/phusion_passenger → resources}/templates/nginx/config_snippets.txt.erb +0 -0
  623. data/{lib/phusion_passenger → resources}/templates/nginx/config_snippets_inserted.txt.erb +0 -0
  624. data/{lib/phusion_passenger → resources}/templates/nginx/confirm_extra_configure_flags.txt.erb +0 -0
  625. data/{lib/phusion_passenger → resources}/templates/nginx/deployment_example.txt.erb +0 -0
  626. data/resources/templates/nginx/not_available_when_natively_packaged.txt.erb +8 -0
  627. data/{lib/phusion_passenger → resources}/templates/nginx/pcre_could_not_be_downloaded.txt.erb +0 -0
  628. data/{lib/phusion_passenger → resources}/templates/nginx/pcre_could_not_be_extracted.txt.erb +0 -0
  629. data/{lib/phusion_passenger → resources}/templates/nginx/possible_solutions_for_compilation_and_installation_problems.txt.erb +0 -0
  630. data/{lib/phusion_passenger → resources}/templates/nginx/possible_solutions_for_download_and_extraction_problems.txt.erb +0 -0
  631. data/{lib/phusion_passenger → resources}/templates/nginx/query_download_and_install.txt.erb +0 -0
  632. data/{lib/phusion_passenger → resources}/templates/nginx/run_installer_as_root.txt.erb +0 -0
  633. data/{lib/phusion_passenger → resources}/templates/nginx/welcome.txt.erb +0 -0
  634. data/{lib/phusion_passenger → resources}/templates/standalone/cannot_write_to_dir.txt.erb +0 -0
  635. data/{lib/phusion_passenger → resources}/templates/standalone/config.erb +26 -5
  636. data/{lib/phusion_passenger → resources}/templates/standalone/possible_solutions_for_download_and_extraction_problems.txt.erb +0 -0
  637. data/{lib/phusion_passenger → resources}/templates/standalone/run_installer_as_root.txt.erb +0 -0
  638. data/{lib/phusion_passenger → resources}/templates/standalone/welcome.txt.erb +0 -0
  639. data/resources/templates/undisclosed_error.html.template +25 -0
  640. data/test/config.json.example +42 -0
  641. data/test/cxx/ApplicationPool2/DirectSpawnerTest.cpp +86 -0
  642. data/test/cxx/ApplicationPool2/OptionsTest.cpp +44 -0
  643. data/test/cxx/ApplicationPool2/PoolTest.cpp +1234 -0
  644. data/test/cxx/ApplicationPool2/ProcessTest.cpp +131 -0
  645. data/test/cxx/ApplicationPool2/SmartSpawnerTest.cpp +229 -0
  646. data/test/cxx/ApplicationPool2/SpawnerTestCases.cpp +744 -0
  647. data/test/cxx/BufferedIOTest.cpp +7 -7
  648. data/test/cxx/CxxTestMain.cpp +65 -2
  649. data/test/cxx/FileBackedPipeTest.cpp +626 -0
  650. data/test/cxx/FileChangeCheckerTest.cpp +20 -18
  651. data/test/cxx/FilterSupportTest.cpp +5 -5
  652. data/test/cxx/IOUtilsTest.cpp +11 -4
  653. data/test/cxx/MessageReadersWritersTest.cpp +1 -1
  654. data/test/cxx/MessageServerTest.cpp +31 -30
  655. data/test/cxx/RequestHandlerTest.cpp +777 -0
  656. data/test/cxx/ScgiRequestParserTest.cpp +36 -16
  657. data/test/cxx/ServerInstanceDirTest.cpp +1 -1
  658. data/test/cxx/StringMapTest.cpp +61 -0
  659. data/test/cxx/TemplateTest.cpp +118 -0
  660. data/test/cxx/TestSupport.cpp +25 -68
  661. data/test/cxx/TestSupport.h +81 -41
  662. data/test/cxx/{LoggingTest.cpp → UnionStationTest.cpp} +79 -74
  663. data/test/cxx/UtilsTest.cpp +59 -5
  664. data/test/integration_tests/apache2_tests.rb +2 -2
  665. data/test/integration_tests/nginx_tests.rb +1 -1
  666. data/test/integration_tests/spec_helper.rb +7 -5
  667. data/test/oxt/oxt_test_main.cpp +2 -0
  668. data/test/oxt/syscall_interruption_test.cpp +1 -0
  669. data/test/ruby/classic_rails/loader_spec.rb +48 -0
  670. data/test/ruby/classic_rails/preloader_spec.rb +54 -0
  671. data/test/ruby/rack/loader_spec.rb +62 -0
  672. data/test/ruby/rack/preloader_spec.rb +74 -0
  673. data/test/ruby/{abstract_request_handler_spec.rb → request_handler_spec.rb} +31 -68
  674. data/test/ruby/shared/loader_spec.rb +241 -0
  675. data/test/ruby/shared/rails/analytics_logging_extensions_spec.rb +141 -182
  676. data/test/ruby/shared/ruby_loader_spec.rb +55 -0
  677. data/test/ruby/spec_helper.rb +8 -53
  678. data/test/ruby/utils/file_system_watcher_spec.rb +9 -1
  679. data/test/ruby/utils_spec.rb +10 -683
  680. data/test/stub/rack/config.ru +28 -3
  681. data/test/stub/rack/start.rb +47 -0
  682. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/Rakefile +0 -0
  683. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/controllers/application_controller.rb +0 -2
  684. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/controllers/bar_controller_1.rb +0 -0
  685. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/controllers/bar_controller_2.rb +0 -0
  686. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/controllers/foo_controller.rb +0 -0
  687. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/app/helpers/application_helper.rb +0 -0
  688. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/boot.rb +0 -0
  689. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/database.yml +3 -3
  690. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/environment.rb +5 -2
  691. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/environments/development.rb +0 -0
  692. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/environments/production.rb +0 -0
  693. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/environments/staging.rb +0 -0
  694. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/initializers/inflections.rb +0 -0
  695. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/initializers/mime_types.rb +0 -0
  696. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/config/routes.rb +1 -0
  697. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/about +0 -0
  698. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/console +0 -0
  699. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/dbconsole +0 -0
  700. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/destroy +0 -0
  701. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/generate +0 -0
  702. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/performance/benchmarker +0 -0
  703. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/performance/profiler +0 -0
  704. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/performance/request +0 -0
  705. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/plugin +0 -0
  706. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/process/inspector +0 -0
  707. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/process/reaper +0 -0
  708. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/process/spawner +0 -0
  709. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/runner +0 -0
  710. data/test/stub/{rails_apps/2.3/foobar → rails2.3}/script/server +0 -0
  711. data/test/stub/{rails_apps/3.0/empty → rails3.0}/Gemfile +0 -0
  712. data/test/stub/rails3.0/Gemfile.lock +80 -0
  713. data/test/stub/{rails_apps/3.0/empty → rails3.0}/Rakefile +0 -0
  714. data/test/stub/{rails_apps/3.0/empty → rails3.0}/app/controllers/application_controller.rb +0 -0
  715. data/test/stub/{rails_apps/3.0/empty → rails3.0}/app/helpers/application_helper.rb +0 -0
  716. data/test/stub/{rails_apps/3.0/empty → rails3.0}/app/views/layouts/application.html.erb +0 -0
  717. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config.ru +0 -0
  718. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/application.rb +0 -0
  719. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/boot.rb +0 -0
  720. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/database.yml +0 -0
  721. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/environment.rb +0 -0
  722. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/environments/development.rb +0 -0
  723. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/environments/production.rb +0 -0
  724. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/environments/test.rb +0 -0
  725. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/backtrace_silencers.rb +0 -0
  726. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/inflections.rb +0 -0
  727. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/mime_types.rb +0 -0
  728. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/passenger.rb +0 -0
  729. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/secret_token.rb +0 -0
  730. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/initializers/session_store.rb +0 -0
  731. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/locales/en.yml +0 -0
  732. data/test/stub/{rails_apps/3.0/empty → rails3.0}/config/routes.rb +0 -0
  733. data/test/stub/{rails_apps/3.0/empty → rails3.0}/db/seeds.rb +0 -0
  734. data/test/stub/{rails_apps/3.0/empty → rails3.0}/doc/README_FOR_APP +0 -0
  735. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/404.html +0 -0
  736. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/422.html +0 -0
  737. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/500.html +0 -0
  738. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/favicon.ico +0 -0
  739. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/index.html +0 -0
  740. data/test/stub/{rails_apps/3.0/empty → rails3.0}/public/robots.txt +0 -0
  741. data/test/stub/{rails_apps/3.0/empty → rails3.0}/script/rails +0 -0
  742. data/test/stub/{rails_apps/3.0/empty → rails3.0}/test/performance/browsing_test.rb +0 -0
  743. data/test/stub/{rails_apps/3.0/empty → rails3.0}/test/test_helper.rb +0 -0
  744. data/test/stub/start_error.pl +24 -0
  745. data/test/stub/wsgi/passenger_wsgi.py +71 -3
  746. data/test/support/apache2_controller.rb +2 -2
  747. data/test/support/placebo-preloader.rb +88 -0
  748. data/test/support/test_helper.rb +1 -14
  749. data/test/tut/tut.h +11 -4
  750. metadata +590 -326
  751. data.tar.gz.asc +0 -12
  752. data/PACKAGING.TXT +0 -25
  753. data/build/config.rb +0 -46
  754. data/ext/apache2/HelperAgent.cpp +0 -364
  755. data/ext/boost/call_traits.hpp +0 -24
  756. data/ext/boost/detail/call_traits.hpp +0 -164
  757. data/ext/common/AbstractSpawnManager.h +0 -110
  758. data/ext/common/AgentBase.cpp +0 -432
  759. data/ext/common/ApplicationPool/Client.h +0 -788
  760. data/ext/common/ApplicationPool/Interface.h +0 -295
  761. data/ext/common/ApplicationPool/Pool.h +0 -1327
  762. data/ext/common/ApplicationPool/Server.h +0 -479
  763. data/ext/common/MessageChannel.h +0 -494
  764. data/ext/common/PoolOptions.h +0 -518
  765. data/ext/common/Process.h +0 -253
  766. data/ext/common/Session.h +0 -436
  767. data/ext/common/SpawnManager.h +0 -611
  768. data/ext/google/ChangeLog +0 -167
  769. data/ext/google/dense_hash_map +0 -310
  770. data/ext/google/dense_hash_set +0 -287
  771. data/ext/google/sparse_hash_map +0 -294
  772. data/ext/google/sparse_hash_set +0 -275
  773. data/ext/google/sparsehash/densehashtable.h +0 -1062
  774. data/ext/google/sparsehash/sparseconfig.h +0 -55
  775. data/ext/google/sparsehash/sparsehashtable.h +0 -1015
  776. data/ext/google/sparsetable +0 -1468
  777. data/ext/google/type_traits.h +0 -250
  778. data/ext/nginx/HelperAgent.cpp +0 -1355
  779. data/ext/nginx/ScgiRequestParser.h +0 -375
  780. data/ext/oxt/backtrace.cpp +0 -185
  781. data/ext/oxt/tracable_exception.cpp +0 -89
  782. data/helper-scripts/passenger-spawn-server +0 -106
  783. data/lib/phusion_passenger/abstract_request_handler.rb +0 -766
  784. data/lib/phusion_passenger/abstract_server.rb +0 -372
  785. data/lib/phusion_passenger/abstract_server_collection.rb +0 -335
  786. data/lib/phusion_passenger/app_process.rb +0 -174
  787. data/lib/phusion_passenger/classic_rails/application_spawner.rb +0 -344
  788. data/lib/phusion_passenger/classic_rails/framework_spawner.rb +0 -311
  789. data/lib/phusion_passenger/exceptions.rb +0 -103
  790. data/lib/phusion_passenger/html_template.rb +0 -107
  791. data/lib/phusion_passenger/rack/application_spawner.rb +0 -231
  792. data/lib/phusion_passenger/spawn_manager.rb +0 -359
  793. data/lib/phusion_passenger/templates/app_exited_during_initialization.html.erb +0 -38
  794. data/lib/phusion_passenger/templates/app_init_error.html.erb +0 -64
  795. data/lib/phusion_passenger/templates/database_error.html.erb +0 -66
  796. data/lib/phusion_passenger/templates/error_layout.html.erb +0 -39
  797. data/lib/phusion_passenger/templates/framework_init_error.html.erb +0 -39
  798. data/lib/phusion_passenger/templates/general_error.html.erb +0 -22
  799. data/lib/phusion_passenger/templates/load_error.html.erb +0 -46
  800. data/lib/phusion_passenger/templates/version_not_found.html.erb +0 -34
  801. data/lib/phusion_passenger/utils/rewindable_input.rb +0 -125
  802. data/lib/phusion_passenger/wsgi/application_spawner.rb +0 -108
  803. data/test/config.yml.example +0 -41
  804. data/test/cxx/ApplicationPool_PoolTest.cpp +0 -33
  805. data/test/cxx/ApplicationPool_PoolTestCases.cpp +0 -1029
  806. data/test/cxx/ApplicationPool_ServerTest.cpp +0 -308
  807. data/test/cxx/ApplicationPool_Server_PoolTest.cpp +0 -80
  808. data/test/cxx/MessageChannelTest.cpp +0 -557
  809. data/test/cxx/PoolOptionsTest.cpp +0 -116
  810. data/test/cxx/SpawnManagerTest.cpp +0 -161
  811. data/test/ruby/abstract_server_collection_spec.rb +0 -247
  812. data/test/ruby/abstract_server_spec.rb +0 -61
  813. data/test/ruby/app_process_spec.rb +0 -43
  814. data/test/ruby/classic_rails/application_spawner_spec.rb +0 -89
  815. data/test/ruby/classic_rails/framework_spawner_spec.rb +0 -92
  816. data/test/ruby/rack/application_spawner_spec.rb +0 -116
  817. data/test/ruby/shared/abstract_server_spec.rb +0 -23
  818. data/test/ruby/shared/spawners/classic_rails/framework_spawner_spec.rb +0 -38
  819. data/test/ruby/shared/spawners/classic_rails/lack_of_rails_gem_version_spec.rb +0 -19
  820. data/test/ruby/shared/spawners/classic_rails/spawner_spec.rb +0 -15
  821. data/test/ruby/shared/spawners/non_preloading_spawner_spec.rb +0 -27
  822. data/test/ruby/shared/spawners/preloading_spawner_spec.rb +0 -29
  823. data/test/ruby/shared/spawners/reload_all_spec.rb +0 -36
  824. data/test/ruby/shared/spawners/reload_single_spec.rb +0 -52
  825. data/test/ruby/shared/spawners/spawn_server_spec.rb +0 -28
  826. data/test/ruby/shared/spawners/spawner_spec.rb +0 -273
  827. data/test/ruby/shared/utils/pseudo_io_spec.rb +0 -60
  828. data/test/ruby/spawn_manager_spec.rb +0 -134
  829. data/test/ruby/wsgi/application_spawner_spec.rb +0 -50
  830. data/test/stub/message_channel.rb +0 -11
  831. data/test/stub/message_channel_2.rb +0 -12
  832. data/test/stub/message_channel_3.rb +0 -19
  833. data/test/stub/rails_apps/3.0/empty/Gemfile.lock +0 -73
  834. data/test/stub/spawn_server.rb +0 -22
  835. metadata.gz.asc +0 -12
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * Phusion Passenger - http://www.modrails.com/
3
- * Copyright (c) 2010 Phusion
3
+ * Copyright (c) 2010, 2011, 2012 Phusion
4
4
  *
5
5
  * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6
6
  *
@@ -41,6 +41,7 @@
41
41
  #include <limits.h>
42
42
  #include <unistd.h>
43
43
  #include <signal.h>
44
+ #include <vector>
44
45
  #include <FileDescriptor.h>
45
46
  #include <MessageServer.h>
46
47
  #include <ResourceLocator.h>
@@ -236,7 +237,7 @@ canonicalizePath(const string &path) {
236
237
  }
237
238
 
238
239
  string
239
- resolveSymlink(const string &path) {
240
+ resolveSymlink(const StaticString &path) {
240
241
  char buf[PATH_MAX];
241
242
  ssize_t size;
242
243
 
@@ -247,7 +248,7 @@ resolveSymlink(const string &path) {
247
248
  } else {
248
249
  int e = errno;
249
250
  string message = "Cannot resolve possible symlink '";
250
- message.append(path);
251
+ message.append(path.c_str(), path.size());
251
252
  message.append("'");
252
253
  throw FileSystemException(message, e, path);
253
254
  }
@@ -255,7 +256,7 @@ resolveSymlink(const string &path) {
255
256
  buf[size] = '\0';
256
257
  if (buf[0] == '\0') {
257
258
  string message = "The file '";
258
- message.append(path);
259
+ message.append(path.c_str(), path.size());
259
260
  message.append("' is a symlink, and it refers to an empty filename. This is not allowed.");
260
261
  throw FileSystemException(message, ENOENT, path);
261
262
  } else if (buf[0] == '/') {
@@ -439,6 +440,63 @@ parseModeString(const StaticString &mode) {
439
440
  return modeBits;
440
441
  }
441
442
 
443
+ string
444
+ absolutizePath(const StaticString &path, const StaticString &workingDir) {
445
+ vector<string> components;
446
+ if (!startsWith(path, "/")) {
447
+ if (workingDir.empty()) {
448
+ char buffer[PATH_MAX];
449
+ getcwd(buffer, sizeof(buffer));
450
+ split(buffer + 1, '/', components);
451
+ } else {
452
+ string absoluteWorkingDir = absolutizePath(workingDir);
453
+ split(StaticString(absoluteWorkingDir.data() + 1, absoluteWorkingDir.size() - 1),
454
+ '/', components);
455
+ }
456
+ }
457
+
458
+ const char *begin = path.data();
459
+ const char *end = path.data() + path.size();
460
+
461
+ // Skip leading slashes.
462
+ while (begin < end && *begin == '/') {
463
+ begin++;
464
+ }
465
+
466
+ while (begin < end) {
467
+ const char *next = (const char *) memchr(begin, '/', end - begin);
468
+ if (next == NULL) {
469
+ next = end;
470
+ }
471
+
472
+ StaticString component(begin, next - begin);
473
+ if (component == "..") {
474
+ if (!components.empty()) {
475
+ components.pop_back();
476
+ }
477
+ } else if (component != ".") {
478
+ components.push_back(component);
479
+ }
480
+
481
+ // Skip slashes until beginning of next path component.
482
+ begin = next + 1;
483
+ while (begin < end && *begin == '/') {
484
+ begin++;
485
+ }
486
+ }
487
+
488
+ string result;
489
+ vector<string>::const_iterator c_it, c_end = components.end();
490
+ for (c_it = components.begin(); c_it != c_end; c_it++) {
491
+ result.append("/");
492
+ result.append(*c_it);
493
+ }
494
+ if (result.empty()) {
495
+ result = "/";
496
+ }
497
+ return result;
498
+ }
499
+
442
500
  const char *
443
501
  getSystemTempDir() {
444
502
  const char *temp_dir = getenv("PASSENGER_TEMP_DIR");
@@ -528,27 +586,54 @@ makeDirTree(const string &path, const StaticString &mode, uid_t owner, gid_t gro
528
586
 
529
587
  void
530
588
  removeDirTree(const string &path) {
531
- char command[PATH_MAX + 30];
532
- int result;
533
-
534
- snprintf(command, sizeof(command), "chmod -R u+rwx \"%s\" 2>/dev/null", path.c_str());
535
- command[sizeof(command) - 1] = '\0';
536
- do {
537
- result = ::system(command);
538
- } while (result == -1 && errno == EINTR);
539
-
540
- snprintf(command, sizeof(command), "rm -rf \"%s\"", path.c_str());
541
- command[sizeof(command) - 1] = '\0';
542
- do {
543
- result = ::system(command);
544
- } while (result == -1 && errno == EINTR);
545
- if (result == -1) {
546
- char message[1024];
589
+ this_thread::disable_interruption di;
590
+ this_thread::disable_syscall_interruption dsi;
591
+ const char *c_path = path.c_str();
592
+ pid_t pid;
593
+
594
+ pid = syscalls::fork();
595
+ if (pid == 0) {
596
+ resetSignalHandlersAndMask();
597
+ disableMallocDebugging();
598
+ int devnull = open("/dev/null", O_RDONLY);
599
+ if (devnull != -1) {
600
+ dup2(devnull, 2);
601
+ }
602
+ closeAllFileDescriptors(2);
603
+ execlp("chmod", "chmod", "-R", "u+rwx", c_path, (char * const) 0);
604
+ perror("Cannot execute chmod");
605
+ _exit(1);
606
+
607
+ } else if (pid == -1) {
547
608
  int e = errno;
548
-
549
- snprintf(message, sizeof(message) - 1, "Cannot remove directory '%s'", path.c_str());
550
- message[sizeof(message) - 1] = '\0';
551
- throw FileSystemException(message, e, path);
609
+ throw SystemException("Cannot fork a new process", e);
610
+
611
+ } else {
612
+ this_thread::restore_interruption ri(di);
613
+ this_thread::restore_syscall_interruption rsi(dsi);
614
+ syscalls::waitpid(pid, NULL, 0);
615
+ }
616
+
617
+ pid = syscalls::fork();
618
+ if (pid == 0) {
619
+ resetSignalHandlersAndMask();
620
+ disableMallocDebugging();
621
+ closeAllFileDescriptors(2);
622
+ execlp("rm", "rm", "-rf", c_path, (char * const) 0);
623
+ perror("Cannot execute rm");
624
+ _exit(1);
625
+
626
+ } else if (pid == -1) {
627
+ int e = errno;
628
+ throw SystemException("Cannot fork a new process", e);
629
+
630
+ } else {
631
+ this_thread::restore_interruption ri(di);
632
+ this_thread::restore_syscall_interruption rsi(dsi);
633
+ int status;
634
+ if (syscalls::waitpid(pid, &status, 0) == -1 || status != 0) {
635
+ throw RuntimeException("Cannot remove directory '" + path + "'");
636
+ }
552
637
  }
553
638
  }
554
639
 
@@ -765,6 +850,65 @@ resetSignalHandlersAndMask() {
765
850
  sigaction(SIGUSR2, &action, NULL);
766
851
  }
767
852
 
853
+ void
854
+ disableMallocDebugging() {
855
+ unsetenv("MALLOC_FILL_SPACE");
856
+ unsetenv("MALLOC_PROTECT_BEFORE");
857
+ unsetenv("MallocGuardEdges");
858
+ unsetenv("MallocScribble");
859
+ unsetenv("MallocPreScribble");
860
+ unsetenv("MallocCheckHeapStart");
861
+ unsetenv("MallocCheckHeapEach");
862
+ unsetenv("MallocCheckHeapAbort");
863
+ unsetenv("MallocBadFreeAbort");
864
+ unsetenv("MALLOC_CHECK_");
865
+
866
+ const char *libs = getenv("DYLD_INSERT_LIBRARIES");
867
+ if (libs != NULL && strstr(libs, "/usr/lib/libgmalloc.dylib")) {
868
+ string newLibs = libs;
869
+ string::size_type pos = newLibs.find("/usr/lib/libgmalloc.dylib");
870
+ size_t len = strlen("/usr/lib/libgmalloc.dylib");
871
+
872
+ // Erase all leading ':' too.
873
+ while (pos > 0 && newLibs[pos - 1] == ':') {
874
+ pos--;
875
+ len++;
876
+ }
877
+ // Erase all trailing ':' too.
878
+ while (pos + len < newLibs.size() && newLibs[pos + len] == ':') {
879
+ len++;
880
+ }
881
+
882
+ newLibs.erase(pos, len);
883
+ if (newLibs.empty()) {
884
+ unsetenv("DYLD_INSERT_LIBRARIES");
885
+ } else {
886
+ setenv("DYLD_INSERT_LIBRARIES", newLibs.c_str(), 1);
887
+ }
888
+ }
889
+ }
890
+
891
+ int
892
+ runShellCommand(const StaticString &command) {
893
+ pid_t pid = fork();
894
+ if (pid == 0) {
895
+ resetSignalHandlersAndMask();
896
+ disableMallocDebugging();
897
+ closeAllFileDescriptors(2);
898
+ execlp("/bin/sh", "/bin/sh", "-c", command.data(), (char * const) 0);
899
+ _exit(1);
900
+ } else if (pid == -1) {
901
+ return -1;
902
+ } else {
903
+ int status;
904
+ if (waitpid(pid, &status, 0) == -1) {
905
+ return -1;
906
+ } else {
907
+ return status;
908
+ }
909
+ }
910
+ }
911
+
768
912
  // Async-signal safe way to get the current process's hard file descriptor limit.
769
913
  static int
770
914
  getFileDescriptorLimit() {
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * Phusion Passenger - http://www.modrails.com/
3
- * Copyright (c) 2010 Phusion
3
+ * Copyright (c) 2010, 2011, 2012 Phusion
4
4
  *
5
5
  * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6
6
  *
@@ -160,13 +160,16 @@ string canonicalizePath(const string &path);
160
160
  * If <em>path</em> doesn't refer to a symlink then this method will return
161
161
  * <em>path</em>.
162
162
  *
163
+ * <em>path</em> MUST be null-terminated!
164
+ *
163
165
  * @throws FileSystemException Something went wrong.
164
166
  * @ingroup Support
165
167
  */
166
- string resolveSymlink(const string &path);
168
+ string resolveSymlink(const StaticString &path);
167
169
 
168
170
  /**
169
171
  * Given a path, extracts its directory name.
172
+ * <em>path</em> MUST be null-terminated!
170
173
  *
171
174
  * @ingroup Support
172
175
  */
@@ -174,6 +177,7 @@ string extractDirName(const StaticString &path);
174
177
 
175
178
  /**
176
179
  * Given a path, extracts its base name.
180
+ * <em>path</em> MUST be null-terminated!
177
181
  *
178
182
  * @ingroup Support
179
183
  */
@@ -216,6 +220,12 @@ string getProcessUsername();
216
220
  */
217
221
  mode_t parseModeString(const StaticString &mode);
218
222
 
223
+ /**
224
+ * Turns the given path into an absolute path. Unlike realpath(), this function does
225
+ * not resolve symlinks.
226
+ */
227
+ string absolutizePath(const StaticString &path, const StaticString &workingDir = "");
228
+
219
229
  /**
220
230
  * Return the path name for the directory in which the system stores general
221
231
  * temporary files. This is usually "/tmp", but might be something else depending
@@ -297,7 +307,7 @@ void makeDirTree(const string &path, const StaticString &mode = "u=rwx,g=,o=",
297
307
  * Remove an entire directory tree recursively. If the directory doesn't exist then this
298
308
  * function does nothing.
299
309
  *
300
- * @throws FileSystemException Something went wrong.
310
+ * @throws RuntimeException Something went wrong.
301
311
  */
302
312
  void removeDirTree(const string &path);
303
313
 
@@ -376,6 +386,18 @@ string getSignalName(int sig);
376
386
  */
377
387
  void resetSignalHandlersAndMask();
378
388
 
389
+ /**
390
+ * Disables malloc() debugging facilities on OS X.
391
+ */
392
+ void disableMallocDebugging();
393
+
394
+ /**
395
+ * Like system(), but properly resets the signal handler mask,
396
+ * disables malloc debugging and closes file descriptors > 2.
397
+ * _command_ must be null-terminated.
398
+ */
399
+ int runShellCommand(const StaticString &command);
400
+
379
401
  /**
380
402
  * Close all file descriptors that are higher than <em>lastToKeepOpen</em>.
381
403
  * This function is async-signal safe. But make sure there are no other
@@ -37,6 +37,8 @@
37
37
  #include <oxt/system_calls.hpp>
38
38
 
39
39
  #include "SystemTime.h"
40
+ #include "StaticString.h"
41
+ #include "Utils/HashMap.h"
40
42
 
41
43
  namespace Passenger {
42
44
 
@@ -139,7 +141,7 @@ public:
139
141
 
140
142
  typedef shared_ptr<Entry> EntryPtr;
141
143
  typedef list<EntryPtr> EntryList;
142
- typedef map<string, EntryList::iterator> EntryMap;
144
+ typedef HashMap<string, EntryList::iterator, StaticString::Hash> EntryMap;
143
145
 
144
146
  unsigned int maxSize;
145
147
  EntryList entries;
@@ -200,8 +202,7 @@ public:
200
202
  entry = *it->second;
201
203
 
202
204
  // Mark this cache item as most recently used.
203
- entries.erase(it->second);
204
- entries.push_front(entry);
205
+ entries.splice(entries.begin(), entries, it->second);
205
206
  cache[filename] = entries.begin();
206
207
  }
207
208
  ret = entry->refresh(throttleRate);
@@ -162,7 +162,7 @@ public:
162
162
  } else {
163
163
  // The file's information was already in the file list.
164
164
  if (ret == -1 && errno == ENOENT) {
165
- result = entry->lastMtime != 0 || entry->lastCtime != 0;
165
+ result = false;
166
166
  entry->lastMtime = 0;
167
167
  entry->lastCtime = 0;
168
168
  } else if (ret == -1) {
@@ -175,7 +175,7 @@ public:
175
175
  return result;
176
176
  }
177
177
  }
178
-
178
+
179
179
  /**
180
180
  * Change the maximum size of the internal file list.
181
181
  *
@@ -0,0 +1,50 @@
1
+ /*
2
+ * Phusion Passenger - http://www.modrails.com/
3
+ * Copyright (c) 2010 Phusion
4
+ *
5
+ * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
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
+
26
+ #ifndef _PASSENGER_HASH_MAP_H_
27
+ #define _PASSENGER_HASH_MAP_H_
28
+
29
+ /*
30
+ * There are too many ways to include hash_map/unordered_map!
31
+ * This header autodetects the correct method.
32
+ */
33
+ #if defined(HAS_TR1_UNORDERED_MAP)
34
+ #include <tr1/unordered_map>
35
+ #define HashMap std::tr1::unordered_map
36
+ #elif defined(HASH_NAMESPACE) && defined(HASH_MAP_HEADER)
37
+ #include HASH_MAP_HEADER
38
+ #define HashMap HASH_NAMESPACE::hash_map
39
+ #elif defined(__GNUC__)
40
+ #include <ext/hash_map>
41
+ #define HashMap __gnu_cxx::hash_map
42
+ #elif defined(_MSC_VER)
43
+ #include <hash_map>
44
+ #define HashMap stdext::hash_map
45
+ #else
46
+ #include <tr/unordered_map>
47
+ #define HashMap std::tr1::unordered_map;
48
+ #endif
49
+
50
+ #endif /* _PASSENGER_HASH_MAP_H_ */
@@ -43,20 +43,31 @@
43
43
  #include <netdb.h>
44
44
  #include <unistd.h>
45
45
  #include <fcntl.h>
46
- #include <limits.h>
46
+ #include <limits.h> // Also for __GLIBC__ macro.
47
+ #include <cstdio>
47
48
  #include <cstdlib>
48
49
  #include <cstring>
49
50
  #include <cerrno>
50
51
  #include <cmath>
51
52
 
52
53
  #ifdef __linux__
54
+ // For accept4 macros
53
55
  #include <sys/syscall.h>
56
+ #include <linux/net.h>
54
57
  #endif
55
58
 
56
- #include "Timer.h"
57
- #include "IOUtils.h"
58
- #include "StrIntUtils.h"
59
- #include "../Exceptions.h"
59
+ #if defined(__APPLE__)
60
+ #define HAVE_FPURGE
61
+ #elif defined(__GLIBC__)
62
+ #include <stdio_ext.h>
63
+ #define HAVE___FPURGE
64
+ #endif
65
+
66
+ #include <Exceptions.h>
67
+ #include <Utils/Timer.h>
68
+ #include <Utils/IOUtils.h>
69
+ #include <Utils/StrIntUtils.h>
70
+ #include <Utils/ScopeGuard.h>
60
71
 
61
72
  namespace Passenger {
62
73
 
@@ -74,6 +85,19 @@ using namespace oxt;
74
85
  static WritevFunction writevFunction = syscalls::writev;
75
86
 
76
87
 
88
+ bool
89
+ purgeStdio(FILE *f) {
90
+ #if defined(HAVE_FPURGE)
91
+ fpurge(f);
92
+ return true;
93
+ #elif defined(HAVE___FPURGE)
94
+ __fpurge(f);
95
+ return true;
96
+ #else
97
+ return false;
98
+ #endif
99
+ }
100
+
77
101
  ServerAddressType
78
102
  getSocketAddressType(const StaticString &address) {
79
103
  const char *data = address.c_str();
@@ -155,24 +179,17 @@ setNonBlocking(int fd) {
155
179
  }
156
180
 
157
181
  int
158
- tryAccept4(int sock, struct sockaddr *addr, socklen_t *addr_len, int options) {
159
- #if defined(__linux__) && defined(__x86_64__)
160
- int ret;
161
- do {
162
- ret = syscall(288, sock, addr, addr_len, options);
163
- } while (ret == -1 && errno == EINTR);
164
- return ret;
165
- #elif defined(__linux__) && defined(__i386__)
182
+ callAccept4(int sock, struct sockaddr *addr, socklen_t *addr_len, int options) {
183
+ #if defined(__NR_accept4) || defined(SYS_ACCEPT4)
166
184
  int ret;
167
185
  do {
168
- ret = syscall(__NR_socketcall, 18,
169
- sock, addr, addr_len, options);
186
+ ret = ::accept4(sock, addr, addr_len, options);
170
187
  } while (ret == -1 && errno == EINTR);
171
188
  return ret;
172
- #elif defined(SYS_ACCEPT4)
189
+ #elif defined(__linux__) && defined(__x86_64__)
173
190
  int ret;
174
191
  do {
175
- ret = ::accept4(sock, addr, addr_len, options);
192
+ ret = syscall(288, sock, addr, addr_len, options);
176
193
  } while (ret == -1 && errno == EINTR);
177
194
  return ret;
178
195
  #else
@@ -252,6 +269,7 @@ createUnixServer(const StaticString &filename, unsigned int backlogSize, bool au
252
269
  throw SystemException("Cannot create a Unix socket file descriptor", e);
253
270
  }
254
271
 
272
+ FdGuard guard(fd, true);
255
273
  addr.sun_family = AF_LOCAL;
256
274
  strncpy(addr.sun_path, filename.c_str(), filename.size());
257
275
  addr.sun_path[filename.size()] = '\0';
@@ -262,30 +280,19 @@ createUnixServer(const StaticString &filename, unsigned int backlogSize, bool au
262
280
  } while (ret == -1 && errno == EINTR);
263
281
  }
264
282
 
265
- try {
266
- ret = syscalls::bind(fd, (const struct sockaddr *) &addr, sizeof(addr));
267
- } catch (...) {
268
- safelyClose(fd, true);
269
- throw;
270
- }
283
+ ret = syscalls::bind(fd, (const struct sockaddr *) &addr, sizeof(addr));
271
284
  if (ret == -1) {
272
285
  int e = errno;
273
286
  string message = "Cannot bind Unix socket '";
274
287
  message.append(filename.toString());
275
288
  message.append("'");
276
- safelyClose(fd, true);
277
289
  throw SystemException(message, e);
278
290
  }
279
291
 
280
292
  if (backlogSize == 0) {
281
293
  backlogSize = 1024;
282
294
  }
283
- try {
284
- ret = syscalls::listen(fd, backlogSize);
285
- } catch (...) {
286
- safelyClose(fd, true);
287
- throw;
288
- }
295
+ ret = syscalls::listen(fd, backlogSize);
289
296
  if (ret == -1) {
290
297
  int e = errno;
291
298
  string message = "Cannot listen on Unix socket '";
@@ -295,6 +302,7 @@ createUnixServer(const StaticString &filename, unsigned int backlogSize, bool au
295
302
  throw SystemException(message, e);
296
303
  }
297
304
 
305
+ guard.clear();
298
306
  return fd;
299
307
  }
300
308
 
@@ -326,53 +334,40 @@ createTcpServer(const char *address, unsigned short port, unsigned int backlogSi
326
334
  throw SystemException("Cannot create a TCP socket file descriptor", e);
327
335
  }
328
336
 
329
- try {
330
- ret = syscalls::bind(fd, (const struct sockaddr *) &addr, sizeof(addr));
331
- } catch (...) {
332
- safelyClose(fd, true);
333
- throw;
334
- }
337
+ FdGuard guard(fd, true);
338
+ ret = syscalls::bind(fd, (const struct sockaddr *) &addr, sizeof(addr));
335
339
  if (ret == -1) {
336
340
  int e = errno;
337
341
  string message = "Cannot bind a TCP socket on address '";
338
342
  message.append(address);
339
343
  message.append("' port ");
340
344
  message.append(toString(port));
341
- safelyClose(fd, true);
342
345
  throw SystemException(message, e);
343
346
  }
344
347
 
345
348
  optval = 1;
346
- try {
347
- if (syscalls::setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
348
- &optval, sizeof(optval)) == -1) {
349
- printf("so_reuseaddr failed: %s\n", strerror(errno));
350
- }
351
- } catch (...) {
352
- safelyClose(fd, true);
353
- throw;
349
+ if (syscalls::setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
350
+ &optval, sizeof(optval)) == -1)
351
+ {
352
+ int e = errno;
353
+ fprintf(stderr, "so_reuseaddr failed: %s\n", strerror(e));
354
354
  }
355
- // Ignore SO_REUSEPORT error, it's not fatal.
355
+ // Ignore SO_REUSEADDR error, it's not fatal.
356
356
 
357
357
  if (backlogSize == 0) {
358
358
  backlogSize = 1024;
359
359
  }
360
- try {
361
- ret = syscalls::listen(fd, backlogSize);
362
- } catch (...) {
363
- safelyClose(fd, true);
364
- throw;
365
- }
360
+ ret = syscalls::listen(fd, backlogSize);
366
361
  if (ret == -1) {
367
362
  int e = errno;
368
363
  string message = "Cannot listen on TCP socket '";
369
364
  message.append(address);
370
365
  message.append("' port ");
371
366
  message.append(toString(port));
372
- safelyClose(fd, true);
373
367
  throw SystemException(message, e);
374
368
  }
375
369
 
370
+ guard.clear();
376
371
  return fd;
377
372
  }
378
373
 
@@ -396,22 +391,23 @@ connectToServer(const StaticString &address) {
396
391
 
397
392
  int
398
393
  connectToUnixServer(const StaticString &filename) {
399
- int fd, ret;
394
+ int fd = syscalls::socket(PF_UNIX, SOCK_STREAM, 0);
395
+ if (fd == -1) {
396
+ int e = errno;
397
+ throw SystemException("Cannot create a Unix socket file descriptor", e);
398
+ }
399
+
400
+ FdGuard guard(fd, true);
401
+ int ret;
400
402
  struct sockaddr_un addr;
401
403
 
402
404
  if (filename.size() > sizeof(addr.sun_path) - 1) {
403
405
  string message = "Cannot connect to Unix socket '";
404
- message.append(filename.toString());
406
+ message.append(filename.data(), filename.size());
405
407
  message.append("': filename is too long.");
406
408
  throw RuntimeException(message);
407
409
  }
408
410
 
409
- fd = syscalls::socket(PF_UNIX, SOCK_STREAM, 0);
410
- if (fd == -1) {
411
- int e = errno;
412
- throw SystemException("Cannot create a Unix socket file descriptor", e);
413
- }
414
-
415
411
  addr.sun_family = AF_UNIX;
416
412
  memcpy(addr.sun_path, filename.c_str(), filename.size());
417
413
  addr.sun_path[filename.size()] = '\0';
@@ -419,12 +415,7 @@ connectToUnixServer(const StaticString &filename) {
419
415
  bool retry = true;
420
416
  int counter = 0;
421
417
  while (retry) {
422
- try {
423
- ret = syscalls::connect(fd, (const sockaddr *) &addr, sizeof(addr));
424
- } catch (...) {
425
- safelyClose(fd, true);
426
- throw;
427
- }
418
+ ret = syscalls::connect(fd, (const sockaddr *) &addr, sizeof(addr));
428
419
  if (ret == -1) {
429
420
  #if defined(sun) || defined(__sun)
430
421
  /* Solaris has this nice kernel bug where connecting to
@@ -446,10 +437,10 @@ connectToUnixServer(const StaticString &filename) {
446
437
  string message("Cannot connect to Unix socket '");
447
438
  message.append(filename.toString());
448
439
  message.append("'");
449
- safelyClose(fd, true);
450
440
  throw SystemException(message, e);
451
441
  }
452
442
  } else {
443
+ guard.clear();
453
444
  return fd;
454
445
  }
455
446
  }
@@ -457,6 +448,51 @@ connectToUnixServer(const StaticString &filename) {
457
448
  return -1; // Shut up compiler warning.
458
449
  }
459
450
 
451
+ void
452
+ setupNonBlockingUnixSocket(NUnix_State &state, const StaticString &filename) {
453
+ state.fd = syscalls::socket(PF_UNIX, SOCK_STREAM, 0);
454
+ if (state.fd == -1) {
455
+ int e = errno;
456
+ throw SystemException("Cannot create a Unix socket file descriptor", e);
457
+ }
458
+
459
+ state.filename = filename;
460
+ setNonBlocking(state.fd);
461
+ }
462
+
463
+ bool
464
+ connectToUnixServer(NUnix_State &state) {
465
+ struct sockaddr_un addr;
466
+ int ret;
467
+
468
+ if (state.filename.size() > sizeof(addr.sun_path) - 1) {
469
+ string message = "Cannot connect to Unix socket '";
470
+ message.append(state.filename.data(), state.filename.size());
471
+ message.append("': filename is too long.");
472
+ throw RuntimeException(message);
473
+ }
474
+
475
+ addr.sun_family = AF_UNIX;
476
+ memcpy(addr.sun_path, state.filename.data(), state.filename.size());
477
+ addr.sun_path[state.filename.size()] = '\0';
478
+
479
+ ret = syscalls::connect(state.fd, (const sockaddr *) &addr, sizeof(addr));
480
+ if (ret == -1) {
481
+ if (errno == EINPROGRESS || errno == EWOULDBLOCK) {
482
+ return false;
483
+ } else if (errno == EISCONN) {
484
+ return true;
485
+ } else {
486
+ int e = errno;
487
+ string message = "Cannot connect to Unix socket '";
488
+ message.append(state.filename.data(), state.filename.size());
489
+ throw SystemException(message, e);
490
+ }
491
+ } else {
492
+ return true;
493
+ }
494
+ }
495
+
460
496
  int
461
497
  connectToTcpServer(const StaticString &hostname, unsigned int port) {
462
498
  struct addrinfo hints, *res;
@@ -510,6 +546,97 @@ connectToTcpServer(const StaticString &hostname, unsigned int port) {
510
546
  return fd;
511
547
  }
512
548
 
549
+ void
550
+ setupNonBlockingTcpSocket(NTCP_State &state, const StaticString &hostname, int port) {
551
+ int ret;
552
+
553
+ memset(&state.hints, 0, sizeof(state.hints));
554
+ state.hints.ai_family = PF_UNSPEC;
555
+ state.hints.ai_socktype = SOCK_STREAM;
556
+ ret = getaddrinfo(hostname.toString().c_str(), toString(port).c_str(),
557
+ &state.hints, &state.res);
558
+ if (ret != 0) {
559
+ string message = "Cannot resolve IP address '";
560
+ message.append(hostname.data(), hostname.size());
561
+ message.append(":");
562
+ message.append(toString(port));
563
+ message.append("': ");
564
+ message.append(gai_strerror(ret));
565
+ throw IOException(message);
566
+ }
567
+
568
+ state.fd = syscalls::socket(PF_INET, SOCK_STREAM, 0);
569
+ if (state.fd == -1) {
570
+ int e = errno;
571
+ throw SystemException("Cannot create a TCP socket file descriptor", e);
572
+ }
573
+
574
+ state.hostname = hostname;
575
+ state.port = port;
576
+ setNonBlocking(state.fd);
577
+ }
578
+
579
+ bool
580
+ connectToTcpServer(NTCP_State &state) {
581
+ int ret;
582
+
583
+ ret = syscalls::connect(state.fd, state.res->ai_addr, state.res->ai_addrlen);
584
+ if (ret == -1) {
585
+ if (errno == EINPROGRESS || errno == EWOULDBLOCK) {
586
+ return false;
587
+ } else if (errno == EISCONN) {
588
+ freeaddrinfo(state.res);
589
+ state.res = NULL;
590
+ return true;
591
+ } else {
592
+ int e = errno;
593
+ string message = "Cannot connect to TCP socket '";
594
+ message.append(state.hostname);
595
+ message.append(":");
596
+ message.append(toString(state.port));
597
+ message.append("'");
598
+ throw SystemException(message, e);
599
+ }
600
+ } else {
601
+ freeaddrinfo(state.res);
602
+ state.res = NULL;
603
+ return true;
604
+ }
605
+ }
606
+
607
+ void
608
+ setupNonBlockingSocket(NConnect_State &state, const StaticString &address) {
609
+ TRACE_POINT();
610
+ state.type = getSocketAddressType(address);
611
+ switch (state.type) {
612
+ case SAT_UNIX:
613
+ setupNonBlockingUnixSocket(state.s_unix, parseUnixSocketAddress(address));
614
+ break;
615
+ case SAT_TCP: {
616
+ string host;
617
+ unsigned short port;
618
+
619
+ parseTcpSocketAddress(address, host, port);
620
+ setupNonBlockingTcpSocket(state.s_tcp, host, port);
621
+ break;
622
+ }
623
+ default:
624
+ throw ArgumentException(string("Unknown address type for '") + address + "'");
625
+ }
626
+ }
627
+
628
+ bool
629
+ connectToServer(NConnect_State &state) {
630
+ switch (state.type) {
631
+ case SAT_UNIX:
632
+ return connectToUnixServer(state.s_unix);
633
+ case SAT_TCP:
634
+ return connectToTcpServer(state.s_tcp);
635
+ default:
636
+ throw RuntimeException("Unknown address type");
637
+ }
638
+ }
639
+
513
640
  SocketPair
514
641
  createUnixSocketPair() {
515
642
  int fds[2];
@@ -996,5 +1123,39 @@ safelyClose(int fd, bool ignoreErrors) {
996
1123
  }
997
1124
  }
998
1125
 
1126
+ string
1127
+ readAll(const string &filename) {
1128
+ FILE *f = fopen(filename.c_str(), "rb");
1129
+ if (f != NULL) {
1130
+ StdioGuard guard(f);
1131
+ return readAll(fileno(f));
1132
+ } else {
1133
+ int e = errno;
1134
+ throw FileSystemException("Cannot open '" + filename + "' for reading",
1135
+ e, filename);
1136
+ }
1137
+ }
1138
+
1139
+ string
1140
+ readAll(int fd) {
1141
+ string result;
1142
+ char buf[1024 * 32];
1143
+ ssize_t ret;
1144
+ while (true) {
1145
+ do {
1146
+ ret = read(fd, buf, sizeof(buf));
1147
+ } while (ret == -1 && errno == EINTR);
1148
+ if (ret == 0) {
1149
+ break;
1150
+ } else if (ret == -1) {
1151
+ int e = errno;
1152
+ throw SystemException("Cannot read from file descriptor", e);
1153
+ } else {
1154
+ result.append(buf, ret);
1155
+ }
1156
+ }
1157
+ return result;
1158
+ }
1159
+
999
1160
 
1000
1161
  } // namespace Passenger