use of com.oracle.svm.core.annotate.Substitute in project graal by oracle.
the class PosixJavaIOSubstitutions method setPermission.
@Substitute
public boolean setPermission(File f, int access, boolean enable, boolean owneronly) {
int amode = 0;
if (access == Target_java_io_FileSystem.ACCESS_READ) {
amode = owneronly ? S_IRUSR() : S_IRUSR() | S_IRGRP() | S_IROTH();
} else if (access == Target_java_io_FileSystem.ACCESS_WRITE) {
amode = owneronly ? S_IWUSR() : S_IWUSR() | S_IWGRP() | S_IWOTH();
} else if (access == Target_java_io_FileSystem.ACCESS_EXECUTE) {
amode = owneronly ? S_IXUSR() : S_IXUSR() | S_IXGRP() | S_IXOTH();
} else {
throw VMError.shouldNotReachHere("illegal access mode");
}
stat stat = StackValue.get(SizeOf.get(stat.class));
try (CCharPointerHolder pathPin = CTypeConversion.toCString(f.getPath())) {
CCharPointer pathPtr = pathPin.get();
if (stat(pathPtr, stat) == 0) {
int newMode;
if (enable) {
newMode = stat.st_mode() | amode;
} else {
newMode = stat.st_mode() & ~amode;
}
if (chmod(pathPtr, newMode) >= 0) {
return true;
}
}
}
return false;
}
use of com.oracle.svm.core.annotate.Substitute in project graal by oracle.
the class PosixJavaIOSubstitutions method list.
@Substitute
public String[] list(File f) {
DIR dir;
try (CCharPointerHolder pathPin = CTypeConversion.toCString(f.getPath())) {
CCharPointer pathPtr = pathPin.get();
dir = opendir(pathPtr);
}
if (dir.isNull()) {
return null;
}
List<String> entries = new ArrayList<>();
dirent dirent = StackValue.get(SizeOf.get(dirent.class) + PATH_MAX() + 1);
direntPointer resultDirent = StackValue.get(SizeOf.get(direntPointer.class));
while (readdir_r(dir, dirent, resultDirent) == 0 && !resultDirent.read().isNull()) {
String name = CTypeConversion.toJavaString(dirent.d_name());
if (name.equals(".") || name.equals("..")) {
continue;
}
entries.add(name);
}
closedir(dir);
return entries.toArray(new String[entries.size()]);
}
use of com.oracle.svm.core.annotate.Substitute in project graal by oracle.
the class PosixJavaIOSubstitutions method length.
@Substitute
public long length() throws IOException {
SignedWord cur = WordFactory.zero();
SignedWord end = WordFactory.zero();
int handle = PosixUtils.getFDHandle(fd);
if ((cur = lseek(handle, WordFactory.zero(), SEEK_CUR())).equal(WordFactory.signed(-1))) {
throw new IOException(lastErrorString("Seek failed"));
} else if ((end = lseek(handle, WordFactory.zero(), SEEK_END())).equal(WordFactory.signed(-1))) {
throw new IOException(lastErrorString("Seek failed"));
} else if (lseek(handle, cur, SEEK_SET()).equal(WordFactory.signed(-1))) {
throw new IOException(lastErrorString("Seek failed"));
}
return end.rawValue();
}
use of com.oracle.svm.core.annotate.Substitute in project graal by oracle.
the class PosixJavaIOSubstitutions method setLength.
@Substitute
public void setLength(long newLength) throws IOException {
SignedWord cur;
int handle = PosixUtils.getFDHandle(fd);
if ((cur = lseek(handle, WordFactory.zero(), SEEK_CUR())).equal(WordFactory.signed(-1))) {
throw new IOException(lastErrorString("setLength failed"));
}
if (ftruncate(handle, newLength) == -1) {
throw new IOException(lastErrorString("setLength failed"));
}
if (cur.greaterThan(WordFactory.signed(newLength))) {
if (lseek(handle, WordFactory.zero(), SEEK_END()).equal(WordFactory.signed(-1))) {
throw new IOException(lastErrorString("setLength failed"));
}
} else {
if (lseek(handle, cur, SEEK_SET()).equal(WordFactory.signed(-1))) {
throw new IOException(lastErrorString("setLength failed"));
}
}
}
use of com.oracle.svm.core.annotate.Substitute in project graal by oracle.
the class PosixJavaLangSubstitutions method forkAndExec.
/*
* NOTE: This implementation uses simple fork() and exec() calls. However, OpenJDK uses
* posix_spawn() on some platforms, specifically on Solaris to avoid swap exhaustion when memory
* is reserved conservatively for the fork'ed process. That implementation is more complex and
* requires a helper tool to cleanly launch the actual target executable.
*/
@Substitute
@SuppressWarnings({ "unused", "static-method" })
int forkAndExec(int mode, byte[] helperpath, byte[] file, byte[] argBlock, int argCount, byte[] envBlock, int envCount, byte[] dir, int[] fds, boolean redirectErrorStream) throws IOException {
int[] pipes = new int[8];
Arrays.fill(pipes, -1);
try (//
PinnedObject filePin = PinnedObject.create(file);
PinnedObject dirPin = PinnedObject.create(dir);
PinnedObject argBlockPin = PinnedObject.create(argBlock);
PinnedObject argvPin = PinnedObject.create(new CCharPointerPointer[argCount + 2]);
PinnedObject envBlockPin = PinnedObject.create(envBlock);
PinnedObject envpPin = PinnedObject.create(new CCharPointerPointer[envCount + 1]);
//
PinnedObject pipesPin = PinnedObject.create(pipes)) {
CCharPointerPointer argv = argvPin.addressOfArrayElement(0);
argv.write(0, filePin.addressOfArrayElement(0));
Java_lang_UNIXProcess_Supplement.gatherCStringPointers(argBlockPin.addressOfArrayElement(0), argBlock.length, argv.addressOf(1), argCount + 1);
CCharPointerPointer envp = WordFactory.nullPointer();
if (envBlock != null) {
envp = envpPin.addressOfArrayElement(0);
Java_lang_UNIXProcess_Supplement.gatherCStringPointers(envBlockPin.addressOfArrayElement(0), envBlock.length, envp.addressOf(0), envCount + 1);
}
CIntPointer[] stdioPipes = new CIntPointer[3];
for (int i = 0; i <= 2; i++) {
if (fds[i] == -1) {
stdioPipes[i] = pipesPin.addressOfArrayElement(2 * i);
if (Unistd.pipe(stdioPipes[i]) < 0) {
throw new IOException("pipe() failed");
}
}
}
CIntPointer failPipe = pipesPin.addressOfArrayElement(2 * stdioPipes.length);
if (Unistd.pipe(failPipe) < 0) {
throw new IOException("pipe() failed");
}
int[] childStdioFds = new int[3];
childStdioFds[0] = (fds[0] != -1) ? fds[0] : stdioPipes[0].read(0);
childStdioFds[1] = (fds[1] != -1) ? fds[1] : stdioPipes[1].read(1);
childStdioFds[2] = (fds[2] != -1) ? fds[2] : stdioPipes[2].read(1);
int childFailFd = failPipe.read(1);
CCharPointer filep = filePin.addressOfArrayElement(0);
CCharPointer dirp = (dir != null) ? dirPin.addressOfArrayElement(0) : WordFactory.nullPointer();
int childPid = Java_lang_UNIXProcess_Supplement.doForkAndExec(filep, dirp, argv, envp, childStdioFds, childFailFd);
if (childPid < 0) {
throw new IOException("fork() failed");
}
// If we are here, we are the parent.
// store fds of our pipe ends for caller, close unused fds (those of the child)
fds[0] = fds[1] = fds[2] = -1;
if (stdioPipes[0].isNonNull()) {
fds[0] = stdioPipes[0].read(1);
Unistd.close(stdioPipes[0].read(0));
}
if (stdioPipes[1].isNonNull()) {
fds[1] = stdioPipes[1].read(0);
Unistd.close(stdioPipes[1].read(1));
}
if (stdioPipes[2].isNonNull()) {
fds[2] = stdioPipes[2].read(0);
Unistd.close(stdioPipes[2].read(1));
}
Unistd.close(failPipe.read(1));
// read status from child
final int intSize = SizeOf.get(CIntPointer.class);
CIntPointer pErrno = StackValue.get(intSize);
SignedWord failBytes = Java_lang_UNIXProcess_Supplement.readEntirely(failPipe.read(0), pErrno, WordFactory.unsigned(intSize));
Unistd.close(failPipe.read(0));
if (failBytes.equal(0)) {
// success: pipe closed during exec()
return childPid;
} else if (failBytes.equal(SizeOf.get(CIntPointer.class))) {
int errbuflen = 256;
try (PinnedObject errbuf = PinnedObject.create(new byte[errbuflen])) {
CCharPointer detailCstr = Errno.strerror_r(pErrno.read(), errbuf.addressOfArrayElement(0), WordFactory.unsigned(errbuflen));
String detail = CTypeConversion.toJavaString(detailCstr);
throw new IOException("error=" + pErrno.read() + ", " + detail);
}
} else {
throw new IOException("unexpected data from child");
}
} catch (IOException e) {
// NOTE: not a finally statement because when successful, some pipes need to stay open
for (int fd : pipes) {
if (fd != -1) {
Unistd.close(fd);
}
}
throw e;
}
}
Aggregations