public ChannelDescriptor reopen(Channel channel, ModeFlags modes) { return new ChannelDescriptor(channel, internalFileno, modes, fileDescriptor); }
/** * Write the bytes in the specified byte list to the associated channel. * * @param buffer the byte list containing the bytes to be written * @return the number of bytes actually written * @throws java.io.IOException if there is an exception during IO * @throws org.jruby.util.io.BadDescriptorException if the associated * channel is already closed */ public int write(ByteBuffer buffer) throws IOException, BadDescriptorException { checkOpen(); return internalWrite(buffer); }
/** * Mimics the POSIX dup2(2) function, returning a new descriptor that references * the same open channel but with a specified fileno. This differs from the fileno * version by making the target descriptor into a new reference to the current * descriptor's channel, closing what it originally pointed to and preserving * its original fileno. * * @param other the descriptor to dup this one into */ public void dup2Into(ChannelDescriptor other) throws BadDescriptorException, IOException { synchronized (refCounter) { refCounter.incrementAndGet(); if (DEBUG) LOG.info("Reopen fileno {}, refs now: {}", internalFileno, refCounter.get()); other.close(); other.channel = channel; other.originalModes = originalModes; other.fileDescriptor = fileDescriptor; other.refCounter = refCounter; other.canBeSeekable = canBeSeekable; other.readableChannel = readableChannel; other.writableChannel = writableChannel; other.seekableChannel = seekableChannel; } }
/** * Construct a new ChannelDescriptor with the given channel, file number, mode flags, * and file descriptor object. The channel will be kept open until all ChannelDescriptor * references to it have been closed. * * @param channel The channel for the new descriptor * @param originalModes The mode flags for the new descriptor */ public ChannelDescriptor(Channel channel, ModeFlags originalModes) { this(channel, getNewFileno(), originalModes, getDescriptorFromChannel(channel), new AtomicInteger(1), true, false); }
/** * Mimics the POSIX dup(2) function, returning a new descriptor that references * the same open channel. * * @return A duplicate ChannelDescriptor based on this one */ public ChannelDescriptor dup() { synchronized (refCounter) { refCounter.incrementAndGet(); int newFileno = getNewFileno(); if (DEBUG) LOG.info("Reopen fileno {}, refs now: {}", newFileno, refCounter.get()); return new ChannelDescriptor(channel, newFileno, originalModes, fileDescriptor, refCounter, canBeSeekable, isInAppendMode); } }
private void resetForWrite() throws IOException { if (descriptor.isSeekable()) { FileChannel fileChannel = (FileChannel)descriptor.getChannel(); if (buffer.hasRemaining()) { // we have read ahead, and need to back up fileChannel.position(fileChannel.position() - buffer.remaining()); } } // FIXME: Clearing read buffer here...is this appropriate? buffer.clear(); reading = false; }
private ChannelStream(Ruby runtime, ChannelDescriptor descriptor, boolean autoclose) { this.runtime = runtime; this.descriptor = descriptor; this.modes = descriptor.getOriginalModes(); buffer = ByteBuffer.allocate(BUFSIZE); buffer.flip(); this.reading = true; this.autoclose = autoclose; runtime.addInternalFinalizer(this); }
/** * Construct a new ChannelDescriptor with the given channel, file number, mode flags, * and file descriptor object. The channel will be kept open until all ChannelDescriptor * references to it have been closed. * * @param channel The channel for the new descriptor * @param originalModes The mode flags for the new descriptor * @param fileDescriptor The java.io.FileDescriptor object for the new descriptor */ public ChannelDescriptor(Channel channel, ModeFlags originalModes, FileDescriptor fileDescriptor) { this(channel, getNewFileno(), originalModes, fileDescriptor, new AtomicInteger(1), true, false); }
/** * Close this descriptor. If in closing the last ChannelDescriptor reference * to the associate channel is closed, the channel itself will be closed. * * @throws org.jruby.util.io.BadDescriptorException if the associated * channel is already closed * @throws java.io.IOException if there is an exception during IO */ public void close() throws BadDescriptorException, IOException { // tidy up finish(true); }
public static Stream fdopen(Ruby runtime, ChannelDescriptor descriptor, ModeFlags modes, boolean autoclose) throws InvalidValueException { // check these modes before constructing, so we don't finalize the partially-initialized stream descriptor.checkNewModes(modes); return maybeWrapWithLineEndingWrapper(new ChannelStream(runtime, descriptor, modes, autoclose), modes); }
@Override public final int refillBuffer() throws IOException { buffer.clear(); int n = ((ReadableByteChannel) descriptor.getChannel()).read(buffer); buffer.flip(); return n; }
private static void registerDescriptor(ChannelDescriptor descriptor) { filenoDescriptorMap.put(descriptor.getFileno(), descriptor); }
case IN: descriptor = new ChannelDescriptor(runtime.getIn(), newModeFlags(runtime, ModeFlags.RDONLY), FileDescriptor.in); runtime.putFilenoMap(0, descriptor.getFileno()); mainStream = ChannelStream.open(runtime, descriptor); openFile.setMainStream(mainStream); break; case OUT: descriptor = new ChannelDescriptor(Channels.newChannel(runtime.getOut()), newModeFlags(runtime, ModeFlags.WRONLY | ModeFlags.APPEND), FileDescriptor.out); runtime.putFilenoMap(1, descriptor.getFileno()); mainStream = ChannelStream.open(runtime, descriptor); openFile.setMainStream(mainStream); break; case ERR: descriptor = new ChannelDescriptor(Channels.newChannel(runtime.getErr()), newModeFlags(runtime, ModeFlags.WRONLY | ModeFlags.APPEND), FileDescriptor.err); runtime.putFilenoMap(2, descriptor.getFileno()); mainStream = ChannelStream.open(runtime, descriptor); openFile.setMainStream(mainStream);
public InputStream newInputStream() { InputStream in = descriptor.getBaseInputStream(); return in == null ? new InputStreamAdapter(this) : in; }
public synchronized int read() throws IOException, BadDescriptorException { try { descriptor.checkOpen(); if (hasUngotChars()) { int c = ungotChars.get(0); ungotChars.delete(0,1); return c; } return bufferedRead(); } catch (EOFException e) { eof = true; return -1; } }
private void resetForWrite() throws IOException { if (descriptor.isSeekable()) { FileChannel fileChannel = (FileChannel)descriptor.getChannel(); if (buffer.hasRemaining()) { // we have read ahead, and need to back up fileChannel.position(fileChannel.position() - buffer.remaining()); } } // FIXME: Clearing read buffer here...is this appropriate? buffer.clear(); reading = false; }
private ChannelStream(Ruby runtime, ChannelDescriptor descriptor, boolean autoclose) { this.runtime = runtime; this.descriptor = descriptor; this.modes = descriptor.getOriginalModes(); buffer = ByteBuffer.allocate(BUFSIZE); buffer.flip(); this.reading = true; this.autoclose = autoclose; runtime.addInternalFinalizer(this); }