Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 570e9b486230
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 161b014d6fd7
Choose a head ref
  • 6 commits
  • 1 file changed
  • 1 contributor

Commits on Jan 26, 2016

  1. Copy the full SHA
    ea0882d View commit details

Commits on Jan 27, 2016

  1. Copy the full SHA
    cff8053 View commit details
  2. Copy the full SHA
    25cd2c9 View commit details
  3. Copy the full SHA
    4ba0fad View commit details
  4. Copy the full SHA
    9a34277 View commit details
  5. Copy the full SHA
    161b014 View commit details
Showing with 143 additions and 5 deletions.
  1. +143 −5 truffle/src/main/java/org/jruby/truffle/runtime/TruffleJavaPOSIX.java
148 changes: 143 additions & 5 deletions truffle/src/main/java/org/jruby/truffle/runtime/TruffleJavaPOSIX.java
Original file line number Diff line number Diff line change
@@ -15,19 +15,45 @@
import jnr.posix.LibC;
import jnr.posix.POSIX;

import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

public class TruffleJavaPOSIX extends POSIXDelegator implements POSIX {

private static class OpenFile {

private final RandomAccessFile randomAccessFile;
private final int flags;

private OpenFile(RandomAccessFile randomAccessFile, int flags) {
this.randomAccessFile = randomAccessFile;
this.flags = flags;
}

public RandomAccessFile getRandomAccessFile() {
return randomAccessFile;
}

public int getFlags() {
return flags;
}
}

private static final int STDIN = 0;
private static final int STDOUT = 1;
private static final int STDERR = 2;

private final RubyContext context;

private final AtomicInteger nextFileHandle = new AtomicInteger(3);
private final Map<Integer, OpenFile> fileHandles = new ConcurrentHashMap<>();

public TruffleJavaPOSIX(RubyContext context, POSIX delegateTo) {
super(delegateTo);
this.context = context;
@@ -43,6 +69,12 @@ public int fcntlInt(int fd, Fcntl fcntlConst, int arg) {
case STDERR:
return OpenFlags.O_WRONLY.intValue();
}

final OpenFile openFile = fileHandles.get(fd);

if (openFile != null) {
return openFile.getFlags();
}
}

return super.fcntlInt(fd, fcntlConst, arg);
@@ -59,15 +91,92 @@ public LibC libc() {
}

@Override
public int write(int fd, byte[] buf, int n) {
return pwrite(fd, buf, n, 0);
public int open(CharSequence path, int flags, int perm) {
if (perm != 0666) {
return super.open(path, flags, perm);
}

final int fileHandle = nextFileHandle.getAndIncrement();

if (fileHandle < 0) {
throw new UnsupportedOperationException();
}

final int basicMode = flags & 3;
final String mode;

if (basicMode == OpenFlags.O_RDONLY.intValue()) {
mode = "r";
} else if (basicMode == OpenFlags.O_WRONLY.intValue()) {
mode = "w";
} else if (basicMode == OpenFlags.O_RDWR.intValue()) {
mode = "rw";
} else {
return super.open(path, flags, perm);
}

final RandomAccessFile randomAccessFile;

try {
randomAccessFile = new RandomAccessFile(path.toString(), mode);
} catch (FileNotFoundException e) {
return -1;
}

fileHandles.put(fileHandle, new OpenFile(randomAccessFile, flags));

return fileHandle;
}

@Override
public int read(int fd, ByteBuffer buf, int n) {
return pread(fd, buf.array(), n, buf.arrayOffset());
}

@Override
public int read(int fd, byte[] buf, int n) {
return pread(fd, buf, n, 0);
}

@Override
public int pread(int fd, byte[] buf, int n, int offset) {
if (fd == STDIN) {
try {
System.in.read(buf, offset, n);
} catch (IOException e) {
return -1;
}

return n;
}

final OpenFile openFile = fileHandles.get(fd);

if (openFile != null) {
final int read;

try {
read = openFile.getRandomAccessFile().read(buf, offset, n);
} catch (IOException e) {
return -1;
}

return read;
}

return super.pwrite(fd, buf, n, offset);
}

@Override
public int write(int fd, ByteBuffer buf, int n) {
return pwrite(fd, buf.array(), n, buf.arrayOffset());
}

@Override
public int write(int fd, byte[] buf, int n) {
return pwrite(fd, buf, n, 0);
}

@Override
public int pwrite(int fd, byte[] buf, int n, int offset) {
if (fd == STDOUT || fd == STDERR) {
@@ -84,14 +193,33 @@ public int pwrite(int fd, byte[] buf, int n, int offset) {
throw new UnsupportedOperationException();
}

stream.write(buf, offset, buf.length);
stream.write(buf, offset, n);

return buf.length;
return n;
}

return super.pwrite(fd, buf, n, offset);
}

@Override
public int close(int fd) {
final OpenFile openFile = fileHandles.get(fd);

if (openFile != null) {
fileHandles.remove(fd);

try {
openFile.getRandomAccessFile().close();
} catch (IOException e) {
return -1;
}

return 0;
}

return super.close(fd);
}

@Override
public int getgid() {
return 0;
@@ -102,4 +230,14 @@ public FileStat allocateStat() {
return new TruffleJavaFileStat(this, null);
}

@Override
public String getenv(String envName) {
final String javaValue = System.getenv(envName);

if (javaValue != null) {
return javaValue;
}

return super.getenv(envName);
}
}