rhodes 3.2.0.beta.4 → 3.2.0.beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (667) hide show
  1. data/CHANGELOG +2 -0
  2. data/Manifest.txt +517 -23
  3. data/Rakefile +52 -7
  4. data/doc/build.txt +7 -1
  5. data/doc/device-caps.txt +1 -1
  6. data/doc/install.txt +12 -0
  7. data/doc/jqt-jqm-transition.txt +121 -0
  8. data/doc/release.txt +6 -1
  9. data/doc/ui.txt +4 -2
  10. data/installer/icon.ico +0 -0
  11. data/lib/extensions/barcode/ext/barcode/shared/src/zbar.c +7 -0
  12. data/lib/extensions/barcode/ext/barcode/shared/zbar/rho_bridge.c +3 -3
  13. data/lib/extensions/barcode/ext/barcode/shared/zbar/zbar/README.TXT +74 -3
  14. data/lib/extensions/fcntl/ext/Rakefile +57 -38
  15. data/lib/extensions/fcntl/ext/build.bat +1 -0
  16. data/lib/extensions/fcntl/ext/fcntl.vcproj +323 -0
  17. data/lib/extensions/fileutils/fileutils.rb +57 -33
  18. data/lib/extensions/net-http/net/ftp.rb +40 -36
  19. data/lib/extensions/net-http/net/http.rb +98 -38
  20. data/lib/extensions/net-http/net/https.rb +3 -13
  21. data/lib/extensions/net-http/net/protocol.rb +20 -4
  22. data/lib/extensions/rexml/rexml/document.rb +11 -9
  23. data/lib/extensions/rexml/rexml/element.rb +1 -1
  24. data/lib/extensions/rexml/rexml/entity.rb +1 -1
  25. data/lib/extensions/rexml/rexml/formatters/default.rb +3 -1
  26. data/lib/extensions/rexml/rexml/formatters/pretty.rb +1 -1
  27. data/lib/extensions/rexml/rexml/light/node.rb +1 -2
  28. data/lib/extensions/rexml/rexml/parent.rb +1 -0
  29. data/lib/extensions/rexml/rexml/parsers/xpathparser.rb +2 -1
  30. data/lib/extensions/rexml/rexml/quickpath.rb +4 -1
  31. data/lib/extensions/rexml/rexml/rexml.rb +1 -1
  32. data/lib/extensions/rexml/rexml/source.rb +25 -14
  33. data/lib/extensions/rexml/rexml/text.rb +20 -21
  34. data/lib/extensions/rexml/rexml/xmldecl.rb +2 -2
  35. data/lib/extensions/rexml/rexml/xmltokens.rb +2 -2
  36. data/lib/extensions/rexml/rexml/xpath_parser.rb +2 -1
  37. data/lib/extensions/set/set.rb +100 -25
  38. data/lib/extensions/uri/uri/common.rb +134 -4
  39. data/lib/extensions/uri/uri/ftp.rb +14 -3
  40. data/lib/extensions/uri/uri/generic.rb +53 -44
  41. data/lib/extensions/uri/uri/http.rb +1 -1
  42. data/lib/extensions/uri/uri/https.rb +1 -1
  43. data/lib/extensions/uri/uri/ldap.rb +1 -1
  44. data/lib/extensions/uri/uri/mailto.rb +9 -9
  45. data/lib/framework/rho/rhoviewhelpers.rb +3 -2
  46. data/lib/framework/rholang/localization_simplified.rb +5 -3
  47. data/platform/android/Rhodes/src/com/rhomobile/rhodes/Logger.java +14 -1
  48. data/platform/android/Rhodes/src/com/rhomobile/rhodes/camera/ImageCapture.java +1 -1
  49. data/platform/android/Rhodes/src/com/rhomobile/rhodes/camera/ImageCaptureCallback.java +0 -1
  50. data/platform/android/Rhodes/src/com/rhomobile/rhodes/file/RhoFileApi.java +12 -5
  51. data/platform/android/build/android.rake +7 -7
  52. data/platform/iphone/Classes/AppManager/AppManager.m +19 -7
  53. data/platform/iphone/rbuild/iphone.rake +1 -1
  54. data/platform/osx/bin/RhoSimulator/RhoSimulator.app/Contents/Frameworks/QtCore.framework/Versions/4/QtCore +0 -0
  55. data/platform/osx/bin/RhoSimulator/RhoSimulator.app/Contents/Frameworks/QtGui.framework/Versions/4/QtGui +0 -0
  56. data/platform/osx/bin/RhoSimulator/RhoSimulator.app/Contents/Frameworks/QtNetwork.framework/Versions/4/QtNetwork +0 -0
  57. data/platform/osx/bin/RhoSimulator/RhoSimulator.app/Contents/Frameworks/QtWebKit.framework/Versions/4/QtWebKit +0 -0
  58. data/platform/osx/bin/RhoSimulator/RhoSimulator.app/Contents/Frameworks/phonon.framework/Versions/4/phonon +0 -0
  59. data/platform/osx/bin/RhoSimulator/RhoSimulator.app/Contents/Info.plist +1 -1
  60. data/platform/osx/bin/RhoSimulator/RhoSimulator.app/Contents/MacOS/RhoSimulator +0 -0
  61. data/platform/osx/bin/RhoSimulator/RhoSimulator.app/Contents/PlugIns/accessible/libqtaccessiblewidgets.dylib +0 -0
  62. data/platform/osx/bin/RhoSimulator/RhoSimulator.app/Contents/PlugIns/bearer/libqgenericbearer.dylib +0 -0
  63. data/platform/osx/bin/RhoSimulator/RhoSimulator.app/Contents/PlugIns/codecs/libqcncodecs.dylib +0 -0
  64. data/platform/osx/bin/RhoSimulator/RhoSimulator.app/Contents/PlugIns/codecs/libqjpcodecs.dylib +0 -0
  65. data/platform/osx/bin/RhoSimulator/RhoSimulator.app/Contents/PlugIns/codecs/libqkrcodecs.dylib +0 -0
  66. data/platform/osx/bin/RhoSimulator/RhoSimulator.app/Contents/PlugIns/codecs/libqtwcodecs.dylib +0 -0
  67. data/platform/osx/bin/RhoSimulator/RhoSimulator.app/Contents/PlugIns/graphicssystems/libqtracegraphicssystem.dylib +0 -0
  68. data/platform/osx/bin/RhoSimulator/RhoSimulator.app/Contents/PlugIns/imageformats/libqgif.dylib +0 -0
  69. data/platform/osx/bin/RhoSimulator/RhoSimulator.app/Contents/PlugIns/imageformats/libqico.dylib +0 -0
  70. data/platform/osx/bin/RhoSimulator/RhoSimulator.app/Contents/PlugIns/imageformats/libqjpeg.dylib +0 -0
  71. data/platform/osx/bin/RhoSimulator/RhoSimulator.app/Contents/PlugIns/imageformats/libqmng.dylib +0 -0
  72. data/platform/osx/bin/RhoSimulator/RhoSimulator.app/Contents/PlugIns/imageformats/libqtiff.dylib +0 -0
  73. data/platform/osx/bin/RhoSimulator/RhoSimulator.app/Contents/PlugIns/phonon_backend/libphonon_qt7.dylib +0 -0
  74. data/platform/osx/bin/RhoSimulator/RhoSimulator.app/Contents/PlugIns/qmltooling/libqmldbg_tcp.dylib +0 -0
  75. data/platform/osx/bin/RhoSimulator/RhoSimulator.app/Contents/Resources/rho.icns +0 -0
  76. data/platform/osx/build/osx.rake +25 -3
  77. data/platform/shared/common/AutoPointer.h +1 -1
  78. data/platform/shared/common/RhoStd.h +10 -10
  79. data/platform/shared/common/RhodesAppBase.cpp +3 -0
  80. data/platform/shared/logging/RhoLogConf.cpp +1 -1
  81. data/platform/shared/qt/rhodes/QtMainWindow.cpp +7 -0
  82. data/platform/shared/qt/rhodes/RhoSimulator.h +3 -1
  83. data/platform/shared/qt/rhodes/main.cpp +3 -0
  84. data/platform/shared/qt/rhodes/resources/rho.icns +0 -0
  85. data/platform/shared/qt/rhodes/resources/rho.ico +0 -0
  86. data/platform/shared/qt/rhodes/resources/rho.png +0 -0
  87. data/platform/shared/qt/rhodes/resources/simulator.qrc +5 -0
  88. data/platform/shared/qt/rhodes/rhodes.pro +2 -0
  89. data/platform/shared/ruby/ext/rho/rhosupport.c +21 -2
  90. data/platform/shared/ruby/ext/socket_192/addrinfo.h +191 -0
  91. data/platform/shared/ruby/ext/socket_192/ancdata.c +1800 -0
  92. data/platform/shared/ruby/ext/socket_192/basicsocket.c +771 -0
  93. data/platform/shared/ruby/ext/socket_192/constants.c +145 -0
  94. data/platform/shared/ruby/ext/socket_192/depend +25 -0
  95. data/platform/shared/ruby/ext/socket_192/extconf.rb +365 -0
  96. data/platform/shared/ruby/ext/socket_192/getaddrinfo.c +674 -0
  97. data/platform/shared/ruby/ext/socket_192/getnameinfo.c +260 -0
  98. data/platform/shared/ruby/ext/socket_192/init.c +575 -0
  99. data/platform/shared/ruby/ext/socket_192/ipsocket.c +308 -0
  100. data/platform/shared/ruby/ext/socket_192/lib/socket.rb +755 -0
  101. data/platform/shared/ruby/ext/socket_192/mkconstants.rb +696 -0
  102. data/platform/shared/ruby/ext/socket_192/option.c +692 -0
  103. data/platform/shared/ruby/ext/socket_192/raddrinfo.c +2211 -0
  104. data/platform/shared/ruby/ext/socket_192/rubysocket.h +306 -0
  105. data/platform/shared/ruby/ext/socket_192/socket.c +1870 -0
  106. data/platform/shared/ruby/ext/socket_192/sockport.h +84 -0
  107. data/platform/shared/ruby/ext/socket_192/sockssocket.c +58 -0
  108. data/platform/shared/ruby/ext/socket_192/tcpserver.c +145 -0
  109. data/platform/shared/ruby/ext/socket_192/tcpsocket.c +69 -0
  110. data/platform/shared/ruby/ext/socket_192/udpsocket.c +264 -0
  111. data/platform/shared/ruby/ext/socket_192/unixserver.c +154 -0
  112. data/platform/shared/ruby/ext/socket_192/unixsocket.c +514 -0
  113. data/platform/shared/ruby/ext/stringio/stringio.c +158 -61
  114. data/platform/shared/ruby/ext/strscan/strscan.c +18 -31
  115. data/platform/shared/ruby/iphone/ruby/config.h +2 -1
  116. data/platform/shared/ruby/linux/ruby/config.h +2 -1
  117. data/platform/shared/ruby/symbian/ruby/config.h +2 -1
  118. data/platform/shared/ruby/win32/ruby/config.h +1 -0
  119. data/platform/shared/ruby/win32/ruby/constdefs.c +5866 -0
  120. data/platform/shared/ruby/win32/ruby/constdefs.h +1788 -0
  121. data/platform/shared/ruby/wince/ruby/config.h +1 -0
  122. data/platform/shared/ruby/wince/ruby/constdefs.c +5866 -0
  123. data/platform/shared/ruby/wince/ruby/constdefs.h +1788 -0
  124. data/platform/symbian/build/symbian.rake +8 -0
  125. data/platform/symbian/rhodes/rhodes.pro +3 -3
  126. data/platform/win32/RhoSimulator/RhoSimulator.exe +0 -0
  127. data/platform/wm/build/wm.rake +1 -1
  128. data/platform/wm/rhodes/Rhodes.cpp +3 -0
  129. data/platform/wm/rhodes/rhodes.vcproj +612 -6
  130. data/platform/wm/rhodes/rhosim.rc +394 -0
  131. data/platform/wm/rhodes/simulator/MainWindowQt.cpp +2 -2
  132. data/platform/wp7/RhoRubyLib/common/RhodesApp.cs +8 -2
  133. data/platform/wp7/RhoRubyLib/net/NetRequest.cs +5 -1
  134. data/platform/wp7/build/wp.rake +1 -1
  135. data/rakefile.rb +52 -7
  136. data/res/generators/templates/application/app/layout.erb +4 -4
  137. data/res/generators/templates/application/public/jqmobile/{jquery.mobile-1.0b3.css → jquery.mobile-1.0rc1.css} +507 -457
  138. data/res/generators/templates/application/public/jqmobile/{jquery.mobile-1.0b3.js → jquery.mobile-1.0rc1.js} +565 -458
  139. data/res/generators/templates/application/public/jqmobile/jquery.mobile-1.0rc1.min.css +12 -0
  140. data/res/generators/templates/application/public/jqmobile/jquery.mobile-1.0rc1.min.js +170 -0
  141. data/res/generators/templates/application/public/jquery/{jquery-1.6.3.js → jquery-1.6.4.js} +10 -8
  142. data/res/generators/templates/application/public/jquery/jquery-1.6.4.min.js +4 -0
  143. data/res/generators/templates/application/public/js/jqmobile-patch.js +47 -1
  144. data/res/icons/rho.icns +0 -0
  145. data/res/icons/rho.ico +0 -0
  146. data/res/icons/rho.png +0 -0
  147. data/res/icons/rho.psd +0 -0
  148. data/res/icons/rhodes.icns +0 -0
  149. data/res/icons/rhodes.ico +0 -0
  150. data/res/icons/rhodes.png +0 -0
  151. data/res/icons/rhodes.psd +0 -0
  152. data/res/icons/rhosim.icns +0 -0
  153. data/res/icons/rhosim.ico +0 -0
  154. data/res/icons/rhosim.png +0 -0
  155. data/res/icons/rhosim.psd +0 -0
  156. data/rhodes.gemspec +1 -1
  157. data/spec/framework_spec/app/spec/core/file/expand_path_spec.rb +4 -4
  158. data/spec/framework_spec/app/spec/library/net/FTPError_spec.rb +8 -0
  159. data/spec/framework_spec/app/spec/library/net/FTPPermError_spec.rb +12 -0
  160. data/spec/framework_spec/app/spec/library/net/FTPProtoError_spec.rb +12 -0
  161. data/spec/framework_spec/app/spec/library/net/FTPReplyError_spec.rb +12 -0
  162. data/spec/framework_spec/app/spec/library/net/FTPTempError_spec.rb +12 -0
  163. data/spec/framework_spec/app/spec/library/net/ftp/abort_spec.rb +62 -0
  164. data/spec/framework_spec/app/spec/library/net/ftp/acct_spec.rb +58 -0
  165. data/spec/framework_spec/app/spec/library/net/ftp/binary_spec.rb +24 -0
  166. data/spec/framework_spec/app/spec/library/net/ftp/chdir_spec.rb +101 -0
  167. data/spec/framework_spec/app/spec/library/net/ftp/close_spec.rb +28 -0
  168. data/spec/framework_spec/app/spec/library/net/ftp/closed_spec.rb +21 -0
  169. data/spec/framework_spec/app/spec/library/net/ftp/connect_spec.rb +49 -0
  170. data/spec/framework_spec/app/spec/library/net/ftp/debug_mode_spec.rb +23 -0
  171. data/spec/framework_spec/app/spec/library/net/ftp/delete_spec.rb +59 -0
  172. data/spec/framework_spec/app/spec/library/net/ftp/dir_spec.rb +8 -0
  173. data/spec/framework_spec/app/spec/library/net/ftp/fixtures/putbinaryfile +3 -0
  174. data/spec/framework_spec/app/spec/library/net/ftp/fixtures/puttextfile +3 -0
  175. data/spec/framework_spec/app/spec/library/net/ftp/fixtures/server.rb +258 -0
  176. data/spec/framework_spec/app/spec/library/net/ftp/get_spec.rb +21 -0
  177. data/spec/framework_spec/app/spec/library/net/ftp/getbinaryfile_spec.rb +8 -0
  178. data/spec/framework_spec/app/spec/library/net/ftp/getdir_spec.rb +7 -0
  179. data/spec/framework_spec/app/spec/library/net/ftp/gettextfile_spec.rb +8 -0
  180. data/spec/framework_spec/app/spec/library/net/ftp/help_spec.rb +66 -0
  181. data/spec/framework_spec/app/spec/library/net/ftp/initialize_spec.rb +87 -0
  182. data/spec/framework_spec/app/spec/library/net/ftp/last_response_code_spec.rb +8 -0
  183. data/spec/framework_spec/app/spec/library/net/ftp/last_response_spec.rb +25 -0
  184. data/spec/framework_spec/app/spec/library/net/ftp/lastresp_spec.rb +8 -0
  185. data/spec/framework_spec/app/spec/library/net/ftp/list_spec.rb +8 -0
  186. data/spec/framework_spec/app/spec/library/net/ftp/login_spec.rb +216 -0
  187. data/spec/framework_spec/app/spec/library/net/ftp/ls_spec.rb +8 -0
  188. data/spec/framework_spec/app/spec/library/net/ftp/mdtm_spec.rb +38 -0
  189. data/spec/framework_spec/app/spec/library/net/ftp/mkdir_spec.rb +61 -0
  190. data/spec/framework_spec/app/spec/library/net/ftp/mtime_spec.rb +50 -0
  191. data/spec/framework_spec/app/spec/library/net/ftp/nlst_spec.rb +122 -0
  192. data/spec/framework_spec/app/spec/library/net/ftp/noop_spec.rb +38 -0
  193. data/spec/framework_spec/app/spec/library/net/ftp/open_spec.rb +55 -0
  194. data/spec/framework_spec/app/spec/library/net/ftp/passive_spec.rb +24 -0
  195. data/spec/framework_spec/app/spec/library/net/ftp/put_spec.rb +21 -0
  196. data/spec/framework_spec/app/spec/library/net/ftp/putbinaryfile_spec.rb +8 -0
  197. data/spec/framework_spec/app/spec/library/net/ftp/puttextfile_spec.rb +8 -0
  198. data/spec/framework_spec/app/spec/library/net/ftp/pwd_spec.rb +53 -0
  199. data/spec/framework_spec/app/spec/library/net/ftp/quit_spec.rb +33 -0
  200. data/spec/framework_spec/app/spec/library/net/ftp/rename_spec.rb +94 -0
  201. data/spec/framework_spec/app/spec/library/net/ftp/resume_spec.rb +23 -0
  202. data/spec/framework_spec/app/spec/library/net/ftp/retrbinary_spec.rb +31 -0
  203. data/spec/framework_spec/app/spec/library/net/ftp/retrlines_spec.rb +35 -0
  204. data/spec/framework_spec/app/spec/library/net/ftp/return_code_spec.rb +24 -0
  205. data/spec/framework_spec/app/spec/library/net/ftp/rmdir_spec.rb +58 -0
  206. data/spec/framework_spec/app/spec/library/net/ftp/sendcmd_spec.rb +54 -0
  207. data/spec/framework_spec/app/spec/library/net/ftp/set_socket_spec.rb +8 -0
  208. data/spec/framework_spec/app/spec/library/net/ftp/shared/getbinaryfile.rb +180 -0
  209. data/spec/framework_spec/app/spec/library/net/ftp/shared/gettextfile.rb +130 -0
  210. data/spec/framework_spec/app/spec/library/net/ftp/shared/last_response_code.rb +25 -0
  211. data/spec/framework_spec/app/spec/library/net/ftp/shared/list.rb +134 -0
  212. data/spec/framework_spec/app/spec/library/net/ftp/shared/putbinaryfile.rb +233 -0
  213. data/spec/framework_spec/app/spec/library/net/ftp/shared/puttextfile.rb +150 -0
  214. data/spec/framework_spec/app/spec/library/net/ftp/shared/pwd.rb +3 -0
  215. data/spec/framework_spec/app/spec/library/net/ftp/site_spec.rb +53 -0
  216. data/spec/framework_spec/app/spec/library/net/ftp/size_spec.rb +48 -0
  217. data/spec/framework_spec/app/spec/library/net/ftp/status_spec.rb +63 -0
  218. data/spec/framework_spec/app/spec/library/net/ftp/storbinary_spec.rb +49 -0
  219. data/spec/framework_spec/app/spec/library/net/ftp/storlines_spec.rb +44 -0
  220. data/spec/framework_spec/app/spec/library/net/ftp/system_spec.rb +48 -0
  221. data/spec/framework_spec/app/spec/library/net/ftp/voidcmd_spec.rb +54 -0
  222. data/spec/framework_spec/app/spec/library/net/ftp/welcome_spec.rb +25 -0
  223. data/spec/framework_spec/app/spec/library/net/http/HTTPBadResponse_spec.rb +8 -0
  224. data/spec/framework_spec/app/spec/library/net/http/HTTPError_spec.rb +12 -0
  225. data/spec/framework_spec/app/spec/library/net/http/HTTPFatalError_spec.rb +12 -0
  226. data/spec/framework_spec/app/spec/library/net/http/HTTPHeaderSyntaxError_spec.rb +8 -0
  227. data/spec/framework_spec/app/spec/library/net/http/HTTPRetriableError_spec.rb +12 -0
  228. data/spec/framework_spec/app/spec/library/net/http/HTTPServerException_spec.rb +12 -0
  229. data/spec/framework_spec/app/spec/library/net/http/http/Proxy_spec.rb +35 -0
  230. data/spec/framework_spec/app/spec/library/net/http/http/active_spec.rb +8 -0
  231. data/spec/framework_spec/app/spec/library/net/http/http/address_spec.rb +9 -0
  232. data/spec/framework_spec/app/spec/library/net/http/http/close_on_empty_response_spec.rb +10 -0
  233. data/spec/framework_spec/app/spec/library/net/http/http/copy_spec.rb +23 -0
  234. data/spec/framework_spec/app/spec/library/net/http/http/default_port_spec.rb +8 -0
  235. data/spec/framework_spec/app/spec/library/net/http/http/delete_spec.rb +23 -0
  236. data/spec/framework_spec/app/spec/library/net/http/http/finish_spec.rb +31 -0
  237. data/spec/framework_spec/app/spec/library/net/http/http/fixtures/http_server.rb +97 -0
  238. data/spec/framework_spec/app/spec/library/net/http/http/get2_spec.rb +8 -0
  239. data/spec/framework_spec/app/spec/library/net/http/http/get_print_spec.rb +29 -0
  240. data/spec/framework_spec/app/spec/library/net/http/http/get_response_spec.rb +29 -0
  241. data/spec/framework_spec/app/spec/library/net/http/http/get_spec.rb +52 -0
  242. data/spec/framework_spec/app/spec/library/net/http/http/head2_spec.rb +9 -0
  243. data/spec/framework_spec/app/spec/library/net/http/http/head_spec.rb +27 -0
  244. data/spec/framework_spec/app/spec/library/net/http/http/http_default_port_spec.rb +8 -0
  245. data/spec/framework_spec/app/spec/library/net/http/http/https_default_port_spec.rb +8 -0
  246. data/spec/framework_spec/app/spec/library/net/http/http/initialize_spec.rb +46 -0
  247. data/spec/framework_spec/app/spec/library/net/http/http/inspect_spec.rb +26 -0
  248. data/spec/framework_spec/app/spec/library/net/http/http/is_version_1_1_spec.rb +7 -0
  249. data/spec/framework_spec/app/spec/library/net/http/http/is_version_1_2_spec.rb +7 -0
  250. data/spec/framework_spec/app/spec/library/net/http/http/lock_spec.rb +23 -0
  251. data/spec/framework_spec/app/spec/library/net/http/http/mkcol_spec.rb +23 -0
  252. data/spec/framework_spec/app/spec/library/net/http/http/move_spec.rb +27 -0
  253. data/spec/framework_spec/app/spec/library/net/http/http/new_spec.rb +86 -0
  254. data/spec/framework_spec/app/spec/library/net/http/http/newobj_spec.rb +48 -0
  255. data/spec/framework_spec/app/spec/library/net/http/http/open_timeout_spec.rb +24 -0
  256. data/spec/framework_spec/app/spec/library/net/http/http/options_spec.rb +27 -0
  257. data/spec/framework_spec/app/spec/library/net/http/http/port_spec.rb +9 -0
  258. data/spec/framework_spec/app/spec/library/net/http/http/post2_spec.rb +8 -0
  259. data/spec/framework_spec/app/spec/library/net/http/http/post_form_spec.rb +21 -0
  260. data/spec/framework_spec/app/spec/library/net/http/http/post_spec.rb +40 -0
  261. data/spec/framework_spec/app/spec/library/net/http/http/propfind_spec.rb +26 -0
  262. data/spec/framework_spec/app/spec/library/net/http/http/proppatch_spec.rb +26 -0
  263. data/spec/framework_spec/app/spec/library/net/http/http/proxy_address_spec.rb +31 -0
  264. data/spec/framework_spec/app/spec/library/net/http/http/proxy_class_spec.rb +9 -0
  265. data/spec/framework_spec/app/spec/library/net/http/http/proxy_pass_spec.rb +39 -0
  266. data/spec/framework_spec/app/spec/library/net/http/http/proxy_port_spec.rb +39 -0
  267. data/spec/framework_spec/app/spec/library/net/http/http/proxy_user_spec.rb +39 -0
  268. data/spec/framework_spec/app/spec/library/net/http/http/put2_spec.rb +8 -0
  269. data/spec/framework_spec/app/spec/library/net/http/http/put_spec.rb +26 -0
  270. data/spec/framework_spec/app/spec/library/net/http/http/read_timeout_spec.rb +24 -0
  271. data/spec/framework_spec/app/spec/library/net/http/http/request_get_spec.rb +8 -0
  272. data/spec/framework_spec/app/spec/library/net/http/http/request_head_spec.rb +8 -0
  273. data/spec/framework_spec/app/spec/library/net/http/http/request_post_spec.rb +8 -0
  274. data/spec/framework_spec/app/spec/library/net/http/http/request_put_spec.rb +8 -0
  275. data/spec/framework_spec/app/spec/library/net/http/http/request_spec.rb +111 -0
  276. data/spec/framework_spec/app/spec/library/net/http/http/request_types_spec.rb +254 -0
  277. data/spec/framework_spec/app/spec/library/net/http/http/send_request_spec.rb +120 -0
  278. data/spec/framework_spec/app/spec/library/net/http/http/set_debug_output_spec.rb +35 -0
  279. data/spec/framework_spec/app/spec/library/net/http/http/shared/request_get.rb +45 -0
  280. data/spec/framework_spec/app/spec/library/net/http/http/shared/request_head.rb +45 -0
  281. data/spec/framework_spec/app/spec/library/net/http/http/shared/request_post.rb +45 -0
  282. data/spec/framework_spec/app/spec/library/net/http/http/shared/request_put.rb +45 -0
  283. data/spec/framework_spec/app/spec/library/net/http/http/shared/started.rb +28 -0
  284. data/spec/framework_spec/app/spec/library/net/http/http/shared/version_1_1.rb +19 -0
  285. data/spec/framework_spec/app/spec/library/net/http/http/shared/version_1_2.rb +6 -0
  286. data/spec/framework_spec/app/spec/library/net/http/http/socket_type_spec.rb +8 -0
  287. data/spec/framework_spec/app/spec/library/net/http/http/start_spec.rb +103 -0
  288. data/spec/framework_spec/app/spec/library/net/http/http/started_spec.rb +8 -0
  289. data/spec/framework_spec/app/spec/library/net/http/http/trace_spec.rb +26 -0
  290. data/spec/framework_spec/app/spec/library/net/http/http/unlock_spec.rb +26 -0
  291. data/spec/framework_spec/app/spec/library/net/http/http/use_ssl_spec.rb +9 -0
  292. data/spec/framework_spec/app/spec/library/net/http/http/version_1_1_spec.rb +22 -0
  293. data/spec/framework_spec/app/spec/library/net/http/http/version_1_2_spec.rb +20 -0
  294. data/spec/framework_spec/app/spec/library/net/http/httpexceptions/fixtures/classes.rb +5 -0
  295. data/spec/framework_spec/app/spec/library/net/http/httpexceptions/initialize_spec.rb +17 -0
  296. data/spec/framework_spec/app/spec/library/net/http/httpexceptions/response_spec.rb +10 -0
  297. data/spec/framework_spec/app/spec/library/net/http/httpgenericrequest/body_exist_spec.rb +27 -0
  298. data/spec/framework_spec/app/spec/library/net/http/httpgenericrequest/body_spec.rb +30 -0
  299. data/spec/framework_spec/app/spec/library/net/http/httpgenericrequest/body_stream_spec.rb +32 -0
  300. data/spec/framework_spec/app/spec/library/net/http/httpgenericrequest/exec_spec.rb +122 -0
  301. data/spec/framework_spec/app/spec/library/net/http/httpgenericrequest/inspect_spec.rb +25 -0
  302. data/spec/framework_spec/app/spec/library/net/http/httpgenericrequest/method_spec.rb +15 -0
  303. data/spec/framework_spec/app/spec/library/net/http/httpgenericrequest/path_spec.rb +12 -0
  304. data/spec/framework_spec/app/spec/library/net/http/httpgenericrequest/request_body_permitted_spec.rb +12 -0
  305. data/spec/framework_spec/app/spec/library/net/http/httpgenericrequest/response_body_permitted_spec.rb +12 -0
  306. data/spec/framework_spec/app/spec/library/net/http/httpgenericrequest/set_body_internal_spec.rb +21 -0
  307. data/spec/framework_spec/app/spec/library/net/http/httpheader/add_field_spec.rb +31 -0
  308. data/spec/framework_spec/app/spec/library/net/http/httpheader/basic_auth_spec.rb +14 -0
  309. data/spec/framework_spec/app/spec/library/net/http/httpheader/canonical_each_spec.rb +8 -0
  310. data/spec/framework_spec/app/spec/library/net/http/httpheader/chunked_spec.rb +22 -0
  311. data/spec/framework_spec/app/spec/library/net/http/httpheader/content_length_spec.rb +54 -0
  312. data/spec/framework_spec/app/spec/library/net/http/httpheader/content_range_spec.rb +34 -0
  313. data/spec/framework_spec/app/spec/library/net/http/httpheader/content_type_spec.rb +26 -0
  314. data/spec/framework_spec/app/spec/library/net/http/httpheader/delete_spec.rb +30 -0
  315. data/spec/framework_spec/app/spec/library/net/http/httpheader/each_capitalized_name_spec.rb +45 -0
  316. data/spec/framework_spec/app/spec/library/net/http/httpheader/each_capitalized_spec.rb +9 -0
  317. data/spec/framework_spec/app/spec/library/net/http/httpheader/each_header_spec.rb +8 -0
  318. data/spec/framework_spec/app/spec/library/net/http/httpheader/each_key_spec.rb +8 -0
  319. data/spec/framework_spec/app/spec/library/net/http/httpheader/each_name_spec.rb +8 -0
  320. data/spec/framework_spec/app/spec/library/net/http/httpheader/each_spec.rb +8 -0
  321. data/spec/framework_spec/app/spec/library/net/http/httpheader/each_value_spec.rb +46 -0
  322. data/spec/framework_spec/app/spec/library/net/http/httpheader/element_reference_spec.rb +39 -0
  323. data/spec/framework_spec/app/spec/library/net/http/httpheader/element_set_spec.rb +41 -0
  324. data/spec/framework_spec/app/spec/library/net/http/httpheader/fetch_spec.rb +69 -0
  325. data/spec/framework_spec/app/spec/library/net/http/httpheader/fixtures/classes.rb +11 -0
  326. data/spec/framework_spec/app/spec/library/net/http/httpheader/form_data_spec.rb +8 -0
  327. data/spec/framework_spec/app/spec/library/net/http/httpheader/get_fields_spec.rb +39 -0
  328. data/spec/framework_spec/app/spec/library/net/http/httpheader/initialize_http_header_spec.rb +29 -0
  329. data/spec/framework_spec/app/spec/library/net/http/httpheader/key_spec.rb +21 -0
  330. data/spec/framework_spec/app/spec/library/net/http/httpheader/length_spec.rb +8 -0
  331. data/spec/framework_spec/app/spec/library/net/http/httpheader/main_type_spec.rb +24 -0
  332. data/spec/framework_spec/app/spec/library/net/http/httpheader/proxy_basic_auth_spec.rb +14 -0
  333. data/spec/framework_spec/app/spec/library/net/http/httpheader/range_length_spec.rb +32 -0
  334. data/spec/framework_spec/app/spec/library/net/http/httpheader/range_spec.rb +48 -0
  335. data/spec/framework_spec/app/spec/library/net/http/httpheader/set_content_type_spec.rb +8 -0
  336. data/spec/framework_spec/app/spec/library/net/http/httpheader/set_form_data_spec.rb +8 -0
  337. data/spec/framework_spec/app/spec/library/net/http/httpheader/set_range_spec.rb +8 -0
  338. data/spec/framework_spec/app/spec/library/net/http/httpheader/shared/each_capitalized.rb +42 -0
  339. data/spec/framework_spec/app/spec/library/net/http/httpheader/shared/each_header.rb +42 -0
  340. data/spec/framework_spec/app/spec/library/net/http/httpheader/shared/each_name.rb +39 -0
  341. data/spec/framework_spec/app/spec/library/net/http/httpheader/shared/set_content_type.rb +18 -0
  342. data/spec/framework_spec/app/spec/library/net/http/httpheader/shared/set_form_data.rb +27 -0
  343. data/spec/framework_spec/app/spec/library/net/http/httpheader/shared/set_range.rb +89 -0
  344. data/spec/framework_spec/app/spec/library/net/http/httpheader/shared/size.rb +18 -0
  345. data/spec/framework_spec/app/spec/library/net/http/httpheader/size_spec.rb +8 -0
  346. data/spec/framework_spec/app/spec/library/net/http/httpheader/sub_type_spec.rb +32 -0
  347. data/spec/framework_spec/app/spec/library/net/http/httpheader/to_hash_spec.rb +25 -0
  348. data/spec/framework_spec/app/spec/library/net/http/httpheader/type_params_spec.rb +24 -0
  349. data/spec/framework_spec/app/spec/library/net/http/httprequest/initialize_spec.rb +45 -0
  350. data/spec/framework_spec/app/spec/library/net/http/httpresponse/body_permitted_spec.rb +13 -0
  351. data/spec/framework_spec/app/spec/library/net/http/httpresponse/body_spec.rb +7 -0
  352. data/spec/framework_spec/app/spec/library/net/http/httpresponse/code_spec.rb +24 -0
  353. data/spec/framework_spec/app/spec/library/net/http/httpresponse/code_type_spec.rb +24 -0
  354. data/spec/framework_spec/app/spec/library/net/http/httpresponse/entity_spec.rb +7 -0
  355. data/spec/framework_spec/app/spec/library/net/http/httpresponse/error_spec.rb +24 -0
  356. data/spec/framework_spec/app/spec/library/net/http/httpresponse/error_type_spec.rb +24 -0
  357. data/spec/framework_spec/app/spec/library/net/http/httpresponse/exception_type_spec.rb +13 -0
  358. data/spec/framework_spec/app/spec/library/net/http/httpresponse/header_spec.rb +9 -0
  359. data/spec/framework_spec/app/spec/library/net/http/httpresponse/http_version_spec.rb +12 -0
  360. data/spec/framework_spec/app/spec/library/net/http/httpresponse/initialize_spec.rb +11 -0
  361. data/spec/framework_spec/app/spec/library/net/http/httpresponse/inspect_spec.rb +15 -0
  362. data/spec/framework_spec/app/spec/library/net/http/httpresponse/message_spec.rb +9 -0
  363. data/spec/framework_spec/app/spec/library/net/http/httpresponse/msg_spec.rb +9 -0
  364. data/spec/framework_spec/app/spec/library/net/http/httpresponse/read_body_spec.rb +86 -0
  365. data/spec/framework_spec/app/spec/library/net/http/httpresponse/read_header_spec.rb +9 -0
  366. data/spec/framework_spec/app/spec/library/net/http/httpresponse/read_new_spec.rb +22 -0
  367. data/spec/framework_spec/app/spec/library/net/http/httpresponse/reading_body_spec.rb +58 -0
  368. data/spec/framework_spec/app/spec/library/net/http/httpresponse/response_spec.rb +9 -0
  369. data/spec/framework_spec/app/spec/library/net/http/httpresponse/shared/body.rb +18 -0
  370. data/spec/framework_spec/app/spec/library/net/http/httpresponse/to_ary_spec.rb +26 -0
  371. data/spec/framework_spec/app/spec/library/net/http/httpresponse/value_spec.rb +24 -0
  372. data/spec/framework_spec/app/spec/library/rexml/attribute/clone_spec.rb +11 -0
  373. data/spec/framework_spec/app/spec/library/rexml/attribute/element_spec.rb +23 -0
  374. data/spec/framework_spec/app/spec/library/rexml/attribute/equal_value_spec.rb +18 -0
  375. data/spec/framework_spec/app/spec/library/rexml/attribute/hash_spec.rb +13 -0
  376. data/spec/framework_spec/app/spec/library/rexml/attribute/initialize_spec.rb +29 -0
  377. data/spec/framework_spec/app/spec/library/rexml/attribute/inspect_spec.rb +20 -0
  378. data/spec/framework_spec/app/spec/library/rexml/attribute/namespace_spec.rb +24 -0
  379. data/spec/framework_spec/app/spec/library/rexml/attribute/node_type_spec.rb +10 -0
  380. data/spec/framework_spec/app/spec/library/rexml/attribute/prefix_spec.rb +18 -0
  381. data/spec/framework_spec/app/spec/library/rexml/attribute/remove_spec.rb +20 -0
  382. data/spec/framework_spec/app/spec/library/rexml/attribute/to_s_spec.rb +14 -0
  383. data/spec/framework_spec/app/spec/library/rexml/attribute/to_string_spec.rb +15 -0
  384. data/spec/framework_spec/app/spec/library/rexml/attribute/value_spec.rb +15 -0
  385. data/spec/framework_spec/app/spec/library/rexml/attribute/write_spec.rb +23 -0
  386. data/spec/framework_spec/app/spec/library/rexml/attribute/xpath_spec.rb +20 -0
  387. data/spec/framework_spec/app/spec/library/rexml/attributes/add_spec.rb +7 -0
  388. data/spec/framework_spec/app/spec/library/rexml/attributes/append_spec.rb +7 -0
  389. data/spec/framework_spec/app/spec/library/rexml/attributes/delete_all_spec.rb +31 -0
  390. data/spec/framework_spec/app/spec/library/rexml/attributes/delete_spec.rb +27 -0
  391. data/spec/framework_spec/app/spec/library/rexml/attributes/each_attribute_spec.rb +24 -0
  392. data/spec/framework_spec/app/spec/library/rexml/attributes/each_spec.rb +24 -0
  393. data/spec/framework_spec/app/spec/library/rexml/attributes/element_reference_spec.rb +19 -0
  394. data/spec/framework_spec/app/spec/library/rexml/attributes/element_set_spec.rb +26 -0
  395. data/spec/framework_spec/app/spec/library/rexml/attributes/get_attribute_ns_spec.rb +14 -0
  396. data/spec/framework_spec/app/spec/library/rexml/attributes/get_attribute_spec.rb +29 -0
  397. data/spec/framework_spec/app/spec/library/rexml/attributes/initialize_spec.rb +19 -0
  398. data/spec/framework_spec/app/spec/library/rexml/attributes/length_spec.rb +7 -0
  399. data/spec/framework_spec/app/spec/library/rexml/attributes/namespaces_spec.rb +6 -0
  400. data/spec/framework_spec/app/spec/library/rexml/attributes/prefixes_spec.rb +24 -0
  401. data/spec/framework_spec/app/spec/library/rexml/attributes/shared/add.rb +17 -0
  402. data/spec/framework_spec/app/spec/library/rexml/attributes/shared/length.rb +13 -0
  403. data/spec/framework_spec/app/spec/library/rexml/attributes/size_spec.rb +7 -0
  404. data/spec/framework_spec/app/spec/library/rexml/attributes/to_a_spec.rb +20 -0
  405. data/spec/framework_spec/app/spec/library/rexml/cdata/clone_spec.rb +10 -0
  406. data/spec/framework_spec/app/spec/library/rexml/cdata/initialize_spec.rb +25 -0
  407. data/spec/framework_spec/app/spec/library/rexml/cdata/shared/to_s.rb +11 -0
  408. data/spec/framework_spec/app/spec/library/rexml/cdata/to_s_spec.rb +7 -0
  409. data/spec/framework_spec/app/spec/library/rexml/cdata/value_spec.rb +7 -0
  410. data/spec/framework_spec/app/spec/library/rexml/document/add_element_spec.rb +31 -0
  411. data/spec/framework_spec/app/spec/library/rexml/document/add_spec.rb +61 -0
  412. data/spec/framework_spec/app/spec/library/rexml/document/clone_spec.rb +20 -0
  413. data/spec/framework_spec/app/spec/library/rexml/document/doctype_spec.rb +15 -0
  414. data/spec/framework_spec/app/spec/library/rexml/document/encoding_spec.rb +22 -0
  415. data/spec/framework_spec/app/spec/library/rexml/document/expanded_name_spec.rb +16 -0
  416. data/spec/framework_spec/app/spec/library/rexml/document/new_spec.rb +38 -0
  417. data/spec/framework_spec/app/spec/library/rexml/document/node_type_spec.rb +8 -0
  418. data/spec/framework_spec/app/spec/library/rexml/document/root_spec.rb +12 -0
  419. data/spec/framework_spec/app/spec/library/rexml/document/stand_alone_spec.rb +19 -0
  420. data/spec/framework_spec/app/spec/library/rexml/document/version_spec.rb +14 -0
  421. data/spec/framework_spec/app/spec/library/rexml/document/write_spec.rb +39 -0
  422. data/spec/framework_spec/app/spec/library/rexml/document/xml_decl_spec.rb +15 -0
  423. data/spec/framework_spec/app/spec/library/rexml/element/add_attribute_spec.rb +41 -0
  424. data/spec/framework_spec/app/spec/library/rexml/element/add_attributes_spec.rb +22 -0
  425. data/spec/framework_spec/app/spec/library/rexml/element/add_element_spec.rb +39 -0
  426. data/spec/framework_spec/app/spec/library/rexml/element/add_namespace_spec.rb +24 -0
  427. data/spec/framework_spec/app/spec/library/rexml/element/add_text_spec.rb +24 -0
  428. data/spec/framework_spec/app/spec/library/rexml/element/attribute_spec.rb +17 -0
  429. data/spec/framework_spec/app/spec/library/rexml/element/attributes_spec.rb +19 -0
  430. data/spec/framework_spec/app/spec/library/rexml/element/cdatas_spec.rb +24 -0
  431. data/spec/framework_spec/app/spec/library/rexml/element/clone_spec.rb +29 -0
  432. data/spec/framework_spec/app/spec/library/rexml/element/comments_spec.rb +21 -0
  433. data/spec/framework_spec/app/spec/library/rexml/element/delete_attribute_spec.rb +39 -0
  434. data/spec/framework_spec/app/spec/library/rexml/element/delete_element_spec.rb +51 -0
  435. data/spec/framework_spec/app/spec/library/rexml/element/delete_namespace_spec.rb +25 -0
  436. data/spec/framework_spec/app/spec/library/rexml/element/document_spec.rb +18 -0
  437. data/spec/framework_spec/app/spec/library/rexml/element/each_element_with_attribute_spec.rb +35 -0
  438. data/spec/framework_spec/app/spec/library/rexml/element/each_element_with_text_spec.rb +31 -0
  439. data/spec/framework_spec/app/spec/library/rexml/element/get_text_spec.rb +18 -0
  440. data/spec/framework_spec/app/spec/library/rexml/element/has_attributes_spec.rb +17 -0
  441. data/spec/framework_spec/app/spec/library/rexml/element/has_elements_spec.rb +18 -0
  442. data/spec/framework_spec/app/spec/library/rexml/element/has_text_spec.rb +16 -0
  443. data/spec/framework_spec/app/spec/library/rexml/element/inspect_spec.rb +27 -0
  444. data/spec/framework_spec/app/spec/library/rexml/element/instructions_spec.rb +21 -0
  445. data/spec/framework_spec/app/spec/library/rexml/element/namespace_spec.rb +27 -0
  446. data/spec/framework_spec/app/spec/library/rexml/element/namespaces_spec.rb +32 -0
  447. data/spec/framework_spec/app/spec/library/rexml/element/new_spec.rb +35 -0
  448. data/spec/framework_spec/app/spec/library/rexml/element/next_element_spec.rb +19 -0
  449. data/spec/framework_spec/app/spec/library/rexml/element/node_type_spec.rb +8 -0
  450. data/spec/framework_spec/app/spec/library/rexml/element/prefixes_spec.rb +23 -0
  451. data/spec/framework_spec/app/spec/library/rexml/element/previous_element_spec.rb +20 -0
  452. data/spec/framework_spec/app/spec/library/rexml/element/raw_spec.rb +24 -0
  453. data/spec/framework_spec/app/spec/library/rexml/element/root_spec.rb +28 -0
  454. data/spec/framework_spec/app/spec/library/rexml/element/text_spec.rb +46 -0
  455. data/spec/framework_spec/app/spec/library/rexml/element/texts_spec.rb +16 -0
  456. data/spec/framework_spec/app/spec/library/rexml/element/whitespace_spec.rb +23 -0
  457. data/spec/framework_spec/app/spec/library/rexml/node/each_recursive_spec.rb +21 -0
  458. data/spec/framework_spec/app/spec/library/rexml/node/find_first_recursive_spec.rb +25 -0
  459. data/spec/framework_spec/app/spec/library/rexml/node/index_in_parent_spec.rb +15 -0
  460. data/spec/framework_spec/app/spec/library/rexml/node/next_sibling_node_spec.rb +21 -0
  461. data/spec/framework_spec/app/spec/library/rexml/node/parent_spec.rb +21 -0
  462. data/spec/framework_spec/app/spec/library/rexml/node/previous_sibling_node_spec.rb +21 -0
  463. data/spec/framework_spec/app/spec/library/rexml/shared/each_element.rb +36 -0
  464. data/spec/framework_spec/app/spec/library/rexml/shared/elements_to_a.rb +36 -0
  465. data/spec/framework_spec/app/spec/library/rexml/text/append_spec.rb +10 -0
  466. data/spec/framework_spec/app/spec/library/rexml/text/clone_spec.rb +10 -0
  467. data/spec/framework_spec/app/spec/library/rexml/text/comparison_spec.rb +25 -0
  468. data/spec/framework_spec/app/spec/library/rexml/text/empty_spec.rb +12 -0
  469. data/spec/framework_spec/app/spec/library/rexml/text/indent_text_spec.rb +24 -0
  470. data/spec/framework_spec/app/spec/library/rexml/text/inspect_spec.rb +8 -0
  471. data/spec/framework_spec/app/spec/library/rexml/text/new_spec.rb +49 -0
  472. data/spec/framework_spec/app/spec/library/rexml/text/node_type_spec.rb +8 -0
  473. data/spec/framework_spec/app/spec/library/rexml/text/normalize_spec.rb +8 -0
  474. data/spec/framework_spec/app/spec/library/rexml/text/read_with_substitution_spec.rb +13 -0
  475. data/spec/framework_spec/app/spec/library/rexml/text/to_s_spec.rb +18 -0
  476. data/spec/framework_spec/app/spec/library/rexml/text/unnormalize_spec.rb +8 -0
  477. data/spec/framework_spec/app/spec/library/rexml/text/value_spec.rb +37 -0
  478. data/spec/framework_spec/app/spec/library/rexml/text/wrap_spec.rb +21 -0
  479. data/spec/framework_spec/app/spec/library/rexml/text/write_with_substitution_spec.rb +33 -0
  480. data/spec/framework_spec/app/spec/library/set/exclusion_spec.rb +2 -2
  481. data/spec/framework_spec/app/spec/library/set/merge_spec.rb +2 -2
  482. data/spec/framework_spec/app/spec/library/set/shared/difference.rb +2 -2
  483. data/spec/framework_spec/app/spec/library/set/shared/intersection.rb +2 -2
  484. data/spec/framework_spec/app/spec/library/set/shared/union.rb +2 -2
  485. data/spec/framework_spec/app/spec/library/set/sortedset/exclusion_spec.rb +2 -2
  486. data/spec/framework_spec/app/spec/library/set/sortedset/merge_spec.rb +2 -2
  487. data/spec/framework_spec/app/spec/library/set/sortedset/shared/difference.rb +2 -2
  488. data/spec/framework_spec/app/spec/library/set/sortedset/shared/intersection.rb +2 -2
  489. data/spec/framework_spec/app/spec/library/set/sortedset/shared/union.rb +2 -2
  490. data/spec/framework_spec/app/spec/library/timeout/timeout_spec.rb +37 -0
  491. data/spec/framework_spec/app/spec/library/uri/eql_spec.rb +12 -0
  492. data/spec/framework_spec/app/spec/library/uri/equality_spec.rb +48 -0
  493. data/spec/framework_spec/app/spec/library/uri/escape/decode_spec.rb +6 -0
  494. data/spec/framework_spec/app/spec/library/uri/escape/encode_spec.rb +6 -0
  495. data/spec/framework_spec/app/spec/library/uri/escape/escape_spec.rb +6 -0
  496. data/spec/framework_spec/app/spec/library/uri/escape/unescape_spec.rb +6 -0
  497. data/spec/framework_spec/app/spec/library/uri/extract_spec.rb +86 -0
  498. data/spec/framework_spec/app/spec/library/uri/fixtures/classes.rb +11 -0
  499. data/spec/framework_spec/app/spec/library/uri/fixtures/normalization.rb +54 -0
  500. data/spec/framework_spec/app/spec/library/uri/ftp/build_spec.rb +6 -0
  501. data/spec/framework_spec/app/spec/library/uri/ftp/merge_spec.rb +6 -0
  502. data/spec/framework_spec/app/spec/library/uri/ftp/new2_spec.rb +6 -0
  503. data/spec/framework_spec/app/spec/library/uri/ftp/path_spec.rb +56 -0
  504. data/spec/framework_spec/app/spec/library/uri/ftp/set_typecode_spec.rb +6 -0
  505. data/spec/framework_spec/app/spec/library/uri/ftp/to_s_spec.rb +25 -0
  506. data/spec/framework_spec/app/spec/library/uri/ftp/typecode_spec.rb +10 -0
  507. data/spec/framework_spec/app/spec/library/uri/generic/absolute_spec.rb +10 -0
  508. data/spec/framework_spec/app/spec/library/uri/generic/build2_spec.rb +6 -0
  509. data/spec/framework_spec/app/spec/library/uri/generic/build_spec.rb +6 -0
  510. data/spec/framework_spec/app/spec/library/uri/generic/coerce_spec.rb +6 -0
  511. data/spec/framework_spec/app/spec/library/uri/generic/component_ary_spec.rb +6 -0
  512. data/spec/framework_spec/app/spec/library/uri/generic/component_spec.rb +10 -0
  513. data/spec/framework_spec/app/spec/library/uri/generic/default_port_spec.rb +10 -0
  514. data/spec/framework_spec/app/spec/library/uri/generic/eql_spec.rb +6 -0
  515. data/spec/framework_spec/app/spec/library/uri/generic/equal_value_spec.rb +6 -0
  516. data/spec/framework_spec/app/spec/library/uri/generic/fragment_spec.rb +10 -0
  517. data/spec/framework_spec/app/spec/library/uri/generic/hash_spec.rb +6 -0
  518. data/spec/framework_spec/app/spec/library/uri/generic/hierarchical_spec.rb +6 -0
  519. data/spec/framework_spec/app/spec/library/uri/generic/host_spec.rb +10 -0
  520. data/spec/framework_spec/app/spec/library/uri/generic/inspect_spec.rb +6 -0
  521. data/spec/framework_spec/app/spec/library/uri/generic/merge_spec.rb +10 -0
  522. data/spec/framework_spec/app/spec/library/uri/generic/minus_spec.rb +6 -0
  523. data/spec/framework_spec/app/spec/library/uri/generic/normalize_spec.rb +10 -0
  524. data/spec/framework_spec/app/spec/library/uri/generic/opaque_spec.rb +10 -0
  525. data/spec/framework_spec/app/spec/library/uri/generic/password_spec.rb +10 -0
  526. data/spec/framework_spec/app/spec/library/uri/generic/path_spec.rb +10 -0
  527. data/spec/framework_spec/app/spec/library/uri/generic/plus_spec.rb +6 -0
  528. data/spec/framework_spec/app/spec/library/uri/generic/port_spec.rb +10 -0
  529. data/spec/framework_spec/app/spec/library/uri/generic/query_spec.rb +10 -0
  530. data/spec/framework_spec/app/spec/library/uri/generic/registry_spec.rb +10 -0
  531. data/spec/framework_spec/app/spec/library/uri/generic/relative_spec.rb +6 -0
  532. data/spec/framework_spec/app/spec/library/uri/generic/route_from_spec.rb +6 -0
  533. data/spec/framework_spec/app/spec/library/uri/generic/route_to_spec.rb +6 -0
  534. data/spec/framework_spec/app/spec/library/uri/generic/scheme_spec.rb +10 -0
  535. data/spec/framework_spec/app/spec/library/uri/generic/select_spec.rb +6 -0
  536. data/spec/framework_spec/app/spec/library/uri/generic/set_fragment_spec.rb +6 -0
  537. data/spec/framework_spec/app/spec/library/uri/generic/set_host_spec.rb +6 -0
  538. data/spec/framework_spec/app/spec/library/uri/generic/set_opaque_spec.rb +6 -0
  539. data/spec/framework_spec/app/spec/library/uri/generic/set_password_spec.rb +6 -0
  540. data/spec/framework_spec/app/spec/library/uri/generic/set_path_spec.rb +6 -0
  541. data/spec/framework_spec/app/spec/library/uri/generic/set_port_spec.rb +6 -0
  542. data/spec/framework_spec/app/spec/library/uri/generic/set_query_spec.rb +6 -0
  543. data/spec/framework_spec/app/spec/library/uri/generic/set_registry_spec.rb +6 -0
  544. data/spec/framework_spec/app/spec/library/uri/generic/set_scheme_spec.rb +6 -0
  545. data/spec/framework_spec/app/spec/library/uri/generic/set_user_spec.rb +6 -0
  546. data/spec/framework_spec/app/spec/library/uri/generic/set_userinfo_spec.rb +6 -0
  547. data/spec/framework_spec/app/spec/library/uri/generic/to_s_spec.rb +6 -0
  548. data/spec/framework_spec/app/spec/library/uri/generic/use_registry_spec.rb +6 -0
  549. data/spec/framework_spec/app/spec/library/uri/generic/user_spec.rb +10 -0
  550. data/spec/framework_spec/app/spec/library/uri/generic/userinfo_spec.rb +10 -0
  551. data/spec/framework_spec/app/spec/library/uri/http/build_spec.rb +6 -0
  552. data/spec/framework_spec/app/spec/library/uri/http/request_uri_spec.rb +16 -0
  553. data/spec/framework_spec/app/spec/library/uri/join_spec.rb +61 -0
  554. data/spec/framework_spec/app/spec/library/uri/ldap/attributes_spec.rb +10 -0
  555. data/spec/framework_spec/app/spec/library/uri/ldap/build_spec.rb +6 -0
  556. data/spec/framework_spec/app/spec/library/uri/ldap/dn_spec.rb +10 -0
  557. data/spec/framework_spec/app/spec/library/uri/ldap/extensions_spec.rb +10 -0
  558. data/spec/framework_spec/app/spec/library/uri/ldap/filter_spec.rb +10 -0
  559. data/spec/framework_spec/app/spec/library/uri/ldap/hierarchical_spec.rb +6 -0
  560. data/spec/framework_spec/app/spec/library/uri/ldap/scope_spec.rb +10 -0
  561. data/spec/framework_spec/app/spec/library/uri/ldap/set_attributes_spec.rb +6 -0
  562. data/spec/framework_spec/app/spec/library/uri/ldap/set_dn_spec.rb +6 -0
  563. data/spec/framework_spec/app/spec/library/uri/ldap/set_extensions_spec.rb +6 -0
  564. data/spec/framework_spec/app/spec/library/uri/ldap/set_filter_spec.rb +6 -0
  565. data/spec/framework_spec/app/spec/library/uri/ldap/set_scope_spec.rb +6 -0
  566. data/spec/framework_spec/app/spec/library/uri/mailto/build_spec.rb +99 -0
  567. data/spec/framework_spec/app/spec/library/uri/mailto/headers_spec.rb +10 -0
  568. data/spec/framework_spec/app/spec/library/uri/mailto/set_headers_spec.rb +6 -0
  569. data/spec/framework_spec/app/spec/library/uri/mailto/set_to_spec.rb +6 -0
  570. data/spec/framework_spec/app/spec/library/uri/mailto/to_mailtext_spec.rb +6 -0
  571. data/spec/framework_spec/app/spec/library/uri/mailto/to_rfc822text_spec.rb +6 -0
  572. data/spec/framework_spec/app/spec/library/uri/mailto/to_s_spec.rb +6 -0
  573. data/spec/framework_spec/app/spec/library/uri/mailto/to_spec.rb +10 -0
  574. data/spec/framework_spec/app/spec/library/uri/merge_spec.rb +22 -0
  575. data/spec/framework_spec/app/spec/library/uri/normalize_spec.rb +35 -0
  576. data/spec/framework_spec/app/spec/library/uri/parse_spec.rb +249 -0
  577. data/spec/framework_spec/app/spec/library/uri/plus_spec.rb +489 -0
  578. data/spec/framework_spec/app/spec/library/uri/regexp_spec.rb +18 -0
  579. data/spec/framework_spec/app/spec/library/uri/route_from_spec.rb +25 -0
  580. data/spec/framework_spec/app/spec/library/uri/route_to_spec.rb +28 -0
  581. data/spec/framework_spec/app/spec/library/uri/select_spec.rb +31 -0
  582. data/spec/framework_spec/app/spec/library/uri/set_component_spec.rb +47 -0
  583. data/spec/framework_spec/app/spec/library/uri/shared/eql.rb +17 -0
  584. data/spec/framework_spec/app/spec/library/uri/split_spec.rb +6 -0
  585. data/spec/framework_spec/app/spec/library/uri/uri_spec.rb +31 -0
  586. data/spec/framework_spec/app/spec/library/uri/util/make_components_hash_spec.rb +6 -0
  587. data/spec/framework_spec/build.yml +2 -2
  588. data/spec/framework_spec/extensions/test-libs/test/unit.rb +328 -0
  589. data/spec/framework_spec/extensions/test-libs/test/unit/assertionfailederror.rb +25 -0
  590. data/spec/framework_spec/extensions/test-libs/test/unit/assertions.rb +1878 -0
  591. data/spec/framework_spec/extensions/test-libs/test/unit/attribute.rb +129 -0
  592. data/spec/framework_spec/extensions/test-libs/test/unit/autorunner.rb +422 -0
  593. data/spec/framework_spec/extensions/test-libs/test/unit/collector.rb +38 -0
  594. data/spec/framework_spec/extensions/test-libs/test/unit/collector/descendant.rb +23 -0
  595. data/spec/framework_spec/extensions/test-libs/test/unit/collector/dir.rb +108 -0
  596. data/spec/framework_spec/extensions/test-libs/test/unit/collector/load.rb +187 -0
  597. data/spec/framework_spec/extensions/test-libs/test/unit/collector/objectspace.rb +34 -0
  598. data/spec/framework_spec/extensions/test-libs/test/unit/collector/xml.rb +250 -0
  599. data/spec/framework_spec/extensions/test-libs/test/unit/color-scheme.rb +153 -0
  600. data/spec/framework_spec/extensions/test-libs/test/unit/color.rb +123 -0
  601. data/spec/framework_spec/extensions/test-libs/test/unit/data.rb +80 -0
  602. data/spec/framework_spec/extensions/test-libs/test/unit/diff.rb +740 -0
  603. data/spec/framework_spec/extensions/test-libs/test/unit/error.rb +151 -0
  604. data/spec/framework_spec/extensions/test-libs/test/unit/exceptionhandler.rb +39 -0
  605. data/spec/framework_spec/extensions/test-libs/test/unit/failure.rb +136 -0
  606. data/spec/framework_spec/extensions/test-libs/test/unit/fixture.rb +214 -0
  607. data/spec/framework_spec/extensions/test-libs/test/unit/notification.rb +133 -0
  608. data/spec/framework_spec/extensions/test-libs/test/unit/omission.rb +191 -0
  609. data/spec/framework_spec/extensions/test-libs/test/unit/pending.rb +150 -0
  610. data/spec/framework_spec/extensions/test-libs/test/unit/priority.rb +182 -0
  611. data/spec/framework_spec/extensions/test-libs/test/unit/runner/console.rb +59 -0
  612. data/spec/framework_spec/extensions/test-libs/test/unit/runner/emacs.rb +8 -0
  613. data/spec/framework_spec/extensions/test-libs/test/unit/runner/tap.rb +8 -0
  614. data/spec/framework_spec/extensions/test-libs/test/unit/runner/xml.rb +15 -0
  615. data/spec/framework_spec/extensions/test-libs/test/unit/testcase.rb +601 -0
  616. data/spec/framework_spec/extensions/test-libs/test/unit/testresult.rb +125 -0
  617. data/spec/framework_spec/extensions/test-libs/test/unit/testsuite.rb +134 -0
  618. data/spec/framework_spec/extensions/test-libs/test/unit/testsuitecreator.rb +79 -0
  619. data/spec/framework_spec/extensions/test-libs/test/unit/ui/console/outputlevel.rb +15 -0
  620. data/spec/framework_spec/extensions/test-libs/test/unit/ui/console/testrunner.rb +561 -0
  621. data/spec/framework_spec/extensions/test-libs/test/unit/ui/emacs/testrunner.rb +63 -0
  622. data/spec/framework_spec/extensions/test-libs/test/unit/ui/tap/testrunner.rb +82 -0
  623. data/spec/framework_spec/extensions/test-libs/test/unit/ui/testrunner.rb +53 -0
  624. data/spec/framework_spec/extensions/test-libs/test/unit/ui/testrunnermediator.rb +86 -0
  625. data/spec/framework_spec/extensions/test-libs/test/unit/ui/testrunnerutilities.rb +41 -0
  626. data/spec/framework_spec/extensions/test-libs/test/unit/ui/xml/testrunner.rb +224 -0
  627. data/spec/framework_spec/extensions/test-libs/test/unit/util/backtracefilter.rb +42 -0
  628. data/spec/framework_spec/extensions/test-libs/test/unit/util/method-owner-finder.rb +28 -0
  629. data/spec/framework_spec/extensions/test-libs/test/unit/util/observable.rb +90 -0
  630. data/spec/framework_spec/extensions/test-libs/test/unit/util/output.rb +31 -0
  631. data/spec/framework_spec/extensions/test-libs/test/unit/util/procwrapper.rb +48 -0
  632. data/spec/framework_spec/extensions/test-libs/test/unit/version.rb +5 -0
  633. data/spec/framework_spec/extensions/test-libs/webrick/accesslog.rb +10 -2
  634. data/spec/framework_spec/extensions/test-libs/webrick/cgi.rb +1 -1
  635. data/spec/framework_spec/extensions/test-libs/webrick/config.rb +1 -1
  636. data/spec/framework_spec/extensions/test-libs/webrick/httpauth/digestauth.rb +1 -1
  637. data/spec/framework_spec/extensions/test-libs/webrick/httpresponse.rb +1 -1
  638. data/spec/framework_spec/extensions/test-libs/webrick/https.rb +2 -2
  639. data/spec/framework_spec/extensions/test-libs/webrick/httpservlet/abstract.rb +1 -2
  640. data/spec/framework_spec/extensions/test-libs/webrick/httpservlet/cgihandler.rb +2 -2
  641. data/spec/framework_spec/extensions/test-libs/webrick/httpservlet/filehandler.rb +9 -5
  642. data/spec/framework_spec/extensions/test-libs/webrick/httpstatus.rb +32 -321
  643. data/spec/framework_spec/extensions/test-libs/webrick/httputils.rb +3 -3
  644. data/spec/framework_spec/extensions/test-libs/webrick/ssl.rb +3 -2
  645. data/spec/phone_spec/build.yml +1 -1
  646. data/version +1 -0
  647. metadata +521 -27
  648. data/lib/extensions/net-http/monitor.rb +0 -265
  649. data/lib/extensions/net-http/thread.rb +0 -367
  650. data/lib/extensions/net-http/timeout.rb +0 -114
  651. data/lib/extensions/net-http/uri.rb +0 -29
  652. data/lib/extensions/net-http/uri/common.rb +0 -727
  653. data/lib/extensions/net-http/uri/ftp.rb +0 -198
  654. data/lib/extensions/net-http/uri/generic.rb +0 -1128
  655. data/lib/extensions/net-http/uri/http.rb +0 -100
  656. data/lib/extensions/net-http/uri/https.rb +0 -20
  657. data/lib/extensions/net-http/uri/ldap.rb +0 -190
  658. data/lib/extensions/net-http/uri/ldaps.rb +0 -12
  659. data/lib/extensions/net-http/uri/mailto.rb +0 -266
  660. data/platform/osx/bin/RhoSimulator/RhoSimulator.app/Contents/Frameworks/QtDBus.framework/Versions/4/QtDBus +0 -0
  661. data/platform/osx/bin/RhoSimulator/RhoSimulator.app/Contents/Frameworks/QtXml.framework/Versions/4/QtXml +0 -0
  662. data/platform/osx/bin/RhoSimulator/RhoSimulator.app/Contents/PlugIns/qmltooling/libtcpserver.dylib +0 -0
  663. data/res/generators/templates/application/public/jqmobile/images/icon-search-black.png +0 -0
  664. data/res/generators/templates/application/public/jqmobile/jquery.mobile-1.0b3.min.css +0 -8
  665. data/res/generators/templates/application/public/jqmobile/jquery.mobile-1.0b3.min.js +0 -169
  666. data/res/generators/templates/application/public/jquery/jquery-1.6.3.min.js +0 -4
  667. data/spec/framework_spec/extensions/test-libs/thread.rb +0 -391
