Skip to content

Commit

Permalink
Fix up BasicSocket#close_read and close_write.
Browse files Browse the repository at this point in the history
Passes specs in rubysl-socket.
headius committed Mar 11, 2016
1 parent fa5b80f commit db72d34
Showing 1 changed file with 26 additions and 47 deletions.
73 changes: 26 additions & 47 deletions core/src/main/java/org/jruby/ext/socket/RubyBasicSocket.java
Original file line number Diff line number Diff line change
@@ -416,60 +416,39 @@ public IRubyObject shutdown(ThreadContext context, IRubyObject[] args) {
}
}

try {
return shutdownInternal(context, how);
}
catch (BadDescriptorException e) {
throw context.runtime.newErrnoEBADFError();
}
OpenFile fptr = getOpenFileChecked();

return shutdownInternal(context, fptr, how);
}

@Override
@JRubyMethod
public IRubyObject close_write(ThreadContext context) {
Ruby runtime = context.runtime;
OpenFile fptr;

// if (rb_safe_level() >= 4 && !OBJ_TAINTED(sock)) {
// rb_raise(rb_eSecurityError, "Insecure: can't close socket");
// }
fptr = getOpenFileChecked();
if ((fptr.getMode() & OpenFile.READABLE) == 0) {
return rbIoClose(runtime);
}
// shutdown write
try {
shutdownInternal(context, 1);
}
catch (BadDescriptorException e) {
throw runtime.newErrnoEBADFError();
}

return context.nil;
return closeHalf(context, OpenFile.WRITABLE);
}

@Override
@JRubyMethod
public IRubyObject close_read(ThreadContext context) {
Ruby runtime = context.runtime;
return closeHalf(context, OpenFile.READABLE);
}

if (!openFile.isOpen()) {
throw context.runtime.newIOError("not opened for reading");
}
private IRubyObject closeHalf(ThreadContext context, int closeHalf) {
Ruby runtime = context.runtime;
OpenFile fptr;

if (!openFile.isWritable()) {
close();
int otherHalf = closeHalf == OpenFile.READABLE ? OpenFile.WRITABLE : OpenFile.READABLE;

} else {
// shutdown read
try {
shutdownInternal(context, 0);
}
catch (BadDescriptorException e) {
throw runtime.newErrnoEBADFError();
}
fptr = getOpenFileChecked();
if ((fptr.getMode() & otherHalf) == 0) {
// shutdown fully
return rbIoClose(runtime);
}

// shutdown half
shutdownInternal(context, fptr, 0);
fptr.setMode(fptr.getMode() & ~closeHalf);

return context.nil;
}

@@ -497,7 +476,7 @@ protected ByteList doRead(ThreadContext context, final ByteBuffer buffer) {
Ruby runtime = context.runtime;
OpenFile fptr;

fptr = getOpenFile();
fptr = getOpenFileInitialized();
fptr.checkReadable(context);

try {
@@ -614,40 +593,40 @@ protected IRubyObject getSocknameCommon(ThreadContext context, String caller) {
return Sockaddr.pack_sockaddr_un(context, unixSocketAddress.path());
}

private IRubyObject shutdownInternal(ThreadContext context, int how) throws BadDescriptorException {
private static IRubyObject shutdownInternal(ThreadContext context, OpenFile fptr, int how) {
Ruby runtime = context.runtime;
Channel channel;

switch (how) {
case 0:
channel = getOpenChannel();
channel = fptr.channel();
try {
SocketType.forChannel(channel).shutdownInput(channel);
}
catch (IOException e) {
// MRI ignores errors from shutdown()
}

openFile.setMode(openFile.getMode() & ~OpenFile.READABLE);
fptr.setMode(fptr.getMode() & ~OpenFile.READABLE);

return RubyFixnum.zero(runtime);

case 1:
channel = getOpenChannel();
channel = fptr.channel();
try {
SocketType.forChannel(channel).shutdownOutput(channel);
}
catch (IOException e) {
// MRI ignores errors from shutdown()
}

openFile.setMode(openFile.getMode() & ~OpenFile.WRITABLE);
fptr.setMode(fptr.getMode() & ~OpenFile.WRITABLE);

return RubyFixnum.zero(runtime);

case 2:
shutdownInternal(context, 0);
shutdownInternal(context, 1);
shutdownInternal(context, fptr, 0);
shutdownInternal(context, fptr, 1);

return RubyFixnum.zero(runtime);

0 comments on commit db72d34

Please sign in to comment.