Navigation Menu

Skip to content

Commit

Permalink
Remove 1.8-incompatible changes to #setsockopt
Browse files Browse the repository at this point in the history
This commit corrects changes mistakenly added to lib/18/socket.rb.
It also adds ruby version guards to ensure the specs only run against 1.9
implementations.
  • Loading branch information
warrenseen committed Nov 20, 2012
1 parent 8f64989 commit 35d531f
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 207 deletions.
77 changes: 0 additions & 77 deletions lib/18/socket.rb
Expand Up @@ -42,12 +42,6 @@ def setsockopt(level, optname, optval)

error = 0

sockname = Socket::Foreign.getsockname descriptor
family = Socket::Foreign.getnameinfo(sockname).first

level = level_arg(family, level)
optname = optname_arg(level, optname)

case optval
when Fixnum then
FFI::MemoryPointer.new :socklen_t do |val|
Expand Down Expand Up @@ -162,77 +156,6 @@ def shutdown(how = 2)
Errno.handle "shutdown" unless err == 0
end

private

def level_arg(family, level)
case level
when Symbol, String
if Socket::Constants.const_defined?(level)
Socket::Constants.const_get(level)
else
if is_ip_family?(family)
ip_level_to_int(level)
else
unknown_level_to_int(level)
end
end
else
level
end
end

def optname_arg(level, optname)
case optname
when Symbol, String
if Socket::Constants.const_defined?(optname)
Socket::Constants.const_get(optname)
else
case(level)
when Socket::Constants::SOL_SOCKET
constant("SO", optname)
when Socket::Constants::IPPROTO_IP
constant("IP", optname)
when Socket::Constants::IPPROTO_TCP
constant("TCP", optname)
when Socket::Constants::IPPROTO_UDP
constant("UDP", optname)
else
if Socket::Constants.const_defined?(Socket::Constants::IPPROTO_IPV6) &&
level == Socket::Constants::IPPROTO_IPV6
constant("IPV6", optname)
else
optname
end
end
end
else
optname
end
end

def is_ip_family?(family)
family == "AF_INET" || family == "AF_INET6"
end

def ip_level_to_int(level)
prefixes = ["IPPROTO", "SOL"]
prefixes.each do |prefix|
if Socket::Constants.const_defined?("#{prefix}_#{level}")
return Socket::Constants.const_get("#{prefix}_#{level}")
end
end
end

def unknown_level_to_int(level)
constant("SOL", level)
end

def constant(prefix, suffix)
if Socket::Constants.const_defined?("#{prefix}_#{suffix}")
Socket::Constants.const_get("#{prefix}_#{suffix}")
end
end

end

class Socket < BasicSocket
Expand Down
234 changes: 118 additions & 116 deletions spec/ruby/library/socket/basicsocket/setsockopt_spec.rb
Expand Up @@ -159,152 +159,154 @@
end
end

describe "using strings" do
context "without prefix" do
it "sets the socket linger to 0" do
linger = [0, 0].pack("ii")
@sock.setsockopt("SOCKET", "LINGER", linger).should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER).to_s

if (n.size == 8) # linger struct on some platforms, not just a value
n.should == [0, 0].pack("ii")
else
n.should == [0].pack("i")
ruby_version_is "1.9" do
describe "using strings" do
context "without prefix" do
it "sets the socket linger to 0" do
linger = [0, 0].pack("ii")
@sock.setsockopt("SOCKET", "LINGER", linger).should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER).to_s

if (n.size == 8) # linger struct on some platforms, not just a value
n.should == [0, 0].pack("ii")
else
n.should == [0].pack("i")
end
end
end

it "sets the socket linger to some positive value" do
linger = [64, 64].pack("ii")
@sock.setsockopt("SOCKET", "LINGER", linger).should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER).to_s
if (n.size == 8) # linger struct on some platforms, not just a value
a = n.unpack('ii')
a[0].should_not == 0
a[1].should == 64
else
n.should == [64].pack("i")
it "sets the socket linger to some positive value" do
linger = [64, 64].pack("ii")
@sock.setsockopt("SOCKET", "LINGER", linger).should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER).to_s
if (n.size == 8) # linger struct on some platforms, not just a value
a = n.unpack('ii')
a[0].should_not == 0
a[1].should == 64
else
n.should == [64].pack("i")
end
end
end

