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
@@ -0,0 +1,306 @@
1
+ #ifndef RUBY_SOCKET_H
2
+ #define RUBY_SOCKET_H 1
3
+
4
+ #include "ruby/ruby.h"
5
+ #include "ruby/io.h"
6
+ #include "ruby/util.h"
7
+ #include <stdio.h>
8
+ #include <sys/types.h>
9
+ #include <sys/stat.h>
10
+
11
+ #ifdef HAVE_UNISTD_H
12
+ #include <unistd.h>
13
+ #endif
14
+
15
+ #ifdef HAVE_SYS_UIO_H
16
+ #include <sys/uio.h>
17
+ #endif
18
+
19
+ #ifdef HAVE_XTI_H
20
+ #include <xti.h>
21
+ #endif
22
+
23
+ #ifndef _WIN32
24
+ #if defined(__BEOS__) && !defined(__HAIKU__) && !defined(BONE)
25
+ # include <net/socket.h>
26
+ #else
27
+ # include <sys/socket.h>
28
+ #endif
29
+ #include <netinet/in.h>
30
+ #ifdef HAVE_NETINET_IN_SYSTM_H
31
+ # include <netinet/in_systm.h>
32
+ #endif
33
+ #ifdef HAVE_NETINET_TCP_H
34
+ # include <netinet/tcp.h>
35
+ #endif
36
+ #ifdef HAVE_NETINET_UDP_H
37
+ # include <netinet/udp.h>
38
+ #endif
39
+ #ifdef HAVE_ARPA_INET_H
40
+ # include <arpa/inet.h>
41
+ #endif
42
+ #include <netdb.h>
43
+ #endif
44
+ #include <errno.h>
45
+ #ifdef HAVE_SYS_UN_H
46
+ #include <sys/un.h>
47
+ #endif
48
+
49
+ #if defined(HAVE_FCNTL)
50
+ #ifdef HAVE_SYS_SELECT_H
51
+ #include <sys/select.h>
52
+ #endif
53
+ #ifdef HAVE_SYS_TYPES_H
54
+ #include <sys/types.h>
55
+ #endif
56
+ #ifdef HAVE_SYS_TIME_H
57
+ #include <sys/time.h>
58
+ #endif
59
+ #ifdef HAVE_FCNTL_H
60
+ #include <fcntl.h>
61
+ #endif
62
+ #endif
63
+
64
+ #ifdef HAVE_IFADDRS_H
65
+ #include <ifaddrs.h>
66
+ #endif
67
+ #ifdef HAVE_SYS_IOCTL_H
68
+ #include <sys/ioctl.h>
69
+ #endif
70
+ #ifdef HAVE_SYS_SOCKIO_H
71
+ #include <sys/sockio.h>
72
+ #endif
73
+ #ifdef HAVE_NET_IF_H
74
+ #include <net/if.h>
75
+ #endif
76
+
77
+ #ifdef HAVE_SYS_PARAM_H
78
+ #include <sys/param.h>
79
+ #endif
80
+ #ifdef HAVE_SYS_UCRED_H
81
+ #include <sys/ucred.h>
82
+ #endif
83
+ #ifdef HAVE_UCRED_H
84
+ #include <ucred.h>
85
+ #endif
86
+
87
+ #ifndef EWOULDBLOCK
88
+ #define EWOULDBLOCK EAGAIN
89
+ #endif
90
+
91
+ /*
92
+ * workaround for NetBSD, OpenBSD and etc.
93
+ * The problem is since 4.4BSD-Lite.
94
+ * FreeBSD fix the problem at FreeBSD 2.2.0.
95
+ * NetBSD fix the problem at NetBSD 3.0 by kern/29624.
96
+ * OpenBSD fix the problem at OpenBSD 3.8.
97
+ */
98
+ #define pseudo_AF_FTIP pseudo_AF_RTIP
99
+
100
+ #ifndef HAVE_GETADDRINFO
101
+ #include "addrinfo.h"
102
+ #endif
103
+ #include "sockport.h"
104
+
105
+ #ifndef NI_MAXHOST
106
+ # define NI_MAXHOST 1025
107
+ #endif
108
+ #ifndef NI_MAXSERV
109
+ # define NI_MAXSERV 32
110
+ #endif
111
+
112
+ #ifdef AF_INET6
113
+ # define IS_IP_FAMILY(af) ((af) == AF_INET || (af) == AF_INET6)
114
+ #else
115
+ # define IS_IP_FAMILY(af) ((af) == AF_INET)
116
+ #endif
117
+
118
+ #ifndef HAVE_SOCKADDR_STORAGE
119
+ /*
120
+ * RFC 2553: protocol-independent placeholder for socket addresses
121
+ */
122
+ #define _SS_MAXSIZE 128
123
+ #define _SS_ALIGNSIZE (sizeof(double))
124
+ #define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(unsigned char) * 2)
125
+ #define _SS_PAD2SIZE (_SS_MAXSIZE - sizeof(unsigned char) * 2 - \
126
+ _SS_PAD1SIZE - _SS_ALIGNSIZE)
127
+
128
+ struct sockaddr_storage {
129
+ #ifdef HAVE_SA_LEN
130
+ unsigned char ss_len; /* address length */
131
+ unsigned char ss_family; /* address family */
132
+ #else
133
+ unsigned short ss_family;
134
+ #endif
135
+ char __ss_pad1[_SS_PAD1SIZE];
136
+ double __ss_align; /* force desired structure storage alignment */
137
+ char __ss_pad2[_SS_PAD2SIZE];
138
+ };
139
+ #endif
140
+
141
+ #if defined __APPLE__ && defined __MACH__
142
+ /*
143
+ * CMSG_ macros are broken on 64bit darwin, because __DARWIN_ALIGN
144
+ * aligns up to __darwin_size_t which is 64bit, but CMSG_DATA is
145
+ * 32bit-aligned.
146
+ */
147
+ #undef __DARWIN_ALIGNBYTES
148
+ #define __DARWIN_ALIGNBYTES (sizeof(unsigned int) - 1)
149
+ #endif
150
+
151
+ #if defined(_AIX)
152
+ #ifndef CMSG_SPACE
153
+ # define CMSG_SPACE(len) (_CMSG_ALIGN(sizeof(struct cmsghdr)) + _CMSG_ALIGN(len))
154
+ #endif
155
+ #ifndef CMSG_LEN
156
+ # define CMSG_LEN(len) (_CMSG_ALIGN(sizeof(struct cmsghdr)) + (len))
157
+ #endif
158
+ #endif
159
+
160
+ #ifdef __BEOS__
161
+ #undef close
162
+ #define close closesocket
163
+ #endif
164
+
165
+ #define INET_CLIENT 0
166
+ #define INET_SERVER 1
167
+ #define INET_SOCKS 2
168
+
169
+ extern int rsock_do_not_reverse_lookup;
170
+ #define FMODE_NOREVLOOKUP 0x100
171
+
172
+ extern VALUE rb_cBasicSocket;
173
+ extern VALUE rb_cIPSocket;
174
+ extern VALUE rb_cTCPSocket;
175
+ extern VALUE rb_cTCPServer;
176
+ extern VALUE rb_cUDPSocket;
177
+ #ifdef HAVE_SYS_UN_H
178
+ extern VALUE rb_cUNIXSocket;
179
+ extern VALUE rb_cUNIXServer;
180
+ #endif
181
+ extern VALUE rb_cSocket;
182
+ extern VALUE rb_cAddrinfo;
183
+ extern VALUE rb_cSockOpt;
184
+
185
+ extern VALUE rb_eSocket;
186
+
187
+ #ifdef SOCKS
188
+ extern VALUE rb_cSOCKSSocket;
189
+ #ifdef SOCKS5
190
+ #include <socks.h>
191
+ #else
192
+ void SOCKSinit();
193
+ int Rconnect();
194
+ #endif
195
+ #endif
196
+
197
+ #include "ruby/constdefs.h"
198
+
199
+ #define BLOCKING_REGION(func, arg) (long)rb_thread_blocking_region((func), (arg), RUBY_UBF_IO, 0)
200
+
201
+ #define SockAddrStringValue(v) rsock_sockaddr_string_value(&(v))
202
+ #define SockAddrStringValuePtr(v) rsock_sockaddr_string_value_ptr(&(v))
203
+ VALUE rsock_sockaddr_string_value(volatile VALUE *);
204
+ char *rsock_sockaddr_string_value_ptr(volatile VALUE *);
205
+ VALUE rb_check_sockaddr_string_type(VALUE);
206
+
207
+ NORETURN(void rsock_raise_socket_error(const char *, int));
208
+
209
+ int rsock_family_arg(VALUE domain);
210
+ int rsock_socktype_arg(VALUE type);
211
+ int rsock_level_arg(int family, VALUE level);
212
+ int rsock_optname_arg(int family, int level, VALUE optname);
213
+ int rsock_cmsg_type_arg(int family, int level, VALUE type);
214
+ int rsock_shutdown_how_arg(VALUE how);
215
+
216
+ int rsock_getfamily(int sockfd);
217
+
218
+ int rb_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res);
219
+ int rb_getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags);
220
+ struct addrinfo *rsock_addrinfo(VALUE host, VALUE port, int socktype, int flags);
221
+ struct addrinfo *rsock_getaddrinfo(VALUE host, VALUE port, struct addrinfo *hints, int socktype_hack);
222
+ VALUE rsock_fd_socket_addrinfo(int fd, struct sockaddr *addr, socklen_t len);
223
+ VALUE rsock_io_socket_addrinfo(VALUE io, struct sockaddr *addr, socklen_t len);
224
+
225
+ VALUE rsock_addrinfo_new(struct sockaddr *addr, socklen_t len, int family, int socktype, int protocol, VALUE canonname, VALUE inspectname);
226
+
227
+ VALUE rsock_make_ipaddr(struct sockaddr *addr);
228
+ VALUE rsock_ipaddr(struct sockaddr *sockaddr, int norevlookup);
229
+ VALUE rsock_make_hostent(VALUE host, struct addrinfo *addr, VALUE (*ipaddr)(struct sockaddr *, size_t));
230
+
231
+ int rsock_revlookup_flag(VALUE revlookup, int *norevlookup);
232
+
233
+ #ifdef HAVE_SYS_UN_H
234
+ const char* rsock_unixpath(struct sockaddr_un *sockaddr, socklen_t len);
235
+ VALUE rsock_unixaddr(struct sockaddr_un *sockaddr, socklen_t len);
236
+ #endif
237
+
238
+ int rsock_socket(int domain, int type, int proto);
239
+ VALUE rsock_init_sock(VALUE sock, int fd);
240
+ VALUE rsock_sock_s_socketpair(int argc, VALUE *argv, VALUE klass);
241
+ VALUE rsock_init_inetsock(VALUE sock, VALUE remote_host, VALUE remote_serv, VALUE local_host, VALUE local_serv, int type);
242
+ VALUE rsock_init_unixsock(VALUE sock, VALUE path, int server);
243
+
244
+ struct rsock_send_arg {
245
+ int fd, flags;
246
+ VALUE mesg;
247
+ struct sockaddr *to;
248
+ socklen_t tolen;
249
+ };
250
+
251
+ VALUE rsock_sendto_blocking(void *data);
252
+ VALUE rsock_send_blocking(void *data);
253
+ VALUE rsock_bsock_send(int argc, VALUE *argv, VALUE sock);
254
+
255
+ enum sock_recv_type {
256
+ RECV_RECV, /* BasicSocket#recv(no from) */
257
+ RECV_IP, /* IPSocket#recvfrom */
258
+ RECV_UNIX, /* UNIXSocket#recvfrom */
259
+ RECV_SOCKET /* Socket#recvfrom */
260
+ };
261
+
262
+ VALUE rsock_s_recvfrom_nonblock(VALUE sock, int argc, VALUE *argv, enum sock_recv_type from);
263
+ VALUE rsock_s_recvfrom(VALUE sock, int argc, VALUE *argv, enum sock_recv_type from);
264
+
265
+ int rsock_connect(int fd, const struct sockaddr *sockaddr, int len, int socks);
266
+
267
+ VALUE rsock_s_accept(VALUE klass, int fd, struct sockaddr *sockaddr, socklen_t *len);
268
+ VALUE rsock_s_accept_nonblock(VALUE klass, rb_io_t *fptr, struct sockaddr *sockaddr, socklen_t *len);
269
+ VALUE rsock_sock_listen(VALUE sock, VALUE log);
270
+
271
+ VALUE rsock_sockopt_new(int family, int level, int optname, VALUE data);
272
+
273
+ #if defined(HAVE_SENDMSG)
274
+ VALUE rsock_bsock_sendmsg(int argc, VALUE *argv, VALUE sock);
275
+ VALUE rsock_bsock_sendmsg_nonblock(int argc, VALUE *argv, VALUE sock);
276
+ #else
277
+ #define rsock_bsock_sendmsg rb_f_notimplement
278
+ #define rsock_bsock_sendmsg_nonblock rb_f_notimplement
279
+ #endif
280
+ #if defined(HAVE_RECVMSG)
281
+ VALUE rsock_bsock_recvmsg(int argc, VALUE *argv, VALUE sock);
282
+ VALUE rsock_bsock_recvmsg_nonblock(int argc, VALUE *argv, VALUE sock);
283
+ #else
284
+ #define rsock_bsock_recvmsg rb_f_notimplement
285
+ #define rsock_bsock_recvmsg_nonblock rb_f_notimplement
286
+ #endif
287
+
288
+ #ifdef HAVE_ST_MSG_CONTROL
289
+ void rsock_discard_cmsg_resource(struct msghdr *mh);
290
+ #endif
291
+
292
+ void rsock_init_basicsocket(void);
293
+ void rsock_init_ipsocket(void);
294
+ void rsock_init_tcpsocket(void);
295
+ void rsock_init_tcpserver(void);
296
+ void rsock_init_sockssocket(void);
297
+ void rsock_init_udpsocket(void);
298
+ void rsock_init_unixsocket(void);
299
+ void rsock_init_unixserver(void);
300
+ void rsock_init_socket_constants(void);
301
+ void rsock_init_ancdata(void);
302
+ void rsock_init_addrinfo(void);
303
+ void rsock_init_sockopt(void);
304
+ void rsock_init_socket_init(void);
305
+
306
+ #endif
@@ -0,0 +1,1870 @@
1
+ /************************************************
2
+
3
+ socket.c -
4
+
5
+ created at: Thu Mar 31 12:21:29 JST 1994
6
+
7
+ Copyright (C) 1993-2007 Yukihiro Matsumoto
8
+
9
+ ************************************************/
10
+
11
+ #include "rubysocket.h"
12
+
13
+ static void
14
+ setup_domain_and_type(VALUE domain, int *dv, VALUE type, int *tv)
15
+ {
16
+ *dv = rsock_family_arg(domain);
17
+ *tv = rsock_socktype_arg(type);
18
+ }
19
+
20
+ /*
21
+ * call-seq:
22
+ * Socket.new(domain, socktype [, protocol]) => socket
23
+ *
24
+ * Creates a new socket object.
25
+ *
26
+ * _domain_ should be a communications domain such as: :INET, :INET6, :UNIX, etc.
27
+ *
28
+ * _socktype_ should be a socket type such as: :STREAM, :DGRAM, :RAW, etc.
29
+ *
30
+ * _protocol_ should be a protocol defined in the domain.
31
+ * This is optional.
32
+ * If it is not given, 0 is used internally.
33
+ *
34
+ * Socket.new(:INET, :STREAM) # TCP socket
35
+ * Socket.new(:INET, :DGRAM) # UDP socket
36
+ * Socket.new(:UNIX, :STREAM) # UNIX stream socket
37
+ * Socket.new(:UNIX, :DGRAM) # UNIX datagram socket
38
+ */
39
+ static VALUE
40
+ sock_initialize(int argc, VALUE *argv, VALUE sock)
41
+ {
42
+ VALUE domain, type, protocol;
43
+ int fd;
44
+ int d, t;
45
+
46
+ rb_scan_args(argc, argv, "21", &domain, &type, &protocol);
47
+ if (NIL_P(protocol))
48
+ protocol = INT2FIX(0);
49
+
50
+ rb_secure(3);
51
+ setup_domain_and_type(domain, &d, type, &t);
52
+ fd = rsock_socket(d, t, NUM2INT(protocol));
53
+ if (fd < 0) rb_sys_fail("socket(2)");
54
+
55
+ return rsock_init_sock(sock, fd);
56
+ }
57
+
58
+ #if defined HAVE_SOCKETPAIR
59
+ static VALUE
60
+ io_call_close(VALUE io)
61
+ {
62
+ return rb_funcall(io, rb_intern("close"), 0, 0);
63
+ }
64
+
65
+ static VALUE
66
+ io_close(VALUE io)
67
+ {
68
+ return rb_rescue(io_call_close, io, 0, 0);
69
+ }
70
+
71
+ static VALUE
72
+ pair_yield(VALUE pair)
73
+ {
74
+ return rb_ensure(rb_yield, pair, io_close, rb_ary_entry(pair, 1));
75
+ }
76
+ #endif
77
+
78
+ #if defined HAVE_SOCKETPAIR
79
+ /*
80
+ * call-seq:
81
+ * Socket.pair(domain, type, protocol) => [socket1, socket2]
82
+ * Socket.socketpair(domain, type, protocol) => [socket1, socket2]
83
+ *
84
+ * Creates a pair of sockets connected each other.
85
+ *
86
+ * _domain_ should be a communications domain such as: :INET, :INET6, :UNIX, etc.
87
+ *
88
+ * _socktype_ should be a socket type such as: :STREAM, :DGRAM, :RAW, etc.
89
+ *
90
+ * _protocol_ should be a protocol defined in the domain.
91
+ * 0 is default protocol for the domain.
92
+ *
93
+ * s1, s2 = Socket.pair(:UNIX, :DGRAM, 0)
94
+ * s1.send "a", 0
95
+ * s1.send "b", 0
96
+ * p s2.recv(10) #=> "a"
97
+ * p s2.recv(10) #=> "b"
98
+ *
99
+ */
100
+ VALUE
101
+ rsock_sock_s_socketpair(int argc, VALUE *argv, VALUE klass)
102
+ {
103
+ VALUE domain, type, protocol;
104
+ int d, t, p, sp[2];
105
+ int ret;
106
+ VALUE s1, s2, r;
107
+
108
+ rb_scan_args(argc, argv, "21", &domain, &type, &protocol);
109
+ if (NIL_P(protocol))
110
+ protocol = INT2FIX(0);
111
+
112
+ setup_domain_and_type(domain, &d, type, &t);
113
+ p = NUM2INT(protocol);
114
+ ret = socketpair(d, t, p, sp);
115
+ if (ret < 0 && (errno == EMFILE || errno == ENFILE)) {
116
+ rb_gc();
117
+ ret = socketpair(d, t, p, sp);
118
+ }
119
+ if (ret < 0) {
120
+ rb_sys_fail("socketpair(2)");
121
+ }
122
+
123
+ s1 = rsock_init_sock(rb_obj_alloc(klass), sp[0]);
124
+ s2 = rsock_init_sock(rb_obj_alloc(klass), sp[1]);
125
+ r = rb_assoc_new(s1, s2);
126
+ if (rb_block_given_p()) {
127
+ return rb_ensure(pair_yield, r, io_close, s1);
128
+ }
129
+ return r;
130
+ }
131
+ #else
132
+ #define rsock_sock_s_socketpair rb_f_notimplement
133
+ #endif
134
+
135
+ /*
136
+ * call-seq:
137
+ * socket.connect(remote_sockaddr) => 0
138
+ *
139
+ * Requests a connection to be made on the given +remote_sockaddr+. Returns 0 if
140
+ * successful, otherwise an exception is raised.
141
+ *
142
+ * === Parameter
143
+ * * +remote_sockaddr+ - the +struct+ sockaddr contained in a string or Addrinfo object
144
+ *
145
+ * === Example:
146
+ * # Pull down Google's web page
147
+ * require 'socket'
148
+ * include Socket::Constants
149
+ * socket = Socket.new( AF_INET, SOCK_STREAM, 0 )
150
+ * sockaddr = Socket.pack_sockaddr_in( 80, 'www.google.com' )
151
+ * socket.connect( sockaddr )
152
+ * socket.write( "GET / HTTP/1.0\r\n\r\n" )
153
+ * results = socket.read
154
+ *
155
+ * === Unix-based Exceptions
156
+ * On unix-based systems the following system exceptions may be raised if
157
+ * the call to _connect_ fails:
158
+ * * Errno::EACCES - search permission is denied for a component of the prefix
159
+ * path or write access to the +socket+ is denied
160
+ * * Errno::EADDRINUSE - the _sockaddr_ is already in use
161
+ * * Errno::EADDRNOTAVAIL - the specified _sockaddr_ is not available from the
162
+ * local machine
163
+ * * Errno::EAFNOSUPPORT - the specified _sockaddr_ is not a valid address for
164
+ * the address family of the specified +socket+
165
+ * * Errno::EALREADY - a connection is already in progress for the specified
166
+ * socket
167
+ * * Errno::EBADF - the +socket+ is not a valid file descriptor
168
+ * * Errno::ECONNREFUSED - the target _sockaddr_ was not listening for connections
169
+ * refused the connection request
170
+ * * Errno::ECONNRESET - the remote host reset the connection request
171
+ * * Errno::EFAULT - the _sockaddr_ cannot be accessed
172
+ * * Errno::EHOSTUNREACH - the destination host cannot be reached (probably
173
+ * because the host is down or a remote router cannot reach it)
174
+ * * Errno::EINPROGRESS - the O_NONBLOCK is set for the +socket+ and the
175
+ * connection cannot be immediately established; the connection will be
176
+ * established asynchronously
177
+ * * Errno::EINTR - the attempt to establish the connection was interrupted by
178
+ * delivery of a signal that was caught; the connection will be established
179
+ * asynchronously
180
+ * * Errno::EISCONN - the specified +socket+ is already connected
181
+ * * Errno::EINVAL - the address length used for the _sockaddr_ is not a valid
182
+ * length for the address family or there is an invalid family in _sockaddr_
183
+ * * Errno::ENAMETOOLONG - the pathname resolved had a length which exceeded
184
+ * PATH_MAX
185
+ * * Errno::ENETDOWN - the local interface used to reach the destination is down
186
+ * * Errno::ENETUNREACH - no route to the network is present
187
+ * * Errno::ENOBUFS - no buffer space is available
188
+ * * Errno::ENOSR - there were insufficient STREAMS resources available to
189
+ * complete the operation
190
+ * * Errno::ENOTSOCK - the +socket+ argument does not refer to a socket
191
+ * * Errno::EOPNOTSUPP - the calling +socket+ is listening and cannot be connected
192
+ * * Errno::EPROTOTYPE - the _sockaddr_ has a different type than the socket
193
+ * bound to the specified peer address
194
+ * * Errno::ETIMEDOUT - the attempt to connect time out before a connection
195
+ * was made.
196
+ *
197
+ * On unix-based systems if the address family of the calling +socket+ is
198
+ * AF_UNIX the follow exceptions may be raised if the call to _connect_
199
+ * fails:
200
+ * * Errno::EIO - an i/o error occurred while reading from or writing to the
201
+ * file system
202
+ * * Errno::ELOOP - too many symbolic links were encountered in translating
203
+ * the pathname in _sockaddr_
204
+ * * Errno::ENAMETOOLLONG - a component of a pathname exceeded NAME_MAX
205
+ * characters, or an entire pathname exceeded PATH_MAX characters
206
+ * * Errno::ENOENT - a component of the pathname does not name an existing file
207
+ * or the pathname is an empty string
208
+ * * Errno::ENOTDIR - a component of the path prefix of the pathname in _sockaddr_
209
+ * is not a directory
210
+ *
211
+ * === Windows Exceptions
212
+ * On Windows systems the following system exceptions may be raised if
213
+ * the call to _connect_ fails:
214
+ * * Errno::ENETDOWN - the network is down
215
+ * * Errno::EADDRINUSE - the socket's local address is already in use
216
+ * * Errno::EINTR - the socket was cancelled
217
+ * * Errno::EINPROGRESS - a blocking socket is in progress or the service provider
218
+ * is still processing a callback function. Or a nonblocking connect call is
219
+ * in progress on the +socket+.
220
+ * * Errno::EALREADY - see Errno::EINVAL
221
+ * * Errno::EADDRNOTAVAIL - the remote address is not a valid address, such as
222
+ * ADDR_ANY TODO check ADDRANY TO INADDR_ANY
223
+ * * Errno::EAFNOSUPPORT - addresses in the specified family cannot be used with
224
+ * with this +socket+
225
+ * * Errno::ECONNREFUSED - the target _sockaddr_ was not listening for connections
226
+ * refused the connection request
227
+ * * Errno::EFAULT - the socket's internal address or address length parameter
228
+ * is too small or is not a valid part of the user space address
229
+ * * Errno::EINVAL - the +socket+ is a listening socket
230
+ * * Errno::EISCONN - the +socket+ is already connected
231
+ * * Errno::ENETUNREACH - the network cannot be reached from this host at this time
232
+ * * Errno::EHOSTUNREACH - no route to the network is present
233
+ * * Errno::ENOBUFS - no buffer space is available
234
+ * * Errno::ENOTSOCK - the +socket+ argument does not refer to a socket
235
+ * * Errno::ETIMEDOUT - the attempt to connect time out before a connection
236
+ * was made.
237
+ * * Errno::EWOULDBLOCK - the socket is marked as nonblocking and the
238
+ * connection cannot be completed immediately
239
+ * * Errno::EACCES - the attempt to connect the datagram socket to the
240
+ * broadcast address failed
241
+ *
242
+ * === See
243
+ * * connect manual pages on unix-based systems
244
+ * * connect function in Microsoft's Winsock functions reference
245
+ */
246
+ static VALUE
247
+ sock_connect(VALUE sock, VALUE addr)
248
+ {
249
+ rb_io_t *fptr;
250
+ int fd, n;
251
+
252
+ SockAddrStringValue(addr);
253
+ addr = rb_str_new4(addr);
254
+ GetOpenFile(sock, fptr);
255
+ fd = fptr->fd;
256
+ n = rsock_connect(fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_LENINT(addr), 0);
257
+ if (n < 0) {
258
+ rb_sys_fail("connect(2)");
259
+ }
260
+
261
+ return INT2FIX(n);
262
+ }
263
+
264
+ /*
265
+ * call-seq:
266
+ * socket.connect_nonblock(remote_sockaddr) => 0
267
+ *
268
+ * Requests a connection to be made on the given +remote_sockaddr+ after
269
+ * O_NONBLOCK is set for the underlying file descriptor.
270
+ * Returns 0 if successful, otherwise an exception is raised.
271
+ *
272
+ * === Parameter
273
+ * * +remote_sockaddr+ - the +struct+ sockaddr contained in a string or Addrinfo object
274
+ *
275
+ * === Example:
276
+ * # Pull down Google's web page
277
+ * require 'socket'
278
+ * include Socket::Constants
279
+ * socket = Socket.new(AF_INET, SOCK_STREAM, 0)
280
+ * sockaddr = Socket.sockaddr_in(80, 'www.google.com')
281
+ * begin # emulate blocking connect
282
+ * socket.connect_nonblock(sockaddr)
283
+ * rescue IO::WaitWritable
284
+ * IO.select(nil, [socket]) # wait 3-way handshake completion
285
+ * begin
286
+ * socket.connect_nonblock(sockaddr) # check connection failure
287
+ * rescue Errno::EISCONN
288
+ * end
289
+ * end
290
+ * socket.write("GET / HTTP/1.0\r\n\r\n")
291
+ * results = socket.read
292
+ *
293
+ * Refer to Socket#connect for the exceptions that may be thrown if the call
294
+ * to _connect_nonblock_ fails.
295
+ *
296
+ * Socket#connect_nonblock may raise any error corresponding to connect(2) failure,
297
+ * including Errno::EINPROGRESS.
298
+ *
299
+ * If the exception is Errno::EINPROGRESS,
300
+ * it is extended by IO::WaitWritable.
301
+ * So IO::WaitWritable can be used to rescue the exceptions for retrying connect_nonblock.
302
+ *
303
+ * === See
304
+ * * Socket#connect
305
+ */
306
+ static VALUE
307
+ sock_connect_nonblock(VALUE sock, VALUE addr)
308
+ {
309
+ rb_io_t *fptr;
310
+ int n;
311
+
312
+ SockAddrStringValue(addr);
313
+ addr = rb_str_new4(addr);
314
+ GetOpenFile(sock, fptr);
315
+ rb_io_set_nonblock(fptr);
316
+ n = connect(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_LENINT(addr));
317
+ if (n < 0) {
318
+ if (errno == EINPROGRESS)
319
+ rb_mod_sys_fail(rb_mWaitWritable, "connect(2) would block");
320
+ rb_sys_fail("connect(2)");
321
+ }
322
+
323
+ return INT2FIX(n);
324
+ }
325
+
326
+ /*
327
+ * call-seq:
328
+ * socket.bind(local_sockaddr) => 0
329
+ *
330
+ * Binds to the given local address.
331
+ *
332
+ * === Parameter
333
+ * * +local_sockaddr+ - the +struct+ sockaddr contained in a string or an Addrinfo object
334
+ *
335
+ * === Example
336
+ * require 'socket'
337
+ *
338
+ * # use Addrinfo
339
+ * socket = Socket.new(:INET, :STREAM, 0)
340
+ * socket.bind(Addrinfo.tcp("127.0.0.1", 2222))
341
+ * p socket.local_address #=> #<Addrinfo: 127.0.0.1:2222 TCP>
342
+ *
343
+ * # use struct sockaddr
344
+ * include Socket::Constants
345
+ * socket = Socket.new( AF_INET, SOCK_STREAM, 0 )
346
+ * sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' )
347
+ * socket.bind( sockaddr )
348
+ *
349
+ * === Unix-based Exceptions
350
+ * On unix-based based systems the following system exceptions may be raised if
351
+ * the call to _bind_ fails:
352
+ * * Errno::EACCES - the specified _sockaddr_ is protected and the current
353
+ * user does not have permission to bind to it
354
+ * * Errno::EADDRINUSE - the specified _sockaddr_ is already in use
355
+ * * Errno::EADDRNOTAVAIL - the specified _sockaddr_ is not available from the
356
+ * local machine
357
+ * * Errno::EAFNOSUPPORT - the specified _sockaddr_ is not a valid address for
358
+ * the family of the calling +socket+
359
+ * * Errno::EBADF - the _sockaddr_ specified is not a valid file descriptor
360
+ * * Errno::EFAULT - the _sockaddr_ argument cannot be accessed
361
+ * * Errno::EINVAL - the +socket+ is already bound to an address, and the
362
+ * protocol does not support binding to the new _sockaddr_ or the +socket+
363
+ * has been shut down.
364
+ * * Errno::EINVAL - the address length is not a valid length for the address
365
+ * family
366
+ * * Errno::ENAMETOOLONG - the pathname resolved had a length which exceeded
367
+ * PATH_MAX
368
+ * * Errno::ENOBUFS - no buffer space is available
369
+ * * Errno::ENOSR - there were insufficient STREAMS resources available to
370
+ * complete the operation
371
+ * * Errno::ENOTSOCK - the +socket+ does not refer to a socket
372
+ * * Errno::EOPNOTSUPP - the socket type of the +socket+ does not support
373
+ * binding to an address
374
+ *
375
+ * On unix-based based systems if the address family of the calling +socket+ is
376
+ * Socket::AF_UNIX the follow exceptions may be raised if the call to _bind_
377
+ * fails:
378
+ * * Errno::EACCES - search permission is denied for a component of the prefix
379
+ * path or write access to the +socket+ is denied
380
+ * * Errno::EDESTADDRREQ - the _sockaddr_ argument is a null pointer
381
+ * * Errno::EISDIR - same as Errno::EDESTADDRREQ
382
+ * * Errno::EIO - an i/o error occurred
383
+ * * Errno::ELOOP - too many symbolic links were encountered in translating
384
+ * the pathname in _sockaddr_
385
+ * * Errno::ENAMETOOLLONG - a component of a pathname exceeded NAME_MAX
386
+ * characters, or an entire pathname exceeded PATH_MAX characters
387
+ * * Errno::ENOENT - a component of the pathname does not name an existing file
388
+ * or the pathname is an empty string
389
+ * * Errno::ENOTDIR - a component of the path prefix of the pathname in _sockaddr_
390
+ * is not a directory
391
+ * * Errno::EROFS - the name would reside on a read only filesystem
392
+ *
393
+ * === Windows Exceptions
394
+ * On Windows systems the following system exceptions may be raised if
395
+ * the call to _bind_ fails:
396
+ * * Errno::ENETDOWN-- the network is down
397
+ * * Errno::EACCES - the attempt to connect the datagram socket to the
398
+ * broadcast address failed
399
+ * * Errno::EADDRINUSE - the socket's local address is already in use
400
+ * * Errno::EADDRNOTAVAIL - the specified address is not a valid address for this
401
+ * computer
402
+ * * Errno::EFAULT - the socket's internal address or address length parameter
403
+ * is too small or is not a valid part of the user space addressed
404
+ * * Errno::EINVAL - the +socket+ is already bound to an address
405
+ * * Errno::ENOBUFS - no buffer space is available
406
+ * * Errno::ENOTSOCK - the +socket+ argument does not refer to a socket
407
+ *
408
+ * === See
409
+ * * bind manual pages on unix-based systems
410
+ * * bind function in Microsoft's Winsock functions reference
411
+ */
412
+ static VALUE
413
+ sock_bind(VALUE sock, VALUE addr)
414
+ {
415
+ rb_io_t *fptr;
416
+
417
+ SockAddrStringValue(addr);
418
+ GetOpenFile(sock, fptr);
419
+ if (bind(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_LENINT(addr)) < 0)
420
+ rb_sys_fail("bind(2)");
421
+
422
+ return INT2FIX(0);
423
+ }
424
+
425
+ /*
426
+ * call-seq:
427
+ * socket.listen( int ) => 0
428
+ *
429
+ * Listens for connections, using the specified +int+ as the backlog. A call
430
+ * to _listen_ only applies if the +socket+ is of type SOCK_STREAM or
431
+ * SOCK_SEQPACKET.
432
+ *
433
+ * === Parameter
434
+ * * +backlog+ - the maximum length of the queue for pending connections.
435
+ *
436
+ * === Example 1
437
+ * require 'socket'
438
+ * include Socket::Constants
439
+ * socket = Socket.new( AF_INET, SOCK_STREAM, 0 )
440
+ * sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' )
441
+ * socket.bind( sockaddr )
442
+ * socket.listen( 5 )
443
+ *
444
+ * === Example 2 (listening on an arbitrary port, unix-based systems only):
445
+ * require 'socket'
446
+ * include Socket::Constants
447
+ * socket = Socket.new( AF_INET, SOCK_STREAM, 0 )
448
+ * socket.listen( 1 )
449
+ *
450
+ * === Unix-based Exceptions
451
+ * On unix based systems the above will work because a new +sockaddr+ struct
452
+ * is created on the address ADDR_ANY, for an arbitrary port number as handed
453
+ * off by the kernel. It will not work on Windows, because Windows requires that
454
+ * the +socket+ is bound by calling _bind_ before it can _listen_.
455
+ *
456
+ * If the _backlog_ amount exceeds the implementation-dependent maximum
457
+ * queue length, the implementation's maximum queue length will be used.
458
+ *
459
+ * On unix-based based systems the following system exceptions may be raised if the
460
+ * call to _listen_ fails:
461
+ * * Errno::EBADF - the _socket_ argument is not a valid file descriptor
462
+ * * Errno::EDESTADDRREQ - the _socket_ is not bound to a local address, and
463
+ * the protocol does not support listening on an unbound socket
464
+ * * Errno::EINVAL - the _socket_ is already connected
465
+ * * Errno::ENOTSOCK - the _socket_ argument does not refer to a socket
466
+ * * Errno::EOPNOTSUPP - the _socket_ protocol does not support listen
467
+ * * Errno::EACCES - the calling process does not have appropriate privileges
468
+ * * Errno::EINVAL - the _socket_ has been shut down
469
+ * * Errno::ENOBUFS - insufficient resources are available in the system to
470
+ * complete the call
471
+ *
472
+ * === Windows Exceptions
473
+ * On Windows systems the following system exceptions may be raised if
474
+ * the call to _listen_ fails:
475
+ * * Errno::ENETDOWN - the network is down
476
+ * * Errno::EADDRINUSE - the socket's local address is already in use. This
477
+ * usually occurs during the execution of _bind_ but could be delayed
478
+ * if the call to _bind_ was to a partially wildcard address (involving
479
+ * ADDR_ANY) and if a specific address needs to be committed at the
480
+ * time of the call to _listen_
481
+ * * Errno::EINPROGRESS - a Windows Sockets 1.1 call is in progress or the
482
+ * service provider is still processing a callback function
483
+ * * Errno::EINVAL - the +socket+ has not been bound with a call to _bind_.
484
+ * * Errno::EISCONN - the +socket+ is already connected
485
+ * * Errno::EMFILE - no more socket descriptors are available
486
+ * * Errno::ENOBUFS - no buffer space is available
487
+ * * Errno::ENOTSOC - +socket+ is not a socket
488
+ * * Errno::EOPNOTSUPP - the referenced +socket+ is not a type that supports
489
+ * the _listen_ method
490
+ *
491
+ * === See
492
+ * * listen manual pages on unix-based systems
493
+ * * listen function in Microsoft's Winsock functions reference
494
+ */
495
+ VALUE
496
+ rsock_sock_listen(VALUE sock, VALUE log)
497
+ {
498
+ rb_io_t *fptr;
499
+ int backlog;
500
+
501
+ rb_secure(4);
502
+ backlog = NUM2INT(log);
503
+ GetOpenFile(sock, fptr);
504
+ if (listen(fptr->fd, backlog) < 0)
505
+ rb_sys_fail("listen(2)");
506
+
507
+ return INT2FIX(0);
508
+ }
509
+
510
+ /*
511
+ * call-seq:
512
+ * socket.recvfrom(maxlen) => [mesg, sender_addrinfo]
513
+ * socket.recvfrom(maxlen, flags) => [mesg, sender_addrinfo]
514
+ *
515
+ * Receives up to _maxlen_ bytes from +socket+. _flags_ is zero or more
516
+ * of the +MSG_+ options. The first element of the results, _mesg_, is the data
517
+ * received. The second element, _sender_addrinfo_, contains protocol-specific
518
+ * address information of the sender.
519
+ *
520
+ * === Parameters
521
+ * * +maxlen+ - the maximum number of bytes to receive from the socket
522
+ * * +flags+ - zero or more of the +MSG_+ options
523
+ *
524
+ * === Example
525
+ * # In one file, start this first
526
+ * require 'socket'
527
+ * include Socket::Constants
528
+ * socket = Socket.new( AF_INET, SOCK_STREAM, 0 )
529
+ * sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' )
530
+ * socket.bind( sockaddr )
531
+ * socket.listen( 5 )
532
+ * client, client_addrinfo = socket.accept
533
+ * data = client.recvfrom( 20 )[0].chomp
534
+ * puts "I only received 20 bytes '#{data}'"
535
+ * sleep 1
536
+ * socket.close
537
+ *
538
+ * # In another file, start this second
539
+ * require 'socket'
540
+ * include Socket::Constants
541
+ * socket = Socket.new( AF_INET, SOCK_STREAM, 0 )
542
+ * sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' )
543
+ * socket.connect( sockaddr )
544
+ * socket.puts "Watch this get cut short!"
545
+ * socket.close
546
+ *
547
+ * === Unix-based Exceptions
548
+ * On unix-based based systems the following system exceptions may be raised if the
549
+ * call to _recvfrom_ fails:
550
+ * * Errno::EAGAIN - the +socket+ file descriptor is marked as O_NONBLOCK and no
551
+ * data is waiting to be received; or MSG_OOB is set and no out-of-band data
552
+ * is available and either the +socket+ file descriptor is marked as
553
+ * O_NONBLOCK or the +socket+ does not support blocking to wait for
554
+ * out-of-band-data
555
+ * * Errno::EWOULDBLOCK - see Errno::EAGAIN
556
+ * * Errno::EBADF - the +socket+ is not a valid file descriptor
557
+ * * Errno::ECONNRESET - a connection was forcibly closed by a peer
558
+ * * Errno::EFAULT - the socket's internal buffer, address or address length
559
+ * cannot be accessed or written
560
+ * * Errno::EINTR - a signal interrupted _recvfrom_ before any data was available
561
+ * * Errno::EINVAL - the MSG_OOB flag is set and no out-of-band data is available
562
+ * * Errno::EIO - an i/o error occurred while reading from or writing to the
563
+ * filesystem
564
+ * * Errno::ENOBUFS - insufficient resources were available in the system to
565
+ * perform the operation
566
+ * * Errno::ENOMEM - insufficient memory was available to fulfill the request
567
+ * * Errno::ENOSR - there were insufficient STREAMS resources available to
568
+ * complete the operation
569
+ * * Errno::ENOTCONN - a receive is attempted on a connection-mode socket that
570
+ * is not connected
571
+ * * Errno::ENOTSOCK - the +socket+ does not refer to a socket
572
+ * * Errno::EOPNOTSUPP - the specified flags are not supported for this socket type
573
+ * * Errno::ETIMEDOUT - the connection timed out during connection establishment
574
+ * or due to a transmission timeout on an active connection
575
+ *
576
+ * === Windows Exceptions
577
+ * On Windows systems the following system exceptions may be raised if
578
+ * the call to _recvfrom_ fails:
579
+ * * Errno::ENETDOWN - the network is down
580
+ * * Errno::EFAULT - the internal buffer and from parameters on +socket+ are not
581
+ * part of the user address space, or the internal fromlen parameter is
582
+ * too small to accommodate the peer address
583
+ * * Errno::EINTR - the (blocking) call was cancelled by an internal call to
584
+ * the WinSock function WSACancelBlockingCall
585
+ * * Errno::EINPROGRESS - a blocking Windows Sockets 1.1 call is in progress or
586
+ * the service provider is still processing a callback function
587
+ * * Errno::EINVAL - +socket+ has not been bound with a call to _bind_, or an
588
+ * unknown flag was specified, or MSG_OOB was specified for a socket with
589
+ * SO_OOBINLINE enabled, or (for byte stream-style sockets only) the internal
590
+ * len parameter on +socket+ was zero or negative
591
+ * * Errno::EISCONN - +socket+ is already connected. The call to _recvfrom_ is
592
+ * not permitted with a connected socket on a socket that is connection
593
+ * oriented or connectionless.
594
+ * * Errno::ENETRESET - the connection has been broken due to the keep-alive
595
+ * activity detecting a failure while the operation was in progress.
596
+ * * Errno::EOPNOTSUPP - MSG_OOB was specified, but +socket+ is not stream-style
597
+ * such as type SOCK_STREAM. OOB data is not supported in the communication
598
+ * domain associated with +socket+, or +socket+ is unidirectional and
599
+ * supports only send operations
600
+ * * Errno::ESHUTDOWN - +socket+ has been shutdown. It is not possible to
601
+ * call _recvfrom_ on a socket after _shutdown_ has been invoked.
602
+ * * Errno::EWOULDBLOCK - +socket+ is marked as nonblocking and a call to
603
+ * _recvfrom_ would block.
604
+ * * Errno::EMSGSIZE - the message was too large to fit into the specified buffer
605
+ * and was truncated.
606
+ * * Errno::ETIMEDOUT - the connection has been dropped, because of a network
607
+ * failure or because the system on the other end went down without
608
+ * notice
609
+ * * Errno::ECONNRESET - the virtual circuit was reset by the remote side
610
+ * executing a hard or abortive close. The application should close the
611
+ * socket; it is no longer usable. On a UDP-datagram socket this error
612
+ * indicates a previous send operation resulted in an ICMP Port Unreachable
613
+ * message.
614
+ */
615
+ static VALUE
616
+ sock_recvfrom(int argc, VALUE *argv, VALUE sock)
617
+ {
618
+ return rsock_s_recvfrom(sock, argc, argv, RECV_SOCKET);
619
+ }
620
+
621
+ /*
622
+ * call-seq:
623
+ * socket.recvfrom_nonblock(maxlen) => [mesg, sender_addrinfo]
624
+ * socket.recvfrom_nonblock(maxlen, flags) => [mesg, sender_addrinfo]
625
+ *
626
+ * Receives up to _maxlen_ bytes from +socket+ using recvfrom(2) after
627
+ * O_NONBLOCK is set for the underlying file descriptor.
628
+ * _flags_ is zero or more of the +MSG_+ options.
629
+ * The first element of the results, _mesg_, is the data received.
630
+ * The second element, _sender_addrinfo_, contains protocol-specific address
631
+ * information of the sender.
632
+ *
633
+ * When recvfrom(2) returns 0, Socket#recvfrom_nonblock returns
634
+ * an empty string as data.
635
+ * The meaning depends on the socket: EOF on TCP, empty packet on UDP, etc.
636
+ *
637
+ * === Parameters
638
+ * * +maxlen+ - the maximum number of bytes to receive from the socket
639
+ * * +flags+ - zero or more of the +MSG_+ options
640
+ *
641
+ * === Example
642
+ * # In one file, start this first
643
+ * require 'socket'
644
+ * include Socket::Constants
645
+ * socket = Socket.new(AF_INET, SOCK_STREAM, 0)
646
+ * sockaddr = Socket.sockaddr_in(2200, 'localhost')
647
+ * socket.bind(sockaddr)
648
+ * socket.listen(5)
649
+ * client, client_addrinfo = socket.accept
650
+ * begin # emulate blocking recvfrom
651
+ * pair = client.recvfrom_nonblock(20)
652
+ * rescue IO::WaitReadable
653
+ * IO.select([client])
654
+ * retry
655
+ * end
656
+ * data = pair[0].chomp
657
+ * puts "I only received 20 bytes '#{data}'"
658
+ * sleep 1
659
+ * socket.close
660
+ *
661
+ * # In another file, start this second
662
+ * require 'socket'
663
+ * include Socket::Constants
664
+ * socket = Socket.new(AF_INET, SOCK_STREAM, 0)
665
+ * sockaddr = Socket.sockaddr_in(2200, 'localhost')
666
+ * socket.connect(sockaddr)
667
+ * socket.puts "Watch this get cut short!"
668
+ * socket.close
669
+ *
670
+ * Refer to Socket#recvfrom for the exceptions that may be thrown if the call
671
+ * to _recvfrom_nonblock_ fails.
672
+ *
673
+ * Socket#recvfrom_nonblock may raise any error corresponding to recvfrom(2) failure,
674
+ * including Errno::EWOULDBLOCK.
675
+ *
676
+ * If the exception is Errno::EWOULDBLOCK or Errno::AGAIN,
677
+ * it is extended by IO::WaitReadable.
678
+ * So IO::WaitReadable can be used to rescue the exceptions for retrying recvfrom_nonblock.
679
+ *
680
+ * === See
681
+ * * Socket#recvfrom
682
+ */
683
+ static VALUE
684
+ sock_recvfrom_nonblock(int argc, VALUE *argv, VALUE sock)
685
+ {
686
+ return rsock_s_recvfrom_nonblock(sock, argc, argv, RECV_SOCKET);
687
+ }
688
+
689
+ /*
690
+ * call-seq:
691
+ * socket.accept => [client_socket, client_addrinfo]
692
+ *
693
+ * Accepts a next connection.
694
+ * Returns a new Socket object and Addrinfo object.
695
+ *
696
+ * serv = Socket.new(:INET, :STREAM, 0)
697
+ * serv.listen(5)
698
+ * c = Socket.new(:INET, :STREAM, 0)
699
+ * c.connect(serv.connect_address)
700
+ * p serv.accept #=> [#<Socket:fd 6>, #<Addrinfo: 127.0.0.1:48555 TCP>]
701
+ *
702
+ */
703
+ static VALUE
704
+ sock_accept(VALUE sock)
705
+ {
706
+ rb_io_t *fptr;
707
+ VALUE sock2;
708
+ struct sockaddr_storage buf;
709
+ socklen_t len = (socklen_t)sizeof buf;
710
+
711
+ GetOpenFile(sock, fptr);
712
+ sock2 = rsock_s_accept(rb_cSocket,fptr->fd,(struct sockaddr*)&buf,&len);
713
+
714
+ return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, (struct sockaddr*)&buf, len));
715
+ }
716
+
717
+ /*
718
+ * call-seq:
719
+ * socket.accept_nonblock => [client_socket, client_addrinfo]
720
+ *
721
+ * Accepts an incoming connection using accept(2) after
722
+ * O_NONBLOCK is set for the underlying file descriptor.
723
+ * It returns an array containing the accepted socket
724
+ * for the incoming connection, _client_socket_,
725
+ * and an Addrinfo, _client_addrinfo_.
726
+ *
727
+ * === Example
728
+ * # In one script, start this first
729
+ * require 'socket'
730
+ * include Socket::Constants
731
+ * socket = Socket.new(AF_INET, SOCK_STREAM, 0)
732
+ * sockaddr = Socket.sockaddr_in(2200, 'localhost')
733
+ * socket.bind(sockaddr)
734
+ * socket.listen(5)
735
+ * begin # emulate blocking accept
736
+ * client_socket, client_addrinfo = socket.accept_nonblock
737
+ * rescue IO::WaitReadable, Errno::EINTR
738
+ * IO.select([socket])
739
+ * retry
740
+ * end
741
+ * puts "The client said, '#{client_socket.readline.chomp}'"
742
+ * client_socket.puts "Hello from script one!"
743
+ * socket.close
744
+ *
745
+ * # In another script, start this second
746
+ * require 'socket'
747
+ * include Socket::Constants
748
+ * socket = Socket.new(AF_INET, SOCK_STREAM, 0)
749
+ * sockaddr = Socket.sockaddr_in(2200, 'localhost')
750
+ * socket.connect(sockaddr)
751
+ * socket.puts "Hello from script 2."
752
+ * puts "The server said, '#{socket.readline.chomp}'"
753
+ * socket.close
754
+ *
755
+ * Refer to Socket#accept for the exceptions that may be thrown if the call
756
+ * to _accept_nonblock_ fails.
757
+ *
758
+ * Socket#accept_nonblock may raise any error corresponding to accept(2) failure,
759
+ * including Errno::EWOULDBLOCK.
760
+ *
761
+ * If the exception is Errno::EWOULDBLOCK, Errno::AGAIN, Errno::ECONNABORTED or Errno::EPROTO,
762
+ * it is extended by IO::WaitReadable.
763
+ * So IO::WaitReadable can be used to rescue the exceptions for retrying accept_nonblock.
764
+ *
765
+ * === See
766
+ * * Socket#accept
767
+ */
768
+ static VALUE
769
+ sock_accept_nonblock(VALUE sock)
770
+ {
771
+ rb_io_t *fptr;
772
+ VALUE sock2;
773
+ struct sockaddr_storage buf;
774
+ socklen_t len = (socklen_t)sizeof buf;
775
+
776
+ GetOpenFile(sock, fptr);
777
+ sock2 = rsock_s_accept_nonblock(rb_cSocket, fptr, (struct sockaddr *)&buf, &len);
778
+ return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, (struct sockaddr*)&buf, len));
779
+ }
780
+
781
+ /*
782
+ * call-seq:
783
+ * socket.sysaccept => [client_socket_fd, client_addrinfo]
784
+ *
785
+ * Accepts an incoming connection returning an array containing the (integer)
786
+ * file descriptor for the incoming connection, _client_socket_fd_,
787
+ * and an Addrinfo, _client_addrinfo_.
788
+ *
789
+ * === Example
790
+ * # In one script, start this first
791
+ * require 'socket'
792
+ * include Socket::Constants
793
+ * socket = Socket.new( AF_INET, SOCK_STREAM, 0 )
794
+ * sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' )
795
+ * socket.bind( sockaddr )
796
+ * socket.listen( 5 )
797
+ * client_fd, client_addrinfo = socket.sysaccept
798
+ * client_socket = Socket.for_fd( client_fd )
799
+ * puts "The client said, '#{client_socket.readline.chomp}'"
800
+ * client_socket.puts "Hello from script one!"
801
+ * socket.close
802
+ *
803
+ * # In another script, start this second
804
+ * require 'socket'
805
+ * include Socket::Constants
806
+ * socket = Socket.new( AF_INET, SOCK_STREAM, 0 )
807
+ * sockaddr = Socket.pack_sockaddr_in( 2200, 'localhost' )
808
+ * socket.connect( sockaddr )
809
+ * socket.puts "Hello from script 2."
810
+ * puts "The server said, '#{socket.readline.chomp}'"
811
+ * socket.close
812
+ *
813
+ * Refer to Socket#accept for the exceptions that may be thrown if the call
814
+ * to _sysaccept_ fails.
815
+ *
816
+ * === See
817
+ * * Socket#accept
818
+ */
819
+ static VALUE
820
+ sock_sysaccept(VALUE sock)
821
+ {
822
+ rb_io_t *fptr;
823
+ VALUE sock2;
824
+ struct sockaddr_storage buf;
825
+ socklen_t len = (socklen_t)sizeof buf;
826
+
827
+ GetOpenFile(sock, fptr);
828
+ sock2 = rsock_s_accept(0,fptr->fd,(struct sockaddr*)&buf,&len);
829
+
830
+ return rb_assoc_new(sock2, rsock_io_socket_addrinfo(sock2, (struct sockaddr*)&buf, len));
831
+ }
832
+
833
+ #ifdef HAVE_GETHOSTNAME
834
+ /*
835
+ * call-seq:
836
+ * Socket.gethostname => hostname
837
+ *
838
+ * Returns the hostname.
839
+ *
840
+ * p Socket.gethostname #=> "hal"
841
+ *
842
+ * Note that it is not guaranteed to be able to convert to IP address using gethostbyname, getaddrinfo, etc.
843
+ * If you need local IP address, use Socket.ip_address_list.
844
+ */
845
+ static VALUE
846
+ sock_gethostname(VALUE obj)
847
+ {
848
+ #ifndef HOST_NAME_MAX
849
+ # define HOST_NAME_MAX 1024
850
+ #endif
851
+ char buf[HOST_NAME_MAX+1];
852
+
853
+ rb_secure(3);
854
+ if (gethostname(buf, (int)sizeof buf - 1) < 0)
855
+ rb_sys_fail("gethostname");
856
+
857
+ buf[sizeof buf - 1] = '\0';
858
+ return rb_str_new2(buf);
859
+ }
860
+ #else
861
+ #ifdef HAVE_UNAME
862
+
863
+ #include <sys/utsname.h>
864
+
865
+ static VALUE
866
+ sock_gethostname(VALUE obj)
867
+ {
868
+ struct utsname un;
869
+
870
+ rb_secure(3);
871
+ uname(&un);
872
+ return rb_str_new2(un.nodename);
873
+ }
874
+ #else
875
+ #define sock_gethostname rb_f_notimplement
876
+ #endif
877
+ #endif
878
+
879
+ static VALUE
880
+ make_addrinfo(struct addrinfo *res0, int norevlookup)
881
+ {
882
+ VALUE base, ary;
883
+ struct addrinfo *res;
884
+
885
+ if (res0 == NULL) {
886
+ rb_raise(rb_eSocket, "host not found");
887
+ }
888
+ base = rb_ary_new();
889
+ for (res = res0; res; res = res->ai_next) {
890
+ ary = rsock_ipaddr(res->ai_addr, norevlookup);
891
+ if (res->ai_canonname) {
892
+ RARRAY_PTR(ary)[2] = rb_str_new2(res->ai_canonname);
893
+ }
894
+ rb_ary_push(ary, INT2FIX(res->ai_family));
895
+ rb_ary_push(ary, INT2FIX(res->ai_socktype));
896
+ rb_ary_push(ary, INT2FIX(res->ai_protocol));
897
+ rb_ary_push(base, ary);
898
+ }
899
+ return base;
900
+ }
901
+
902
+ static VALUE
903
+ sock_sockaddr(struct sockaddr *addr, size_t len)
904
+ {
905
+ char *ptr;
906
+
907
+ switch (addr->sa_family) {
908
+ case AF_INET:
909
+ ptr = (char*)&((struct sockaddr_in*)addr)->sin_addr.s_addr;
910
+ len = sizeof(((struct sockaddr_in*)addr)->sin_addr.s_addr);
911
+ break;
912
+ #ifdef AF_INET6
913
+ case AF_INET6:
914
+ ptr = (char*)&((struct sockaddr_in6*)addr)->sin6_addr.s6_addr;
915
+ len = sizeof(((struct sockaddr_in6*)addr)->sin6_addr.s6_addr);
916
+ break;
917
+ #endif
918
+ default:
919
+ rb_raise(rb_eSocket, "unknown socket family:%d", addr->sa_family);
920
+ break;
921
+ }
922
+ return rb_str_new(ptr, len);
923
+ }
924
+
925
+ /*
926
+ * call-seq:
927
+ * Socket.gethostbyname(hostname) => [official_hostname, alias_hostnames, address_family, *address_list]
928
+ *
929
+ * Obtains the host information for _hostname_.
930
+ *
931
+ * p Socket.gethostbyname("hal") #=> ["localhost", ["hal"], 2, "\x7F\x00\x00\x01"]
932
+ *
933
+ */
934
+ static VALUE
935
+ sock_s_gethostbyname(VALUE obj, VALUE host)
936
+ {
937
+ rb_secure(3);
938
+ return rsock_make_hostent(host, rsock_addrinfo(host, Qnil, SOCK_STREAM, AI_CANONNAME), sock_sockaddr);
939
+ }
940
+
941
+ /*
942
+ * call-seq:
943
+ * Socket.gethostbyaddr(address_string [, address_family]) => hostent
944
+ *
945
+ * Obtains the host information for _address_.
946
+ *
947
+ * p Socket.gethostbyaddr([221,186,184,68].pack("CCCC"))
948
+ * #=> ["carbon.ruby-lang.org", [], 2, "\xDD\xBA\xB8D"]
949
+ */
950
+ static VALUE
951
+ sock_s_gethostbyaddr(int argc, VALUE *argv)
952
+ {
953
+ VALUE addr, family;
954
+ struct hostent *h;
955
+ struct sockaddr *sa;
956
+ char **pch;
957
+ VALUE ary, names;
958
+ int t = AF_INET;
959
+
960
+ rb_scan_args(argc, argv, "11", &addr, &family);
961
+ sa = (struct sockaddr*)StringValuePtr(addr);
962
+ if (!NIL_P(family)) {
963
+ t = rsock_family_arg(family);
964
+ }
965
+ #ifdef AF_INET6
966
+ else if (RSTRING_LEN(addr) == 16) {
967
+ t = AF_INET6;
968
+ }
969
+ #endif
970
+ h = gethostbyaddr(RSTRING_PTR(addr), RSTRING_LENINT(addr), t);
971
+ if (h == NULL) {
972
+ #ifdef HAVE_HSTRERROR
973
+ extern int h_errno;
974
+ rb_raise(rb_eSocket, "%s", (char*)hstrerror(h_errno));
975
+ #else
976
+ rb_raise(rb_eSocket, "host not found");
977
+ #endif
978
+ }
979
+ ary = rb_ary_new();
980
+ rb_ary_push(ary, rb_str_new2(h->h_name));
981
+ names = rb_ary_new();
982
+ rb_ary_push(ary, names);
983
+ if (h->h_aliases != NULL) {
984
+ for (pch = h->h_aliases; *pch; pch++) {
985
+ rb_ary_push(names, rb_str_new2(*pch));
986
+ }
987
+ }
988
+ rb_ary_push(ary, INT2NUM(h->h_addrtype));
989
+ #ifdef h_addr
990
+ for (pch = h->h_addr_list; *pch; pch++) {
991
+ rb_ary_push(ary, rb_str_new(*pch, h->h_length));
992
+ }
993
+ #else
994
+ rb_ary_push(ary, rb_str_new(h->h_addr, h->h_length));
995
+ #endif
996
+
997
+ return ary;
998
+ }
999
+
1000
+ /*
1001
+ * call-seq:
1002
+ * Socket.getservbyname(service_name) => port_number
1003
+ * Socket.getservbyname(service_name, protocol_name) => port_number
1004
+ *
1005
+ * Obtains the port number for _service_name_.
1006
+ *
1007
+ * If _protocol_name_ is not given, "tcp" is assumed.
1008
+ *
1009
+ * Socket.getservbyname("smtp") #=> 25
1010
+ * Socket.getservbyname("shell") #=> 514
1011
+ * Socket.getservbyname("syslog", "udp") #=> 514
1012
+ */
1013
+ static VALUE
1014
+ sock_s_getservbyname(int argc, VALUE *argv)
1015
+ {
1016
+ VALUE service, proto;
1017
+ struct servent *sp;
1018
+ long port;
1019
+ const char *servicename, *protoname = "tcp";
1020
+
1021
+ rb_scan_args(argc, argv, "11", &service, &proto);
1022
+ StringValue(service);
1023
+ if (!NIL_P(proto)) StringValue(proto);
1024
+ servicename = StringValueCStr(service);
1025
+ if (!NIL_P(proto)) protoname = StringValueCStr(proto);
1026
+ sp = getservbyname(servicename, protoname);
1027
+ if (sp) {
1028
+ port = ntohs(sp->s_port);
1029
+ }
1030
+ else {
1031
+ char *end;
1032
+
1033
+ port = STRTOUL(servicename, &end, 0);
1034
+ if (*end != '\0') {
1035
+ rb_raise(rb_eSocket, "no such service %s/%s", servicename, protoname);
1036
+ }
1037
+ }
1038
+ return INT2FIX(port);
1039
+ }
1040
+
1041
+ /*
1042
+ * call-seq:
1043
+ * Socket.getservbyport(port [, protocol_name]) => service
1044
+ *
1045
+ * Obtains the port number for _port_.
1046
+ *
1047
+ * If _protocol_name_ is not given, "tcp" is assumed.
1048
+ *
1049
+ * Socket.getservbyport(80) #=> "www"
1050
+ * Socket.getservbyport(514, "tcp") #=> "shell"
1051
+ * Socket.getservbyport(514, "udp") #=> "syslog"
1052
+ *
1053
+ */
1054
+ static VALUE
1055
+ sock_s_getservbyport(int argc, VALUE *argv)
1056
+ {
1057
+ VALUE port, proto;
1058
+ struct servent *sp;
1059
+ long portnum;
1060
+ const char *protoname = "tcp";
1061
+
1062
+ rb_scan_args(argc, argv, "11", &port, &proto);
1063
+ portnum = NUM2LONG(port);
1064
+ if (portnum != (uint16_t)portnum) {
1065
+ const char *s = portnum > 0 ? "big" : "small";
1066
+ rb_raise(rb_eRangeError, "integer %ld too %s to convert into `int16_t'", portnum, s);
1067
+ }
1068
+ if (!NIL_P(proto)) protoname = StringValueCStr(proto);
1069
+
1070
+ sp = getservbyport((int)htons((uint16_t)portnum), protoname);
1071
+ if (!sp) {
1072
+ rb_raise(rb_eSocket, "no such service for port %d/%s", (int)portnum, protoname);
1073
+ }
1074
+ return rb_tainted_str_new2(sp->s_name);
1075
+ }
1076
+
1077
+ /*
1078
+ * call-seq:
1079
+ * Socket.getaddrinfo(nodename, servname[, family[, socktype[, protocol[, flags[, reverse_lookup]]]]]) => array
1080
+ *
1081
+ * Obtains address information for _nodename_:_servname_.
1082
+ *
1083
+ * _family_ should be an address family such as: :INET, :INET6, :UNIX, etc.
1084
+ *
1085
+ * _socktype_ should be a socket type such as: :STREAM, :DGRAM, :RAW, etc.
1086
+ *
1087
+ * _protocol_ should be a protocol defined in the family.
1088
+ * 0 is default protocol for the family.
1089
+ *
1090
+ * _flags_ should be bitwise OR of Socket::AI_* constants.
1091
+ *
1092
+ * Socket.getaddrinfo("www.ruby-lang.org", "http", nil, :STREAM)
1093
+ * #=> [["AF_INET", 80, "carbon.ruby-lang.org", "221.186.184.68", 2, 1, 6]] # PF_INET/SOCK_STREAM/IPPROTO_TCP
1094
+ *
1095
+ * Socket.getaddrinfo("localhost", nil)
1096
+ * #=> [["AF_INET", 0, "localhost", "127.0.0.1", 2, 1, 6], # PF_INET/SOCK_STREAM/IPPROTO_TCP
1097
+ * # ["AF_INET", 0, "localhost", "127.0.0.1", 2, 2, 17], # PF_INET/SOCK_DGRAM/IPPROTO_UDP
1098
+ * # ["AF_INET", 0, "localhost", "127.0.0.1", 2, 3, 0]] # PF_INET/SOCK_RAW/IPPROTO_IP
1099
+ *
1100
+ * _reverse_lookup_ directs the form of the third element, and has to
1101
+ * be one of below.
1102
+ * If it is ommitted, the default value is +nil+.
1103
+ *
1104
+ * +true+, +:hostname+: hostname is obtained from numeric address using reverse lookup, which may take a time.
1105
+ * +false+, +:numeric+: hostname is same as numeric address.
1106
+ * +nil+: obey to the current +do_not_reverse_lookup+ flag.
1107
+ *
1108
+ * If Addrinfo object is preferred, use Addrinfo.getaddrinfo.
1109
+ */
1110
+ static VALUE
1111
+ sock_s_getaddrinfo(int argc, VALUE *argv)
1112
+ {
1113
+ VALUE host, port, family, socktype, protocol, flags, ret, revlookup;
1114
+ struct addrinfo hints, *res;
1115
+ int norevlookup;
1116
+
1117
+ rb_scan_args(argc, argv, "25", &host, &port, &family, &socktype, &protocol, &flags, &revlookup);
1118
+
1119
+ MEMZERO(&hints, struct addrinfo, 1);
1120
+ hints.ai_family = NIL_P(family) ? PF_UNSPEC : rsock_family_arg(family);
1121
+
1122
+ if (!NIL_P(socktype)) {
1123
+ hints.ai_socktype = rsock_socktype_arg(socktype);
1124
+ }
1125
+ if (!NIL_P(protocol)) {
1126
+ hints.ai_protocol = NUM2INT(protocol);
1127
+ }
1128
+ if (!NIL_P(flags)) {
1129
+ hints.ai_flags = NUM2INT(flags);
1130
+ }
1131
+ if (NIL_P(revlookup) || !rsock_revlookup_flag(revlookup, &norevlookup)) {
1132
+ norevlookup = rsock_do_not_reverse_lookup;
1133
+ }
1134
+ res = rsock_getaddrinfo(host, port, &hints, 0);
1135
+
1136
+ ret = make_addrinfo(res, norevlookup);
1137
+ freeaddrinfo(res);
1138
+ return ret;
1139
+ }
1140
+
1141
+ /*
1142
+ * call-seq:
1143
+ * Socket.getnameinfo(sockaddr [, flags]) => [hostname, servicename]
1144
+ *
1145
+ * Obtains name information for _sockaddr_.
1146
+ *
1147
+ * _sockaddr_ should be one of follows.
1148
+ * - packed sockaddr string such as Socket.sockaddr_in(80, "127.0.0.1")
1149
+ * - 3-elements array such as ["AF_INET", 80, "127.0.0.1"]
1150
+ * - 4-elements array such as ["AF_INET", 80, ignored, "127.0.0.1"]
1151
+ *
1152
+ * _flags_ should be bitwise OR of Socket::NI_* constants.
1153
+ *
1154
+ * Note that the last form is compatible with IPSocket#{addr,peeraddr}.
1155
+ *
1156
+ * Socket.getnameinfo(Socket.sockaddr_in(80, "127.0.0.1")) #=> ["localhost", "www"]
1157
+ * Socket.getnameinfo(["AF_INET", 80, "127.0.0.1"]) #=> ["localhost", "www"]
1158
+ * Socket.getnameinfo(["AF_INET", 80, "localhost", "127.0.0.1"]) #=> ["localhost", "www"]
1159
+ *
1160
+ * If Addrinfo object is preferred, use Addrinfo#getnameinfo.
1161
+ */
1162
+ static VALUE
1163
+ sock_s_getnameinfo(int argc, VALUE *argv)
1164
+ {
1165
+ VALUE sa, af = Qnil, host = Qnil, port = Qnil, flags, tmp;
1166
+ char *hptr, *pptr;
1167
+ char hbuf[1024], pbuf[1024];
1168
+ int fl;
1169
+ struct addrinfo hints, *res = NULL, *r;
1170
+ int error;
1171
+ struct sockaddr_storage ss;
1172
+ struct sockaddr *sap;
1173
+
1174
+ sa = flags = Qnil;
1175
+ rb_scan_args(argc, argv, "11", &sa, &flags);
1176
+
1177
+ fl = 0;
1178
+ if (!NIL_P(flags)) {
1179
+ fl = NUM2INT(flags);
1180
+ }
1181
+ tmp = rb_check_sockaddr_string_type(sa);
1182
+ if (!NIL_P(tmp)) {
1183
+ sa = tmp;
1184
+ if (sizeof(ss) < (size_t)RSTRING_LEN(sa)) {
1185
+ rb_raise(rb_eTypeError, "sockaddr length too big");
1186
+ }
1187
+ memcpy(&ss, RSTRING_PTR(sa), RSTRING_LEN(sa));
1188
+ if ((size_t)RSTRING_LEN(sa) != SS_LEN(&ss)) {
1189
+ rb_raise(rb_eTypeError, "sockaddr size differs - should not happen");
1190
+ }
1191
+ sap = (struct sockaddr*)&ss;
1192
+ goto call_nameinfo;
1193
+ }
1194
+ tmp = rb_check_array_type(sa);
1195
+ if (!NIL_P(tmp)) {
1196
+ sa = tmp;
1197
+ MEMZERO(&hints, struct addrinfo, 1);
1198
+ if (RARRAY_LEN(sa) == 3) {
1199
+ af = RARRAY_PTR(sa)[0];
1200
+ port = RARRAY_PTR(sa)[1];
1201
+ host = RARRAY_PTR(sa)[2];
1202
+ }
1203
+ else if (RARRAY_LEN(sa) >= 4) {
1204
+ af = RARRAY_PTR(sa)[0];
1205
+ port = RARRAY_PTR(sa)[1];
1206
+ host = RARRAY_PTR(sa)[3];
1207
+ if (NIL_P(host)) {
1208
+ host = RARRAY_PTR(sa)[2];
1209
+ }
1210
+ else {
1211
+ /*
1212
+ * 4th element holds numeric form, don't resolve.
1213
+ * see rsock_ipaddr().
1214
+ */
1215
+ #ifdef AI_NUMERICHOST /* AIX 4.3.3 doesn't have AI_NUMERICHOST. */
1216
+ hints.ai_flags |= AI_NUMERICHOST;
1217
+ #endif
1218
+ }
1219
+ }
1220
+ else {
1221
+ rb_raise(rb_eArgError, "array size should be 3 or 4, %ld given",
1222
+ RARRAY_LEN(sa));
1223
+ }
1224
+ /* host */
1225
+ if (NIL_P(host)) {
1226
+ hptr = NULL;
1227
+ }
1228
+ else {
1229
+ strncpy(hbuf, StringValuePtr(host), sizeof(hbuf));
1230
+ hbuf[sizeof(hbuf) - 1] = '\0';
1231
+ hptr = hbuf;
1232
+ }
1233
+ /* port */
1234
+ if (NIL_P(port)) {
1235
+ strcpy(pbuf, "0");
1236
+ pptr = NULL;
1237
+ }
1238
+ else if (FIXNUM_P(port)) {
1239
+ snprintf(pbuf, sizeof(pbuf), "%ld", NUM2LONG(port));
1240
+ pptr = pbuf;
1241
+ }
1242
+ else {
1243
+ strncpy(pbuf, StringValuePtr(port), sizeof(pbuf));
1244
+ pbuf[sizeof(pbuf) - 1] = '\0';
1245
+ pptr = pbuf;
1246
+ }
1247
+ hints.ai_socktype = (fl & NI_DGRAM) ? SOCK_DGRAM : SOCK_STREAM;
1248
+ /* af */
1249
+ hints.ai_family = NIL_P(af) ? PF_UNSPEC : rsock_family_arg(af);
1250
+ error = rb_getaddrinfo(hptr, pptr, &hints, &res);
1251
+ if (error) goto error_exit_addr;
1252
+ sap = res->ai_addr;
1253
+ }
1254
+ else {
1255
+ rb_raise(rb_eTypeError, "expecting String or Array");
1256
+ }
1257
+
1258
+ call_nameinfo:
1259
+ error = rb_getnameinfo(sap, SA_LEN(sap), hbuf, sizeof(hbuf),
1260
+ pbuf, sizeof(pbuf), fl);
1261
+ if (error) goto error_exit_name;
1262
+ if (res) {
1263
+ for (r = res->ai_next; r; r = r->ai_next) {
1264
+ char hbuf2[1024], pbuf2[1024];
1265
+
1266
+ sap = r->ai_addr;
1267
+ error = rb_getnameinfo(sap, SA_LEN(sap), hbuf2, sizeof(hbuf2),
1268
+ pbuf2, sizeof(pbuf2), fl);
1269
+ if (error) goto error_exit_name;
1270
+ if (strcmp(hbuf, hbuf2) != 0|| strcmp(pbuf, pbuf2) != 0) {
1271
+ freeaddrinfo(res);
1272
+ rb_raise(rb_eSocket, "sockaddr resolved to multiple nodename");
1273
+ }
1274
+ }
1275
+ freeaddrinfo(res);
1276
+ }
1277
+ return rb_assoc_new(rb_str_new2(hbuf), rb_str_new2(pbuf));
1278
+
1279
+ error_exit_addr:
1280
+ if (res) freeaddrinfo(res);
1281
+ rsock_raise_socket_error("getaddrinfo", error);
1282
+
1283
+ error_exit_name:
1284
+ if (res) freeaddrinfo(res);
1285
+ rsock_raise_socket_error("getnameinfo", error);
1286
+ }
1287
+
1288
+ /*
1289
+ * call-seq:
1290
+ * Socket.sockaddr_in(port, host) => sockaddr
1291
+ * Socket.pack_sockaddr_in(port, host) => sockaddr
1292
+ *
1293
+ * Packs _port_ and _host_ as an AF_INET/AF_INET6 sockaddr string.
1294
+ *
1295
+ * Socket.sockaddr_in(80, "127.0.0.1")
1296
+ * #=> "\x02\x00\x00P\x7F\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"
1297
+ *
1298
+ * Socket.sockaddr_in(80, "::1")
1299
+ * #=> "\n\x00\x00P\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00"
1300
+ *
1301
+ */
1302
+ static VALUE
1303
+ sock_s_pack_sockaddr_in(VALUE self, VALUE port, VALUE host)
1304
+ {
1305
+ struct addrinfo *res = rsock_addrinfo(host, port, 0, 0);
1306
+ VALUE addr = rb_str_new((char*)res->ai_addr, res->ai_addrlen);
1307
+
1308
+ freeaddrinfo(res);
1309
+ OBJ_INFECT(addr, port);
1310
+ OBJ_INFECT(addr, host);
1311
+
1312
+ return addr;
1313
+ }
1314
+
1315
+ /*
1316
+ * call-seq:
1317
+ * Socket.unpack_sockaddr_in(sockaddr) => [port, ip_address]
1318
+ *
1319
+ * Unpacks _sockaddr_ into port and ip_address.
1320
+ *
1321
+ * _sockaddr_ should be a string or an addrinfo for AF_INET/AF_INET6.
1322
+ *
1323
+ * sockaddr = Socket.sockaddr_in(80, "127.0.0.1")
1324
+ * p sockaddr #=> "\x02\x00\x00P\x7F\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"
1325
+ * p Socket.unpack_sockaddr_in(sockaddr) #=> [80, "127.0.0.1"]
1326
+ *
1327
+ */
1328
+ static VALUE
1329
+ sock_s_unpack_sockaddr_in(VALUE self, VALUE addr)
1330
+ {
1331
+ struct sockaddr_in * sockaddr;
1332
+ VALUE host;
1333
+
1334
+ sockaddr = (struct sockaddr_in*)SockAddrStringValuePtr(addr);
1335
+ if (RSTRING_LEN(addr) <
1336
+ (char*)&((struct sockaddr *)sockaddr)->sa_family +
1337
+ sizeof(((struct sockaddr *)sockaddr)->sa_family) -
1338
+ (char*)sockaddr)
1339
+ rb_raise(rb_eArgError, "too short sockaddr");
1340
+ if (((struct sockaddr *)sockaddr)->sa_family != AF_INET
1341
+ #ifdef INET6
1342
+ && ((struct sockaddr *)sockaddr)->sa_family != AF_INET6
1343
+ #endif
1344
+ ) {
1345
+ #ifdef INET6
1346
+ rb_raise(rb_eArgError, "not an AF_INET/AF_INET6 sockaddr");
1347
+ #else
1348
+ rb_raise(rb_eArgError, "not an AF_INET sockaddr");
1349
+ #endif
1350
+ }
1351
+ host = rsock_make_ipaddr((struct sockaddr*)sockaddr);
1352
+ OBJ_INFECT(host, addr);
1353
+ return rb_assoc_new(INT2NUM(ntohs(sockaddr->sin_port)), host);
1354
+ }
1355
+
1356
+ #ifdef HAVE_SYS_UN_H
1357
+
1358
+ /*
1359
+ * call-seq:
1360
+ * Socket.sockaddr_un(path) => sockaddr
1361
+ * Socket.pack_sockaddr_un(path) => sockaddr
1362
+ *
1363
+ * Packs _path_ as an AF_UNIX sockaddr string.
1364
+ *
1365
+ * Socket.sockaddr_un("/tmp/sock") #=> "\x01\x00/tmp/sock\x00\x00..."
1366
+ *
1367
+ */
1368
+ static VALUE
1369
+ sock_s_pack_sockaddr_un(VALUE self, VALUE path)
1370
+ {
1371
+ struct sockaddr_un sockaddr;
1372
+ char *sun_path;
1373
+ VALUE addr;
1374
+
1375
+ MEMZERO(&sockaddr, struct sockaddr_un, 1);
1376
+ sockaddr.sun_family = AF_UNIX;
1377
+ sun_path = StringValueCStr(path);
1378
+ if (sizeof(sockaddr.sun_path) <= strlen(sun_path)) {
1379
+ rb_raise(rb_eArgError, "too long unix socket path (max: %dbytes)",
1380
+ (int)sizeof(sockaddr.sun_path)-1);
1381
+ }
1382
+ strncpy(sockaddr.sun_path, sun_path, sizeof(sockaddr.sun_path)-1);
1383
+ addr = rb_str_new((char*)&sockaddr, sizeof(sockaddr));
1384
+ OBJ_INFECT(addr, path);
1385
+
1386
+ return addr;
1387
+ }
1388
+
1389
+ /*
1390
+ * call-seq:
1391
+ * Socket.unpack_sockaddr_un(sockaddr) => path
1392
+ *
1393
+ * Unpacks _sockaddr_ into path.
1394
+ *
1395
+ * _sockaddr_ should be a string or an addrinfo for AF_UNIX.
1396
+ *
1397
+ * sockaddr = Socket.sockaddr_un("/tmp/sock")
1398
+ * p Socket.unpack_sockaddr_un(sockaddr) #=> "/tmp/sock"
1399
+ *
1400
+ */
1401
+ static VALUE
1402
+ sock_s_unpack_sockaddr_un(VALUE self, VALUE addr)
1403
+ {
1404
+ struct sockaddr_un * sockaddr;
1405
+ const char *sun_path;
1406
+ VALUE path;
1407
+
1408
+ sockaddr = (struct sockaddr_un*)SockAddrStringValuePtr(addr);
1409
+ if (RSTRING_LEN(addr) <
1410
+ (char*)&((struct sockaddr *)sockaddr)->sa_family +
1411
+ sizeof(((struct sockaddr *)sockaddr)->sa_family) -
1412
+ (char*)sockaddr)
1413
+ rb_raise(rb_eArgError, "too short sockaddr");
1414
+ if (((struct sockaddr *)sockaddr)->sa_family != AF_UNIX) {
1415
+ rb_raise(rb_eArgError, "not an AF_UNIX sockaddr");
1416
+ }
1417
+ if (sizeof(struct sockaddr_un) < (size_t)RSTRING_LEN(addr)) {
1418
+ rb_raise(rb_eTypeError, "too long sockaddr_un - %ld longer than %d",
1419
+ RSTRING_LEN(addr), (int)sizeof(struct sockaddr_un));
1420
+ }
1421
+ sun_path = rsock_unixpath(sockaddr, RSTRING_LENINT(addr));
1422
+ if (sizeof(struct sockaddr_un) == RSTRING_LEN(addr) &&
1423
+ sun_path == sockaddr->sun_path &&
1424
+ sun_path + strlen(sun_path) == RSTRING_PTR(addr) + RSTRING_LEN(addr)) {
1425
+ rb_raise(rb_eArgError, "sockaddr_un.sun_path not NUL terminated");
1426
+ }
1427
+ path = rb_str_new2(sun_path);
1428
+ OBJ_INFECT(path, addr);
1429
+ return path;
1430
+ }
1431
+ #endif
1432
+
1433
+ #if defined(HAVE_GETIFADDRS) || defined(SIOCGLIFCONF) || defined(SIOCGIFCONF) || defined(_WIN32)
1434
+ static VALUE
1435
+ sockaddr_obj(struct sockaddr *addr)
1436
+ {
1437
+ socklen_t len;
1438
+ #if defined(AF_INET6) && defined(__KAME__)
1439
+ struct sockaddr_in6 addr6;
1440
+ #endif
1441
+
1442
+ if (addr == NULL)
1443
+ return Qnil;
1444
+
1445
+ switch (addr->sa_family) {
1446
+ case AF_INET:
1447
+ len = (socklen_t)sizeof(struct sockaddr_in);
1448
+ break;
1449
+
1450
+ #ifdef AF_INET6
1451
+ case AF_INET6:
1452
+ len = (socklen_t)sizeof(struct sockaddr_in6);
1453
+ # ifdef __KAME__
1454
+ /* KAME uses the 2nd 16bit word of link local IPv6 address as interface index internally */
1455
+ /* http://orange.kame.net/dev/cvsweb.cgi/kame/IMPLEMENTATION */
1456
+ /* convert fe80:1::1 to fe80::1%1 */
1457
+ memcpy(&addr6, addr, len);
1458
+ addr = (struct sockaddr *)&addr6;
1459
+ if (IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr) &&
1460
+ addr6.sin6_scope_id == 0 &&
1461
+ (addr6.sin6_addr.s6_addr[2] || addr6.sin6_addr.s6_addr[3])) {
1462
+ addr6.sin6_scope_id = (addr6.sin6_addr.s6_addr[2] << 8) | addr6.sin6_addr.s6_addr[3];
1463
+ addr6.sin6_addr.s6_addr[2] = 0;
1464
+ addr6.sin6_addr.s6_addr[3] = 0;
1465
+ }
1466
+ # endif
1467
+ break;
1468
+ #endif
1469
+
1470
+ #ifdef HAVE_SYS_UN_H
1471
+ case AF_UNIX:
1472
+ len = (socklen_t)sizeof(struct sockaddr_un);
1473
+ break;
1474
+ #endif
1475
+
1476
+ default:
1477
+ len = (socklen_t)sizeof(struct sockaddr_in);
1478
+ break;
1479
+ }
1480
+ #ifdef SA_LEN
1481
+ if (len < (socklen_t)SA_LEN(addr))
1482
+ len = (socklen_t)SA_LEN(addr);
1483
+ #endif
1484
+
1485
+ return rsock_addrinfo_new(addr, len, addr->sa_family, 0, 0, Qnil, Qnil);
1486
+ }
1487
+ #endif
1488
+
1489
+ #if defined(HAVE_GETIFADDRS) || (defined(SIOCGLIFCONF) && defined(SIOCGLIFNUM) && !defined(__hpux)) || defined(SIOCGIFCONF) || defined(_WIN32)
1490
+ /*
1491
+ * call-seq:
1492
+ * Socket.ip_address_list => array
1493
+ *
1494
+ * Returns local IP addresses as an array.
1495
+ *
1496
+ * The array contains Addrinfo objects.
1497
+ *
1498
+ * pp Socket.ip_address_list
1499
+ * #=> [#<Addrinfo: 127.0.0.1>,
1500
+ * #<Addrinfo: 192.168.0.128>,
1501
+ * #<Addrinfo: ::1>,
1502
+ * ...]
1503
+ *
1504
+ */
1505
+ static VALUE
1506
+ socket_s_ip_address_list(VALUE self)
1507
+ {
1508
+ #if defined(HAVE_GETIFADDRS)
1509
+ struct ifaddrs *ifp = NULL;
1510
+ struct ifaddrs *p;
1511
+ int ret;
1512
+ VALUE list;
1513
+
1514
+ ret = getifaddrs(&ifp);
1515
+ if (ret == -1) {
1516
+ rb_sys_fail("getifaddrs");
1517
+ }
1518
+
1519
+ list = rb_ary_new();
1520
+ for (p = ifp; p; p = p->ifa_next) {
1521
+ if (p->ifa_addr != NULL && IS_IP_FAMILY(p->ifa_addr->sa_family)) {
1522
+ rb_ary_push(list, sockaddr_obj(p->ifa_addr));
1523
+ }
1524
+ }
1525
+
1526
+ freeifaddrs(ifp);
1527
+
1528
+ return list;
1529
+ #elif defined(SIOCGLIFCONF) && defined(SIOCGLIFNUM) && !defined(__hpux)
1530
+ /* Solaris if_tcp(7P) */
1531
+ /* HP-UX has SIOCGLIFCONF too. But it uses different struct */
1532
+ int fd = -1;
1533
+ int ret;
1534
+ struct lifnum ln;
1535
+ struct lifconf lc;
1536
+ char *reason = NULL;
1537
+ int save_errno;
1538
+ int i;
1539
+ VALUE list = Qnil;
1540
+
1541
+ lc.lifc_buf = NULL;
1542
+
1543
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
1544
+ if (fd == -1)
1545
+ rb_sys_fail("socket");
1546
+
1547
+ memset(&ln, 0, sizeof(ln));
1548
+ ln.lifn_family = AF_UNSPEC;
1549
+
1550
+ ret = ioctl(fd, SIOCGLIFNUM, &ln);
1551
+ if (ret == -1) {
1552
+ reason = "SIOCGLIFNUM";
1553
+ goto finish;
1554
+ }
1555
+
1556
+ memset(&lc, 0, sizeof(lc));
1557
+ lc.lifc_family = AF_UNSPEC;
1558
+ lc.lifc_flags = 0;
1559
+ lc.lifc_len = sizeof(struct lifreq) * ln.lifn_count;
1560
+ lc.lifc_req = xmalloc(lc.lifc_len);
1561
+
1562
+ ret = ioctl(fd, SIOCGLIFCONF, &lc);
1563
+ if (ret == -1) {
1564
+ reason = "SIOCGLIFCONF";
1565
+ goto finish;
1566
+ }
1567
+
1568
+ list = rb_ary_new();
1569
+ for (i = 0; i < ln.lifn_count; i++) {
1570
+ struct lifreq *req = &lc.lifc_req[i];
1571
+ if (IS_IP_FAMILY(req->lifr_addr.ss_family)) {
1572
+ if (req->lifr_addr.ss_family == AF_INET6 &&
1573
+ IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)(&req->lifr_addr))->sin6_addr) &&
1574
+ ((struct sockaddr_in6 *)(&req->lifr_addr))->sin6_scope_id == 0) {
1575
+ struct lifreq req2;
1576
+ memcpy(req2.lifr_name, req->lifr_name, LIFNAMSIZ);
1577
+ ret = ioctl(fd, SIOCGLIFINDEX, &req2);
1578
+ if (ret == -1) {
1579
+ reason = "SIOCGLIFINDEX";
1580
+ goto finish;
1581
+ }
1582
+ ((struct sockaddr_in6 *)(&req->lifr_addr))->sin6_scope_id = req2.lifr_index;
1583
+ }
1584
+ rb_ary_push(list, sockaddr_obj((struct sockaddr *)&req->lifr_addr));
1585
+ }
1586
+ }
1587
+
1588
+ finish:
1589
+ save_errno = errno;
1590
+ if (lc.lifc_buf != NULL)
1591
+ xfree(lc.lifc_req);
1592
+ if (fd != -1)
1593
+ close(fd);
1594
+ errno = save_errno;
1595
+
1596
+ if (reason)
1597
+ rb_sys_fail(reason);
1598
+ return list;
1599
+
1600
+ #elif defined(SIOCGIFCONF)
1601
+ int fd = -1;
1602
+ int ret;
1603
+ #define EXTRA_SPACE (sizeof(struct ifconf) + sizeof(struct sockaddr_storage))
1604
+ char initbuf[4096+EXTRA_SPACE];
1605
+ char *buf = initbuf;
1606
+ int bufsize;
1607
+ struct ifconf conf;
1608
+ struct ifreq *req;
1609
+ VALUE list = Qnil;
1610
+ const char *reason = NULL;
1611
+ int save_errno;
1612
+
1613
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
1614
+ if (fd == -1)
1615
+ rb_sys_fail("socket");
1616
+
1617
+ bufsize = sizeof(initbuf);
1618
+ buf = initbuf;
1619
+
1620
+ retry:
1621
+ conf.ifc_len = bufsize;
1622
+ conf.ifc_req = (struct ifreq *)buf;
1623
+
1624
+ /* fprintf(stderr, "bufsize: %d\n", bufsize); */
1625
+
1626
+ ret = ioctl(fd, SIOCGIFCONF, &conf);
1627
+ if (ret == -1) {
1628
+ reason = "SIOCGIFCONF";
1629
+ goto finish;
1630
+ }
1631
+
1632
+ /* fprintf(stderr, "conf.ifc_len: %d\n", conf.ifc_len); */
1633
+
1634
+ if (bufsize - EXTRA_SPACE < conf.ifc_len) {
1635
+ if (bufsize < conf.ifc_len) {
1636
+ /* NetBSD returns required size for all interfaces. */
1637
+ bufsize = conf.ifc_len + EXTRA_SPACE;
1638
+ }
1639
+ else {
1640
+ bufsize = bufsize << 1;
1641
+ }
1642
+ if (buf == initbuf)
1643
+ buf = NULL;
1644
+ buf = xrealloc(buf, bufsize);
1645
+ goto retry;
1646
+ }
1647
+
1648
+ close(fd);
1649
+ fd = -1;
1650
+
1651
+ list = rb_ary_new();
1652
+ req = conf.ifc_req;
1653
+ while ((char*)req < (char*)conf.ifc_req + conf.ifc_len) {
1654
+ struct sockaddr *addr = &req->ifr_addr;
1655
+ if (IS_IP_FAMILY(addr->sa_family)) {
1656
+ rb_ary_push(list, sockaddr_obj(addr));
1657
+ }
1658
+ #ifdef HAVE_SA_LEN
1659
+ # ifndef _SIZEOF_ADDR_IFREQ
1660
+ # define _SIZEOF_ADDR_IFREQ(r) \
1661
+ (sizeof(struct ifreq) + \
1662
+ (sizeof(struct sockaddr) < (r).ifr_addr.sa_len ? \
1663
+ (r).ifr_addr.sa_len - sizeof(struct sockaddr) : \
1664
+ 0))
1665
+ # endif
1666
+ req = (struct ifreq *)((char*)req + _SIZEOF_ADDR_IFREQ(*req));
1667
+ #else
1668
+ req = (struct ifreq *)((char*)req + sizeof(struct ifreq));
1669
+ #endif
1670
+ }
1671
+
1672
+ finish:
1673
+
1674
+ save_errno = errno;
1675
+ if (buf != initbuf)
1676
+ xfree(buf);
1677
+ if (fd != -1)
1678
+ close(fd);
1679
+ errno = save_errno;
1680
+
1681
+ if (reason)
1682
+ rb_sys_fail(reason);
1683
+ return list;
1684
+
1685
+ #undef EXTRA_SPACE
1686
+ #elif defined(_WIN32)
1687
+ typedef struct ip_adapter_unicast_address_st {
1688
+ unsigned LONG_LONG dummy0;
1689
+ struct ip_adapter_unicast_address_st *Next;
1690
+ struct {
1691
+ struct sockaddr *lpSockaddr;
1692
+ int iSockaddrLength;
1693
+ } Address;
1694
+ int dummy1;
1695
+ int dummy2;
1696
+ int dummy3;
1697
+ long dummy4;
1698
+ long dummy5;
1699
+ long dummy6;
1700
+ } ip_adapter_unicast_address_t;
1701
+ typedef struct ip_adapter_anycast_address_st {
1702
+ unsigned LONG_LONG dummy0;
1703
+ struct ip_adapter_anycast_address_st *Next;
1704
+ struct {
1705
+ struct sockaddr *lpSockaddr;
1706
+ int iSockaddrLength;
1707
+ } Address;
1708
+ } ip_adapter_anycast_address_t;
1709
+ typedef struct ip_adapter_addresses_st {
1710
+ unsigned LONG_LONG dummy0;
1711
+ struct ip_adapter_addresses_st *Next;
1712
+ void *dummy1;
1713
+ ip_adapter_unicast_address_t *FirstUnicastAddress;
1714
+ ip_adapter_anycast_address_t *FirstAnycastAddress;
1715
+ void *dummy2;
1716
+ void *dummy3;
1717
+ void *dummy4;
1718
+ void *dummy5;
1719
+ void *dummy6;
1720
+ BYTE dummy7[8];
1721
+ DWORD dummy8;
1722
+ DWORD dummy9;
1723
+ DWORD dummy10;
1724
+ DWORD IfType;
1725
+ int OperStatus;
1726
+ DWORD dummy12;
1727
+ DWORD dummy13[16];
1728
+ void *dummy14;
1729
+ } ip_adapter_addresses_t;
1730
+ typedef ULONG (WINAPI *GetAdaptersAddresses_t)(ULONG, ULONG, PVOID, ip_adapter_addresses_t *, PULONG);
1731
+ HMODULE h;
1732
+ GetAdaptersAddresses_t pGetAdaptersAddresses;
1733
+ ULONG len;
1734
+ DWORD ret;
1735
+ ip_adapter_addresses_t *adapters;
1736
+ VALUE list;
1737
+
1738
+ h = LoadLibrary("iphlpapi.dll");
1739
+ if (!h)
1740
+ rb_notimplement();
1741
+ pGetAdaptersAddresses = (GetAdaptersAddresses_t)GetProcAddress(h, "GetAdaptersAddresses");
1742
+ if (!pGetAdaptersAddresses) {
1743
+ FreeLibrary(h);
1744
+ rb_notimplement();
1745
+ }
1746
+
1747
+ ret = pGetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &len);
1748
+ if (ret != ERROR_SUCCESS && ret != ERROR_BUFFER_OVERFLOW) {
1749
+ errno = rb_w32_map_errno(ret);
1750
+ FreeLibrary(h);
1751
+ rb_sys_fail("GetAdaptersAddresses");
1752
+ }
1753
+ adapters = (ip_adapter_addresses_t *)ALLOCA_N(BYTE, len);
1754
+ ret = pGetAdaptersAddresses(AF_UNSPEC, 0, NULL, adapters, &len);
1755
+ if (ret != ERROR_SUCCESS) {
1756
+ errno = rb_w32_map_errno(ret);
1757
+ FreeLibrary(h);
1758
+ rb_sys_fail("GetAdaptersAddresses");
1759
+ }
1760
+
1761
+ list = rb_ary_new();
1762
+ for (; adapters; adapters = adapters->Next) {
1763
+ ip_adapter_unicast_address_t *uni;
1764
+ ip_adapter_anycast_address_t *any;
1765
+ if (adapters->OperStatus != 1) /* 1 means IfOperStatusUp */
1766
+ continue;
1767
+ for (uni = adapters->FirstUnicastAddress; uni; uni = uni->Next) {
1768
+ #ifndef INET6
1769
+ if (uni->Address.lpSockaddr->sa_family == AF_INET)
1770
+ #else
1771
+ if (IS_IP_FAMILY(uni->Address.lpSockaddr->sa_family))
1772
+ #endif
1773
+ rb_ary_push(list, sockaddr_obj(uni->Address.lpSockaddr));
1774
+ }
1775
+ for (any = adapters->FirstAnycastAddress; any; any = any->Next) {
1776
+ #ifndef INET6
1777
+ if (any->Address.lpSockaddr->sa_family == AF_INET)
1778
+ #else
1779
+ if (IS_IP_FAMILY(any->Address.lpSockaddr->sa_family))
1780
+ #endif
1781
+ rb_ary_push(list, sockaddr_obj(any->Address.lpSockaddr));
1782
+ }
1783
+ }
1784
+
1785
+ FreeLibrary(h);
1786
+ return list;
1787
+ #endif
1788
+ }
1789
+ #else
1790
+ #define socket_s_ip_address_list rb_f_notimplement
1791
+ #endif
1792
+
1793
+ /*
1794
+ * Document-class: ::Socket < BasicSocket
1795
+ *
1796
+ * Class +Socket+ provides access to the underlying operating system
1797
+ * socket implementations. It can be used to provide more operating system
1798
+ * specific functionality than the protocol-specific socket classes.
1799
+ *
1800
+ * The constants defined under Socket::Constants are also defined under Socket.
1801
+ * For example, Socket::AF_INET is usable as well as Socket::Constants::AF_INET.
1802
+ * See Socket::Constants for the list of constants.
1803
+ *
1804
+ * === Exception Handling
1805
+ * Ruby's implementation of +Socket+ causes an exception to be raised
1806
+ * based on the error generated by the system dependent implementation.
1807
+ * This is why the methods are documented in a way that isolate
1808
+ * Unix-based system exceptions from Windows based exceptions. If more
1809
+ * information on particular exception is needed please refer to the
1810
+ * Unix manual pages or the Windows WinSock reference.
1811
+ *
1812
+ * === Convenient methods
1813
+ *
1814
+ * Although the general way to create socket is Socket.new,
1815
+ * there are several methods for socket creation for most cases.
1816
+ *
1817
+ * * TCP client socket: Socket.tcp, TCPSocket.open
1818
+ * * TCP server socket: Socket.tcp_server_loop, TCPServer.open
1819
+ * * UNIX client socket: Socket.unix, UNIXSocket.open
1820
+ * * UNIX server socket: Socket.unix_server_loop, UNIXServer.open
1821
+ *
1822
+ * === Documentation by
1823
+ * * Zach Dennis
1824
+ * * Sam Roberts
1825
+ * * <em>Programming Ruby</em> from The Pragmatic Bookshelf.
1826
+ *
1827
+ * Much material in this documentation is taken with permission from
1828
+ * <em>Programming Ruby</em> from The Pragmatic Bookshelf.
1829
+ */
1830
+ void
1831
+ Init_socket()
1832
+ {
1833
+ rsock_init_basicsocket();
1834
+
1835
+ rb_cSocket = rb_define_class("Socket", rb_cBasicSocket);
1836
+
1837
+ rsock_init_socket_init();
1838
+
1839
+ rb_define_method(rb_cSocket, "initialize", sock_initialize, -1);
1840
+ rb_define_method(rb_cSocket, "connect", sock_connect, 1);
1841
+ rb_define_method(rb_cSocket, "connect_nonblock", sock_connect_nonblock, 1);
1842
+ rb_define_method(rb_cSocket, "bind", sock_bind, 1);
1843
+ rb_define_method(rb_cSocket, "listen", rsock_sock_listen, 1);
1844
+ rb_define_method(rb_cSocket, "accept", sock_accept, 0);
1845
+ rb_define_method(rb_cSocket, "accept_nonblock", sock_accept_nonblock, 0);
1846
+ rb_define_method(rb_cSocket, "sysaccept", sock_sysaccept, 0);
1847
+
1848
+ rb_define_method(rb_cSocket, "recvfrom", sock_recvfrom, -1);
1849
+ rb_define_method(rb_cSocket, "recvfrom_nonblock", sock_recvfrom_nonblock, -1);
1850
+
1851
+ rb_define_singleton_method(rb_cSocket, "socketpair", rsock_sock_s_socketpair, -1);
1852
+ rb_define_singleton_method(rb_cSocket, "pair", rsock_sock_s_socketpair, -1);
1853
+ rb_define_singleton_method(rb_cSocket, "gethostname", sock_gethostname, 0);
1854
+ rb_define_singleton_method(rb_cSocket, "gethostbyname", sock_s_gethostbyname, 1);
1855
+ rb_define_singleton_method(rb_cSocket, "gethostbyaddr", sock_s_gethostbyaddr, -1);
1856
+ rb_define_singleton_method(rb_cSocket, "getservbyname", sock_s_getservbyname, -1);
1857
+ rb_define_singleton_method(rb_cSocket, "getservbyport", sock_s_getservbyport, -1);
1858
+ rb_define_singleton_method(rb_cSocket, "getaddrinfo", sock_s_getaddrinfo, -1);
1859
+ rb_define_singleton_method(rb_cSocket, "getnameinfo", sock_s_getnameinfo, -1);
1860
+ rb_define_singleton_method(rb_cSocket, "sockaddr_in", sock_s_pack_sockaddr_in, 2);
1861
+ rb_define_singleton_method(rb_cSocket, "pack_sockaddr_in", sock_s_pack_sockaddr_in, 2);
1862
+ rb_define_singleton_method(rb_cSocket, "unpack_sockaddr_in", sock_s_unpack_sockaddr_in, 1);
1863
+ #ifdef HAVE_SYS_UN_H
1864
+ rb_define_singleton_method(rb_cSocket, "sockaddr_un", sock_s_pack_sockaddr_un, 1);
1865
+ rb_define_singleton_method(rb_cSocket, "pack_sockaddr_un", sock_s_pack_sockaddr_un, 1);
1866
+ rb_define_singleton_method(rb_cSocket, "unpack_sockaddr_un", sock_s_unpack_sockaddr_un, 1);
1867
+ #endif
1868
+
1869
+ rb_define_singleton_method(rb_cSocket, "ip_address_list", socket_s_ip_address_list, 0);
1870
+ }