@@ -191,6 +191,9 @@ const char* rho_rhodesapp_getplatform()
191
191
  if ( strPlatform.compare("iphone") == 0 )
192
192
  return "APPLE";
193
193
 
194
+ if ( strPlatform.compare("symbian") == 0 )
195
+ return "SYMBIAN";
196
+
194
197
  return "UNKNOWN";
195
198
  }
196
199
  #else
@@ -258,7 +258,7 @@ void rho_logconf_Init(const char* szRootPath, const char* szLogPort){
258
258
 
259
259
  LOGCONF().setLogPrefix(true);
260
260
 
261
- rho::String logPath = oLogPath.makeFullPath("RhoLog.txt");
261
+ rho::String logPath = oLogPath.makeFullPath("rholog.txt");
262
262
  LOGCONF().setLogToFile(true);
263
263
  LOGCONF().setLogFilePath( logPath.c_str() );
264
264
  LOGCONF().setMaxLogFileSize(1024*50);
@@ -77,6 +77,11 @@ QtMainWindow::QtMainWindow(QWidget *parent) :
77
77
  m_LogicalDpiY(0)
78
78
  //TODO: m_SyncStatusDlg
79
79
  {
80
+ #ifdef OS_WINDOWS
81
+ QPixmap icon(":/images/rho.png");
82
+ QApplication::setWindowIcon(icon);
83
+ #endif
84
+
80
85
  ui->setupUi(this);
81
86
 
82
87
  QWebSettings* qs = QWebSettings::globalSettings(); //this->ui->webView->settings();
@@ -596,7 +601,9 @@ void QtMainWindow::menuActionEvent(bool checked)
596
601
 
597
602
  void QtMainWindow::on_actionAbout_triggered()
598
603
  {
604
+ #ifndef RHO_SYMBIAN
599
605
  QMessageBox::about(this, RHOSIMULATOR_NAME, RHOSIMULATOR_NAME " v" RHOSIMULATOR_VERSION);
606
+ #endif
600
607
  }
601
608
 
602
609
  // slots:
@@ -28,6 +28,8 @@
28
28
  #define RHOSIMULATOR_H
29
29
 
30
30
  #define RHOSIMULATOR_NAME "RhoSimulator"
31
- #define RHOSIMULATOR_VERSION "3.2.0.beta1"
31
+ #ifndef RHO_SYMBIAN
32
+ #include "RhoSimulatorVersion.h"
33
+ #endif
32
34
 
33
35
  #endif // RHOSIMULATOR_H
@@ -149,6 +149,9 @@ int main(int argc, char *argv[])
149
149
  if ( m_strRhodesPath.length() > 0 )
150
150
  RHOSIMCONF().setString("rhodes_path", m_strRhodesPath, false );
151
151
  RHOCONF().setString( "rhosim_platform", RHOSIMCONF().getString( "platform"), false);
152
+ RHOSIMCONF().setString( "ext_path", RHOSIMCONF().getString( "ext_path") + CFilePath::join( m_strRhodesPath, "/lib/extensions/debugger;"), false);
153
+ RHOSIMCONF().setString( "ext_path", RHOSIMCONF().getString( "ext_path") + CFilePath::join( m_strRhodesPath, "/lib/extensions/uri;"), false);
154
+ RHOSIMCONF().setString( "ext_path", RHOSIMCONF().getString( "ext_path") + CFilePath::join( m_strRhodesPath, "/lib/extensions/timeout;"), false);
152
155
  #endif
153
156
 
154
157
  if ( !rho_rhodesapp_canstartapp(g_strCmdLine.c_str(), " /-,") )
@@ -0,0 +1,5 @@
1
+ <RCC>
2
+ <qresource prefix="/images">
3
+ <file>rho.png</file>
4
+ </qresource>
5
+ </RCC>
@@ -11,6 +11,7 @@ INCLUDEPATH += ../..\
11
11
 
12
12
  macx {
13
13
  ICON = resources/rho.icns
14
+ QMAKE_INFO_PLIST = resources/Info.plist
14
15
  DESTDIR = ../../../osx/bin/RhoSimulator
15
16
  MOC_DIR = ../../../osx/bin/RhoSimulator/generated_files
16
17
  UI_DIR = ../../../osx/bin/RhoSimulator/generated_files
@@ -40,6 +41,7 @@ win32 {
40
41
  HEADERS += ../../../wm/rhodes/rho/net/NetRequestImpl.h\
41
42
  impl/RhoThreadImpl.h
42
43
  SOURCES += ../../../wm/rhodes/rho/net/NetRequestImpl.cpp
44
+ RESOURCES += resources/simulator.qrc
43
45
  INCLUDEPATH += ../../../wm/rhodes\
44
46
  ../../wtl80/include
45
47
  DEFINES -= _UNICODE
@@ -220,7 +220,7 @@ static VALUE checkRhoBundleInPath(VALUE fname)
220
220
 
221
221
  return rb_str_new2(slash1+1);
222
222
  }
223
-
223
+ /*
224
224
  static VALUE check_extension(VALUE res, VALUE fname, int nAddExtName)
225
225
  {
226
226
  if ( nAddExtName )
@@ -240,6 +240,7 @@ static VALUE check_extension(VALUE res, VALUE fname, int nAddExtName)
240
240
 
241
241
  return eaccess(RSTRING_PTR(res), R_OK) == 0 ? res : 0;
242
242
  }
243
+ */
243
244
 
244
245
  static VALUE check_app_file_exist(VALUE dir, VALUE fname1, const char* szPlatform)
245
246
  {
@@ -309,7 +310,7 @@ static VALUE find_file(VALUE fname)
309
310
  {
310
311
  #ifdef RHODES_EMULATOR
311
312
  //check for extensions
312
- res = rb_str_new2(rho_simconf_getRhodesPath() );
313
+ /* res = rb_str_new2(rho_simconf_getRhodesPath() );
313
314
  rb_str_cat2(res,"/lib/extensions/");
314
315
 
315
316
  res = check_extension(res, fname, 1);
@@ -326,6 +327,24 @@ static VALUE find_file(VALUE fname)
326
327
  res = rb_str_new2( rho_simconf_getString("ext_path") );
327
328
  res = check_extension(res, fname, 0);
328
329
  }
330
+ */
331
+ const char* szPaths = rho_simconf_getString("ext_path");
332
+ const char* szPath = szPaths;
333
+ const char* szSep = strchr(szPath, ';');
334
+ res = 0;
335
+ for( ; szSep; szSep = strchr(szPath, ';') )
336
+ {
337
+ res = rb_str_new( szPath, szSep-szPath);
338
+ rb_str_cat2(res,"/");
339
+ rb_str_append(res,fname);
340
+ rb_str_cat2(res,RHO_RB_EXT);
341
+
342
+ if ( eaccess(RSTRING_PTR(res), R_OK) == 0 )
343
+ break;
344
+
345
+ res = 0;
346
+ szPath = szSep+1;
347
+ }
329
348
 
330
349
  if( res )
331
350
  nOK = 1;
@@ -0,0 +1,191 @@
1
+ /*
2
+ * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without
6
+ * modification, are permitted provided that the following conditions
7
+ * are met:
8
+ * 1. Redistributions of source code must retain the above copyright
9
+ * notice, this list of conditions and the following disclaimer.
10
+ * 2. Redistributions in binary form must reproduce the above copyright
11
+ * notice, this list of conditions and the following disclaimer in the
12
+ * documentation and/or other materials provided with the distribution.
13
+ * 3. Neither the name of the project nor the names of its contributors
14
+ * may be used to endorse or promote products derived from this software
15
+ * without specific prior written permission.
16
+ *
17
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
18
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
21
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
+ * SUCH DAMAGE.
28
+ */
29
+
30
+ #ifndef ADDR_INFO_H
31
+ #define ADDR_INFO_H
32
+
33
+ /* special compatibility hack */
34
+ #undef EAI_ADDRFAMILY
35
+ #undef EAI_AGAIN
36
+ #undef EAI_BADFLAGS
37
+ #undef EAI_FAIL
38
+ #undef EAI_FAMILY
39
+ #undef EAI_MEMORY
40
+ #undef EAI_NODATA
41
+ #undef EAI_NONAME
42
+ #undef EAI_SERVICE
43
+ #undef EAI_SOCKTYPE
44
+ #undef EAI_SYSTEM
45
+ #undef EAI_BADHINTS
46
+ #undef EAI_PROTOCOL
47
+ #undef EAI_MAX
48
+
49
+ #undef AI_PASSIVE
50
+ #undef AI_CANONNAME
51
+ #undef AI_NUMERICHOST
52
+ #undef AI_NUMERICSERV
53
+ #undef AI_ALL
54
+ #undef AI_ADDRCONFIG
55
+ #undef AI_V4MAPPED
56
+ #undef AI_DEFAULT
57
+
58
+ #undef NI_NOFQDN
59
+ #undef NI_NUMERICHOST
60
+ #undef NI_NAMEREQD
61
+ #undef NI_NUMERICSERV
62
+ #undef NI_DGRAM
63
+
64
+ #ifndef __P
65
+ # ifdef HAVE_PROTOTYPES
66
+ # define __P(args) args
67
+ # else
68
+ # define __P(args) ()
69
+ # endif
70
+ #endif
71
+
72
+ /* special compatibility hack -- end*/
73
+
74
+
75
+ /*
76
+ * Error return codes from getaddrinfo()
77
+ */
78
+ #define EAI_ADDRFAMILY 1 /* address family for hostname not supported */
79
+ #define EAI_AGAIN 2 /* temporary failure in name resolution */
80
+ #define EAI_BADFLAGS 3 /* invalid value for ai_flags */
81
+ #define EAI_FAIL 4 /* non-recoverable failure in name resolution */
82
+ #define EAI_FAMILY 5 /* ai_family not supported */
83
+ #define EAI_MEMORY 6 /* memory allocation failure */
84
+ #define EAI_NODATA 7 /* no address associated with hostname */
85
+ #define EAI_NONAME 8 /* hostname nor servname provided, or not known */
86
+ #define EAI_SERVICE 9 /* servname not supported for ai_socktype */
87
+ #define EAI_SOCKTYPE 10 /* ai_socktype not supported */
88
+ #define EAI_SYSTEM 11 /* system error returned in errno */
89
+ #define EAI_BADHINTS 12
90
+ #define EAI_PROTOCOL 13
91
+ #define EAI_MAX 14
92
+
93
+ /*
94
+ * Flag values for getaddrinfo()
95
+ */
96
+ #define AI_PASSIVE 0x00000001 /* get address to use bind() */
97
+ #define AI_CANONNAME 0x00000002 /* fill ai_canonname */
98
+ #define AI_NUMERICHOST 0x00000004 /* prevent name resolution */
99
+ #define AI_NUMERICSERV 0x00000008 /* prevent service name resolution */
100
+ /* valid flags for addrinfo */
101
+ #ifndef __HAIKU__
102
+ #undef AI_MASK
103
+ #define AI_MASK (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST | AI_NUMERICSERV)
104
+ #endif
105
+
106
+ #define AI_ALL 0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */
107
+ #define AI_V4MAPPED_CFG 0x00000200 /* accept IPv4-mapped if kernel supports */
108
+ #define AI_ADDRCONFIG 0x00000400 /* only if any address is assigned */
109
+ #define AI_V4MAPPED 0x00000800 /* accept IPv4-mapped IPv6 address */
110
+ /* special recommended flags for getipnodebyname */
111
+ #define AI_DEFAULT (AI_V4MAPPED_CFG | AI_ADDRCONFIG)
112
+
113
+ /*
114
+ * Constants for getnameinfo()
115
+ */
116
+ #ifndef NI_MAXHOST
117
+ #define NI_MAXHOST 1025
118
+ #define NI_MAXSERV 32
119
+ #endif
120
+
121
+ /*
122
+ * Flag values for getnameinfo()
123
+ */
124
+ #define NI_NOFQDN 0x00000001
125
+ #define NI_NUMERICHOST 0x00000002
126
+ #define NI_NAMEREQD 0x00000004
127
+ #define NI_NUMERICSERV 0x00000008
128
+ #define NI_DGRAM 0x00000010
129
+
130
+ #ifndef HAVE_TYPE_STRUCT_ADDRINFO
131
+ struct addrinfo {
132
+ int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
133
+ int ai_family; /* PF_xxx */
134
+ int ai_socktype; /* SOCK_xxx */
135
+ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
136
+ size_t ai_addrlen; /* length of ai_addr */
137
+ char *ai_canonname; /* canonical name for hostname */
138
+ struct sockaddr *ai_addr; /* binary address */
139
+ struct addrinfo *ai_next; /* next structure in linked list */
140
+ };
141
+ #endif
142
+
143
+ #ifndef HAVE_GETADDRINFO
144
+ #undef getaddrinfo
145
+ #define getaddrinfo getaddrinfo__compat
146
+ #endif
147
+ #ifndef HAVE_GETNAMEINFO
148
+ #undef getnameinfo
149
+ #define getnameinfo getnameinfo__compat
150
+ #endif
151
+ #ifndef HAVE_FREEHOSTENT
152
+ #undef freehostent
153
+ #define freehostent freehostent__compat
154
+ #endif
155
+ #ifndef HAVE_FREEADDRINFO
156
+ #undef freeaddrinfo
157
+ #define freeaddrinfo freeaddrinfo__compat
158
+ #endif
159
+
160
+ extern int getaddrinfo __P((
161
+ const char *hostname, const char *servname,
162
+ const struct addrinfo *hints,
163
+ struct addrinfo **res));
164
+
165
+ extern int getnameinfo __P((
166
+ const struct sockaddr *sa,
167
+ socklen_t salen,
168
+ char *host,
169
+ socklen_t hostlen,
170
+ char *serv,
171
+ socklen_t servlen,
172
+ int flags));
173
+
174
+ extern void freehostent __P((struct hostent *));
175
+ #ifndef HAVE_PADDRINFO
176
+ extern void freeaddrinfo __P((struct addrinfo *));
177
+ #endif
178
+ extern
179
+ #ifdef GAI_STRERROR_CONST
180
+ const
181
+ #endif
182
+ char *gai_strerror __P((int));
183
+
184
+ /* In case there is no definition of offsetof() provided - though any proper
185
+ Standard C system should have one. */
186
+
187
+ #ifndef offsetof
188
+ #define offsetof(p_type,field) ((size_t)&(((p_type *)0)->field))
189
+ #endif
190
+
191
+ #endif
@@ -0,0 +1,1800 @@
1
+ #include "rubysocket.h"
2
+
3
+ #include <time.h>
4
+
5
+ #if defined(HAVE_ST_MSG_CONTROL)
6
+ static VALUE rb_cAncillaryData;
7
+
8
+ static VALUE
9
+ constant_to_sym(int constant, ID (*intern_const)(int))
10
+ {
11
+ ID name = intern_const(constant);
12
+ if (name) {
13
+ return ID2SYM(name);
14
+ }
15
+
16
+ return INT2NUM(constant);
17
+ }
18
+
19
+ static VALUE
20
+ ip_cmsg_type_to_sym(int level, int cmsg_type)
21
+ {
22
+ switch (level) {
23
+ case SOL_SOCKET:
24
+ return constant_to_sym(cmsg_type, rsock_intern_scm_optname);
25
+ case IPPROTO_IP:
26
+ return constant_to_sym(cmsg_type, rsock_intern_ip_optname);
27
+ #ifdef IPPROTO_IPV6
28
+ case IPPROTO_IPV6:
29
+ return constant_to_sym(cmsg_type, rsock_intern_ipv6_optname);
30
+ #endif
31
+ case IPPROTO_TCP:
32
+ return constant_to_sym(cmsg_type, rsock_intern_tcp_optname);
33
+ case IPPROTO_UDP:
34
+ return constant_to_sym(cmsg_type, rsock_intern_udp_optname);
35
+ default:
36
+ return INT2NUM(cmsg_type);
37
+ }
38
+ }
39
+
40
+ /*
41
+ * call-seq:
42
+ * Socket::AncillaryData.new(family, cmsg_level, cmsg_type, cmsg_data) -> ancillarydata
43
+ *
44
+ * _family_ should be an integer, a string or a symbol.
45
+ * - Socket::AF_INET, "AF_INET", "INET", :AF_INET, :INET
46
+ * - Socket::AF_UNIX, "AF_UNIX", "UNIX", :AF_UNIX, :UNIX
47
+ * - etc.
48
+ *
49
+ * _cmsg_level_ should be an integer, a string or a symbol.
50
+ * - Socket::SOL_SOCKET, "SOL_SOCKET", "SOCKET", :SOL_SOCKET and :SOCKET
51
+ * - Socket::IPPROTO_IP, "IP" and :IP
52
+ * - Socket::IPPROTO_IPV6, "IPV6" and :IPV6
53
+ * - Socket::IPPROTO_TCP, "TCP" and :TCP
54
+ * - etc.
55
+ *
56
+ * _cmsg_type_ should be an integer, a string or a symbol.
57
+ * If a string/symbol is specified, it is interpreted depend on _cmsg_level_.
58
+ * - Socket::SCM_RIGHTS, "SCM_RIGHTS", "RIGHTS", :SCM_RIGHTS, :RIGHTS for SOL_SOCKET
59
+ * - Socket::IP_RECVTTL, "RECVTTL" and :RECVTTL for IPPROTO_IP
60
+ * - Socket::IPV6_PKTINFO, "PKTINFO" and :PKTINFO for IPPROTO_IPV6
61
+ * - etc.
62
+ *
63
+ * _cmsg_data_ should be a string.
64
+ *
65
+ * p Socket::AncillaryData.new(:INET, :TCP, :NODELAY, "")
66
+ * #=> #<Socket::AncillaryData: INET TCP NODELAY "">
67
+ *
68
+ * p Socket::AncillaryData.new(:INET6, :IPV6, :PKTINFO, "")
69
+ * #=> #<Socket::AncillaryData: INET6 IPV6 PKTINFO "">
70
+ *
71
+ */
72
+ static VALUE
73
+ ancillary_initialize(VALUE self, VALUE vfamily, VALUE vlevel, VALUE vtype, VALUE data)
74
+ {
75
+ int family = rsock_family_arg(vfamily);
76
+ int level = rsock_level_arg(family, vlevel);
77
+ int type = rsock_cmsg_type_arg(family, level, vtype);
78
+ StringValue(data);
79
+ rb_ivar_set(self, rb_intern("family"), INT2NUM(family));
80
+ rb_ivar_set(self, rb_intern("level"), INT2NUM(level));
81
+ rb_ivar_set(self, rb_intern("type"), INT2NUM(type));
82
+ rb_ivar_set(self, rb_intern("data"), data);
83
+ return self;
84
+ }
85
+
86
+ static VALUE
87
+ ancdata_new(int family, int level, int type, VALUE data)
88
+ {
89
+ NEWOBJ(obj, struct RObject);
90
+ OBJSETUP(obj, rb_cAncillaryData, T_OBJECT);
91
+ StringValue(data);
92
+ ancillary_initialize((VALUE)obj, INT2NUM(family), INT2NUM(level), INT2NUM(type), data);
93
+ return (VALUE)obj;
94
+ }
95
+
96
+ static int
97
+ ancillary_family(VALUE self)
98
+ {
99
+ VALUE v = rb_attr_get(self, rb_intern("family"));
100
+ return NUM2INT(v);
101
+ }
102
+
103
+ /*
104
+ * call-seq:
105
+ * ancillarydata.family => integer
106
+ *
107
+ * returns the socket family as an integer.
108
+ *
109
+ * p Socket::AncillaryData.new(:INET6, :IPV6, :PKTINFO, "").family
110
+ * #=> 10
111
+ */
112
+ static VALUE
113
+ ancillary_family_m(VALUE self)
114
+ {
115
+ return INT2NUM(ancillary_family(self));
116
+ }
117
+
118
+ static int
119
+ ancillary_level(VALUE self)
120
+ {
121
+ VALUE v = rb_attr_get(self, rb_intern("level"));
122
+ return NUM2INT(v);
123
+ }
124
+
125
+ /*
126
+ * call-seq:
127
+ * ancillarydata.level => integer
128
+ *
129
+ * returns the cmsg level as an integer.
130
+ *
131
+ * p Socket::AncillaryData.new(:INET6, :IPV6, :PKTINFO, "").level
132
+ * #=> 41
133
+ */
134
+ static VALUE
135
+ ancillary_level_m(VALUE self)
136
+ {
137
+ return INT2NUM(ancillary_level(self));
138
+ }
139
+
140
+ static int
141
+ ancillary_type(VALUE self)
142
+ {
143
+ VALUE v = rb_attr_get(self, rb_intern("type"));
144
+ return NUM2INT(v);
145
+ }
146
+
147
+ /*
148
+ * call-seq:
149
+ * ancillarydata.type => integer
150
+ *
151
+ * returns the cmsg type as an integer.
152
+ *
153
+ * p Socket::AncillaryData.new(:INET6, :IPV6, :PKTINFO, "").type
154
+ * #=> 2
155
+ */
156
+ static VALUE
157
+ ancillary_type_m(VALUE self)
158
+ {
159
+ return INT2NUM(ancillary_type(self));
160
+ }
161
+
162
+ /*
163
+ * call-seq:
164
+ * ancillarydata.data => string
165
+ *
166
+ * returns the cmsg data as a string.
167
+ *
168
+ * p Socket::AncillaryData.new(:INET6, :IPV6, :PKTINFO, "").data
169
+ * #=> ""
170
+ */
171
+ static VALUE
172
+ ancillary_data(VALUE self)
173
+ {
174
+ VALUE v = rb_attr_get(self, rb_intern("data"));
175
+ StringValue(v);
176
+ return v;
177
+ }
178
+
179
+ #ifdef SCM_RIGHTS
180
+ /*
181
+ * call-seq:
182
+ * Socket::AncillaryData.unix_rights(io1, io2, ...) => ancillarydata
183
+ *
184
+ * Creates a new Socket::AncillaryData object which contains file descriptors as data.
185
+ *
186
+ * p Socket::AncillaryData.unix_rights(STDERR)
187
+ * #=> #<Socket::AncillaryData: UNIX SOCKET RIGHTS 2>
188
+ */
189
+ static VALUE
190
+ ancillary_s_unix_rights(int argc, VALUE *argv, VALUE klass)
191
+ {
192
+ VALUE result, str, ary;
193
+ int i;
194
+
195
+ ary = rb_ary_new();
196
+
197
+ for (i = 0 ; i < argc; i++) {
198
+ VALUE obj = argv[i];
199
+ if (TYPE(obj) != T_FILE) {
200
+ rb_raise(rb_eTypeError, "IO expected");
201
+ }
202
+ rb_ary_push(ary, obj);
203
+ }
204
+
205
+ str = rb_str_buf_new(sizeof(int) * argc);
206
+
207
+ for (i = 0 ; i < argc; i++) {
208
+ VALUE obj = RARRAY_PTR(ary)[i];
209
+ rb_io_t *fptr;
210
+ int fd;
211
+ GetOpenFile(obj, fptr);
212
+ fd = fptr->fd;
213
+ rb_str_buf_cat(str, (char *)&fd, sizeof(int));
214
+ }
215
+
216
+ result = ancdata_new(AF_UNIX, SOL_SOCKET, SCM_RIGHTS, str);
217
+ rb_ivar_set(result, rb_intern("unix_rights"), ary);
218
+ return result;
219
+ }
220
+ #else
221
+ #define ancillary_s_unix_rights rb_f_notimplement
222
+ #endif
223
+
224
+ #ifdef SCM_RIGHTS
225
+ /*
226
+ * call-seq:
227
+ * ancillarydata.unix_rights => array-of-IOs or nil
228
+ *
229
+ * returns the array of IO objects for SCM_RIGHTS control message in UNIX domain socket.
230
+ *
231
+ * The class of the IO objects in the array is IO or Socket.
232
+ *
233
+ * The array is attached to _ancillarydata_ when it is instantiated.
234
+ * For example, BasicSocket#recvmsg attach the array when
235
+ * receives a SCM_RIGHTS control message and :scm_rights=>true option is given.
236
+ *
237
+ * # recvmsg needs :scm_rights=>true for unix_rights
238
+ * s1, s2 = UNIXSocket.pair
239
+ * p s1 #=> #<UNIXSocket:fd 3>
240
+ * s1.sendmsg "stdin and a socket", 0, nil, Socket::AncillaryData.unix_rights(STDIN, s1)
241
+ * _, _, _, ctl = s2.recvmsg(:scm_rights=>true)
242
+ * p ctl #=> #<Socket::AncillaryData: UNIX SOCKET RIGHTS 6 7>
243
+ * p ctl.unix_rights #=> [#<IO:fd 6>, #<Socket:fd 7>]
244
+ * p File.identical?(STDIN, ctl.unix_rights[0]) #=> true
245
+ * p File.identical?(s1, ctl.unix_rights[1]) #=> true
246
+ *
247
+ * # If :scm_rights=>true is not given, unix_rights returns nil
248
+ * s1, s2 = UNIXSocket.pair
249
+ * s1.sendmsg "stdin and a socket", 0, nil, Socket::AncillaryData.unix_rights(STDIN, s1)
250
+ * _, _, _, ctl = s2.recvmsg
251
+ * p ctl #=> #<Socket::AncillaryData: UNIX SOCKET RIGHTS 6 7>
252
+ * p ctl.unix_rights #=> nil
253
+ *
254
+ */
255
+ static VALUE
256
+ ancillary_unix_rights(VALUE self)
257
+ {
258
+ int level, type;
259
+
260
+ level = ancillary_level(self);
261
+ type = ancillary_type(self);
262
+
263
+ if (level != SOL_SOCKET || type != SCM_RIGHTS)
264
+ rb_raise(rb_eTypeError, "SCM_RIGHTS ancillary data expected");
265
+
266
+ return rb_attr_get(self, rb_intern("unix_rights"));
267
+ }
268
+ #else
269
+ #define ancillary_unix_rights rb_f_notimplement
270
+ #endif
271
+
272
+ #if defined(SCM_TIMESTAMP) || defined(SCM_TIMESTAMPNS) || defined(SCM_BINTIME)
273
+ /*
274
+ * call-seq:
275
+ * ancillarydata.timestamp => time
276
+ *
277
+ * returns the timestamp as a time object.
278
+ *
279
+ * _ancillarydata_ should be one of following type:
280
+ * - SOL_SOCKET/SCM_TIMESTAMP (micro second) GNU/Linux, FreeBSD, NetBSD, OpenBSD, Solaris, MacOS X
281
+ * - SOL_SOCKET/SCM_TIMESTAMPNS (nano second) GNU/Linux
282
+ * - SOL_SOCKET/SCM_BINTIME (2**(-64) second) FreeBSD
283
+ *
284
+ * Addrinfo.udp("127.0.0.1", 0).bind {|s1|
285
+ * Addrinfo.udp("127.0.0.1", 0).bind {|s2|
286
+ * s1.setsockopt(:SOCKET, :TIMESTAMP, true)
287
+ * s2.send "a", 0, s1.local_address
288
+ * ctl = s1.recvmsg.last
289
+ * p ctl #=> #<Socket::AncillaryData: INET SOCKET TIMESTAMP 2009-02-24 17:35:46.775581>
290
+ * t = ctl.timestamp
291
+ * p t #=> 2009-02-24 17:35:46 +0900
292
+ * p t.usec #=> 775581
293
+ * p t.nsec #=> 775581000
294
+ * }
295
+ * }
296
+ *
297
+ */
298
+ static VALUE
299
+ ancillary_timestamp(VALUE self)
300
+ {
301
+ int level, type;
302
+ VALUE data;
303
+ VALUE result = Qnil;
304
+
305
+ level = ancillary_level(self);
306
+ type = ancillary_type(self);
307
+ data = ancillary_data(self);
308
+
309
+ # ifdef SCM_TIMESTAMP
310
+ if (level == SOL_SOCKET && type == SCM_TIMESTAMP &&
311
+ RSTRING_LEN(data) == sizeof(struct timeval)) {
312
+ struct timeval tv;
313
+ memcpy((char*)&tv, RSTRING_PTR(data), sizeof(tv));
314
+ result = rb_time_new(tv.tv_sec, tv.tv_usec);
315
+ }
316
+ # endif
317
+
318
+ # ifdef SCM_TIMESTAMPNS
319
+ if (level == SOL_SOCKET && type == SCM_TIMESTAMPNS &&
320
+ RSTRING_LEN(data) == sizeof(struct timespec)) {
321
+ struct timespec ts;
322
+ memcpy((char*)&ts, RSTRING_PTR(data), sizeof(ts));
323
+ result = rb_time_nano_new(ts.tv_sec, ts.tv_nsec);
324
+ }
325
+ # endif
326
+
327
+ #define add(x,y) (rb_funcall((x), '+', 1, (y)))
328
+ #define mul(x,y) (rb_funcall((x), '*', 1, (y)))
329
+ #define quo(x,y) (rb_funcall((x), rb_intern("quo"), 1, (y)))
330
+
331
+ # ifdef SCM_BINTIME
332
+ if (level == SOL_SOCKET && type == SCM_BINTIME &&
333
+ RSTRING_LEN(data) == sizeof(struct bintime)) {
334
+ struct bintime bt;
335
+ VALUE d, timev;
336
+ memcpy((char*)&bt, RSTRING_PTR(data), sizeof(bt));
337
+ d = ULL2NUM(0x100000000UL);
338
+ d = mul(d,d);
339
+ timev = add(TIMET2NUM(bt.sec), quo(ULL2NUM(bt.frac), d));
340
+ result = rb_time_num_new(timev, Qnil);
341
+ }
342
+ # endif
343
+
344
+ if (result == Qnil)
345
+ rb_raise(rb_eTypeError, "timestamp ancillary data expected");
346
+
347
+ return result;
348
+ }
349
+ #else
350
+ #define ancillary_timestamp rb_f_notimplement
351
+ #endif
352
+
353
+ /*
354
+ * call-seq:
355
+ * Socket::AncillaryData.int(family, cmsg_level, cmsg_type, integer) => ancillarydata
356
+ *
357
+ * Creates a new Socket::AncillaryData object which contains a int as data.
358
+ *
359
+ * The size and endian is dependent on the host.
360
+ *
361
+ * p Socket::AncillaryData.int(:UNIX, :SOCKET, :RIGHTS, STDERR.fileno)
362
+ * #=> #<Socket::AncillaryData: UNIX SOCKET RIGHTS 2>
363
+ */
364
+ static VALUE
365
+ ancillary_s_int(VALUE klass, VALUE vfamily, VALUE vlevel, VALUE vtype, VALUE integer)
366
+ {
367
+ int family = rsock_family_arg(vfamily);
368
+ int level = rsock_level_arg(family, vlevel);
369
+ int type = rsock_cmsg_type_arg(family, level, vtype);
370
+ int i = NUM2INT(integer);
371
+ return ancdata_new(family, level, type, rb_str_new((char*)&i, sizeof(i)));
372
+ }
373
+
374
+ /*
375
+ * call-seq:
376
+ * ancillarydata.int => integer
377
+ *
378
+ * Returns the data in _ancillarydata_ as an int.
379
+ *
380
+ * The size and endian is dependent on the host.
381
+ *
382
+ * ancdata = Socket::AncillaryData.int(:UNIX, :SOCKET, :RIGHTS, STDERR.fileno)
383
+ * p ancdata.int #=> 2
384
+ */
385
+ static VALUE
386
+ ancillary_int(VALUE self)
387
+ {
388
+ VALUE data;
389
+ int i;
390
+ data = ancillary_data(self);
391
+ if (RSTRING_LEN(data) != sizeof(int))
392
+ rb_raise(rb_eTypeError, "size differ. expected as sizeof(int)=%d but %ld", (int)sizeof(int), (long)RSTRING_LEN(data));
393
+ memcpy((char*)&i, RSTRING_PTR(data), sizeof(int));
394
+ return INT2NUM(i);
395
+ }
396
+
397
+ #if defined(IPPROTO_IP) && defined(IP_PKTINFO) && defined(HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST) /* GNU/Linux */
398
+ /*
399
+ * call-seq:
400
+ * Socket::AncillaryData.ip_pktinfo(addr, ifindex) => ancdata
401
+ * Socket::AncillaryData.ip_pktinfo(addr, ifindex, spec_dst) => ancdata
402
+ *
403
+ * Returns new ancillary data for IP_PKTINFO.
404
+ *
405
+ * If spec_dst is not given, addr is used.
406
+ *
407
+ * IP_PKTINFO is not standard.
408
+ *
409
+ * Supported platform: GNU/Linux
410
+ *
411
+ * addr = Addrinfo.ip("127.0.0.1")
412
+ * ifindex = 0
413
+ * spec_dst = Addrinfo.ip("127.0.0.1")
414
+ * p Socket::AncillaryData.ip_pktinfo(addr, ifindex, spec_dst)
415
+ * #=> #<Socket::AncillaryData: INET IP PKTINFO 127.0.0.1 ifindex:0 spec_dst:127.0.0.1>
416
+ *
417
+ */
418
+ static VALUE
419
+ ancillary_s_ip_pktinfo(int argc, VALUE *argv, VALUE self)
420
+ {
421
+ VALUE v_addr, v_ifindex, v_spec_dst;
422
+ unsigned int ifindex;
423
+ struct sockaddr_in sa;
424
+ struct in_pktinfo pktinfo;
425
+
426
+ rb_scan_args(argc, argv, "21", &v_addr, &v_ifindex, &v_spec_dst);
427
+
428
+ SockAddrStringValue(v_addr);
429
+ ifindex = NUM2UINT(v_ifindex);
430
+ if (NIL_P(v_spec_dst))
431
+ v_spec_dst = v_addr;
432
+ else
433
+ SockAddrStringValue(v_spec_dst);
434
+
435
+ memset(&pktinfo, 0, sizeof(pktinfo));
436
+
437
+ memset(&sa, 0, sizeof(sa));
438
+ if (RSTRING_LEN(v_addr) != sizeof(sa))
439
+ rb_raise(rb_eArgError, "addr size different to AF_INET sockaddr");
440
+ memcpy(&sa, RSTRING_PTR(v_addr), sizeof(sa));
441
+ if (sa.sin_family != AF_INET)
442
+ rb_raise(rb_eArgError, "addr is not AF_INET sockaddr");
443
+ memcpy(&pktinfo.ipi_addr, &sa.sin_addr, sizeof(pktinfo.ipi_addr));
444
+
445
+ pktinfo.ipi_ifindex = ifindex;
446
+
447
+ memset(&sa, 0, sizeof(sa));
448
+ if (RSTRING_LEN(v_spec_dst) != sizeof(sa))
449
+ rb_raise(rb_eArgError, "spec_dat size different to AF_INET sockaddr");
450
+ memcpy(&sa, RSTRING_PTR(v_spec_dst), sizeof(sa));
451
+ if (sa.sin_family != AF_INET)
452
+ rb_raise(rb_eArgError, "spec_dst is not AF_INET sockaddr");
453
+ memcpy(&pktinfo.ipi_spec_dst, &sa.sin_addr, sizeof(pktinfo.ipi_spec_dst));
454
+
455
+ return ancdata_new(AF_INET, IPPROTO_IP, IP_PKTINFO, rb_str_new((char *)&pktinfo, sizeof(pktinfo)));
456
+ }
457
+ #else
458
+ #define ancillary_s_ip_pktinfo rb_f_notimplement
459
+ #endif
460
+
461
+ #if defined(IPPROTO_IP) && defined(IP_PKTINFO) && defined(HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST) /* GNU/Linux */
462
+ /*
463
+ * call-seq:
464
+ * ancdata.ip_pktinfo => [addr, ifindex, spec_dst]
465
+ *
466
+ * Extracts addr, ifindex and spec_dst from IP_PKTINFO ancillary data.
467
+ *
468
+ * IP_PKTINFO is not standard.
469
+ *
470
+ * Supported platform: GNU/Linux
471
+ *
472
+ * addr = Addrinfo.ip("127.0.0.1")
473
+ * ifindex = 0
474
+ * spec_dest = Addrinfo.ip("127.0.0.1")
475
+ * ancdata = Socket::AncillaryData.ip_pktinfo(addr, ifindex, spec_dest)
476
+ * p ancdata.ip_pktinfo
477
+ * #=> [#<Addrinfo: 127.0.0.1>, 0, #<Addrinfo: 127.0.0.1>]
478
+ *
479
+ *
480
+ */
481
+ static VALUE
482
+ ancillary_ip_pktinfo(VALUE self)
483
+ {
484
+ int level, type;
485
+ VALUE data;
486
+ struct in_pktinfo pktinfo;
487
+ struct sockaddr_in sa;
488
+ VALUE v_spec_dst, v_addr;
489
+
490
+ level = ancillary_level(self);
491
+ type = ancillary_type(self);
492
+ data = ancillary_data(self);
493
+
494
+ if (level != IPPROTO_IP || type != IP_PKTINFO ||
495
+ RSTRING_LEN(data) != sizeof(struct in_pktinfo)) {
496
+ rb_raise(rb_eTypeError, "IP_PKTINFO ancillary data expected");
497
+ }
498
+
499
+ memcpy(&pktinfo, RSTRING_PTR(data), sizeof(struct in_pktinfo));
500
+ memset(&sa, 0, sizeof(sa));
501
+
502
+ sa.sin_family = AF_INET;
503
+ memcpy(&sa.sin_addr, &pktinfo.ipi_addr, sizeof(sa.sin_addr));
504
+ v_addr = rsock_addrinfo_new((struct sockaddr *)&sa, sizeof(sa), PF_INET, 0, 0, Qnil, Qnil);
505
+
506
+ sa.sin_family = AF_INET;
507
+ memcpy(&sa.sin_addr, &pktinfo.ipi_spec_dst, sizeof(sa.sin_addr));
508
+ v_spec_dst = rsock_addrinfo_new((struct sockaddr *)&sa, sizeof(sa), PF_INET, 0, 0, Qnil, Qnil);
509
+
510
+ return rb_ary_new3(3, v_addr, UINT2NUM(pktinfo.ipi_ifindex), v_spec_dst);
511
+ }
512
+ #else
513
+ #define ancillary_ip_pktinfo rb_f_notimplement
514
+ #endif
515
+
516
+ #if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO) /* IPv6 RFC3542 */
517
+ /*
518
+ * call-seq:
519
+ * Socket::AncillaryData.ipv6_pktinfo(addr, ifindex) => ancdata
520
+ *
521
+ * Returns new ancillary data for IPV6_PKTINFO.
522
+ *
523
+ * IPV6_PKTINFO is defined by RFC 3542.
524
+ *
525
+ * addr = Addrinfo.ip("::1")
526
+ * ifindex = 0
527
+ * p Socket::AncillaryData.ipv6_pktinfo(addr, ifindex)
528
+ * #=> #<Socket::AncillaryData: INET6 IPV6 PKTINFO ::1 ifindex:0>
529
+ *
530
+ */
531
+ static VALUE
532
+ ancillary_s_ipv6_pktinfo(VALUE self, VALUE v_addr, VALUE v_ifindex)
533
+ {
534
+ unsigned int ifindex;
535
+ struct sockaddr_in6 sa;
536
+ struct in6_pktinfo pktinfo;
537
+
538
+ SockAddrStringValue(v_addr);
539
+ ifindex = NUM2UINT(v_ifindex);
540
+
541
+ memset(&pktinfo, 0, sizeof(pktinfo));
542
+
543
+ memset(&sa, 0, sizeof(sa));
544
+ if (RSTRING_LEN(v_addr) != sizeof(sa))
545
+ rb_raise(rb_eArgError, "addr size different to AF_INET6 sockaddr");
546
+ memcpy(&sa, RSTRING_PTR(v_addr), sizeof(sa));
547
+ if (sa.sin6_family != AF_INET6)
548
+ rb_raise(rb_eArgError, "addr is not AF_INET6 sockaddr");
549
+ memcpy(&pktinfo.ipi6_addr, &sa.sin6_addr, sizeof(pktinfo.ipi6_addr));
550
+
551
+ pktinfo.ipi6_ifindex = ifindex;
552
+
553
+ return ancdata_new(AF_INET6, IPPROTO_IPV6, IPV6_PKTINFO, rb_str_new((char *)&pktinfo, sizeof(pktinfo)));
554
+ }
555
+ #else
556
+ #define ancillary_s_ipv6_pktinfo rb_f_notimplement
557
+ #endif
558
+
559
+ #if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO) /* IPv6 RFC3542 */
560
+ static void
561
+ extract_ipv6_pktinfo(VALUE self, struct in6_pktinfo *pktinfo_ptr, struct sockaddr_in6 *sa_ptr)
562
+ {
563
+ int level, type;
564
+ VALUE data;
565
+
566
+ level = ancillary_level(self);
567
+ type = ancillary_type(self);
568
+ data = ancillary_data(self);
569
+
570
+ if (level != IPPROTO_IPV6 || type != IPV6_PKTINFO ||
571
+ RSTRING_LEN(data) != sizeof(struct in6_pktinfo)) {
572
+ rb_raise(rb_eTypeError, "IPV6_PKTINFO ancillary data expected");
573
+ }
574
+
575
+ memcpy(pktinfo_ptr, RSTRING_PTR(data), sizeof(*pktinfo_ptr));
576
+
577
+ memset(sa_ptr, 0, sizeof(*sa_ptr));
578
+ SET_SA_LEN((struct sockaddr *)sa_ptr, sizeof(struct sockaddr_in6));
579
+ sa_ptr->sin6_family = AF_INET6;
580
+ memcpy(&sa_ptr->sin6_addr, &pktinfo_ptr->ipi6_addr, sizeof(sa_ptr->sin6_addr));
581
+ if (IN6_IS_ADDR_LINKLOCAL(&sa_ptr->sin6_addr))
582
+ sa_ptr->sin6_scope_id = pktinfo_ptr->ipi6_ifindex;
583
+ }
584
+ #endif
585
+
586
+ #if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO) /* IPv6 RFC3542 */
587
+ /*
588
+ * call-seq:
589
+ * ancdata.ipv6_pktinfo => [addr, ifindex]
590
+ *
591
+ * Extracts addr and ifindex from IPV6_PKTINFO ancillary data.
592
+ *
593
+ * IPV6_PKTINFO is defined by RFC 3542.
594
+ *
595
+ * addr = Addrinfo.ip("::1")
596
+ * ifindex = 0
597
+ * ancdata = Socket::AncillaryData.ipv6_pktinfo(addr, ifindex)
598
+ * p ancdata.ipv6_pktinfo #=> [#<Addrinfo: ::1>, 0]
599
+ *
600
+ */
601
+ static VALUE
602
+ ancillary_ipv6_pktinfo(VALUE self)
603
+ {
604
+ struct in6_pktinfo pktinfo;
605
+ struct sockaddr_in6 sa;
606
+ VALUE v_addr;
607
+
608
+ extract_ipv6_pktinfo(self, &pktinfo, &sa);
609
+ v_addr = rsock_addrinfo_new((struct sockaddr *)&sa, (socklen_t)sizeof(sa), PF_INET6, 0, 0, Qnil, Qnil);
610
+ return rb_ary_new3(2, v_addr, UINT2NUM(pktinfo.ipi6_ifindex));
611
+ }
612
+ #else
613
+ #define ancillary_ipv6_pktinfo rb_f_notimplement
614
+ #endif
615
+
616
+ #if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO) /* IPv6 RFC3542 */
617
+ /*
618
+ * call-seq:
619
+ * ancdata.ipv6_pktinfo_addr => addr
620
+ *
621
+ * Extracts addr from IPV6_PKTINFO ancillary data.
622
+ *
623
+ * IPV6_PKTINFO is defined by RFC 3542.
624
+ *
625
+ * addr = Addrinfo.ip("::1")
626
+ * ifindex = 0
627
+ * ancdata = Socket::AncillaryData.ipv6_pktinfo(addr, ifindex)
628
+ * p ancdata.ipv6_pktinfo_addr #=> #<Addrinfo: ::1>
629
+ *
630
+ */
631
+ static VALUE
632
+ ancillary_ipv6_pktinfo_addr(VALUE self)
633
+ {
634
+ struct in6_pktinfo pktinfo;
635
+ struct sockaddr_in6 sa;
636
+ extract_ipv6_pktinfo(self, &pktinfo, &sa);
637
+ return rsock_addrinfo_new((struct sockaddr *)&sa, (socklen_t)sizeof(sa), PF_INET6, 0, 0, Qnil, Qnil);
638
+ }
639
+ #else
640
+ #define ancillary_ipv6_pktinfo_addr rb_f_notimplement
641
+ #endif
642
+
643
+ #if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO) /* IPv6 RFC3542 */
644
+ /*
645
+ * call-seq:
646
+ * ancdata.ipv6_pktinfo_ifindex => addr
647
+ *
648
+ * Extracts ifindex from IPV6_PKTINFO ancillary data.
649
+ *
650
+ * IPV6_PKTINFO is defined by RFC 3542.
651
+ *
652
+ * addr = Addrinfo.ip("::1")
653
+ * ifindex = 0
654
+ * ancdata = Socket::AncillaryData.ipv6_pktinfo(addr, ifindex)
655
+ * p ancdata.ipv6_pktinfo_ifindex #=> 0
656
+ *
657
+ */
658
+ static VALUE
659
+ ancillary_ipv6_pktinfo_ifindex(VALUE self)
660
+ {
661
+ struct in6_pktinfo pktinfo;
662
+ struct sockaddr_in6 sa;
663
+ extract_ipv6_pktinfo(self, &pktinfo, &sa);
664
+ return UINT2NUM(pktinfo.ipi6_ifindex);
665
+ }
666
+ #else
667
+ #define ancillary_ipv6_pktinfo_ifindex rb_f_notimplement
668
+ #endif
669
+
670
+ #if defined(SOL_SOCKET) && defined(SCM_RIGHTS) /* 4.4BSD */
671
+ static int
672
+ anc_inspect_socket_rights(int level, int type, VALUE data, VALUE ret)
673
+ {
674
+ if (level == SOL_SOCKET && type == SCM_RIGHTS &&
675
+ 0 < RSTRING_LEN(data) && (RSTRING_LEN(data) % sizeof(int) == 0)) {
676
+ long off;
677
+ for (off = 0; off < RSTRING_LEN(data); off += sizeof(int)) {
678
+ int fd;
679
+ memcpy((char*)&fd, RSTRING_PTR(data)+off, sizeof(int));
680
+ rb_str_catf(ret, " %d", fd);
681
+ }
682
+ return 1;
683
+ }
684
+ else {
685
+ return 0;
686
+ }
687
+ }
688
+ #endif
689
+
690
+ #if defined(SCM_CREDENTIALS) /* GNU/Linux */
691
+ static int
692
+ anc_inspect_passcred_credentials(int level, int type, VALUE data, VALUE ret)
693
+ {
694
+ if (level == SOL_SOCKET && type == SCM_CREDENTIALS &&
695
+ RSTRING_LEN(data) == sizeof(struct ucred)) {
696
+ struct ucred cred;
697
+ memcpy(&cred, RSTRING_PTR(data), sizeof(struct ucred));
698
+ rb_str_catf(ret, " pid=%u uid=%u gid=%u", cred.pid, cred.uid, cred.gid);
699
+ rb_str_cat2(ret, " (ucred)");
700
+ return 1;
701
+ }
702
+ else {
703
+ return 0;
704
+ }
705
+ }
706
+ #endif
707
+
708
+ #if defined(SCM_CREDS)
709
+ #define INSPECT_SCM_CREDS
710
+ static int
711
+ anc_inspect_socket_creds(int level, int type, VALUE data, VALUE ret)
712
+ {
713
+ if (level != SOL_SOCKET && type != SCM_CREDS)
714
+ return 0;
715
+
716
+ /*
717
+ * FreeBSD has struct cmsgcred and struct sockcred.
718
+ * They use both SOL_SOCKET/SCM_CREDS in the ancillary message.
719
+ * They are not ambiguous from the view of the caller
720
+ * because struct sockcred is sent if and only if the caller sets LOCAL_CREDS socket option.
721
+ * But inspect method doesn't know it.
722
+ * So they are ambiguous from the view of inspect.
723
+ * This function distinguish them by the size of the ancillary message.
724
+ * This heuristics works well except when sc_ngroups == CMGROUP_MAX.
725
+ */
726
+
727
+ #if defined(HAVE_TYPE_STRUCT_CMSGCRED) /* FreeBSD */
728
+ if (RSTRING_LEN(data) == sizeof(struct cmsgcred)) {
729
+ struct cmsgcred cred;
730
+ memcpy(&cred, RSTRING_PTR(data), sizeof(struct cmsgcred));
731
+ rb_str_catf(ret, " pid=%u", cred.cmcred_pid);
732
+ rb_str_catf(ret, " uid=%u", cred.cmcred_uid);
733
+ rb_str_catf(ret, " euid=%u", cred.cmcred_euid);
734
+ rb_str_catf(ret, " gid=%u", cred.cmcred_gid);
735
+ if (cred.cmcred_ngroups) {
736
+ int i;
737
+ const char *sep = " groups=";
738
+ for (i = 0; i < cred.cmcred_ngroups; i++) {
739
+ rb_str_catf(ret, "%s%u", sep, cred.cmcred_groups[i]);
740
+ sep = ",";
741
+ }
742
+ }
743
+ rb_str_cat2(ret, " (cmsgcred)");
744
+ return 1;
745
+ }
746
+ #endif
747
+ #if defined(HAVE_TYPE_STRUCT_SOCKCRED) /* FreeBSD, NetBSD */
748
+ if ((size_t)RSTRING_LEN(data) >= SOCKCREDSIZE(0)) {
749
+ struct sockcred cred0, *cred;
750
+ memcpy(&cred0, RSTRING_PTR(data), SOCKCREDSIZE(0));
751
+ if ((size_t)RSTRING_LEN(data) == SOCKCREDSIZE(cred0.sc_ngroups)) {
752
+ cred = (struct sockcred *)ALLOCA_N(char, SOCKCREDSIZE(cred0.sc_ngroups));
753
+ memcpy(cred, RSTRING_PTR(data), SOCKCREDSIZE(cred0.sc_ngroups));
754
+ rb_str_catf(ret, " uid=%u", cred->sc_uid);
755
+ rb_str_catf(ret, " euid=%u", cred->sc_euid);
756
+ rb_str_catf(ret, " gid=%u", cred->sc_gid);
757
+ rb_str_catf(ret, " egid=%u", cred->sc_egid);
758
+ if (cred0.sc_ngroups) {
759
+ int i;
760
+ const char *sep = " groups=";
761
+ for (i = 0; i < cred0.sc_ngroups; i++) {
762
+ rb_str_catf(ret, "%s%u", sep, cred->sc_groups[i]);
763
+ sep = ",";
764
+ }
765
+ }
766
+ rb_str_cat2(ret, " (sockcred)");
767
+ return 1;
768
+ }
769
+ }
770
+ #endif
771
+ return 0;
772
+ }
773
+ #endif
774
+
775
+ #if defined(IPPROTO_IP) && defined(IP_RECVDSTADDR) /* 4.4BSD */
776
+ static int
777
+ anc_inspect_ip_recvdstaddr(int level, int type, VALUE data, VALUE ret)
778
+ {
779
+ if (level == IPPROTO_IP && type == IP_RECVDSTADDR &&
780
+ RSTRING_LEN(data) == sizeof(struct in_addr)) {
781
+ struct in_addr addr;
782
+ char addrbuf[INET_ADDRSTRLEN];
783
+ memcpy(&addr, RSTRING_PTR(data), sizeof(addr));
784
+ if (inet_ntop(AF_INET, &addr, addrbuf, (socklen_t)sizeof(addrbuf)) == NULL)
785
+ rb_str_cat2(ret, " invalid-address");
786
+ else
787
+ rb_str_catf(ret, " %s", addrbuf);
788
+ return 1;
789
+ }
790
+ else {
791
+ return 0;
792
+ }
793
+ }
794
+ #endif
795
+
796
+ #if defined(IPPROTO_IP) && defined(IP_PKTINFO) && defined(HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST) /* GNU/Linux */
797
+ static int
798
+ anc_inspect_ip_pktinfo(int level, int type, VALUE data, VALUE ret)
799
+ {
800
+ if (level == IPPROTO_IP && type == IP_PKTINFO &&
801
+ RSTRING_LEN(data) == sizeof(struct in_pktinfo)) {
802
+ struct in_pktinfo pktinfo;
803
+ char buf[INET_ADDRSTRLEN > IFNAMSIZ ? INET_ADDRSTRLEN : IFNAMSIZ];
804
+ memcpy(&pktinfo, RSTRING_PTR(data), sizeof(pktinfo));
805
+ if (inet_ntop(AF_INET, &pktinfo.ipi_addr, buf, sizeof(buf)) == NULL)
806
+ rb_str_cat2(ret, " invalid-address");
807
+ else
808
+ rb_str_catf(ret, " %s", buf);
809
+ if (if_indextoname(pktinfo.ipi_ifindex, buf) == NULL)
810
+ rb_str_catf(ret, " ifindex:%d", pktinfo.ipi_ifindex);
811
+ else
812
+ rb_str_catf(ret, " %s", buf);
813
+ if (inet_ntop(AF_INET, &pktinfo.ipi_spec_dst, buf, sizeof(buf)) == NULL)
814
+ rb_str_cat2(ret, " spec_dst:invalid-address");
815
+ else
816
+ rb_str_catf(ret, " spec_dst:%s", buf);
817
+ return 1;
818
+ }
819
+ else {
820
+ return 0;
821
+ }
822
+ }
823
+ #endif
824
+
825
+ #if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO) && defined(HAVE_TYPE_STRUCT_IN6_PKTINFO) /* IPv6 RFC3542 */
826
+ static int
827
+ anc_inspect_ipv6_pktinfo(int level, int type, VALUE data, VALUE ret)
828
+ {
829
+ if (level == IPPROTO_IPV6 && type == IPV6_PKTINFO &&
830
+ RSTRING_LEN(data) == sizeof(struct in6_pktinfo)) {
831
+ struct in6_pktinfo *pktinfo = (struct in6_pktinfo *)RSTRING_PTR(data);
832
+ struct in6_addr addr;
833
+ unsigned int ifindex;
834
+ char addrbuf[INET6_ADDRSTRLEN], ifbuf[IFNAMSIZ];
835
+ memcpy(&addr, &pktinfo->ipi6_addr, sizeof(addr));
836
+ memcpy(&ifindex, &pktinfo->ipi6_ifindex, sizeof(ifindex));
837
+ if (inet_ntop(AF_INET6, &addr, addrbuf, (socklen_t)sizeof(addrbuf)) == NULL)
838
+ rb_str_cat2(ret, " invalid-address");
839
+ else
840
+ rb_str_catf(ret, " %s", addrbuf);
841
+ if (if_indextoname(ifindex, ifbuf) == NULL)
842
+ rb_str_catf(ret, " ifindex:%d", ifindex);
843
+ else
844
+ rb_str_catf(ret, " %s", ifbuf);
845
+ return 1;
846
+ }
847
+ else {
848
+ return 0;
849
+ }
850
+ }
851
+ #endif
852
+
853
+ #if defined(SCM_TIMESTAMP) /* GNU/Linux, FreeBSD, NetBSD, OpenBSD, MacOS X, Solaris */
854
+ static int
855
+ inspect_timeval_as_abstime(int level, int optname, VALUE data, VALUE ret)
856
+ {
857
+ if (RSTRING_LEN(data) == sizeof(struct timeval)) {
858
+ struct timeval tv;
859
+ time_t time;
860
+ struct tm tm;
861
+ char buf[32];
862
+ memcpy((char*)&tv, RSTRING_PTR(data), sizeof(tv));
863
+ time = tv.tv_sec;
864
+ tm = *localtime(&time);
865
+ strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tm);
866
+ rb_str_catf(ret, " %s.%06ld", buf, (long)tv.tv_usec);
867
+ return 1;
868
+ }
869
+ else {
870
+ return 0;
871
+ }
872
+ }
873
+ #endif
874
+
875
+ #if defined(SCM_TIMESTAMPNS) /* GNU/Linux */
876
+ static int
877
+ inspect_timespec_as_abstime(int level, int optname, VALUE data, VALUE ret)
878
+ {
879
+ if (RSTRING_LEN(data) == sizeof(struct timespec)) {
880
+ struct timespec ts;
881
+ struct tm tm;
882
+ char buf[32];
883
+ memcpy((char*)&ts, RSTRING_PTR(data), sizeof(ts));
884
+ tm = *localtime(&ts.tv_sec);
885
+ strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tm);
886
+ rb_str_catf(ret, " %s.%09ld", buf, (long)ts.tv_nsec);
887
+ return 1;
888
+ }
889
+ else {
890
+ return 0;
891
+ }
892
+ }
893
+ #endif
894
+
895
+ #if defined(SCM_BINTIME) /* FreeBSD */
896
+ static int
897
+ inspect_bintime_as_abstime(int level, int optname, VALUE data, VALUE ret)
898
+ {
899
+ if (RSTRING_LEN(data) == sizeof(struct bintime)) {
900
+ struct bintime bt;
901
+ struct tm tm;
902
+ uint64_t frac_h, frac_l;
903
+ uint64_t scale_h, scale_l;
904
+ uint64_t tmp1, tmp2;
905
+ uint64_t res_h, res_l;
906
+ char buf[32];
907
+ memcpy((char*)&bt, RSTRING_PTR(data), sizeof(bt));
908
+ tm = *localtime(&bt.sec);
909
+ strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tm);
910
+
911
+ /* res_h = frac * 10**19 / 2**64 */
912
+
913
+ frac_h = bt.frac >> 32;
914
+ frac_l = bt.frac & 0xffffffff;
915
+
916
+ scale_h = 0x8ac72304; /* 0x8ac7230489e80000 == 10**19 */
917
+ scale_l = 0x89e80000;
918
+
919
+ res_h = frac_h * scale_h;
920
+ res_l = frac_l * scale_l;
921
+
922
+ tmp1 = frac_h * scale_l;
923
+ res_h += tmp1 >> 32;
924
+ tmp2 = res_l;
925
+ res_l += tmp1 & 0xffffffff;
926
+ if (res_l < tmp2) res_h++;
927
+
928
+ tmp1 = frac_l * scale_h;
929
+ res_h += tmp1 >> 32;
930
+ tmp2 = res_l;
931
+ res_l += tmp1 & 0xffffffff;
932
+ if (res_l < tmp2) res_h++;
933
+
934
+ rb_str_catf(ret, " %s.%019"PRIu64, buf, res_h);
935
+ return 1;
936
+ }
937
+ else {
938
+ return 0;
939
+ }
940
+ }
941
+ #endif
942
+
943
+ /*
944
+ * call-seq:
945
+ * ancillarydata.inspect => string
946
+ *
947
+ * returns a string which shows ancillarydata in human-readable form.
948
+ *
949
+ * p Socket::AncillaryData.new(:INET6, :IPV6, :PKTINFO, "").inspect
950
+ * #=> "#<Socket::AncillaryData: INET6 IPV6 PKTINFO \"\">"
951
+ */
952
+ static VALUE
953
+ ancillary_inspect(VALUE self)
954
+ {
955
+ VALUE ret;
956
+ int family, level, type;
957
+ VALUE data;
958
+ ID family_id, level_id, type_id;
959
+ VALUE vtype;
960
+ int inspected;
961
+
962
+ family = ancillary_family(self);
963
+ level = ancillary_level(self);
964
+ type = ancillary_type(self);
965
+ data = ancillary_data(self);
966
+
967
+ ret = rb_sprintf("#<%s:", rb_obj_classname(self));
968
+
969
+ family_id = rsock_intern_family_noprefix(family);
970
+ if (family_id)
971
+ rb_str_catf(ret, " %s", rb_id2name(family_id));
972
+ else
973
+ rb_str_catf(ret, " family:%d", family);
974
+
975
+ if (level == SOL_SOCKET) {
976
+ rb_str_cat2(ret, " SOCKET");
977
+
978
+ type_id = rsock_intern_scm_optname(type);
979
+ if (type_id)
980
+ rb_str_catf(ret, " %s", rb_id2name(type_id));
981
+ else
982
+ rb_str_catf(ret, " cmsg_type:%d", type);
983
+ }
984
+ else if (IS_IP_FAMILY(family)) {
985
+ level_id = rsock_intern_iplevel(level);
986
+ if (level_id)
987
+ rb_str_catf(ret, " %s", rb_id2name(level_id));
988
+ else
989
+ rb_str_catf(ret, " cmsg_level:%d", level);
990
+
991
+ vtype = ip_cmsg_type_to_sym(level, type);
992
+ if (SYMBOL_P(vtype))
993
+ rb_str_catf(ret, " %s", rb_id2name(SYM2ID(vtype)));
994
+ else
995
+ rb_str_catf(ret, " cmsg_type:%d", type);
996
+ }
997
+ else {
998
+ rb_str_catf(ret, " cmsg_level:%d", level);
999
+ rb_str_catf(ret, " cmsg_type:%d", type);
1000
+ }
1001
+
1002
+ inspected = 0;
1003
+
1004
+ if (level == SOL_SOCKET)
1005
+ family = AF_UNSPEC;
1006
+
1007
+ switch (family) {
1008
+ case AF_UNSPEC:
1009
+ switch (level) {
1010
+ # if defined(SOL_SOCKET)
1011
+ case SOL_SOCKET:
1012
+ switch (type) {
1013
+ # if defined(SCM_TIMESTAMP) /* GNU/Linux, FreeBSD, NetBSD, OpenBSD, MacOS X, Solaris */
1014
+ case SCM_TIMESTAMP: inspected = inspect_timeval_as_abstime(level, type, data, ret); break;
1015
+ # endif
1016
+ # if defined(SCM_TIMESTAMPNS) /* GNU/Linux */
1017
+ case SCM_TIMESTAMPNS: inspected = inspect_timespec_as_abstime(level, type, data, ret); break;
1018
+ # endif
1019
+ # if defined(SCM_BINTIME) /* FreeBSD */
1020
+ case SCM_BINTIME: inspected = inspect_bintime_as_abstime(level, type, data, ret); break;
1021
+ # endif
1022
+ # if defined(SCM_RIGHTS) /* 4.4BSD */
1023
+ case SCM_RIGHTS: inspected = anc_inspect_socket_rights(level, type, data, ret); break;
1024
+ # endif
1025
+ # if defined(SCM_CREDENTIALS) /* GNU/Linux */
1026
+ case SCM_CREDENTIALS: inspected = anc_inspect_passcred_credentials(level, type, data, ret); break;
1027
+ # endif
1028
+ # if defined(INSPECT_SCM_CREDS) /* NetBSD */
1029
+ case SCM_CREDS: inspected = anc_inspect_socket_creds(level, type, data, ret); break;
1030
+ # endif
1031
+ }
1032
+ break;
1033
+ # endif
1034
+ }
1035
+ break;
1036
+
1037
+ case AF_INET:
1038
+ #ifdef INET6
1039
+ case AF_INET6:
1040
+ #endif
1041
+ switch (level) {
1042
+ # if defined(IPPROTO_IP)
1043
+ case IPPROTO_IP:
1044
+ switch (type) {
1045
+ # if defined(IP_RECVDSTADDR) /* 4.4BSD */
1046
+ case IP_RECVDSTADDR: inspected = anc_inspect_ip_recvdstaddr(level, type, data, ret); break;
1047
+ # endif
1048
+ # if defined(IP_PKTINFO) && defined(HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST) /* GNU/Linux */
1049
+ case IP_PKTINFO: inspected = anc_inspect_ip_pktinfo(level, type, data, ret); break;
1050
+ # endif
1051
+ }
1052
+ break;
1053
+ # endif
1054
+
1055
+ # if defined(IPPROTO_IPV6)
1056
+ case IPPROTO_IPV6:
1057
+ switch (type) {
1058
+ # if defined(IPV6_PKTINFO) /* RFC 3542 */
1059
+ case IPV6_PKTINFO: inspected = anc_inspect_ipv6_pktinfo(level, type, data, ret); break;
1060
+ # endif
1061
+ }
1062
+ break;
1063
+ # endif
1064
+ }
1065
+ break;
1066
+ }
1067
+
1068
+ if (!inspected) {
1069
+ rb_str_cat2(ret, " ");
1070
+ rb_str_append(ret, rb_str_dump(data));
1071
+ }
1072
+
1073
+ rb_str_cat2(ret, ">");
1074
+
1075
+ return ret;
1076
+ }
1077
+
1078
+ /*
1079
+ * call-seq:
1080
+ * ancillarydata.cmsg_is?(level, type) => true or false
1081
+ *
1082
+ * tests the level and type of _ancillarydata_.
1083
+ *
1084
+ * ancdata = Socket::AncillaryData.new(:INET6, :IPV6, :PKTINFO, "")
1085
+ * ancdata.cmsg_is?(Socket::IPPROTO_IPV6, Socket::IPV6_PKTINFO) #=> true
1086
+ * ancdata.cmsg_is?(:IPV6, :PKTINFO) #=> true
1087
+ * ancdata.cmsg_is?(:IP, :PKTINFO) #=> false
1088
+ * ancdata.cmsg_is?(:SOCKET, :RIGHTS) #=> false
1089
+ */
1090
+ static VALUE
1091
+ ancillary_cmsg_is_p(VALUE self, VALUE vlevel, VALUE vtype)
1092
+ {
1093
+ int family = ancillary_family(self);
1094
+ int level = rsock_level_arg(family, vlevel);
1095
+ int type = rsock_cmsg_type_arg(family, level, vtype);
1096
+
1097
+ if (ancillary_level(self) == level &&
1098
+ ancillary_type(self) == type)
1099
+ return Qtrue;
1100
+ else
1101
+ return Qfalse;
1102
+ }
1103
+
1104
+ #endif
1105
+
1106
+ #if defined(HAVE_SENDMSG)
1107
+ struct sendmsg_args_struct {
1108
+ int fd;
1109
+ const struct msghdr *msg;
1110
+ int flags;
1111
+ };
1112
+
1113
+ static VALUE
1114
+ nogvl_sendmsg_func(void *ptr)
1115
+ {
1116
+ struct sendmsg_args_struct *args = ptr;
1117
+ return sendmsg(args->fd, args->msg, args->flags);
1118
+ }
1119
+
1120
+ static ssize_t
1121
+ rb_sendmsg(int fd, const struct msghdr *msg, int flags)
1122
+ {
1123
+ struct sendmsg_args_struct args;
1124
+ args.fd = fd;
1125
+ args.msg = msg;
1126
+ args.flags = flags;
1127
+ return rb_thread_blocking_region(nogvl_sendmsg_func, &args, RUBY_UBF_IO, 0);
1128
+ }
1129
+
1130
+ static VALUE
1131
+ bsock_sendmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock)
1132
+ {
1133
+ rb_io_t *fptr;
1134
+ VALUE data, vflags, dest_sockaddr;
1135
+ VALUE *controls_ptr;
1136
+ int controls_num;
1137
+ struct msghdr mh;
1138
+ struct iovec iov;
1139
+ #if defined(HAVE_ST_MSG_CONTROL)
1140
+ volatile VALUE controls_str = 0;
1141
+ #endif
1142
+ int flags;
1143
+ ssize_t ss;
1144
+ int family;
1145
+
1146
+ rb_secure(4);
1147
+ GetOpenFile(sock, fptr);
1148
+ family = rsock_getfamily(fptr->fd);
1149
+
1150
+ data = vflags = dest_sockaddr = Qnil;
1151
+ controls_ptr = NULL;
1152
+ controls_num = 0;
1153
+
1154
+ if (argc == 0)
1155
+ rb_raise(rb_eArgError, "mesg argument required");
1156
+ data = argv[0];
1157
+ if (1 < argc) vflags = argv[1];
1158
+ if (2 < argc) dest_sockaddr = argv[2];
1159
+ if (3 < argc) { controls_ptr = &argv[3]; controls_num = argc - 3; }
1160
+
1161
+ StringValue(data);
1162
+
1163
+ if (controls_num) {
1164
+ #if defined(HAVE_ST_MSG_CONTROL)
1165
+ int i;
1166
+ size_t last_pad = 0;
1167
+ int last_level = 0;
1168
+ int last_type = 0;
1169
+ controls_str = rb_str_tmp_new(0);
1170
+ for (i = 0; i < controls_num; i++) {
1171
+ VALUE elt = controls_ptr[i], v;
1172
+ VALUE vlevel, vtype;
1173
+ int level, type;
1174
+ VALUE cdata;
1175
+ long oldlen;
1176
+ struct cmsghdr cmh;
1177
+ char *cmsg;
1178
+ size_t cspace;
1179
+ v = rb_check_convert_type(elt, T_ARRAY, "Array", "to_ary");
1180
+ if (!NIL_P(v)) {
1181
+ elt = v;
1182
+ if (RARRAY_LEN(elt) != 3)
1183
+ rb_raise(rb_eArgError, "an element of controls should be 3-elements array");
1184
+ vlevel = rb_ary_entry(elt, 0);
1185
+ vtype = rb_ary_entry(elt, 1);
1186
+ cdata = rb_ary_entry(elt, 2);
1187
+ }
1188
+ else {
1189
+ vlevel = rb_funcall(elt, rb_intern("level"), 0);
1190
+ vtype = rb_funcall(elt, rb_intern("type"), 0);
1191
+ cdata = rb_funcall(elt, rb_intern("data"), 0);
1192
+ }
1193
+ level = rsock_level_arg(family, vlevel);
1194
+ type = rsock_cmsg_type_arg(family, level, vtype);
1195
+ StringValue(cdata);
1196
+ oldlen = RSTRING_LEN(controls_str);
1197
+ cspace = CMSG_SPACE(RSTRING_LEN(cdata));
1198
+ rb_str_resize(controls_str, oldlen + cspace);
1199
+ cmsg = RSTRING_PTR(controls_str)+oldlen;
1200
+ memset((char *)cmsg, 0, cspace);
1201
+ memset((char *)&cmh, 0, sizeof(cmh));
1202
+ cmh.cmsg_level = level;
1203
+ cmh.cmsg_type = type;
1204
+ cmh.cmsg_len = (socklen_t)CMSG_LEN(RSTRING_LEN(cdata));
1205
+ MEMCPY(cmsg, &cmh, char, sizeof(cmh));
1206
+ MEMCPY(cmsg+((char*)CMSG_DATA(&cmh)-(char*)&cmh), RSTRING_PTR(cdata), char, RSTRING_LEN(cdata));
1207
+ last_level = cmh.cmsg_level;
1208
+ last_type = cmh.cmsg_type;
1209
+ last_pad = cspace - cmh.cmsg_len;
1210
+ }
1211
+ if (last_pad) {
1212
+ /*
1213
+ * This code removes the last padding from msg_controllen.
1214
+ *
1215
+ * 4.3BSD-Reno reject the padding for SCM_RIGHTS. (There was no 64bit environments in those days?)
1216
+ * RFC 2292 require the padding.
1217
+ * RFC 3542 relaxes the condition - implementation must accept both as valid.
1218
+ *
1219
+ * Actual problems:
1220
+ *
1221
+ * - NetBSD 4.0.1
1222
+ * SCM_RIGHTS with padding causes EINVAL
1223
+ * IPV6_PKTINFO without padding causes "page fault trap"
1224
+ * http://www.netbsd.org/cgi-bin/query-pr-single.pl?number=40661
1225
+ *
1226
+ * - OpenBSD 4.4
1227
+ * IPV6_PKTINFO without padding causes EINVAL
1228
+ *
1229
+ * Basically, msg_controllen should contains the padding.
1230
+ * So the padding is removed only if a problem really exists.
1231
+ */
1232
+ #if defined(__NetBSD__)
1233
+ if (last_level == SOL_SOCKET && last_type == SCM_RIGHTS)
1234
+ rb_str_set_len(controls_str, RSTRING_LEN(controls_str)-last_pad);
1235
+ #endif
1236
+ }
1237
+ #else
1238
+ rb_raise(rb_eNotImpError, "control message for sendmsg is unimplemented");
1239
+ #endif
1240
+ }
1241
+
1242
+ flags = NIL_P(vflags) ? 0 : NUM2INT(vflags);
1243
+ #ifdef MSG_DONTWAIT
1244
+ if (nonblock)
1245
+ flags |= MSG_DONTWAIT;
1246
+ #endif
1247
+
1248
+ if (!NIL_P(dest_sockaddr))
1249
+ SockAddrStringValue(dest_sockaddr);
1250
+
1251
+ rb_io_check_closed(fptr);
1252
+
1253
+ retry:
1254
+ memset(&mh, 0, sizeof(mh));
1255
+ if (!NIL_P(dest_sockaddr)) {
1256
+ mh.msg_name = RSTRING_PTR(dest_sockaddr);
1257
+ mh.msg_namelen = RSTRING_LENINT(dest_sockaddr);
1258
+ }
1259
+ mh.msg_iovlen = 1;
1260
+ mh.msg_iov = &iov;
1261
+ iov.iov_base = RSTRING_PTR(data);
1262
+ iov.iov_len = RSTRING_LEN(data);
1263
+ #if defined(HAVE_ST_MSG_CONTROL)
1264
+ if (controls_str) {
1265
+ mh.msg_control = RSTRING_PTR(controls_str);
1266
+ mh.msg_controllen = RSTRING_LENINT(controls_str);
1267
+ }
1268
+ else {
1269
+ mh.msg_control = NULL;
1270
+ mh.msg_controllen = 0;
1271
+ }
1272
+ #endif
1273
+
1274
+ rb_io_check_closed(fptr);
1275
+ if (nonblock)
1276
+ rb_io_set_nonblock(fptr);
1277
+
1278
+ ss = rb_sendmsg(fptr->fd, &mh, flags);
1279
+
1280
+ if (!nonblock && rb_io_wait_writable(fptr->fd)) {
1281
+ rb_io_check_closed(fptr);
1282
+ goto retry;
1283
+ }
1284
+
1285
+ if (ss == -1) {
1286
+ if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN))
1287
+ rb_mod_sys_fail(rb_mWaitWritable, "sendmsg(2) would block");
1288
+ rb_sys_fail("sendmsg(2)");
1289
+ }
1290
+
1291
+ return SSIZET2NUM(ss);
1292
+ }
1293
+ #endif
1294
+
1295
+ #if defined(HAVE_SENDMSG)
1296
+ /*
1297
+ * call-seq:
1298
+ * basicsocket.sendmsg(mesg, flags=0, dest_sockaddr=nil, *controls) => numbytes_sent
1299
+ *
1300
+ * sendmsg sends a message using sendmsg(2) system call in blocking manner.
1301
+ *
1302
+ * _mesg_ is a string to send.
1303
+ *
1304
+ * _flags_ is bitwise OR of MSG_* constants such as Socket::MSG_OOB.
1305
+ *
1306
+ * _dest_sockaddr_ is a destination socket address for connection-less socket.
1307
+ * It should be a sockaddr such as a result of Socket.sockaddr_in.
1308
+ * An Addrinfo object can be used too.
1309
+ *
1310
+ * _controls_ is a list of ancillary data.
1311
+ * The element of _controls_ should be Socket::AncillaryData or
1312
+ * 3-elements array.
1313
+ * The 3-element array should contains cmsg_level, cmsg_type and data.
1314
+ *
1315
+ * The return value, _numbytes_sent_ is an integer which is the number of bytes sent.
1316
+ *
1317
+ * sendmsg can be used to implement send_io as follows:
1318
+ *
1319
+ * # use Socket::AncillaryData.
1320
+ * ancdata = Socket::AncillaryData.int(:UNIX, :SOCKET, :RIGHTS, io.fileno)
1321
+ * sock.sendmsg("a", 0, nil, ancdata)
1322
+ *
1323
+ * # use 3-element array.
1324
+ * ancdata = [:SOCKET, :RIGHTS, [io.fileno].pack("i!")]
1325
+ * sock.sendmsg("\0", 0, nil, ancdata)
1326
+ *
1327
+ */
1328
+ VALUE
1329
+ rsock_bsock_sendmsg(int argc, VALUE *argv, VALUE sock)
1330
+ {
1331
+ return bsock_sendmsg_internal(argc, argv, sock, 0);
1332
+ }
1333
+ #endif
1334
+
1335
+ #if defined(HAVE_SENDMSG)
1336
+ /*
1337
+ * call-seq:
1338
+ * basicsocket.sendmsg_nonblock(mesg, flags=0, dest_sockaddr=nil, *controls) => numbytes_sent
1339
+ *
1340
+ * sendmsg_nonblock sends a message using sendmsg(2) system call in non-blocking manner.
1341
+ *
1342
+ * It is similar to BasicSocket#sendmsg
1343
+ * but the non-blocking flag is set before the system call
1344
+ * and it doesn't retry the system call.
1345
+ *
1346
+ */
1347
+ VALUE
1348
+ rsock_bsock_sendmsg_nonblock(int argc, VALUE *argv, VALUE sock)
1349
+ {
1350
+ return bsock_sendmsg_internal(argc, argv, sock, 1);
1351
+ }
1352
+ #endif
1353
+
1354
+ #if defined(HAVE_RECVMSG)
1355
+ struct recvmsg_args_struct {
1356
+ int fd;
1357
+ struct msghdr *msg;
1358
+ int flags;
1359
+ };
1360
+
1361
+ static VALUE
1362
+ nogvl_recvmsg_func(void *ptr)
1363
+ {
1364
+ struct recvmsg_args_struct *args = ptr;
1365
+ return recvmsg(args->fd, args->msg, args->flags);
1366
+ }
1367
+
1368
+ static ssize_t
1369
+ rb_recvmsg(int fd, struct msghdr *msg, int flags)
1370
+ {
1371
+ struct recvmsg_args_struct args;
1372
+ args.fd = fd;
1373
+ args.msg = msg;
1374
+ args.flags = flags;
1375
+ return rb_thread_blocking_region(nogvl_recvmsg_func, &args, RUBY_UBF_IO, 0);
1376
+ }
1377
+
1378
+ #if defined(HAVE_ST_MSG_CONTROL)
1379
+ static void
1380
+ discard_cmsg(struct cmsghdr *cmh, char *msg_end)
1381
+ {
1382
+ if (cmh->cmsg_level == SOL_SOCKET && cmh->cmsg_type == SCM_RIGHTS) {
1383
+ int *fdp = (int *)CMSG_DATA(cmh);
1384
+ int *end = (int *)((char *)cmh + cmh->cmsg_len);
1385
+ while ((char *)fdp + sizeof(int) <= (char *)end &&
1386
+ (char *)fdp + sizeof(int) <= msg_end) {
1387
+ close(*fdp);
1388
+ fdp++;
1389
+ }
1390
+ }
1391
+ }
1392
+ #endif
1393
+
1394
+ void
1395
+ rsock_discard_cmsg_resource(struct msghdr *mh)
1396
+ {
1397
+ #if defined(HAVE_ST_MSG_CONTROL)
1398
+ struct cmsghdr *cmh;
1399
+ char *msg_end;
1400
+
1401
+ if (mh->msg_controllen == 0)
1402
+ return;
1403
+
1404
+ msg_end = (char *)mh->msg_control + mh->msg_controllen;
1405
+
1406
+ for (cmh = CMSG_FIRSTHDR(mh); cmh != NULL; cmh = CMSG_NXTHDR(mh, cmh)) {
1407
+ discard_cmsg(cmh, msg_end);
1408
+ }
1409
+ #endif
1410
+ }
1411
+
1412
+ #if defined(HAVE_ST_MSG_CONTROL)
1413
+ static void
1414
+ make_io_for_unix_rights(VALUE ctl, struct cmsghdr *cmh, char *msg_end)
1415
+ {
1416
+ if (cmh->cmsg_level == SOL_SOCKET && cmh->cmsg_type == SCM_RIGHTS) {
1417
+ int *fdp, *end;
1418
+ VALUE ary = rb_ary_new();
1419
+ rb_ivar_set(ctl, rb_intern("unix_rights"), ary);
1420
+ fdp = (int *)CMSG_DATA(cmh);
1421
+ end = (int *)((char *)cmh + cmh->cmsg_len);
1422
+ while ((char *)fdp + sizeof(int) <= (char *)end &&
1423
+ (char *)fdp + sizeof(int) <= msg_end) {
1424
+ int fd = *fdp;
1425
+ struct stat stbuf;
1426
+ VALUE io;
1427
+ if (fstat(fd, &stbuf) == -1)
1428
+ rb_raise(rb_eSocket, "invalid fd in SCM_RIGHTS");
1429
+ if (S_ISSOCK(stbuf.st_mode))
1430
+ io = rsock_init_sock(rb_obj_alloc(rb_cSocket), fd);
1431
+ else
1432
+ io = rb_io_fdopen(fd, O_RDWR, NULL);
1433
+ ary = rb_attr_get(ctl, rb_intern("unix_rights"));
1434
+ rb_ary_push(ary, io);
1435
+ fdp++;
1436
+ }
1437
+ OBJ_FREEZE(ary);
1438
+ }
1439
+ }
1440
+ #endif
1441
+
1442
+ static VALUE
1443
+ bsock_recvmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock)
1444
+ {
1445
+ rb_io_t *fptr;
1446
+ VALUE vmaxdatlen, vmaxctllen, vflags, vopts;
1447
+ int grow_buffer;
1448
+ size_t maxdatlen;
1449
+ int flags, orig_flags;
1450
+ int request_scm_rights;
1451
+ struct msghdr mh;
1452
+ struct iovec iov;
1453
+ struct sockaddr_storage namebuf;
1454
+ char datbuf0[4096], *datbuf;
1455
+ VALUE dat_str = Qnil;
1456
+ VALUE ret;
1457
+ ssize_t ss;
1458
+ #if defined(HAVE_ST_MSG_CONTROL)
1459
+ struct cmsghdr *cmh;
1460
+ size_t maxctllen;
1461
+ union {
1462
+ char bytes[4096];
1463
+ struct cmsghdr align;
1464
+ } ctlbuf0;
1465
+ char *ctlbuf;
1466
+ VALUE ctl_str = Qnil;
1467
+ int family;
1468
+ int gc_done = 0;
1469
+ #endif
1470
+
1471
+ rb_secure(4);
1472
+
1473
+ vopts = Qnil;
1474
+ if (0 < argc && TYPE(argv[argc-1]) == T_HASH)
1475
+ vopts = argv[--argc];
1476
+
1477
+ rb_scan_args(argc, argv, "03", &vmaxdatlen, &vflags, &vmaxctllen);
1478
+
1479
+ maxdatlen = NIL_P(vmaxdatlen) ? sizeof(datbuf0) : NUM2SIZET(vmaxdatlen);
1480
+ #if defined(HAVE_ST_MSG_CONTROL)
1481
+ maxctllen = NIL_P(vmaxctllen) ? sizeof(ctlbuf0) : NUM2SIZET(vmaxctllen);
1482
+ #else
1483
+ if (!NIL_P(vmaxctllen))
1484
+ rb_raise(rb_eArgError, "control message not supported");
1485
+ #endif
1486
+ flags = NIL_P(vflags) ? 0 : NUM2INT(vflags);
1487
+ #ifdef MSG_DONTWAIT
1488
+ if (nonblock)
1489
+ flags |= MSG_DONTWAIT;
1490
+ #endif
1491
+ orig_flags = flags;
1492
+
1493
+ grow_buffer = NIL_P(vmaxdatlen) || NIL_P(vmaxctllen);
1494
+
1495
+ request_scm_rights = 0;
1496
+ if (!NIL_P(vopts) && RTEST(rb_hash_aref(vopts, ID2SYM(rb_intern("scm_rights")))))
1497
+ request_scm_rights = 1;
1498
+
1499
+ GetOpenFile(sock, fptr);
1500
+ if (rb_io_read_pending(fptr)) {
1501
+ rb_raise(rb_eIOError, "recvmsg for buffered IO");
1502
+ }
1503
+
1504
+ #if !defined(HAVE_ST_MSG_CONTROL)
1505
+ if (grow_buffer) {
1506
+ int socktype;
1507
+ socklen_t optlen = (socklen_t)sizeof(socktype);
1508
+ if (getsockopt(fptr->fd, SOL_SOCKET, SO_TYPE, (void*)&socktype, &optlen) == -1) {
1509
+ rb_sys_fail("getsockopt(SO_TYPE)");
1510
+ }
1511
+ if (socktype == SOCK_STREAM)
1512
+ grow_buffer = 0;
1513
+ }
1514
+ #endif
1515
+
1516
+ retry:
1517
+ if (maxdatlen <= sizeof(datbuf0))
1518
+ datbuf = datbuf0;
1519
+ else {
1520
+ if (NIL_P(dat_str))
1521
+ dat_str = rb_str_tmp_new(maxdatlen);
1522
+ else
1523
+ rb_str_resize(dat_str, maxdatlen);
1524
+ datbuf = RSTRING_PTR(dat_str);
1525
+ }
1526
+
1527
+ #if defined(HAVE_ST_MSG_CONTROL)
1528
+ if (maxctllen <= sizeof(ctlbuf0))
1529
+ ctlbuf = ctlbuf0.bytes;
1530
+ else {
1531
+ if (NIL_P(ctl_str))
1532
+ ctl_str = rb_str_tmp_new(maxctllen);
1533
+ else
1534
+ rb_str_resize(ctl_str, maxctllen);
1535
+ ctlbuf = RSTRING_PTR(ctl_str);
1536
+ }
1537
+ #endif
1538
+
1539
+ memset(&mh, 0, sizeof(mh));
1540
+
1541
+ memset(&namebuf, 0, sizeof(namebuf));
1542
+ mh.msg_name = (struct sockaddr *)&namebuf;
1543
+ mh.msg_namelen = (socklen_t)sizeof(namebuf);
1544
+
1545
+ mh.msg_iov = &iov;
1546
+ mh.msg_iovlen = 1;
1547
+ iov.iov_base = datbuf;
1548
+ iov.iov_len = maxdatlen;
1549
+
1550
+ #if defined(HAVE_ST_MSG_CONTROL)
1551
+ mh.msg_control = ctlbuf;
1552
+ mh.msg_controllen = (socklen_t)maxctllen;
1553
+ #endif
1554
+
1555
+ if (grow_buffer)
1556
+ flags |= MSG_PEEK;
1557
+
1558
+ rb_io_check_closed(fptr);
1559
+ if (nonblock)
1560
+ rb_io_set_nonblock(fptr);
1561
+
1562
+ ss = rb_recvmsg(fptr->fd, &mh, flags);
1563
+
1564
+ if (!nonblock && rb_io_wait_readable(fptr->fd)) {
1565
+ rb_io_check_closed(fptr);
1566
+ goto retry;
1567
+ }
1568
+
1569
+ if (ss == -1) {
1570
+ if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN))
1571
+ rb_mod_sys_fail(rb_mWaitReadable, "recvmsg(2) would block");
1572
+ #if defined(HAVE_ST_MSG_CONTROL)
1573
+ if (!gc_done && (errno == EMFILE || errno == EMSGSIZE)) {
1574
+ /*
1575
+ * When SCM_RIGHTS hit the file descriptors limit:
1576
+ * - Linux 2.6.18 causes success with MSG_CTRUNC
1577
+ * - MacOS X 10.4 causes EMSGSIZE (and lost file descriptors?)
1578
+ * - Solaris 11 causes EMFILE
1579
+ */
1580
+ gc_and_retry:
1581
+ rb_gc();
1582
+ gc_done = 1;
1583
+ goto retry;
1584
+ }
1585
+ #endif
1586
+ rb_sys_fail("recvmsg(2)");
1587
+ }
1588
+
1589
+ if (grow_buffer) {
1590
+ int grown = 0;
1591
+ #if defined(HAVE_ST_MSG_CONTROL)
1592
+ if (NIL_P(vmaxdatlen) && (mh.msg_flags & MSG_TRUNC)) {
1593
+ if (SIZE_MAX/2 < maxdatlen)
1594
+ rb_raise(rb_eArgError, "max data length too big");
1595
+ maxdatlen *= 2;
1596
+ grown = 1;
1597
+ }
1598
+ if (NIL_P(vmaxctllen) && (mh.msg_flags & MSG_CTRUNC)) {
1599
+ #define BIG_ENOUGH_SPACE 65536
1600
+ if (BIG_ENOUGH_SPACE < maxctllen &&
1601
+ mh.msg_controllen < maxctllen - BIG_ENOUGH_SPACE) {
1602
+ /* there are big space bug truncated.
1603
+ * file descriptors limit? */
1604
+ if (!gc_done) {
1605
+ rsock_discard_cmsg_resource(&mh);
1606
+ goto gc_and_retry;
1607
+ }
1608
+ }
1609
+ else {
1610
+ if (SIZE_MAX/2 < maxctllen)
1611
+ rb_raise(rb_eArgError, "max control message length too big");
1612
+ maxctllen *= 2;
1613
+ grown = 1;
1614
+ }
1615
+ #undef BIG_ENOUGH_SPACE
1616
+ }
1617
+ #else
1618
+ if (NIL_P(vmaxdatlen) && ss != -1 && ss == (ssize_t)iov.iov_len) {
1619
+ if (SIZE_MAX/2 < maxdatlen)
1620
+ rb_raise(rb_eArgError, "max data length too big");
1621
+ maxdatlen *= 2;
1622
+ grown = 1;
1623
+ }
1624
+ #endif
1625
+ if (grown) {
1626
+ rsock_discard_cmsg_resource(&mh);
1627
+ goto retry;
1628
+ }
1629
+ else {
1630
+ grow_buffer = 0;
1631
+ if (flags != orig_flags) {
1632
+ flags = orig_flags;
1633
+ rsock_discard_cmsg_resource(&mh);
1634
+ goto retry;
1635
+ }
1636
+ }
1637
+ }
1638
+
1639
+ if (NIL_P(dat_str))
1640
+ dat_str = rb_tainted_str_new(datbuf, ss);
1641
+ else {
1642
+ rb_str_resize(dat_str, ss);
1643
+ OBJ_TAINT(dat_str);
1644
+ RBASIC(dat_str)->klass = rb_cString;
1645
+ }
1646
+
1647
+ ret = rb_ary_new3(3, dat_str,
1648
+ rsock_io_socket_addrinfo(sock, mh.msg_name, mh.msg_namelen),
1649
+ #if defined(HAVE_ST_MSG_CONTROL)
1650
+ INT2NUM(mh.msg_flags)
1651
+ #else
1652
+ Qnil
1653
+ #endif
1654
+ );
1655
+
1656
+ #if defined(HAVE_ST_MSG_CONTROL)
1657
+ family = rsock_getfamily(fptr->fd);
1658
+ if (mh.msg_controllen) {
1659
+ char *msg_end = (char *)mh.msg_control + mh.msg_controllen;
1660
+ for (cmh = CMSG_FIRSTHDR(&mh); cmh != NULL; cmh = CMSG_NXTHDR(&mh, cmh)) {
1661
+ VALUE ctl;
1662
+ char *ctl_end;
1663
+ size_t clen;
1664
+ if (cmh->cmsg_len == 0) {
1665
+ rb_raise(rb_eTypeError, "invalid control message (cmsg_len == 0)");
1666
+ }
1667
+ ctl_end = (char*)cmh + cmh->cmsg_len;
1668
+ clen = (ctl_end <= msg_end ? ctl_end : msg_end) - (char*)CMSG_DATA(cmh);
1669
+ ctl = ancdata_new(family, cmh->cmsg_level, cmh->cmsg_type, rb_tainted_str_new((char*)CMSG_DATA(cmh), clen));
1670
+ if (request_scm_rights)
1671
+ make_io_for_unix_rights(ctl, cmh, msg_end);
1672
+ else
1673
+ discard_cmsg(cmh, msg_end);
1674
+ rb_ary_push(ret, ctl);
1675
+ }
1676
+ }
1677
+ #endif
1678
+
1679
+ return ret;
1680
+ }
1681
+ #endif
1682
+
1683
+ #if defined(HAVE_RECVMSG)
1684
+ /*
1685
+ * call-seq:
1686
+ * basicsocket.recvmsg(maxmesglen=nil, flags=0, maxcontrollen=nil, opts={}) => [mesg, sender_addrinfo, rflags, *controls]
1687
+ *
1688
+ * recvmsg receives a message using recvmsg(2) system call in blocking manner.
1689
+ *
1690
+ * _maxmesglen_ is the maximum length of mesg to receive.
1691
+ *
1692
+ * _flags_ is bitwise OR of MSG_* constants such as Socket::MSG_PEEK.
1693
+ *
1694
+ * _maxcontrollen_ is the maximum length of controls (ancillary data) to receive.
1695
+ *
1696
+ * _opts_ is option hash.
1697
+ * Currently :scm_rights=>bool is the only option.
1698
+ *
1699
+ * :scm_rights option specifies that application expects SCM_RIGHTS control message.
1700
+ * If the value is nil or false, application don't expects SCM_RIGHTS control message.
1701
+ * In this case, recvmsg closes the passed file descriptors immediately.
1702
+ * This is the default behavior.
1703
+ *
1704
+ * If :scm_rights value is neither nil nor false, application expects SCM_RIGHTS control message.
1705
+ * In this case, recvmsg creates IO objects for each file descriptors for
1706
+ * Socket::AncillaryData#unix_rights method.
1707
+ *
1708
+ * The return value is 4-elements array.
1709
+ *
1710
+ * _mesg_ is a string of the received message.
1711
+ *
1712
+ * _sender_addrinfo_ is a sender socket address for connection-less socket.
1713
+ * It is an Addrinfo object.
1714
+ * For connection-oriented socket such as TCP, sender_addrinfo is platform dependent.
1715
+ *
1716
+ * _rflags_ is a flags on the received message which is bitwise OR of MSG_* constants such as Socket::MSG_TRUNC.
1717
+ * It will be nil if the system uses 4.3BSD style old recvmsg system call.
1718
+ *
1719
+ * _controls_ is ancillary data which is an array of Socket::AncillaryData objects such as:
1720
+ *
1721
+ * #<Socket::AncillaryData: AF_UNIX SOCKET RIGHTS 7>
1722
+ *
1723
+ * _maxmesglen_ and _maxcontrollen_ can be nil.
1724
+ * In that case, the buffer will be grown until the message is not truncated.
1725
+ * Internally, MSG_PEEK is used and MSG_TRUNC/MSG_CTRUNC are checked.
1726
+ *
1727
+ * recvmsg can be used to implement recv_io as follows:
1728
+ *
1729
+ * mesg, sender_sockaddr, rflags, *controls = sock.recvmsg(:scm_rights=>true)
1730
+ * controls.each {|ancdata|
1731
+ * if ancdata.cmsg_is?(:SOCKET, :RIGHTS)
1732
+ * return ancdata.unix_rights[0]
1733
+ * end
1734
+ * }
1735
+ *
1736
+ */
1737
+ VALUE
1738
+ rsock_bsock_recvmsg(int argc, VALUE *argv, VALUE sock)
1739
+ {
1740
+ return bsock_recvmsg_internal(argc, argv, sock, 0);
1741
+ }
1742
+ #endif
1743
+
1744
+ #if defined(HAVE_RECVMSG)
1745
+ /*
1746
+ * call-seq:
1747
+ * basicsocket.recvmsg_nonblock(maxdatalen=nil, flags=0, maxcontrollen=nil, opts={}) => [data, sender_addrinfo, rflags, *controls]
1748
+ *
1749
+ * recvmsg receives a message using recvmsg(2) system call in non-blocking manner.
1750
+ *
1751
+ * It is similar to BasicSocket#recvmsg
1752
+ * but non-blocking flag is set before the system call
1753
+ * and it doesn't retry the system call.
1754
+ *
1755
+ */
1756
+ VALUE
1757
+ rsock_bsock_recvmsg_nonblock(int argc, VALUE *argv, VALUE sock)
1758
+ {
1759
+ return bsock_recvmsg_internal(argc, argv, sock, 1);
1760
+ }
1761
+ #endif
1762
+
1763
+ /*
1764
+ * Document-class: ::Socket::AncillaryData
1765
+ *
1766
+ * Socket::AncillaryData represents the ancillary data (control information)
1767
+ * used by sendmsg and recvmsg system call.
1768
+ * It contains socket family, cmsg level, cmsg type and cmsg data.
1769
+ */
1770
+ void
1771
+ rsock_init_ancdata(void)
1772
+ {
1773
+ #if defined(HAVE_ST_MSG_CONTROL)
1774
+ rb_cAncillaryData = rb_define_class_under(rb_cSocket, "AncillaryData", rb_cObject);
1775
+ rb_define_method(rb_cAncillaryData, "initialize", ancillary_initialize, 4);
1776
+ rb_define_method(rb_cAncillaryData, "inspect", ancillary_inspect, 0);
1777
+ rb_define_method(rb_cAncillaryData, "family", ancillary_family_m, 0);
1778
+ rb_define_method(rb_cAncillaryData, "level", ancillary_level_m, 0);
1779
+ rb_define_method(rb_cAncillaryData, "type", ancillary_type_m, 0);
1780
+ rb_define_method(rb_cAncillaryData, "data", ancillary_data, 0);
1781
+
1782
+ rb_define_method(rb_cAncillaryData, "cmsg_is?", ancillary_cmsg_is_p, 2);
1783
+
1784
+ rb_define_singleton_method(rb_cAncillaryData, "int", ancillary_s_int, 4);
1785
+ rb_define_method(rb_cAncillaryData, "int", ancillary_int, 0);
1786
+
1787
+ rb_define_singleton_method(rb_cAncillaryData, "unix_rights", ancillary_s_unix_rights, -1);
1788
+ rb_define_method(rb_cAncillaryData, "unix_rights", ancillary_unix_rights, 0);
1789
+
1790
+ rb_define_method(rb_cAncillaryData, "timestamp", ancillary_timestamp, 0);
1791
+
1792
+ rb_define_singleton_method(rb_cAncillaryData, "ip_pktinfo", ancillary_s_ip_pktinfo, -1);
1793
+ rb_define_method(rb_cAncillaryData, "ip_pktinfo", ancillary_ip_pktinfo, 0);
1794
+
1795
+ rb_define_singleton_method(rb_cAncillaryData, "ipv6_pktinfo", ancillary_s_ipv6_pktinfo, 2);
1796
+ rb_define_method(rb_cAncillaryData, "ipv6_pktinfo", ancillary_ipv6_pktinfo, 0);
1797
+ rb_define_method(rb_cAncillaryData, "ipv6_pktinfo_addr", ancillary_ipv6_pktinfo_addr, 0);
1798
+ rb_define_method(rb_cAncillaryData, "ipv6_pktinfo_ifindex", ancillary_ipv6_pktinfo_ifindex, 0);
1799
+ #endif
1800
+ }