passenger 2.0.6 → 2.1.2

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 (497) hide show
  1. data/DEVELOPERS.TXT +10 -4
  2. data/LICENSE +1 -1
  3. data/NEWS +0 -0
  4. data/Rakefile +183 -117
  5. data/benchmark/dispatcher.rb +5 -9
  6. data/bin/passenger-install-apache2-module +52 -18
  7. data/bin/passenger-memory-stats +67 -13
  8. data/bin/passenger-spawn-server +8 -4
  9. data/bin/passenger-status +21 -46
  10. data/bin/passenger-stress-test +5 -5
  11. data/debian/postinst +1 -1
  12. data/doc/ApplicationPool algorithm.txt +180 -128
  13. data/doc/Architectural overview.html +1 -778
  14. data/doc/Security of user switching support.html +1 -643
  15. data/doc/Users guide Apache.html +3127 -0
  16. data/doc/Users guide Nginx.html +1458 -0
  17. data/doc/Users guide.html +1404 -467
  18. data/doc/Users guide.txt +843 -105
  19. data/doc/cxxapi/ApplicationPoolServer_8h-source.html +751 -641
  20. data/doc/cxxapi/ApplicationPool_8h-source.html +168 -171
  21. data/doc/cxxapi/Application_8h-source.html +494 -394
  22. data/doc/cxxapi/Bucket_8h-source.html +21 -15
  23. data/doc/cxxapi/CachedFileStat_8h-source.html +191 -0
  24. data/doc/cxxapi/Configuration_8h-source.html +311 -149
  25. data/doc/cxxapi/DirectoryMapper_8h-source.html +309 -0
  26. data/doc/cxxapi/DummySpawnManager_8h-source.html +3 -4
  27. data/doc/cxxapi/Exceptions_8h-source.html +182 -165
  28. data/doc/cxxapi/FileChecker_8h-source.html +130 -0
  29. data/doc/cxxapi/Hooks_8h-source.html +2 -3
  30. data/doc/cxxapi/Logging_8h-source.html +92 -89
  31. data/doc/cxxapi/MessageChannel_8h-source.html +585 -477
  32. data/doc/cxxapi/PoolOptions_8h-source.html +305 -0
  33. data/doc/cxxapi/SpawnManager_8h-source.html +515 -540
  34. data/doc/cxxapi/StandardApplicationPool_8h-source.html +779 -679
  35. data/doc/cxxapi/SystemTime_8h-source.html +104 -0
  36. data/doc/cxxapi/Utils_8h-source.html +331 -227
  37. data/doc/cxxapi/annotated.html +6 -7
  38. data/doc/cxxapi/classClient-members.html +1 -2
  39. data/doc/cxxapi/classClient.html +1 -2
  40. data/doc/cxxapi/classHooks-members.html +5 -2
  41. data/doc/cxxapi/classHooks.html +112 -2
  42. data/doc/cxxapi/classPassenger_1_1Application-members.html +2 -3
  43. data/doc/cxxapi/classPassenger_1_1Application.html +8 -9
  44. data/doc/cxxapi/classPassenger_1_1ApplicationPool-members.html +4 -4
  45. data/doc/cxxapi/classPassenger_1_1ApplicationPool.html +42 -81
  46. data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer-members.html +1 -2
  47. data/doc/cxxapi/classPassenger_1_1ApplicationPoolServer.html +3 -4
  48. data/doc/cxxapi/classPassenger_1_1ApplicationPool__inherit__graph.png +0 -0
  49. data/doc/cxxapi/classPassenger_1_1Application_1_1Session-members.html +3 -2
  50. data/doc/cxxapi/classPassenger_1_1Application_1_1Session.html +74 -3
  51. data/doc/cxxapi/classPassenger_1_1BusyException-members.html +1 -2
  52. data/doc/cxxapi/classPassenger_1_1BusyException.html +2 -3
  53. data/doc/cxxapi/classPassenger_1_1ConfigurationException-members.html +1 -2
  54. data/doc/cxxapi/classPassenger_1_1ConfigurationException.html +2 -3
  55. data/doc/cxxapi/classPassenger_1_1DirectoryMapper-members.html +38 -0
  56. data/doc/cxxapi/classPassenger_1_1DirectoryMapper.html +256 -0
  57. data/doc/cxxapi/classPassenger_1_1DummySpawnManager-members.html +1 -2
  58. data/doc/cxxapi/classPassenger_1_1DummySpawnManager.html +2 -3
  59. data/doc/cxxapi/{classPassenger_1_1Thread-members.html → classPassenger_1_1FileChecker-members.html} +4 -5
  60. data/doc/cxxapi/classPassenger_1_1FileChecker.html +121 -0
  61. data/doc/cxxapi/classPassenger_1_1FileNotFoundException-members.html +1 -2
  62. data/doc/cxxapi/classPassenger_1_1FileNotFoundException.html +2 -3
  63. data/doc/cxxapi/classPassenger_1_1FileNotFoundException__inherit__graph.png +0 -0
  64. data/doc/cxxapi/classPassenger_1_1FileSystemException-members.html +2 -3
  65. data/doc/cxxapi/classPassenger_1_1FileSystemException.html +2 -3
  66. data/doc/cxxapi/classPassenger_1_1FileSystemException__inherit__graph.png +0 -0
  67. data/doc/cxxapi/classPassenger_1_1IOException-members.html +1 -2
  68. data/doc/cxxapi/classPassenger_1_1IOException.html +2 -3
  69. data/doc/cxxapi/classPassenger_1_1IOException__inherit__graph.png +0 -0
  70. data/doc/cxxapi/classPassenger_1_1MessageChannel-members.html +5 -2
  71. data/doc/cxxapi/classPassenger_1_1MessageChannel.html +155 -5
  72. data/doc/cxxapi/{classboost_1_1this__thread_1_1enable__syscall__interruption-members.html → classPassenger_1_1RuntimeException-members.html} +2 -3
  73. data/doc/cxxapi/{classboost_1_1this__thread_1_1enable__syscall__interruption.html → classPassenger_1_1RuntimeException.html} +10 -8
  74. data/doc/cxxapi/classPassenger_1_1SpawnException-members.html +1 -2
  75. data/doc/cxxapi/classPassenger_1_1SpawnException.html +2 -3
  76. data/doc/cxxapi/classPassenger_1_1SpawnManager-members.html +2 -3
  77. data/doc/cxxapi/classPassenger_1_1SpawnManager.html +15 -56
  78. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool-members.html +5 -4
  79. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool.html +20 -81
  80. data/doc/cxxapi/classPassenger_1_1StandardApplicationPool__inherit__graph.png +0 -0
  81. data/doc/cxxapi/classPassenger_1_1SystemException-members.html +2 -3
  82. data/doc/cxxapi/classPassenger_1_1SystemException.html +9 -10
  83. data/doc/cxxapi/classPassenger_1_1SystemException__inherit__graph.png +0 -0
  84. data/doc/cxxapi/{classboost_1_1this__thread_1_1disable__syscall__interruption-members.html → classPassenger_1_1SystemTime-members.html} +5 -3
  85. data/doc/cxxapi/classPassenger_1_1SystemTime.html +86 -0
  86. data/doc/cxxapi/classPassenger_1_1TempFile-members.html +2 -3
  87. data/doc/cxxapi/classPassenger_1_1TempFile.html +17 -9
  88. data/doc/cxxapi/definitions_8h-source.html +1 -2
  89. data/doc/cxxapi/files.html +6 -3
  90. data/doc/cxxapi/functions.html +98 -35
  91. data/doc/cxxapi/functions_func.html +60 -32
  92. data/doc/cxxapi/functions_type.html +1 -2
  93. data/doc/cxxapi/functions_vars.html +27 -2
  94. data/doc/cxxapi/graph_legend.html +1 -2
  95. data/doc/cxxapi/graph_legend.png +0 -0
  96. data/doc/cxxapi/group__Configuration.html +3 -4
  97. data/doc/cxxapi/group__Configuration.png +0 -0
  98. data/doc/cxxapi/group__Core.html +3 -4
  99. data/doc/cxxapi/group__Core.png +0 -0
  100. data/doc/cxxapi/group__Exceptions.html +4 -2
  101. data/doc/cxxapi/group__Hooks.html +1 -6
  102. data/doc/cxxapi/group__Hooks.png +0 -0
  103. data/doc/cxxapi/group__Support.html +259 -36
  104. data/doc/cxxapi/hierarchy.html +6 -7
  105. data/doc/cxxapi/inherit__graph__0.map +1 -1
  106. data/doc/cxxapi/inherit__graph__0.md5 +1 -1
  107. data/doc/cxxapi/inherit__graph__0.png +0 -0
  108. data/doc/cxxapi/inherit__graph__1.map +1 -1
  109. data/doc/cxxapi/inherit__graph__1.md5 +1 -1
  110. data/doc/cxxapi/inherit__graph__1.png +0 -0
  111. data/doc/cxxapi/inherit__graph__10.map +1 -1
  112. data/doc/cxxapi/inherit__graph__10.md5 +1 -1
  113. data/doc/cxxapi/inherit__graph__10.png +0 -0
  114. data/doc/cxxapi/inherit__graph__11.map +1 -1
  115. data/doc/cxxapi/inherit__graph__11.md5 +1 -1
  116. data/doc/cxxapi/inherit__graph__11.png +0 -0
  117. data/doc/cxxapi/inherit__graph__12.map +2 -1
  118. data/doc/cxxapi/inherit__graph__12.md5 +1 -1
  119. data/doc/cxxapi/inherit__graph__12.png +0 -0
  120. data/doc/cxxapi/inherit__graph__13.map +1 -1
  121. data/doc/cxxapi/inherit__graph__13.md5 +1 -1
  122. data/doc/cxxapi/inherit__graph__13.png +0 -0
  123. data/doc/cxxapi/inherit__graph__14.map +1 -2
  124. data/doc/cxxapi/inherit__graph__14.md5 +1 -1
  125. data/doc/cxxapi/inherit__graph__14.png +0 -0
  126. data/doc/cxxapi/inherit__graph__15.map +1 -1
  127. data/doc/cxxapi/inherit__graph__15.md5 +1 -1
  128. data/doc/cxxapi/inherit__graph__15.png +0 -0
  129. data/doc/cxxapi/inherit__graph__16.map +1 -1
  130. data/doc/cxxapi/inherit__graph__16.md5 +1 -1
  131. data/doc/cxxapi/inherit__graph__16.png +0 -0
  132. data/doc/cxxapi/inherit__graph__17.png +0 -0
  133. data/doc/cxxapi/inherit__graph__18.png +0 -0
  134. data/doc/cxxapi/inherit__graph__19.png +0 -0
  135. data/doc/cxxapi/inherit__graph__2.map +1 -1
  136. data/doc/cxxapi/inherit__graph__2.md5 +1 -1
  137. data/doc/cxxapi/inherit__graph__2.png +0 -0
  138. data/doc/cxxapi/inherit__graph__20.map +1 -1
  139. data/doc/cxxapi/inherit__graph__20.md5 +1 -1
  140. data/doc/cxxapi/inherit__graph__20.png +0 -0
  141. data/doc/cxxapi/inherit__graph__21.map +1 -1
  142. data/doc/cxxapi/inherit__graph__21.md5 +1 -1
  143. data/doc/cxxapi/inherit__graph__21.png +0 -0
  144. data/doc/cxxapi/inherit__graph__3.map +1 -1
  145. data/doc/cxxapi/inherit__graph__3.md5 +1 -1
  146. data/doc/cxxapi/inherit__graph__3.png +0 -0
  147. data/doc/cxxapi/inherit__graph__4.map +1 -1
  148. data/doc/cxxapi/inherit__graph__4.md5 +1 -1
  149. data/doc/cxxapi/inherit__graph__4.png +0 -0
  150. data/doc/cxxapi/inherit__graph__5.map +2 -1
  151. data/doc/cxxapi/inherit__graph__5.md5 +1 -1
  152. data/doc/cxxapi/inherit__graph__5.png +0 -0
  153. data/doc/cxxapi/inherit__graph__6.map +1 -1
  154. data/doc/cxxapi/inherit__graph__6.md5 +1 -1
  155. data/doc/cxxapi/inherit__graph__6.png +0 -0
  156. data/doc/cxxapi/inherit__graph__7.map +1 -1
  157. data/doc/cxxapi/inherit__graph__7.md5 +1 -1
  158. data/doc/cxxapi/inherit__graph__7.png +0 -0
  159. data/doc/cxxapi/inherit__graph__8.map +1 -1
  160. data/doc/cxxapi/inherit__graph__8.md5 +1 -1
  161. data/doc/cxxapi/inherit__graph__8.png +0 -0
  162. data/doc/cxxapi/inherit__graph__9.map +1 -2
  163. data/doc/cxxapi/inherit__graph__9.md5 +1 -1
  164. data/doc/cxxapi/inherit__graph__9.png +0 -0
  165. data/doc/cxxapi/inherits.html +30 -31
  166. data/doc/cxxapi/main.html +1 -2
  167. data/doc/cxxapi/modules.html +1 -2
  168. data/doc/cxxapi/structPassenger_1_1AnythingToString-members.html +1 -2
  169. data/doc/cxxapi/structPassenger_1_1AnythingToString.html +2 -3
  170. data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4-members.html +1 -2
  171. data/doc/cxxapi/structPassenger_1_1AnythingToString_3_01vector_3_01string_01_4_01_4.html +2 -3
  172. data/doc/cxxapi/structPassenger_1_1PoolOptions-members.html +49 -0
  173. data/doc/cxxapi/structPassenger_1_1PoolOptions.html +404 -0
  174. data/doc/cxxapi/tree.html +18 -20
  175. data/doc/images/conservative_spawning.png +0 -0
  176. data/doc/images/conservative_spawning.svg +248 -0
  177. data/doc/images/smart-lv2.png +0 -0
  178. data/doc/images/smart-lv2.svg +320 -0
  179. data/doc/rdoc/classes/ConditionVariable.html +68 -34
  180. data/doc/rdoc/classes/Exception.html +16 -16
  181. data/doc/rdoc/classes/GC.html +9 -9
  182. data/doc/rdoc/classes/IO.html +36 -17
  183. data/doc/rdoc/classes/PhusionPassenger.html +183 -0
  184. data/doc/rdoc/classes/PhusionPassenger/AbstractRequestHandler.html +511 -0
  185. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer.html +285 -242
  186. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer/ServerAlreadyStarted.html +3 -3
  187. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer/ServerError.html +3 -3
  188. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer/ServerNotStarted.html +3 -3
  189. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AbstractServer/UnknownMessage.html +3 -3
  190. data/doc/rdoc/classes/PhusionPassenger/AbstractServerCollection.html +598 -0
  191. data/doc/rdoc/classes/PhusionPassenger/AdminTools.html +140 -0
  192. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess.html +247 -0
  193. data/doc/rdoc/classes/PhusionPassenger/AdminTools/ControlProcess/Instance.html +138 -0
  194. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/AppInitError.html +36 -19
  195. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/Application.html +81 -96
  196. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/ConsoleTextTemplate.html +18 -18
  197. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/FrameworkInitError.html +20 -18
  198. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/HTMLTemplate.html +18 -18
  199. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/InitializationError.html +9 -9
  200. data/doc/rdoc/classes/PhusionPassenger/InvalidPath.html +92 -0
  201. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/MessageChannel.html +93 -92
  202. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/NativeSupport.html +55 -25
  203. data/doc/rdoc/classes/PhusionPassenger/Rack.html +91 -0
  204. data/doc/rdoc/classes/PhusionPassenger/Rack/ApplicationSpawner.html +185 -0
  205. data/doc/rdoc/classes/PhusionPassenger/Rack/RequestHandler.html +182 -0
  206. data/doc/rdoc/classes/PhusionPassenger/Railz.html +95 -0
  207. data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner.html +424 -0
  208. data/doc/rdoc/classes/PhusionPassenger/Railz/ApplicationSpawner/Error.html +98 -0
  209. data/doc/rdoc/classes/PhusionPassenger/Railz/CGIFixed.html +200 -0
  210. data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner.html +444 -0
  211. data/doc/rdoc/classes/PhusionPassenger/Railz/FrameworkSpawner/Error.html +98 -0
  212. data/doc/rdoc/classes/PhusionPassenger/Railz/RequestHandler.html +154 -0
  213. data/doc/rdoc/classes/PhusionPassenger/SpawnManager.html +408 -0
  214. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/UnknownError.html +13 -13
  215. data/doc/rdoc/classes/PhusionPassenger/Utils.html +687 -0
  216. data/doc/rdoc/classes/{Passenger → PhusionPassenger}/VersionNotFound.html +8 -8
  217. data/doc/rdoc/classes/PhusionPassenger/WSGI.html +89 -0
  218. data/doc/rdoc/classes/PhusionPassenger/WSGI/ApplicationSpawner.html +188 -0
  219. data/doc/rdoc/classes/PlatformInfo.html +663 -159
  220. data/doc/rdoc/classes/RakeExtensions.html +4 -4
  221. data/doc/rdoc/classes/Signal.html +134 -0
  222. data/doc/rdoc/created.rid +1 -1
  223. data/doc/rdoc/files/DEVELOPERS_TXT.html +15 -10
  224. data/doc/rdoc/files/README.html +5 -7
  225. data/doc/rdoc/files/ext/{passenger → phusion_passenger}/native_support_c.html +2 -2
  226. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/abstract_request_handler_rb.html +7 -9
  227. data/doc/rdoc/files/lib/phusion_passenger/abstract_server_collection_rb.html +120 -0
  228. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/abstract_server_rb.html +7 -10
  229. data/doc/rdoc/files/lib/phusion_passenger/admin_tools/control_process_rb.html +99 -0
  230. data/doc/rdoc/files/lib/phusion_passenger/admin_tools_rb.html +92 -0
  231. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/application_rb.html +6 -8
  232. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/console_text_template_rb.html +5 -7
  233. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/constants_rb.html +4 -5
  234. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/dependencies_rb.html +6 -8
  235. data/doc/rdoc/files/lib/phusion_passenger/events_rb.html +116 -0
  236. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/exceptions_rb.html +5 -7
  237. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/html_template_rb.html +5 -7
  238. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/message_channel_rb.html +5 -7
  239. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/platform_info_rb.html +6 -7
  240. data/doc/rdoc/files/lib/phusion_passenger/rack/application_spawner_rb.html +123 -0
  241. data/doc/rdoc/files/lib/phusion_passenger/rack/request_handler_rb.html +117 -0
  242. data/doc/rdoc/files/lib/{passenger/utils_rb.html → phusion_passenger/railz/application_spawner_rb.html} +24 -17
  243. data/doc/rdoc/files/lib/phusion_passenger/railz/cgi_fixed_rb.html +126 -0
  244. data/doc/rdoc/files/lib/phusion_passenger/railz/framework_spawner_rb.html +139 -0
  245. data/doc/rdoc/files/lib/phusion_passenger/railz/request_handler_rb.html +118 -0
  246. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/simple_benchmarking_rb.html +5 -7
  247. data/doc/rdoc/files/lib/{passenger → phusion_passenger}/spawn_manager_rb.html +40 -24
  248. data/doc/rdoc/files/lib/phusion_passenger/utils_rb.html +169 -0
  249. data/doc/rdoc/files/lib/phusion_passenger/wsgi/application_spawner_rb.html +120 -0
  250. data/doc/rdoc/files/lib/rake/extensions_rb.html +3 -4
  251. data/doc/rdoc/fr_class_index.html +37 -19
  252. data/doc/rdoc/fr_file_index.html +25 -14
  253. data/doc/rdoc/fr_method_index.html +145 -74
  254. data/ext/apache2/Application.h +145 -44
  255. data/ext/apache2/ApplicationPool.h +27 -29
  256. data/ext/apache2/ApplicationPoolServer.h +183 -72
  257. data/ext/apache2/ApplicationPoolServerExecutable.cpp +249 -42
  258. data/ext/apache2/Bucket.cpp +61 -9
  259. data/ext/apache2/Bucket.h +15 -8
  260. data/ext/apache2/CachedFileStat.cpp +114 -0
  261. data/ext/apache2/CachedFileStat.h +169 -0
  262. data/ext/apache2/Configuration.cpp +213 -22
  263. data/ext/apache2/Configuration.h +176 -13
  264. data/ext/apache2/DirectoryMapper.h +287 -0
  265. data/ext/apache2/Exceptions.h +30 -12
  266. data/ext/apache2/FileChecker.h +108 -0
  267. data/ext/apache2/Hooks.cpp +709 -493
  268. data/ext/apache2/LICENSE-CNRI.TXT +15 -0
  269. data/ext/apache2/Logging.h +26 -22
  270. data/ext/apache2/MessageChannel.h +124 -15
  271. data/ext/apache2/PoolOptions.h +283 -0
  272. data/ext/apache2/SpawnManager.h +75 -99
  273. data/ext/apache2/StandardApplicationPool.h +296 -195
  274. data/ext/apache2/SystemTime.cpp +28 -0
  275. data/ext/apache2/SystemTime.h +82 -0
  276. data/ext/apache2/Utils.cpp +172 -18
  277. data/ext/apache2/Utils.h +124 -19
  278. data/ext/boost/cstdint.hpp +4 -2
  279. data/ext/boost/current_function.hpp +67 -0
  280. data/ext/boost/detail/sp_counted_base.hpp +4 -4
  281. data/ext/boost/thread/exceptions.hpp +2 -1
  282. data/ext/boost/thread/pthread/thread.hpp +11 -3
  283. data/ext/boost/thread/pthread/thread_data.hpp +2 -1
  284. data/ext/oxt/backtrace.cpp +172 -0
  285. data/ext/oxt/backtrace.hpp +135 -0
  286. data/ext/oxt/detail/backtrace_disabled.hpp +39 -0
  287. data/ext/oxt/detail/backtrace_enabled.hpp +155 -0
  288. data/ext/oxt/detail/spin_lock_gcc_x86.hpp +82 -0
  289. data/ext/oxt/detail/spin_lock_portable.hpp +38 -0
  290. data/ext/oxt/detail/spin_lock_pthreads.hpp +97 -0
  291. data/ext/oxt/detail/tracable_exception_disabled.hpp +46 -0
  292. data/ext/oxt/detail/tracable_exception_enabled.hpp +48 -0
  293. data/ext/oxt/macros.hpp +58 -0
  294. data/ext/oxt/spin_lock.hpp +55 -0
  295. data/ext/{apache2/System.cpp → oxt/system_calls.cpp} +87 -52
  296. data/ext/oxt/system_calls.hpp +234 -0
  297. data/ext/oxt/thread.cpp +32 -0
  298. data/ext/oxt/thread.hpp +223 -0
  299. data/ext/oxt/tracable_exception.cpp +87 -0
  300. data/ext/oxt/tracable_exception.hpp +35 -0
  301. data/{lib/passenger/constants.rb → ext/phusion_passenger/extconf.rb} +14 -9
  302. data/ext/{passenger → phusion_passenger}/native_support.c +33 -6
  303. data/lib/{passenger → phusion_passenger}/abstract_request_handler.rb +209 -93
  304. data/lib/{passenger → phusion_passenger}/abstract_server.rb +23 -8
  305. data/lib/phusion_passenger/abstract_server_collection.rb +301 -0
  306. data/lib/phusion_passenger/admin_tools.rb +25 -0
  307. data/lib/phusion_passenger/admin_tools/control_process.rb +107 -0
  308. data/lib/{passenger → phusion_passenger}/application.rb +13 -16
  309. data/lib/{passenger → phusion_passenger}/console_text_template.rb +2 -2
  310. data/{ext/passenger/extconf.rb → lib/phusion_passenger/constants.rb} +5 -5
  311. data/lib/{passenger → phusion_passenger}/dependencies.rb +38 -32
  312. data/lib/phusion_passenger/events.rb +45 -0
  313. data/lib/{passenger → phusion_passenger}/exceptions.rb +12 -5
  314. data/lib/{passenger → phusion_passenger}/html_template.rb +2 -2
  315. data/lib/{passenger → phusion_passenger}/message_channel.rb +3 -2
  316. data/lib/phusion_passenger/platform_info.rb +500 -0
  317. data/lib/{passenger → phusion_passenger}/rack/application_spawner.rb +29 -22
  318. data/lib/{passenger → phusion_passenger}/rack/request_handler.rb +14 -9
  319. data/lib/{passenger → phusion_passenger}/railz/application_spawner.rb +94 -74
  320. data/lib/{passenger → phusion_passenger}/railz/cgi_fixed.rb +2 -2
  321. data/lib/{passenger → phusion_passenger}/railz/framework_spawner.rb +86 -98
  322. data/lib/{passenger → phusion_passenger}/railz/request_handler.rb +6 -6
  323. data/lib/{passenger → phusion_passenger}/simple_benchmarking.rb +0 -0
  324. data/lib/{passenger → phusion_passenger}/spawn_manager.rb +136 -128
  325. data/lib/{passenger → phusion_passenger}/templates/apache2_config_snippets.txt.erb +0 -0
  326. data/lib/{passenger → phusion_passenger}/templates/apache_must_be_compiled_with_compatible_mpm.txt.erb +0 -0
  327. data/lib/phusion_passenger/templates/app_exited_during_initialization.html.erb +38 -0
  328. data/lib/{passenger → phusion_passenger}/templates/app_init_error.html.erb +0 -0
  329. data/lib/{passenger → phusion_passenger}/templates/database_error.html.erb +0 -0
  330. data/lib/{passenger → phusion_passenger}/templates/deployment_example.txt.erb +1 -1
  331. data/lib/{passenger → phusion_passenger}/templates/error_layout.css +0 -0
  332. data/lib/{passenger → phusion_passenger}/templates/error_layout.html.erb +0 -0
  333. data/lib/{passenger → phusion_passenger}/templates/framework_init_error.html.erb +0 -0
  334. data/lib/{passenger → phusion_passenger}/templates/general_error.html.erb +0 -0
  335. data/lib/{passenger → phusion_passenger}/templates/invalid_app_root.html.erb +1 -1
  336. data/lib/{passenger → phusion_passenger}/templates/load_error.html.erb +0 -0
  337. data/lib/{passenger → phusion_passenger}/templates/no_write_permission_to_passenger_root.txt.erb +0 -0
  338. data/lib/{passenger → phusion_passenger}/templates/possible_solutions_for_compilation_and_installation_problems.txt.erb +0 -0
  339. data/lib/{passenger → phusion_passenger}/templates/run_installer_as_root.txt.erb +0 -0
  340. data/lib/{passenger → phusion_passenger}/templates/version_not_found.html.erb +0 -0
  341. data/lib/{passenger → phusion_passenger}/templates/welcome.txt.erb +0 -0
  342. data/lib/{passenger → phusion_passenger}/utils.rb +210 -44
  343. data/lib/{passenger → phusion_passenger}/wsgi/application_spawner.rb +18 -15
  344. data/lib/{passenger → phusion_passenger}/wsgi/request_handler.py +7 -1
  345. data/man/passenger-memory-stats.8 +1 -1
  346. data/misc/render_error_pages.rb +1 -1
  347. data/test/ApplicationPoolServerTest.cpp +0 -28
  348. data/test/ApplicationPoolServer_ApplicationPoolTest.cpp +4 -0
  349. data/test/ApplicationPoolTest.cpp +307 -69
  350. data/test/CachedFileStatTest.cpp +262 -0
  351. data/test/FileCheckerTest.cpp +79 -0
  352. data/test/MessageChannelTest.cpp +3 -3
  353. data/test/PoolOptionsTest.cpp +37 -0
  354. data/test/SpawnManagerTest.cpp +4 -4
  355. data/test/StandardApplicationPoolTest.cpp +4 -0
  356. data/test/SystemTimeTest.cpp +37 -0
  357. data/test/UtilsTest.cpp +137 -0
  358. data/test/integration_tests.rb +270 -23
  359. data/test/oxt/backtrace_test.cpp +128 -0
  360. data/test/oxt/oxt_test_main.cpp +25 -0
  361. data/test/oxt/syscall_interruption_test.cpp +50 -0
  362. data/test/ruby/abstract_request_handler_spec.rb +83 -0
  363. data/test/ruby/abstract_server_collection_spec.rb +246 -0
  364. data/test/ruby/application_spec.rb +3 -3
  365. data/test/ruby/message_channel_spec.rb +2 -2
  366. data/test/ruby/rack/application_spawner_spec.rb +3 -5
  367. data/test/ruby/rails/application_spawner_spec.rb +54 -15
  368. data/test/ruby/rails/framework_spawner_spec.rb +6 -8
  369. data/test/ruby/rails/minimal_spawner_spec.rb +29 -0
  370. data/test/ruby/rails/spawner_error_handling_spec.rb +1 -1
  371. data/test/ruby/rails/spawner_privilege_lowering_spec.rb +3 -3
  372. data/test/ruby/spawn_manager_spec.rb +23 -12
  373. data/test/ruby/utils_spec.rb +36 -2
  374. data/test/ruby/wsgi/application_spawner_spec.rb +47 -0
  375. data/test/stub/apache2/httpd.conf.erb +3 -5
  376. data/test/stub/message_channel.rb +2 -2
  377. data/test/stub/message_channel_2.rb +2 -2
  378. data/test/stub/message_channel_3.rb +3 -3
  379. data/test/stub/minimal-railsapp/README +0 -0
  380. data/test/stub/minimal-railsapp/config/application.rb +0 -0
  381. data/test/stub/minimal-railsapp/config/environment.rb +0 -0
  382. data/test/stub/minimal-railsapp/vendor/rails/actionmailer/lib/action_mailer.rb +0 -0
  383. data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_controller.rb +0 -0
  384. data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_pack.rb +0 -0
  385. data/test/stub/minimal-railsapp/vendor/rails/actionpack/lib/action_view.rb +0 -0
  386. data/test/stub/minimal-railsapp/vendor/rails/activerecord/lib/active_record.rb +0 -0
  387. data/test/stub/minimal-railsapp/vendor/rails/activeresource/lib/active_resource.rb +0 -0
  388. data/test/stub/minimal-railsapp/vendor/rails/activesupport/lib/active_support.rb +0 -0
  389. data/test/stub/minimal-railsapp/vendor/rails/activesupport/lib/active_support/whiny_nil.rb +0 -0
  390. data/test/stub/minimal-railsapp/vendor/rails/railties/lib/dispatcher.rb +0 -0
  391. data/test/stub/minimal-railsapp/vendor/rails/railties/lib/initializer.rb +0 -0
  392. data/test/stub/minimal-railsapp/vendor/rails/railties/lib/ruby_version_check.rb +0 -0
  393. data/test/stub/rails_apps/foobar/app/controllers/foo_controller.rb +8 -0
  394. data/test/stub/rails_apps/foobar/config/environments/development.rb +1 -2
  395. data/test/stub/rails_apps/mycook/app/controllers/welcome_controller.rb +21 -1
  396. data/test/stub/rails_apps/mycook/sites/some.site/public/uploads.html +26 -0
  397. data/test/stub/rails_apps/mycook/sites/some.site/public/welcome/cached.html +26 -0
  398. data/test/stub/railsapp/app/controllers/application.rb +0 -0
  399. data/test/stub/railsapp/app/controllers/bar_controller_1.rb +0 -0
  400. data/test/stub/railsapp/app/controllers/bar_controller_2.rb +1 -1
  401. data/test/stub/railsapp/app/controllers/foo_controller.rb +4 -0
  402. data/test/stub/railsapp/app/helpers/application_helper.rb +0 -0
  403. data/test/stub/railsapp/config/boot.rb +0 -0
  404. data/test/stub/railsapp/config/database.yml +0 -0
  405. data/test/stub/railsapp/config/environment.rb +0 -0
  406. data/test/stub/railsapp/config/environments/development.rb +0 -0
  407. data/test/stub/railsapp/config/environments/production.rb +0 -0
  408. data/test/stub/railsapp/config/initializers/inflections.rb +0 -0
  409. data/test/stub/railsapp/config/initializers/mime_types.rb +0 -0
  410. data/test/stub/railsapp/config/routes.rb +0 -0
  411. data/test/stub/railsapp/public/useless.txt +0 -0
  412. data/test/stub/spawn_server.rb +3 -4
  413. data/test/stub/wsgi/passenger_wsgi.pyc +0 -0
  414. data/test/support/apache2_controller.rb +57 -7
  415. data/test/support/tut.h +15 -0
  416. data/vendor/README +12 -0
  417. data/vendor/README_FOR_PACKAGERS +1 -0
  418. data/vendor/rack-0.9.1/AUTHORS +8 -0
  419. data/vendor/rack-0.9.1/COPYING +18 -0
  420. data/vendor/rack-0.9.1/ChangeLog +1423 -0
  421. data/vendor/rack-0.9.1/KNOWN-ISSUES +18 -0
  422. data/vendor/rack-0.9.1/README +306 -0
  423. data/vendor/rack-0.9.1/Rakefile +188 -0
  424. data/vendor/rack-0.9.1/SPEC +129 -0
  425. data/vendor/rack-0.9.1/lib/rack.rb +86 -0
  426. data/vendor/rack-0.9.1/lib/rack/adapter/camping.rb +22 -0
  427. data/vendor/rack-0.9.1/lib/rack/auth/abstract/handler.rb +28 -0
  428. data/vendor/rack-0.9.1/lib/rack/auth/abstract/request.rb +37 -0
  429. data/vendor/rack-0.9.1/lib/rack/auth/basic.rb +58 -0
  430. data/vendor/rack-0.9.1/lib/rack/auth/digest/md5.rb +124 -0
  431. data/vendor/rack-0.9.1/lib/rack/auth/digest/nonce.rb +51 -0
  432. data/vendor/rack-0.9.1/lib/rack/auth/digest/params.rb +55 -0
  433. data/vendor/rack-0.9.1/lib/rack/auth/digest/request.rb +40 -0
  434. data/vendor/rack-0.9.1/lib/rack/auth/openid.rb +438 -0
  435. data/vendor/rack-0.9.1/lib/rack/builder.rb +67 -0
  436. data/vendor/rack-0.9.1/lib/rack/cascade.rb +36 -0
  437. data/vendor/rack-0.9.1/lib/rack/commonlogger.rb +61 -0
  438. data/vendor/rack-0.9.1/lib/rack/conditionalget.rb +43 -0
  439. data/vendor/rack-0.9.1/lib/rack/content_length.rb +25 -0
  440. data/vendor/rack-0.9.1/lib/rack/deflater.rb +87 -0
  441. data/vendor/rack-0.9.1/lib/rack/directory.rb +150 -0
  442. data/vendor/rack-0.9.1/lib/rack/file.rb +85 -0
  443. data/vendor/rack-0.9.1/lib/rack/handler.rb +48 -0
  444. data/vendor/rack-0.9.1/lib/rack/handler/cgi.rb +57 -0
  445. data/vendor/rack-0.9.1/lib/rack/handler/evented_mongrel.rb +8 -0
  446. data/vendor/rack-0.9.1/lib/rack/handler/fastcgi.rb +86 -0
  447. data/vendor/rack-0.9.1/lib/rack/handler/lsws.rb +52 -0
  448. data/vendor/rack-0.9.1/lib/rack/handler/mongrel.rb +82 -0
  449. data/vendor/rack-0.9.1/lib/rack/handler/scgi.rb +57 -0
  450. data/vendor/rack-0.9.1/lib/rack/handler/swiftiplied_mongrel.rb +8 -0
  451. data/vendor/rack-0.9.1/lib/rack/handler/thin.rb +15 -0
  452. data/vendor/rack-0.9.1/lib/rack/handler/webrick.rb +61 -0
  453. data/vendor/rack-0.9.1/lib/rack/head.rb +19 -0
  454. data/vendor/rack-0.9.1/lib/rack/lint.rb +465 -0
  455. data/vendor/rack-0.9.1/lib/rack/lobster.rb +65 -0
  456. data/vendor/rack-0.9.1/lib/rack/methodoverride.rb +27 -0
  457. data/vendor/rack-0.9.1/lib/rack/mime.rb +204 -0
  458. data/vendor/rack-0.9.1/lib/rack/mock.rb +160 -0
  459. data/vendor/rack-0.9.1/lib/rack/recursive.rb +57 -0
  460. data/vendor/rack-0.9.1/lib/rack/reloader.rb +64 -0
  461. data/vendor/rack-0.9.1/lib/rack/request.rb +218 -0
  462. data/vendor/rack-0.9.1/lib/rack/response.rb +171 -0
  463. data/vendor/rack-0.9.1/lib/rack/session/abstract/id.rb +153 -0
  464. data/vendor/rack-0.9.1/lib/rack/session/cookie.rb +89 -0
  465. data/vendor/rack-0.9.1/lib/rack/session/memcache.rb +97 -0
  466. data/vendor/rack-0.9.1/lib/rack/session/pool.rb +73 -0
  467. data/vendor/rack-0.9.1/lib/rack/showexceptions.rb +348 -0
  468. data/vendor/rack-0.9.1/lib/rack/showstatus.rb +106 -0
  469. data/vendor/rack-0.9.1/lib/rack/static.rb +38 -0
  470. data/vendor/rack-0.9.1/lib/rack/urlmap.rb +48 -0
  471. data/vendor/rack-0.9.1/lib/rack/utils.rb +347 -0
  472. metadata +1197 -1055
  473. data/doc/cxxapi/System_8h-source.html +0 -251
  474. data/doc/cxxapi/classDirectoryMapper-members.html +0 -38
  475. data/doc/cxxapi/classDirectoryMapper.html +0 -203
  476. data/doc/cxxapi/classPassenger_1_1Thread.html +0 -100
  477. data/doc/cxxapi/classboost_1_1this__thread_1_1disable__syscall__interruption.html +0 -46
  478. data/doc/cxxapi/classboost_1_1this__thread_1_1restore__syscall__interruption-members.html +0 -33
  479. data/doc/cxxapi/classboost_1_1this__thread_1_1restore__syscall__interruption.html +0 -44
  480. data/doc/cxxapi/namespacePassenger.html +0 -208
  481. data/doc/cxxapi/namespacePassenger_1_1InterruptableCalls.html +0 -43
  482. data/doc/cxxapi/namespacemembers.html +0 -70
  483. data/doc/cxxapi/namespacemembers_func.html +0 -66
  484. data/doc/cxxapi/namespacemembers_type.html +0 -46
  485. data/doc/cxxapi/namespaces.html +0 -35
  486. data/doc/rdoc/classes/Passenger.html +0 -136
  487. data/doc/rdoc/classes/Passenger/AbstractRequestHandler.html +0 -402
  488. data/doc/rdoc/classes/Passenger/SpawnManager.html +0 -379
  489. data/doc/rdoc/classes/Passenger/Utils.html +0 -578
  490. data/ext/apache2/System.h +0 -228
  491. data/lib/passenger/platform_info.rb +0 -302
  492. data/lib/passenger/templates/app_exited_during_initialization.html.erb +0 -19
  493. data/test/stub/apache2/httpd.conf +0 -75
  494. data/test/stub/rails_apps/foobar/config/environments/test.rb +0 -22
  495. data/test/stub/rails_apps/mycook/config/environments/test.rb +0 -22
  496. data/test/stub/railsapp/config/environments/test.rb +0 -22
  497. data/test/stub/railsapp2/config/environments/test.rb +0 -22