it "sets the socket option Socket::SO_OOBINLINE" do
@sock.setsockopt("SOCKET", "OOBINLINE", true).should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
n.should_not == [0].pack("i")
it "sets the socket option Socket::SO_OOBINLINE" do
@sock.setsockopt("SOCKET", "OOBINLINE", true).should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
n.should_not == [0].pack("i")

@sock.setsockopt("SOCKET", "OOBINLINE", false).should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
n.should == [0].pack("i")
@sock.setsockopt("SOCKET", "OOBINLINE", false).should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
n.should == [0].pack("i")

@sock.setsockopt("SOCKET", "OOBINLINE", 1).should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
n.should_not == [0].pack("i")
@sock.setsockopt("SOCKET", "OOBINLINE", 1).should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
n.should_not == [0].pack("i")

@sock.setsockopt("SOCKET", "OOBINLINE", 0).should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
n.should == [0].pack("i")
@sock.setsockopt("SOCKET", "OOBINLINE", 0).should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
n.should == [0].pack("i")

@sock.setsockopt("SOCKET", "OOBINLINE", 2).should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
n.should_not == [0].pack("i")
@sock.setsockopt("SOCKET", "OOBINLINE", 2).should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
n.should_not == [0].pack("i")

platform_is_not :os => :windows do
lambda {
@sock.setsockopt("SOCKET", "OOBINLINE", "")
}.should raise_error(SystemCallError)
end
platform_is_not :os => :windows do
lambda {
@sock.setsockopt("SOCKET", "OOBINLINE", "")
}.should raise_error(SystemCallError)
end

@sock.setsockopt("SOCKET", "OOBINLINE", "blah").should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
n.should_not == [0].pack("i")
@sock.setsockopt("SOCKET", "OOBINLINE", "blah").should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
n.should_not == [0].pack("i")

platform_is_not :os => :windows do
lambda {
@sock.setsockopt("SOCKET", "OOBINLINE", "0")
}.should raise_error(SystemCallError)
end
platform_is_not :os => :windows do
lambda {
@sock.setsockopt("SOCKET", "OOBINLINE", "0")
}.should raise_error(SystemCallError)
end

@sock.setsockopt("SOCKET", "OOBINLINE", "\x00\x00\x00\x00").should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
n.should == [0].pack("i")
@sock.setsockopt("SOCKET", "OOBINLINE", "\x00\x00\x00\x00").should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
n.should == [0].pack("i")

platform_is_not :os => :windows do
lambda {
@sock.setsockopt("SOCKET", "OOBINLINE", "1")
}.should raise_error(SystemCallError)
end
platform_is_not :os => :windows do
lambda {
@sock.setsockopt("SOCKET", "OOBINLINE", "1")
}.should raise_error(SystemCallError)
end

platform_is_not :os => :windows do
lambda {
@sock.setsockopt("SOCKET", "OOBINLINE", "\x00\x00\x00")
}.should raise_error(SystemCallError)
end
platform_is_not :os => :windows do
lambda {
@sock.setsockopt("SOCKET", "OOBINLINE", "\x00\x00\x00")
}.should raise_error(SystemCallError)
end

@sock.setsockopt("SOCKET", "OOBINLINE", [1].pack('i')).should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
n.should_not == [0].pack("i")
@sock.setsockopt("SOCKET", "OOBINLINE", [1].pack('i')).should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
n.should_not == [0].pack("i")

@sock.setsockopt("SOCKET", "OOBINLINE", [0].pack('i')).should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
n.should == [0].pack("i")
@sock.setsockopt("SOCKET", "OOBINLINE", [0].pack('i')).should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
n.should == [0].pack("i")

