예제 #1
0
  /**
   * Flush the write buffer to the channel (if needed)
   *
   * @throws IOException
   */
  private boolean flushWrite(final boolean block) throws IOException, BadDescriptorException {
    if (reading || !modes.isWritable() || buffer.position() == 0) return false; // Don't bother
    int len = buffer.position();
    int nWritten = 0;
    buffer.flip();

    // For Sockets, only write as much as will fit.
    if (descriptor.getChannel() instanceof SelectableChannel) {
      SelectableChannel selectableChannel = (SelectableChannel) descriptor.getChannel();
      synchronized (selectableChannel.blockingLock()) {
        boolean oldBlocking = selectableChannel.isBlocking();
        try {
          if (oldBlocking != block) {
            selectableChannel.configureBlocking(block);
          }
          nWritten = descriptor.write(buffer);
        } finally {
          if (oldBlocking != block) {
            selectableChannel.configureBlocking(oldBlocking);
          }
        }
      }
    } else {
      nWritten = descriptor.write(buffer);
    }
    if (nWritten != len) {
      buffer.compact();
      return false;
    }
    buffer.clear();
    return true;
  }
예제 #2
0
  /**
   * Flush the write buffer to the channel (if needed)
   *
   * @throws IOException
   */
  private void flushWrite() throws IOException, BadDescriptorException {
    if (reading || !modes.isWritable() || buffer.position() == 0) return; // Don't bother

    int len = buffer.position();
    buffer.flip();
    int n = descriptor.write(buffer);

    if (n != len) {
      // TODO: check the return value here
    }
    buffer.clear();
  }
예제 #3
0
  public synchronized void freopen(Ruby runtime, String path, ModeFlags modes)
      throws DirectoryAsFileException, IOException, InvalidValueException, PipeException,
          BadDescriptorException {
    // flush first
    flushWrite();

    // reset buffer
    buffer.clear();
    if (reading) {
      buffer.flip();
    }

    this.modes = modes;

    if (descriptor.isOpen()) {
      descriptor.close();
    }

    if (path.equals("/dev/null") || path.equalsIgnoreCase("nul:") || path.equalsIgnoreCase("nul")) {
      descriptor = descriptor.reopen(new NullChannel(), modes);
    } else {
      String cwd = runtime.getCurrentDirectory();
      JRubyFile theFile = JRubyFile.create(cwd, path);

      if (theFile.isDirectory() && modes.isWritable()) throw new DirectoryAsFileException();

      if (modes.isCreate()) {
        if (theFile.exists() && modes.isExclusive()) {
          throw runtime.newErrnoEEXISTError("File exists - " + path);
        }
        theFile.createNewFile();
      } else {
        if (!theFile.exists()) {
          throw runtime.newErrnoENOENTError("file not found - " + path);
        }
      }

      // We always open this rw since we can only open it r or rw.
      RandomAccessFile file = new RandomAccessFile(theFile, modes.toJavaModeString());

      if (modes.isTruncate()) file.setLength(0L);

      descriptor = descriptor.reopen(file, modes);

      try {
        if (modes.isAppendable()) lseek(0, SEEK_END);
      } catch (PipeException pe) {
        // ignore, it's a pipe or fifo
      }
    }
  }
예제 #4
0
 public void checkWritable() throws IOException {
   if (!modes.isWritable()) throw new IOException("not opened for writing");
 }