@@ -17,7 +17,7 @@
17
17
  # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
18
 
19
19
  require 'erb'
20
- module Passenger
20
+ module PhusionPassenger
21
21
 
22
22
  class ConsoleTextTemplate
23
23
  TEMPLATE_DIR = "#{File.dirname(__FILE__)}/templates"
@@ -58,4 +58,4 @@ private
58
58
  end
59
59
  end
60
60
 
61
- end # module Passenger
61
+ end # module PhusionPassenger
@@ -1,8 +1,6 @@
1
1
  # Phusion Passenger - http://www.modrails.com/
2
2
  # Copyright (C) 2008 Phusion
3
3
  #
4
- # Phusion Passenger is a trademark of Hongli Lai & Ninh Bui.
5
- #
6
4
  # This program is free software; you can redistribute it and/or modify
7
5
  # it under the terms of the GNU General Public License as published by
8
6
  # the Free Software Foundation; version 2 of the License.
@@ -15,6 +13,8 @@
15
13
  # You should have received a copy of the GNU General Public License along
16
14
  # with this program; if not, write to the Free Software Foundation, Inc.,
17
15
  # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
- require 'mkmf'
19
- $LIBS=""
20
- create_makefile('native_support')
16
+
17
+ module PhusionPassenger
18
+ DEFAULT_FRAMEWORK_SPAWNER_MAX_IDLE_TIME = 30 * 60
19
+ DEFAULT_APP_SPAWNER_MAX_IDLE_TIME = 10 * 60
20
+ end
@@ -16,8 +16,8 @@
16
16
  # with this program; if not, write to the Free Software Foundation, Inc.,