@sock.setsockopt("SOCKET", "OOBINLINE", [1000].pack('i')).should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
n.should_not == [0].pack("i")
end
@sock.setsockopt("SOCKET", "OOBINLINE", [1000].pack('i')).should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_OOBINLINE).to_s
n.should_not == [0].pack("i")
end

it "sets the socket option Socket::SO_SNDBUF" do
@sock.setsockopt("SOCKET", "SNDBUF", 4000).should == 0
sndbuf = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s
# might not always be possible to set to exact size
sndbuf.unpack('i')[0].should >= 4000
it "sets the socket option Socket::SO_SNDBUF" do
@sock.setsockopt("SOCKET", "SNDBUF", 4000).should == 0
sndbuf = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s
# might not always be possible to set to exact size
sndbuf.unpack('i')[0].should >= 4000

@sock.setsockopt("SOCKET", "SNDBUF", true).should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s
n.unpack('i')[0].should >= 1
@sock.setsockopt("SOCKET", "SNDBUF", true).should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s
n.unpack('i')[0].should >= 1

lambda {
@sock.setsockopt("SOCKET", "SNDBUF", nil).should == 0
}.should raise_error(TypeError)
lambda {
@sock.setsockopt("SOCKET", "SNDBUF", nil).should == 0
}.should raise_error(TypeError)

@sock.setsockopt("SOCKET", "SNDBUF", 1).should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s
n.unpack('i')[0].should >= 1
@sock.setsockopt("SOCKET", "SNDBUF", 1).should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s
n.unpack('i')[0].should >= 1

@sock.setsockopt("SOCKET", "SNDBUF", 2).should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s
n.unpack('i')[0].should >= 2
@sock.setsockopt("SOCKET", "SNDBUF", 2).should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s
n.unpack('i')[0].should >= 2

lambda {
@sock.setsockopt("SOCKET", "SNDBUF", "")
}.should raise_error(SystemCallError)
lambda {
@sock.setsockopt("SOCKET", "SNDBUF", "")
}.should raise_error(SystemCallError)

lambda {
@sock.setsockopt("SOCKET", "SNDBUF", "bla")
}.should raise_error(SystemCallError)
lambda {
@sock.setsockopt("SOCKET", "SNDBUF", "bla")
}.should raise_error(SystemCallError)

lambda {
@sock.setsockopt("SOCKET", "SNDBUF", "0")
}.should raise_error(SystemCallError)
lambda {
@sock.setsockopt("SOCKET", "SNDBUF", "0")
}.should raise_error(SystemCallError)

lambda {
@sock.setsockopt("SOCKET", "SNDBUF", "1")
}.should raise_error(SystemCallError)
lambda {
@sock.setsockopt("SOCKET", "SNDBUF", "1")
}.should raise_error(SystemCallError)

lambda {
@sock.setsockopt("SOCKET", "SNDBUF", "\x00\x00\x00")
}.should raise_error(SystemCallError)
lambda {
@sock.setsockopt("SOCKET", "SNDBUF", "\x00\x00\x00")
}.should raise_error(SystemCallError)

@sock.setsockopt("SOCKET", "SNDBUF", "\x00\x00\x01\x00").should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s
n.unpack('i')[0].should >= "\x00\x00\x01\x00".unpack('i')[0]
@sock.setsockopt("SOCKET", "SNDBUF", "\x00\x00\x01\x00").should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s
n.unpack('i')[0].should >= "\x00\x00\x01\x00".unpack('i')[0]

@sock.setsockopt("SOCKET", "SNDBUF", [4000].pack('i')).should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s
n.unpack('i')[0].should >= 4000
@sock.setsockopt("SOCKET", "SNDBUF", [4000].pack('i')).should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s
n.unpack('i')[0].should >= 4000

@sock.setsockopt("SOCKET", "SNDBUF", [1000].pack('i')).should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s
n.unpack('i')[0].should >= 1000
@sock.setsockopt("SOCKET", "SNDBUF", [1000].pack('i')).should == 0
n = @sock.getsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF).to_s
n.unpack('i')[0].should >= 1000
end
end
end
end
Expand Down

0 comments on commit 35d531f

Please sign in to comment.