private void initializeModes(Object modeArgument) { Ruby runtime = getRuntime(); if (modeArgument == null) { data.modes = RubyIO.newModeFlags(runtime, "r+"); } else if (modeArgument instanceof Long) { data.modes = RubyIO.newModeFlags(runtime, ((Long) modeArgument).longValue()); } else { data.modes = RubyIO.newModeFlags(runtime, (String) modeArgument); } setupModes(); }
@JRubyMethod public static IRubyObject rbuf_fill(IRubyObject recv) { RubyString buf = (RubyString) recv.getInstanceVariables().getInstanceVariable("@rbuf"); RubyIO io = (RubyIO) recv.getInstanceVariables().getInstanceVariable("@io"); int timeout = RubyNumeric.fix2int(recv.getInstanceVariables().getInstanceVariable("@read_timeout")) * 1000; NativeImpl nim = (NativeImpl) recv.dataGetStruct(); Selector selector = null; synchronized (nim.channel.blockingLock()) { boolean oldBlocking = nim.channel.isBlocking(); try { selector = SelectorFactory.openWithRetryFrom(recv.getRuntime(), SelectorProvider.provider()); nim.channel.configureBlocking(false); SelectionKey key = nim.channel.register(selector, SelectionKey.OP_READ); int n = selector.select(timeout); if (n > 0) { IRubyObject readItems = io.read(new IRubyObject[] {recv.getRuntime().newFixnum(1024 * 16)}); return buf.concat(readItems); } else { RubyClass exc = (RubyClass) (recv.getRuntime().getModule("Timeout").getConstant("Error")); throw new RaiseException( RubyException.newException(recv.getRuntime(), exc, "execution expired"), false); } } catch (IOException exception) { throw recv.getRuntime().newIOErrorFromException(exception); } finally { if (selector != null) { try { selector.close(); } catch (Exception e) { } } try { nim.channel.configureBlocking(oldBlocking); } catch (IOException ioe) { } } } }
private static IRubyObject puts(ThreadContext context, IRubyObject maybeIO, IRubyObject[] args) { // TODO: This should defer to RubyIO logic, but we don't have puts right there for 1.9 Ruby runtime = context.runtime; if (args.length == 0) { RubyIO.write(context, maybeIO, RubyString.newStringShared(runtime, NEWLINE)); return runtime.getNil(); } for (int i = 0; i < args.length; i++) { RubyString line = null; if (!args[i].isNil()) { IRubyObject tmp = args[i].checkArrayType(); if (!tmp.isNil()) { RubyArray arr = (RubyArray) tmp; if (runtime.isInspecting(arr)) { line = runtime.newString("[...]"); } else { inspectPuts(context, maybeIO, arr); continue; } } else { if (args[i] instanceof RubyString) { line = (RubyString) args[i]; } else { line = args[i].asString(); } } } if (line != null) RubyIO.write(context, maybeIO, line); if (line == null || !line.getByteList().endsWith(NEWLINE)) { RubyIO.write(context, maybeIO, RubyString.newStringShared(runtime, NEWLINE)); } } return runtime.getNil(); }
@JRubyMethod(required = 1, visibility = Visibility.PRIVATE) public static IRubyObject initialize(IRubyObject recv, IRubyObject io) { try { if (io instanceof RubyIO) { RubyIO rubyIO = (RubyIO) io; OpenFile of = rubyIO.getOpenFile(); Stream stream = of.getMainStreamSafe(); if (stream instanceof ChannelStream) { ChannelStream cStream = (ChannelStream) stream; if (cStream.getDescriptor().getChannel() instanceof SelectableChannel) { SelectableChannel selChannel = (SelectableChannel) cStream.getDescriptor().getChannel(); ((RubyObject) recv) .extend( new IRubyObject[] { ((RubyModule) recv.getRuntime().getModule("Net").getConstant("BufferedIO")) .getConstant("NativeImplementation") }); SelectableChannel sc = (SelectableChannel) (selChannel); recv.dataWrapStruct(new NativeImpl(sc)); } } } recv.getInstanceVariables().setInstanceVariable("@io", io); recv.getInstanceVariables() .setInstanceVariable("@read_timeout", recv.getRuntime().newFixnum(60)); recv.getInstanceVariables().setInstanceVariable("@debug_output", recv.getRuntime().getNil()); recv.getInstanceVariables() .setInstanceVariable("@rbuf", RubyString.newEmptyString(recv.getRuntime())); return recv; } catch (BadDescriptorException e) { throw recv.getRuntime().newErrnoEBADFError(); } }
@JRubyMethod public IRubyObject initialize( ThreadContext context, IRubyObject selectable, IRubyObject interests, IRubyObject selector) { this.io = RubyIO.convertToIO(context, selectable); this.interests = interests; this.selector = selector; this.value = context.nil; this.closed = context.getRuntime().getFalse(); return context.nil; }
@JRubyMethod(name = "readline", module = true, visibility = Visibility.PRIVATE) public static IRubyObject s_readline( ThreadContext context, IRubyObject recv, IRubyObject prompt, IRubyObject add_to_hist) throws IOException { Ruby runtime = context.getRuntime(); ConsoleHolder holder = getHolder(runtime); if (holder.readline == null) { initReadline(runtime, holder); // not overridden, let's go } IRubyObject line = runtime.getNil(); String v = null; while (true) { try { holder.readline.getTerminal().disableEcho(); v = holder.readline.readLine(prompt.toString()); break; } catch (IOException ioe) { if (RubyIO.restartSystemCall(ioe)) { // This is for JRUBY-2988, since after a suspend the terminal seems // to need to be reinitialized. Since we can't easily detect suspension, // initialize after every readline. Probably not fast, but this is for // interactive terminals anyway...so who cares? try { holder.readline.getTerminal().initializeTerminal(); } catch (Exception e) { } continue; } throw runtime.newIOErrorFromException(ioe); } finally { holder.readline.getTerminal().enableEcho(); } } if (null != v) { if (add_to_hist.isTrue()) { holder.readline.getHistory().addToHistory(v); } /* Explicitly use UTF-8 here. c.f. history.addToHistory using line.asUTF8() */ line = RubyString.newUnicodeString(recv.getRuntime(), v); } return line; }
@JRubyMethod public IRubyObject register(ThreadContext context, IRubyObject io, IRubyObject interests) { Ruby runtime = context.getRuntime(); Channel rawChannel = RubyIO.convertToIO(context, io).getChannel(); if (!this.selector.isOpen()) { throw context.getRuntime().newIOError("selector is closed"); } if (!(rawChannel instanceof SelectableChannel)) { throw runtime.newArgumentError("not a selectable IO object"); } SelectableChannel channel = (SelectableChannel) rawChannel; try { channel.configureBlocking(false); } catch (IOException ie) { throw runtime.newIOError(ie.getLocalizedMessage()); } int interestOps = Nio4r.symbolToInterestOps(runtime, channel, interests); SelectionKey key; key = this.cancelledKeys.remove(channel); if (key != null) { key.interestOps(interestOps); } else { try { key = channel.register(this.selector, interestOps); } catch (java.lang.IllegalArgumentException ia) { throw runtime.newArgumentError("mode not supported for this object: " + interests); } catch (java.nio.channels.ClosedChannelException cce) { throw context.runtime.newIOError(cce.getLocalizedMessage()); } } RubyClass monitorClass = runtime.getModule("NIO").getClass("Monitor"); Monitor monitor = (Monitor) monitorClass.newInstance(context, io, interests, this, null); monitor.setSelectionKey(key); return monitor; }
@JRubyMethod(name = "registered?") public IRubyObject isRegistered(ThreadContext context, IRubyObject io) { Ruby runtime = context.getRuntime(); Channel rawChannel = RubyIO.convertToIO(context, io).getChannel(); if (!(rawChannel instanceof SelectableChannel)) { throw runtime.newArgumentError("not a selectable IO object"); } SelectableChannel channel = (SelectableChannel) rawChannel; SelectionKey key = channel.keyFor(this.selector); if (key == null) return context.nil; if (((Monitor) key.attachment()).isClosed(context) == runtime.getTrue()) { return runtime.getFalse(); } else { return runtime.getTrue(); } }
@JRubyMethod public IRubyObject deregister(ThreadContext context, IRubyObject io) { Ruby runtime = context.getRuntime(); Channel rawChannel = RubyIO.convertToIO(context, io).getChannel(); if (!(rawChannel instanceof SelectableChannel)) { throw runtime.newArgumentError("not a selectable IO object"); } SelectableChannel channel = (SelectableChannel) rawChannel; SelectionKey key = channel.keyFor(this.selector); if (key == null) return context.nil; Monitor monitor = (Monitor) key.attachment(); monitor.close(context, runtime.getFalse()); cancelledKeys.put(channel, key); return monitor; }
@JRubyMethod(name = "print", rest = true) public IRubyObject print(ThreadContext context, IRubyObject[] args) { return RubyIO.print19(context, this, args); }
@JRubyMethod(name = "syswrite", required = 1) public IRubyObject syswrite(ThreadContext context, IRubyObject arg) { return RubyIO.write(context, this, arg); }