@RubyLevelMethod(name = "open") public static RubyValue open(RubyValue receiver, RubyArray args, RubyBlock block) { String filename = args.get(0).toStr(); RubyIO io; if (args.size() <= 1) { io = ObjectFactory.createFile(filename, "r"); } else if (args.get(1) instanceof RubyFixnum) { String mode = "r"; int i = args.get(1).toInt(); if ((i & RDWR) != 0) { mode = mode + "w"; } io = ObjectFactory.createFile(filename, mode); } else { RubyString mode = (RubyString) args.get(1); io = ObjectFactory.createFile(filename, mode.toString()); } if (null == block) { return io; } else { RubyValue v = block.invoke(receiver, io); io.close(); return v; } }
private void initializeModes(Object modeArgument) { try { if (modeArgument == null) { modes = new ModeFlags(RubyIO.getIOModesIntFromString(getRuntime(), "r+")); } else if (modeArgument instanceof Long) { modes = new ModeFlags(((Long) modeArgument).longValue()); } else { modes = new ModeFlags(RubyIO.getIOModesIntFromString(getRuntime(), (String) modeArgument)); } } catch (InvalidValueException e) { throw getRuntime().newErrnoEINVALError(); } setupModes(); }
@Override public IRubyObject set(IRubyObject value) { if (value == get()) { return value; } if (value instanceof RubyIO) { RubyIO io = (RubyIO) value; // HACK: in order to have stdout/err act like ttys and flush always, // we set anything assigned to stdout/stderr to sync io.getHandler().setSync(true); } if (!value.respondsTo("write")) { throw runtime.newTypeError( name() + " must have write method, " + value.getType().getName() + " given"); } return super.set(value); }
public boolean waitForIO(ThreadContext context, RubyIO io, int ops) { Channel channel = io.getChannel(); if (!(channel instanceof SelectableChannel)) { return true; } try { io.addBlockingThread(this); blockingIO = BlockingIO.newCondition(channel, ops); boolean ready = blockingIO.await(); // check for thread events, in case we've been woken up to die pollThreadEvents(); return ready; } catch (IOException ioe) { throw context.runtime.newRuntimeError("Error with selector: " + ioe); } catch (InterruptedException ex) { // FIXME: not correct exception throw context.runtime.newRuntimeError("Interrupted"); } finally { blockingIO = null; io.removeBlockingThread(this); } }
public boolean select(Channel channel, RubyIO io, int ops, long timeout) { if (channel instanceof SelectableChannel) { SelectableChannel selectable = (SelectableChannel) channel; synchronized (selectable.blockingLock()) { boolean oldBlocking = selectable.isBlocking(); SelectionKey key = null; try { selectable.configureBlocking(false); if (io != null) io.addBlockingThread(this); currentSelector = getRuntime().getSelectorPool().get(selectable.provider()); key = selectable.register(currentSelector, ops); beforeBlockingCall(); int result; if (timeout < 0) { result = currentSelector.select(); } else if (timeout == 0) { result = currentSelector.selectNow(); } else { result = currentSelector.select(timeout); } // check for thread events, in case we've been woken up to die pollThreadEvents(); if (result == 1) { Set<SelectionKey> keySet = currentSelector.selectedKeys(); if (keySet.iterator().next() == key) { return true; } } return false; } catch (IOException ioe) { throw getRuntime().newIOErrorFromException(ioe); } finally { // Note: I don't like ignoring these exceptions, but it's // unclear how likely they are to happen or what damage we // might do by ignoring them. Note that the pieces are separate // so that we can ensure one failing does not affect the others // running. // clean up the key in the selector try { if (key != null) key.cancel(); if (currentSelector != null) currentSelector.selectNow(); } catch (Exception e) { // ignore } // shut down and null out the selector try { if (currentSelector != null) { getRuntime().getSelectorPool().put(currentSelector); } } catch (Exception e) { // ignore } finally { currentSelector = null; } // remove this thread as a blocker against the given IO if (io != null) io.removeBlockingThread(this); // go back to previous blocking state on the selectable try { selectable.configureBlocking(oldBlocking); } catch (Exception e) { // ignore } // clear thread state from blocking call afterBlockingCall(); } } } else { // can't select, just have to do a blocking call return true; } }
public boolean select(RubyIO io, int ops, long timeout) { return select(io.getChannel(), io, ops, timeout); }
public boolean select(RubyIO io, int ops) { return select(io.getChannel(), io, ops); }
public static void createGlobals(ThreadContext context, Ruby runtime) { GlobalVariables globals = runtime.getGlobalVariables(); runtime.defineGlobalConstant("TOPLEVEL_BINDING", runtime.newBinding()); runtime.defineGlobalConstant("TRUE", runtime.getTrue()); runtime.defineGlobalConstant("FALSE", runtime.getFalse()); runtime.defineGlobalConstant("NIL", runtime.getNil()); initARGV(runtime); IAccessor d = new ValueAccessor(runtime.newString(runtime.getInstanceConfig().displayedFileName())); globals.define("$PROGRAM_NAME", d, GLOBAL); globals.define("$0", d, GLOBAL); // Version information: IRubyObject version = null; IRubyObject patchlevel = null; IRubyObject release = runtime.newString(Constants.COMPILE_DATE).freeze(context); IRubyObject platform = runtime.newString(Constants.PLATFORM).freeze(context); IRubyObject engine = runtime.newString(Constants.ENGINE).freeze(context); version = runtime.newString(Constants.RUBY_VERSION).freeze(context); patchlevel = runtime.newFixnum(Constants.RUBY_PATCHLEVEL); runtime.defineGlobalConstant("RUBY_VERSION", version); runtime.defineGlobalConstant("RUBY_PATCHLEVEL", patchlevel); runtime.defineGlobalConstant("RUBY_RELEASE_DATE", release); runtime.defineGlobalConstant("RUBY_PLATFORM", platform); IRubyObject description = runtime.newString(OutputStrings.getVersionString()).freeze(context); runtime.defineGlobalConstant("RUBY_DESCRIPTION", description); IRubyObject copyright = runtime.newString(OutputStrings.getCopyrightString()).freeze(context); runtime.defineGlobalConstant("RUBY_COPYRIGHT", copyright); runtime.defineGlobalConstant("RELEASE_DATE", release); runtime.defineGlobalConstant("PLATFORM", platform); IRubyObject jrubyVersion = runtime.newString(Constants.VERSION).freeze(context); IRubyObject jrubyRevision = runtime.newString(Constants.REVISION).freeze(context); runtime.defineGlobalConstant("JRUBY_VERSION", jrubyVersion); runtime.defineGlobalConstant("JRUBY_REVISION", jrubyRevision); // needs to be a fixnum, but our revision is a sha1 hash from git runtime.defineGlobalConstant("RUBY_REVISION", runtime.newFixnum(Constants.RUBY_REVISION)); runtime.defineGlobalConstant("RUBY_ENGINE", engine); runtime.defineGlobalConstant("RUBY_ENGINE_VERSION", jrubyVersion); RubyInstanceConfig.Verbosity verbosity = runtime.getInstanceConfig().getVerbosity(); runtime.defineVariable(new WarningGlobalVariable(runtime, "$-W", verbosity), GLOBAL); final GlobalVariable kcodeGV; kcodeGV = new NonEffectiveGlobalVariable(runtime, "$KCODE", runtime.getNil()); runtime.defineVariable(kcodeGV, GLOBAL); runtime.defineVariable(new GlobalVariable.Copy(runtime, "$-K", kcodeGV), GLOBAL); IRubyObject defaultRS = runtime.newString(runtime.getInstanceConfig().getRecordSeparator()).freeze(context); GlobalVariable rs = new StringGlobalVariable(runtime, "$/", defaultRS); runtime.defineVariable(rs, GLOBAL); runtime.setRecordSeparatorVar(rs); globals.setDefaultSeparator(defaultRS); runtime.defineVariable(new StringGlobalVariable(runtime, "$\\", runtime.getNil()), GLOBAL); runtime.defineVariable(new StringGlobalVariable(runtime, "$,", runtime.getNil()), GLOBAL); runtime.defineVariable(new LineNumberGlobalVariable(runtime, "$."), GLOBAL); runtime.defineVariable(new LastlineGlobalVariable(runtime, "$_"), FRAME); runtime.defineVariable(new LastExitStatusVariable(runtime, "$?"), THREAD); runtime.defineVariable(new ErrorInfoGlobalVariable(runtime, "$!", runtime.getNil()), THREAD); runtime.defineVariable( new NonEffectiveGlobalVariable(runtime, "$=", runtime.getFalse()), GLOBAL); if (runtime.getInstanceConfig().getInputFieldSeparator() == null) { runtime.defineVariable(new GlobalVariable(runtime, "$;", runtime.getNil()), GLOBAL); } else { runtime.defineVariable( new GlobalVariable( runtime, "$;", RubyRegexp.newRegexp( runtime, runtime.getInstanceConfig().getInputFieldSeparator(), new RegexpOptions())), GLOBAL); } RubyInstanceConfig.Verbosity verbose = runtime.getInstanceConfig().getVerbosity(); IRubyObject verboseValue = null; if (verbose == RubyInstanceConfig.Verbosity.NIL) { verboseValue = runtime.getNil(); } else if (verbose == RubyInstanceConfig.Verbosity.TRUE) { verboseValue = runtime.getTrue(); } else { verboseValue = runtime.getFalse(); } runtime.defineVariable(new VerboseGlobalVariable(runtime, "$VERBOSE", verboseValue), GLOBAL); runtime.defineVariable(new VerboseGlobalVariable(runtime, "$-v", verboseValue), GLOBAL); runtime.defineVariable(new VerboseGlobalVariable(runtime, "$-w", verboseValue), GLOBAL); IRubyObject debug = runtime.newBoolean(runtime.getInstanceConfig().isDebug()); runtime.defineVariable(new DebugGlobalVariable(runtime, "$DEBUG", debug), GLOBAL); runtime.defineVariable(new DebugGlobalVariable(runtime, "$-d", debug), GLOBAL); runtime.defineVariable(new SafeGlobalVariable(runtime, "$SAFE"), THREAD); runtime.defineVariable(new BacktraceGlobalVariable(runtime, "$@"), THREAD); IRubyObject stdin = RubyIO.prepStdio( runtime, runtime.getIn(), prepareStdioChannel(runtime, STDIO.IN, runtime.getIn()), OpenFile.READABLE, runtime.getIO(), "<STDIN>"); IRubyObject stdout = RubyIO.prepStdio( runtime, runtime.getOut(), prepareStdioChannel(runtime, STDIO.OUT, runtime.getOut()), OpenFile.WRITABLE, runtime.getIO(), "<STDOUT>"); IRubyObject stderr = RubyIO.prepStdio( runtime, runtime.getErr(), prepareStdioChannel(runtime, STDIO.ERR, runtime.getErr()), OpenFile.WRITABLE | OpenFile.SYNC, runtime.getIO(), "<STDERR>"); runtime.defineVariable(new InputGlobalVariable(runtime, "$stdin", stdin), GLOBAL); runtime.defineVariable(new OutputGlobalVariable(runtime, "$stdout", stdout), GLOBAL); globals.alias("$>", "$stdout"); runtime.defineVariable(new OutputGlobalVariable(runtime, "$stderr", stderr), GLOBAL); runtime.defineGlobalConstant("STDIN", stdin); runtime.defineGlobalConstant("STDOUT", stdout); runtime.defineGlobalConstant("STDERR", stderr); runtime.defineVariable(new LoadedFeatures(runtime, "$\""), GLOBAL); runtime.defineVariable(new LoadedFeatures(runtime, "$LOADED_FEATURES"), GLOBAL); runtime.defineVariable(new LoadPath(runtime, "$:"), GLOBAL); runtime.defineVariable(new LoadPath(runtime, "$-I"), GLOBAL); runtime.defineVariable(new LoadPath(runtime, "$LOAD_PATH"), GLOBAL); runtime.defineVariable(new MatchMatchGlobalVariable(runtime, "$&"), FRAME); runtime.defineVariable(new PreMatchGlobalVariable(runtime, "$`"), FRAME); runtime.defineVariable(new PostMatchGlobalVariable(runtime, "$'"), FRAME); runtime.defineVariable(new LastMatchGlobalVariable(runtime, "$+"), FRAME); runtime.defineVariable(new BackRefGlobalVariable(runtime, "$~"), FRAME); // On platforms without a c-library accessable through JNA, getpid will return hashCode // as $$ used to. Using $$ to kill processes could take down many runtimes, but by basing // $$ on getpid() where available, we have the same semantics as MRI. globals.defineReadonly("$$", new PidAccessor(runtime), GLOBAL); // after defn of $stderr as the call may produce warnings defineGlobalEnvConstants(runtime); // Fixme: Do we need the check or does Main.java not call this...they should consolidate if (globals.get("$*").isNil()) { globals.defineReadonly("$*", new ValueAccessor(runtime.newArray()), GLOBAL); } globals.defineReadonly( "$-p", new ValueAccessor(runtime.newBoolean(runtime.getInstanceConfig().isAssumePrinting())), GLOBAL); globals.defineReadonly( "$-a", new ValueAccessor(runtime.newBoolean(runtime.getInstanceConfig().isSplit())), GLOBAL); globals.defineReadonly( "$-l", new ValueAccessor(runtime.newBoolean(runtime.getInstanceConfig().isProcessLineEnds())), GLOBAL); // ARGF, $< object RubyArgsFile.initArgsFile(runtime); globals.alias("$-0", "$/"); // Define aliases originally in the "English.rb" stdlib globals.alias("$ERROR_INFO", "$!"); globals.alias("$ERROR_POSITION", "$@"); globals.alias("$FS", "$;"); globals.alias("$FIELD_SEPARATOR", "$;"); globals.alias("$OFS", "$,"); globals.alias("$OUTPUT_FIELD_SEPARATOR", "$,"); globals.alias("$RS", "$/"); globals.alias("$INPUT_RECORD_SEPARATOR", "$/"); globals.alias("$ORS", "$\\"); globals.alias("$OUTPUT_RECORD_SEPARATOR", "$\\"); globals.alias("$NR", "$."); globals.alias("$INPUT_LINE_NUMBER", "$."); globals.alias("$LAST_READ_LINE", "$_"); globals.alias("$DEFAULT_OUTPUT", "$>"); globals.alias("$DEFAULT_INPUT", "$<"); globals.alias("$PID", "$$"); globals.alias("$PROCESS_ID", "$$"); globals.alias("$CHILD_STATUS", "$?"); globals.alias("$LAST_MATCH_INFO", "$~"); globals.alias("$IGNORECASE", "$="); globals.alias("$ARGV", "$*"); globals.alias("$MATCH", "$&"); globals.alias("$PREMATCH", "$`"); globals.alias("$POSTMATCH", "$'"); globals.alias("$LAST_PAREN_MATCH", "$+"); }