17
17
  # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
18
 
19
- require 'passenger/platform_info'
20
- module Passenger
19
+ require 'phusion_passenger/platform_info'
20
+ module PhusionPassenger
21
21
 
22
22
  # Represents a dependency software that Passenger requires. It's used by the
23
23
  # installer to check whether all dependencies are available. A Dependency object
@@ -53,11 +53,11 @@ class Dependency # :nodoc: all
53
53
 
54
54
  private
55
55
  class Result
56
- def found(filename_or_boolean = nil)
57
- if filename_or_boolean.nil?
56
+ def found(*args)
57
+ if args.empty?
58
58
  @found = true
59
59
  else
60
- @found = filename_or_boolean
60
+ @found = args.first
61
61
  end
62
62
  end
63
63
 
@@ -90,8 +90,12 @@ end
90
90
  # Namespace which contains the different dependencies that Passenger may require.
91
91
  # See Dependency for more information.
92
92
  module Dependencies # :nodoc: all
93
- include PlatformInfo
94
-
93
+ # Returns whether fastthread is a required dependency for the current
94
+ # Ruby interpreter.
95
+ def self.fastthread_required?
96
+ return (!defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby") && RUBY_VERSION < "1.8.7"
97
+ end
98
+
95
99
  GCC = Dependency.new do |dep|
96
100
  dep.name = "GNU C++ compiler"
97
101
  dep.define_checker do |result|
@@ -103,7 +107,7 @@ module Dependencies # :nodoc: all
103
107
  end
104
108
  end
105
109
  if RUBY_PLATFORM =~ /linux/
106
- case LINUX_DISTRO
110
+ case PlatformInfo.linux_distro
107
111
  when :ubuntu, :debian
108
112
  dep.install_command = "apt-get install build-essential"
109
113
  when :rhel, :fedora, :centos
@@ -123,13 +127,14 @@ module Dependencies # :nodoc: all
123
127
  require 'rbconfig'
124
128
  begin
125
129
  require 'mkmf'
126
- result.found(File.exist?(Config::CONFIG['archdir'] + "/ruby.h"))
130
+ header_dir = Config::CONFIG['rubyhdrdir'] || Config::CONFIG['archdir']
131
+ result.found(File.exist?("#{header_dir}/ruby.h"))
127
132
  rescue LoadError
128
133
  result.not_found
129
134
  end
130
135
  end
131
136
  if RUBY_PLATFORM =~ /linux/
132
- case LINUX_DISTRO
137
+ case PlatformInfo.linux_distro
133
138
  when :ubuntu, :debian
134
139
  dep.install_command = "apt-get install ruby1.8-dev"
135
140
  when :rhel, :fedora, :centos
@@ -155,7 +160,7 @@ module Dependencies # :nodoc: all
155
160
  end
156
161
  end
157
162
  if RUBY_PLATFORM =~ /linux/
158
- case LINUX_DISTRO
163
+ case PlatformInfo.linux_distro
159
164
  when :ubuntu, :debian
160
165
  dep.install_command = "apt-get install libopenssl-ruby"
161
166
  end
@@ -185,17 +190,10 @@ module Dependencies # :nodoc: all
185
190
  Rake = Dependency.new do |dep|
186
191
  dep.name = "Rake"
187
192
  dep.define_checker do |result|
188
- bindir = File.dirname(PlatformInfo::RUBY)
189
- rake = File.join(bindir, "rake")
190
- if File.executable?(rake)
191
- result.found(rake)
193
+ if PlatformInfo.rake.nil?
194
+ result.not_found
192
195
  else
193
- rake = PlatformInfo.find_command("rake")
194
- if rake.nil?
195
- result.not_found
196
- else
197
- result.found(rake)
198
- end
196
+ result.found(PlatformInfo.rake)
199
197
  end
200
198
  end
201
199
  dep.website = "http://rake.rubyforge.org/"
@@ -205,14 +203,14 @@ module Dependencies # :nodoc: all
205
203
  Apache2 = Dependency.new do |dep|
206
204
  dep.name = "Apache 2"
207
205
  dep.define_checker do |result|
208
- if HTTPD.nil?
206
+ if PlatformInfo.httpd.nil?
209
207
  result.not_found
210
208
  else
211
- result.found(HTTPD)
209
+ result.found(PlatformInfo.httpd)
212
210
  end
213
211
  end
214
212
  if RUBY_PLATFORM =~ /linux/
215
- case LINUX_DISTRO
213
+ case PlatformInfo.linux_distro
216
214
  when :ubuntu, :debian
217
215
  dep.install_command = "apt-get install apache2-mpm-prefork"
218
216
  when :rhel, :fedora, :centos
@@ -230,14 +228,14 @@ module Dependencies # :nodoc: all
230
228
  Apache2_DevHeaders = Dependency.new do |dep|
231
229
  dep.name = "Apache 2 development headers"
232
230
  dep.define_checker do |result|
233
- if APXS2.nil?
231
+ if PlatformInfo.apxs2.nil?
234
232
  result.not_found
235
233
  else
236
- result.found(APXS2)
234
+ result.found(PlatformInfo.apxs2)
237
235
  end
238
236
  end
239
237
  if RUBY_PLATFORM =~ /linux/
240
- case LINUX_DISTRO
238
+ case PlatformInfo.linux_distro
241
239
  when :ubuntu, :debian
242
240
  dep.install_command = "apt-get install apache2-prefork-dev"
243
241
  dep.provides = [Apache2]
@@ -257,10 +255,14 @@ module Dependencies # :nodoc: all
257
255
  APR_DevHeaders = Dependency.new do |dep|
258
256
  dep.name = "Apache Portable Runtime (APR) development headers"
259
257
  dep.define_checker do |result|
260
- result.found(APR_CONFIG)
258
+ if PlatformInfo.apr_config.nil?
259
+ result.not_found
260
+ else
261
+ result.found(PlatformInfo.apr_config)
262
+ end
261
263
  end
262
264
  if RUBY_PLATFORM =~ /linux/
263
- case LINUX_DISTRO
265
+ case PlatformInfo.linux_distro
264
266
  when :ubuntu, :debian
265
267
  dep.install_command = "apt-get install libapr1-dev"
266
268
  when :rhel, :fedora, :centos
@@ -278,9 +280,13 @@ module Dependencies # :nodoc: all
278
280
  end
279
281
 
280
282
  APU_DevHeaders = Dependency.new do |dep|
281
- dep.name = "Apache Portable Runtime Utility (APR) development headers"
283
+ dep.name = "Apache Portable Runtime Utility (APU) development headers"
282
284
  dep.define_checker do |result|
283
- result.found(APU_CONFIG)
285
+ if PlatformInfo.apu_config.nil?
286
+ result.not_found
287
+ else
288
+ result.found(PlatformInfo.apu_config)
289
+ end
284
290
  end
285
291
  dep.website = "http://httpd.apache.org/"
286
292
  dep.website_comments = "APR Utility is an integrated part of Apache."
@@ -321,4 +327,4 @@ module Dependencies # :nodoc: all
321
327
  end
322
328
  end
323
329
 
324
- end # module Passenger
330
+ end # module PhusionPassenger
@@ -0,0 +1,45 @@
1
+ # Phusion Passenger - http://www.modrails.com/
2
+ # Copyright (C) 2009 Phusion
3
+ #
4
+ # Phusion Passenger is a trademark of Hongli Lai & Ninh Bui.
5
+ #
6
+ # This program is free software; you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation; version 2 of the License.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License along
16
+ # with this program; if not, write to the Free Software Foundation, Inc.,
17
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
+
19
+ module PhusionPassenger
20
+ @@event_starting_worker_process = []
21
+ @@event_stopping_worker_process = []
22
+
23
+ def self.on_event(name, &block)
24
+ callback_list_for_event(name) << block
25
+ end
26
+
27
+ def self.call_event(name, *args)
28
+ callback_list_for_event(name).each do |callback|
29
+ callback.call(*args)
30
+ end
31
+ end
32
+
33
+ private
34
+ def self.callback_list_for_event(name)
35
+ return case name
36
+ when :starting_worker_process
37
+ @@event_starting_worker_process
38
+ when :stopping_worker_process
39
+ @@event_stopping_worker_process
40
+ else
41
+ raise ArgumentError, "Unknown event name '#{name}'"
42
+ end
43
+ end
44
+
45
+ end # module PhusionPassenger
@@ -16,7 +16,7 @@
16
16
  # with this program; if not, write to the Free Software Foundation, Inc.,
17
17
  # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
18
 
19
- module Passenger
19
+ module PhusionPassenger
20
20
 
21
21
  # Indicates that there is no Ruby on Rails version installed that satisfies
22
22
  # a given Ruby on Rails Gem version specification.
@@ -50,14 +50,18 @@ end
50
50
  # Railz::FrameworkSpawner or SpawnManager was unable to spawn an application,
51
51
  # because the application either threw an exception or called exit.
52
52
  #
53
- # If the +child_exception+ attribute is nil, then it means that the application
54
- # called exit.
53
+ # If the application called exit, then +child_exception+ is an instance of
54
+ # +SystemExit+.
55
55
  class AppInitError < InitializationError
56
+ # The application type, e.g. "rails" or "rack".
56
57
  attr_accessor :app_type
58
+ # Any messages printed to stderr before the failure. May be nil.
59
+ attr_accessor :stderr
57
60
 
58
- def initialize(message, child_exception = nil, app_type = "rails")
61
+ def initialize(message, child_exception = nil, app_type = "rails", stderr = nil)
59
62
  super(message, child_exception)
60
63
  @app_type = app_type
64
+ @stderr = stderr
61
65
  end
62
66
  end
63
67
 
@@ -88,4 +92,7 @@ class UnknownError < StandardError
88
92
  end
89
93
  end
90
94
 
91
- end # module Passenger
95
+ class InvalidPath < StandardError
96
+ end
97
+
98
+ end # module PhusionPassenger
@@ -18,7 +18,7 @@
18
18
 
19
19
  require 'erb'
20
20
 
21
- module Passenger
21
+ module PhusionPassenger
22
22
 
23
23
  # A convenience utility class for rendering our error pages.
24
24
  class HTMLTemplate
@@ -101,4 +101,4 @@ private
101
101
  end
102
102
  end
103
103
 
104
- end # module Passenger
104
+ end # module PhusionPassenger
@@ -16,7 +16,7 @@
16
16
  # with this program; if not, write to the Free Software Foundation, Inc.,
17
17
  # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
18
 
19
- module Passenger
19
+ module PhusionPassenger
20
20
 
21
21
  # This class provides convenience methods for:
22
22
  # - sending and receiving raw data over an IO channel.
@@ -140,6 +140,7 @@ class MessageChannel
140
140
  end
141
141
  buffer = ''
142
142
  while buffer.size < size
143
+ temp = '' # JRuby doesn't clear the buffer. TODO: remove this when JRuby has been fixed.
143
144
  buffer << @io.readpartial(size - buffer.size, temp)
144
145
  end
145
146
  return buffer
@@ -219,4 +220,4 @@ private
219
220
  end
220
221
  end
221
222
 
222
- end # module Passenger
223
+ end # module PhusionPassenger
@@ -0,0 +1,500 @@
1
+ # Phusion Passenger - http://www.modrails.com/
2
+ # Copyright (C) 2008, 2009 Phusion
3
+ #
4
+ # Phusion Passenger is a trademark of Hongli Lai & Ninh Bui.
5
+ #
6
+ # This program is free software; you can redistribute it and/or modify
7
+ # it under the terms of the GNU General Public License as published by
8
+ # the Free Software Foundation; version 2 of the License.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License along
16
+ # with this program; if not, write to the Free Software Foundation, Inc.,
17
+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
+
19
+ require 'rbconfig'
20
+
21
+ # Wow, I can't believe in how many ways one can build Apache in OS
22
+ # X! We have to resort to all sorts of tricks to make Passenger build
23
+ # out of the box on OS X. :-(
24
+ #
25
+ # In the name of usability and the "end user is the king" line of thought,
26
+ # I shall suffer the horrible faith of writing tons of autodetection code!
27
+
28
+ # This module autodetects various platform-specific information, and
29
+ # provides that information through constants.
30
+ #
31
+ # Users can change the detection behavior by setting the environment variable
32
+ # <tt>APXS2</tt> to the correct 'apxs' (or 'apxs2') binary, as provided by
33
+ # Apache.
34
+ module PlatformInfo
35
+ private
36
+ # Turn the specified class method into a memoized one. If the given
37
+ # class method is called without arguments, then its result will be
38
+ # memoized, frozen, and returned upon subsequent calls without arguments.
39
+ # Calls with arguments are never memoized.
40
+ #
41
+ # def self.foo(max = 10)
42
+ # return rand(max)
43
+ # end
44
+ # memoize :foo
45
+ #
46
+ # foo # => 3
47
+ # foo # => 3
48
+ # foo(100) # => 49
49
+ # foo(100) # => 26
50
+ # foo # => 3
51
+ def self.memoize(method)
52
+ metaclass = class << self; self; end
53
+ metaclass.send(:alias_method, "_unmemoized_#{method}", method)
54
+ variable_name = "@@memoized_#{method}".sub(/\?/, '')
55
+ check_variable_name = "@@has_memoized_#{method}".sub(/\?/, '')
56
+ eval("#{variable_name} = nil")
57
+ eval("#{check_variable_name} = false")
58
+ source = %Q{
59
+ def self.#{method}(*args) # def self.httpd(*args)
60
+ if args.empty? # if args.empty?
61
+ if !#{check_variable_name} # if !@@has_memoized_httpd
62
+ #{variable_name} = _unmemoized_#{method}.freeze # @@memoized_httpd = _unmemoized_httpd.freeze
63
+ #{check_variable_name} = true # @@has_memoized_httpd = true
64
+ end # end
65
+ return #{variable_name} # return @@memoized_httpd
66
+ else # else
67
+ return _unmemoized_#{method}(*args) # return _unmemoized_httpd(*args)
68
+ end # end
69
+ end # end
70
+ }
71
+ class_eval(source)
72
+ end
73
+
74
+ def self.env_defined?(name)
75
+ return !ENV[name].nil? && !ENV[name].empty?
76
+ end
77
+
78
+ def self.locate_ruby_executable(name)
79
+ if RUBY_PLATFORM =~ /darwin/ &&
80
+ RUBY =~ %r(\A/System/Library/Frameworks/Ruby.framework/Versions/.*?/usr/bin/ruby\Z)
81
+ # On OS X we must look for Ruby binaries in /usr/bin.
82
+ # RubyGems puts executables (e.g. 'rake') in there, not in
83
+ # /System/Libraries/(...)/bin.
84
+ filename = "/usr/bin/#{name}"
85
+ else
86
+ filename = File.dirname(RUBY) + "/#{name}"
87
+ end
88
+ if File.file?(filename) && File.executable?(filename)
89
+ return filename
90
+ else
91
+ # RubyGems might put binaries in a directory other
92
+ # than Ruby's bindir. Debian packaged RubyGems and
93
+ # DebGem packaged RubyGems are the prime examples.
94
+ begin
95
+ require 'rubygems' unless defined?(Gem)
96
+ filename = Gem.bindir + "/#{name}"
97
+ if File.file?(filename) && File.executable?(filename)
98
+ return filename
99
+ else
100
+ return nil
101
+ end
102
+ rescue LoadError
103
+ return nil
104
+ end
105
+ end
106
+ end
107
+
108
+ # Look in the directory +dir+ and check whether there's an executable
109
+ # whose base name is equal to one of the elements in +possible_names+.
110
+ # If so, returns the full filename. If not, returns nil.
111
+ def self.select_executable(dir, *possible_names)
112
+ possible_names.each do |name|
113
+ filename = "#{dir}/#{name}"
114
+ if File.file?(filename) && File.executable?(filename)
115
+ return filename
116
+ end
117
+ end
118
+ return nil
119
+ end
120
+
121
+ def self.find_apache2_executable(*possible_names)
122
+ [apache2_bindir, apache2_sbindir].each do |bindir|
123
+ if bindir.nil?
124
+ next
125
+ end
126
+ possible_names.each do |name|
127
+ filename = "#{bindir}/#{name}"
128
+ if File.file?(filename) && File.executable?(filename)
129
+ return filename
130
+ end
131
+ end
132
+ end
133
+ return nil
134
+ end
135
+
136
+ def self.determine_apr_info
137
+ if apr_config.nil?
138
+ return [nil, nil]
139
+ else
140
+ flags = `#{apr_config} --cppflags --includes`.strip
141
+ libs = `#{apr_config} --link-ld`.strip
142
+ flags.gsub!(/-O\d? /, '')
143
+ if RUBY_PLATFORM =~ /solaris/
144
+ # Remove flags not supported by GCC
145
+ flags = flags.split(/ +/).reject{ |f| f =~ /^\-mt/ }.join(' ')
146
+ end
147
+ return [flags, libs]
148
+ end
149
+ end
150
+ memoize :determine_apr_info
151
+
152
+ def self.determine_apu_info
153
+ if apu_config.nil?
154
+ return [nil, nil]
155
+ else
156
+ flags = `#{apu_config} --includes`.strip
157
+ libs = `#{apu_config} --link-ld`.strip
158
+ flags.gsub!(/-O\d? /, '')
159
+ return [flags, libs]
160
+ end
161
+ end
162
+ memoize :determine_apu_info
163
+
164
+ def self.read_file(filename)
165
+ return File.read(filename)
166
+ rescue
167
+ return ""
168
+ end
169
+
170
+ public
171
+ # The absolute path to the current Ruby interpreter.
172
+ RUBY = Config::CONFIG['bindir'] + '/' + Config::CONFIG['RUBY_INSTALL_NAME'] + Config::CONFIG['EXEEXT']
173
+ # The correct 'gem' command for this Ruby interpreter.
174
+ GEM = locate_ruby_executable('gem')
175
+
176
+ # Check whether the specified command is in $PATH, and return its
177
+ # absolute filename. Returns nil if the command is not found.
178
+ #
179
+ # This function exists because system('which') doesn't always behave
180
+ # correctly, for some weird reason.
181
+ def self.find_command(name)
182
+ ENV['PATH'].split(File::PATH_SEPARATOR).detect do |directory|
183
+ path = File.join(directory, name.to_s)
184
+ if File.executable?(path)
185
+ return path
186
+ end
187
+ end
188
+ return nil
189
+ end
190
+
191
+
192
+ ################ Programs ################
193
+
194
+
195
+ # Returns the absolute path to the Rake executable that
196
+ # belongs to the current Ruby interpreter. Returns nil if it
197
+ # doesn't exist.
198
+ def self.rake
199
+ return locate_ruby_executable('rake')
200
+ end
201
+ memoize :rake
202
+
203
+ # Returns the absolute path to the RSpec runner program that
204
+ # belongs to the current Ruby interpreter. Returns nil if it
205
+ # doesn't exist.
206
+ def self.rspec
207
+ return locate_ruby_executable('spec')
208
+ end
209
+ memoize :rspec
210
+
211
+ # The absolute path to the 'apxs' or 'apxs2' executable, or nil if not found.
212
+ def self.apxs2
213
+ if env_defined?("APXS2")
214
+ return ENV["APXS2"]
215
+ end
216
+ ['apxs2', 'apxs'].each do |name|
217
+ command = find_command(name)
218
+ if !command.nil?
219
+ return command
220
+ end
221
+ end
222
+ return nil
223
+ end
224
+ memoize :apxs2
225
+
226
+ # The absolute path to the 'apachectl' or 'apache2ctl' binary.
227
+ def self.apache2ctl
228
+ return find_apache2_executable('apache2ctl', 'apachectl2', 'apachectl')
229
+ end
230
+ memoize :apache2ctl
231
+
232
+ # The absolute path to the Apache binary (that is, 'httpd', 'httpd2', 'apache' or 'apache2').
233
+ def self.httpd
234
+ if env_defined?('HTTPD')
235
+ return ENV['HTTPD']
236
+ elsif apxs2.nil?
237
+ ["apache2", "httpd2", "apache", "httpd"].each do |name|
238
+ command = find_command(name)
239
+ if !command.nil?
240
+ return command
241
+ end
242
+ end
243
+ return nil
244
+ else
245
+ return find_apache2_executable(`#{apxs2} -q TARGET`.strip)
246
+ end
247
+ end
248
+ memoize :httpd
249
+
250
+ # The absolute path to the 'apr-config' or 'apr-1-config' executable.
251
+ def self.apr_config
252
+ if env_defined?('APR_CONFIG')
253
+ return ENV['APR_CONFIG']
254
+ elsif apxs2.nil?
255
+ return nil
256
+ else
257
+ filename = `#{apxs2} -q APR_CONFIG 2>/dev/null`.strip
258
+ if filename.empty?
259
+ apr_bindir = `#{apxs2} -q APR_BINDIR 2>/dev/null`.strip
260
+ if apr_bindir.empty?
261
+ return nil
262
+ else
263
+ return select_executable(apr_bindir,
264
+ "apr-1-config", "apr-config")
265
+ end
266
+ elsif File.exist?(filename)
267
+ return filename
268
+ else
269
+ return nil
270
+ end
271
+ end
272
+ end
273
+ memoize :apr_config
274
+
275
+ # The absolute path to the 'apu-config' or 'apu-1-config' executable.
276
+ def self.apu_config
277
+ if env_defined?('APU_CONFIG')
278
+ return ENV['APU_CONFIG']
279
+ elsif apxs2.nil?
280
+ return nil
281
+ else
282
+ filename = `#{apxs2} -q APU_CONFIG 2>/dev/null`.strip
283
+ if filename.empty?
284
+ apu_bindir = `#{apxs2} -q APU_BINDIR 2>/dev/null`.strip
285
+ if apu_bindir.empty?
286
+ return nil
287
+ else
288
+ return select_executable(apu_bindir,
289
+ "apu-1-config", "apu-config")
290
+ end
291
+ elsif File.exist?(filename)
292
+ return filename
293
+ else
294
+ return nil
295
+ end
296
+ end
297
+ end
298
+ memoize :apu_config
299
+
300
+
301
+ ################ Directories ################
302
+
303
+
304
+ # The absolute path to the Apache 2 'bin' directory.
305
+ def self.apache2_bindir
306
+ if apxs2.nil?
307
+ return nil
308
+ else
309
+ return `#{apxs2} -q BINDIR 2>/dev/null`.strip
310
+ end
311
+ end
312
+ memoize :apache2_bindir
313
+
314
+ # The absolute path to the Apache 2 'sbin' directory.
315
+ def self.apache2_sbindir
316
+ if apxs2.nil?
317
+ return nil
318
+ else
319
+ return `#{apxs2} -q SBINDIR`.strip
320
+ end
321
+ end
322
+ memoize :apache2_sbindir
323
+
324
+
325
+ ################ Compiler and linker flags ################
326
+
327
+
328
+ # Compiler flags that should be used for compiling every C/C++ program,
329
+ # for portability reasons. These flags should be specified as last
330
+ # when invoking the compiler.
331
+ def self.portability_cflags
332
+ # _GLIBCPP__PTHREADS is for fixing Boost compilation on OpenBSD.
333
+ flags = ["-D_REENTRANT -D_GLIBCPP__PTHREADS -I/usr/local/include"]
334
+ if RUBY_PLATFORM =~ /solaris/
335
+ flags << '-D_XOPEN_SOURCE=500 -D_XPG4_2 -D__EXTENSIONS__ -D__SOLARIS__'
336
+ flags << '-DBOOST_HAS_STDINT_H' unless RUBY_PLATFORM =~ /solaris2.9/
337
+ flags << '-D__SOLARIS9__ -DBOOST__STDC_CONSTANT_MACROS_DEFINED' if RUBY_PLATFORM =~ /solaris2.9/
338
+ flags << '-mcpu=ultrasparc' if RUBY_PLATFORM =~ /sparc/
339
+ elsif RUBY_PLATFORM =~ /openbsd/
340
+ flags << '-DBOOST_HAS_STDINT_H'
341
+ end
342
+ return flags.compact.join(" ").strip
343
+ end
344
+ memoize :portability_cflags
345
+
346
+ # Linker flags that should be used for linking every C/C++ program,
347
+ # for portability reasons. These flags should be specified as last
348
+ # when invoking the linker.
349
+ def self.portability_ldflags
350
+ if RUBY_PLATFORM =~ /solaris/
351
+ return '-lxnet -lrt -lsocket -lnsl -lpthread'
352
+ else
353
+ return '-lpthread'
354
+ end
355
+ end
356
+ memoize :portability_ldflags
357
+
358
+ # C compiler flags that should be passed in order to enable debugging information.
359
+ def self.debugging_cflags
360
+ if RUBY_PLATFORM =~ /openbsd/
361
+ # According to OpenBSD's pthreads man page, pthreads do not work
362
+ # correctly when an app is compiled with -g. It recommends using
363
+ # -ggdb instead.
364
+ return '-ggdb'
365
+ else
366
+ return '-g'
367
+ end
368
+ end
369
+
370
+ # The C compiler flags that are necessary to compile an Apache module.
371
+ # Includes portability_cflags.
372
+ def self.apache2_module_cflags(with_apr_flags = true)
373
+ flags = ["-fPIC"]
374
+ if with_apr_flags
375
+ flags << apr_flags
376
+ flags << apu_flags
377
+ end
378
+ if !apxs2.nil?
379
+ apxs2_flags = `#{apxs2} -q CFLAGS`.strip << " -I" << `#{apxs2} -q INCLUDEDIR`.strip
380
+ apxs2_flags.gsub!(/-O\d? /, '')
381
+
382
+ # Remove flags not supported by GCC
383
+ if RUBY_PLATFORM =~ /solaris/ # TODO: Add support for people using SunStudio
384
+ # The big problem is Coolstack apxs includes a bunch of solaris -x directives.
385
+ options = apxs2_flags.split
386
+ options.reject! { |f| f =~ /^\-x/ }
387
+ options.reject! { |f| f =~ /^\-Xa/ }
388
+ apxs2_flags = options.join(' ')
389
+ end
390
+
391
+ apxs2_flags.strip!
392
+ flags << apxs2_flags
393
+ end
394
+ if !httpd.nil? && RUBY_PLATFORM =~ /darwin/
395
+ # Add possible universal binary flags.
396
+ architectures = []
397
+ `file "#{httpd}"`.split("\n").grep(/for architecture/).each do |line|
398
+ line =~ /for architecture (.*?)\)/
399
+ architectures << "-arch #{$1}"
400
+ end
401
+ flags << architectures.join(' ')
402
+ end
403
+ flags << portability_cflags
404
+ return flags.compact.join(' ').strip
405
+ end
406
+ memoize :apache2_module_cflags
407
+
408
+ # Linker flags that are necessary for linking an Apache module.
409
+ # Includes portability_ldflags
410
+ def self.apache2_module_ldflags
411
+ flags = "-fPIC #{apr_libs} #{apu_libs} #{portability_ldflags}"
412
+ flags.strip!
413
+ return flags
414
+ end
415
+ memoize :apache2_module_ldflags
416
+
417
+ # The C compiler flags that are necessary for programs that use APR.
418
+ def self.apr_flags
419
+ return determine_apr_info[0]
420
+ end
421
+
422
+ # The linker flags that are necessary for linking programs that use APR.
423
+ def self.apr_libs
424
+ return determine_apr_info[1]
425
+ end
426
+
427
+ # The C compiler flags that are necessary for programs that use APR-Util.
428
+ def self.apu_flags
429
+ return determine_apu_info[0]
430
+ end
431
+
432
+ # The linker flags that are necessary for linking programs that use APR-Util.
433
+ def self.apu_libs
434
+ return determine_apu_info[1]
435
+ end
436
+
437
+
438
+ ################ Miscellaneous information ################
439
+
440
+
441
+ # Returns whether it is necessary to use information outputted by
442
+ # 'apr-config' and 'apu-config' in order to compile an Apache module.
443
+ # When Apache is installed with --with-included-apr, the APR/APU
444
+ # headers are placed into the same directory as the Apache headers,
445
+ # and so 'apr-config' and 'apu-config' won't be necessary in that case.
446
+ def self.apr_config_needed_for_building_apache_modules?
447
+ filename = File.join("/tmp/passenger-platform-check-#{Process.pid}.c")
448
+ File.open(filename, "w") do |f|
449
+ f.puts("#include <apr.h>")
450
+ end
451
+ begin
452
+ return !system("(gcc #{apache2_module_cflags(false)} -c '#{filename}' -o '#{filename}.o') >/dev/null 2>/dev/null")
453
+ ensure
454
+ File.unlink(filename) rescue nil
455
+ File.unlink("#{filename}.o") rescue nil
456
+ end
457
+ end
458
+ memoize :apr_config_needed_for_building_apache_modules?
459
+
460
+ # The current platform's shared library extension ('so' on most Unices).
461
+ def self.library_extension
462
+ if RUBY_PLATFORM =~ /darwin/
463
+ return "bundle"
464
+ else
465
+ return "so"
466
+ end
467
+ end
468
+
469
+ # An identifier for the current Linux distribution. nil if the operating system is not Linux.
470
+ def self.linux_distro
471
+ if RUBY_PLATFORM !~ /linux/
472
+ return nil
473
+ end
474
+ lsb_release = read_file("/etc/lsb-release")
475
+ if lsb_release =~ /Ubuntu/
476
+ return :ubuntu
477
+ elsif File.exist?("/etc/debian_version")
478
+ return :debian
479
+ elsif File.exist?("/etc/redhat-release")
480
+ redhat_release = read_file("/etc/redhat-release")
481
+ if redhat_release =~ /CentOS/
482
+ return :centos
483
+ elsif redhat_release =~ /Fedora/ # is this correct?
484
+ return :fedora
485
+ else
486
+ # On official RHEL distros, the content is in the form of
487
+ # "Red Hat Enterprise Linux Server release 5.1 (Tikanga)"
488
+ return :rhel
489
+ end
490
+ elsif File.exist?("/etc/suse-release")
491
+ return :suse
492
+ elsif File.exist?("/etc/gentoo-release")
493
+ return :gentoo
494
+ else
495
+ return :unknown
496
+ end
497
+ # TODO: Slackware, Mandrake/Mandriva
498
+ end
499
+ memoize :linux_distro
500
+ end