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