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

Sign up to get free protection for your applications and to get access to all the features.
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
+ }