use of org.graalvm.word.SignedWord in project graal by oracle.
the class PosixJavaIOSubstitutions method available.
@Substitute
public int available() throws IOException {
int handle = PosixUtils.getFDHandle(fd);
SignedWord ret = WordFactory.zero();
boolean av = false;
stat stat = StackValue.get(SizeOf.get(stat.class));
if (fstat(handle, stat) >= 0) {
int mode = stat.st_mode();
if (Util_java_io_FileInputStream.isChr(mode) || Util_java_io_FileInputStream.isFifo(mode) || Util_java_io_FileInputStream.isSock(mode)) {
CIntPointer np = StackValue.get(SizeOf.get(CIntPointer.class));
if (ioctl(handle, FIONREAD(), np) >= 0) {
ret = WordFactory.signed(np.read());
av = true;
}
}
}
if (!av) {
SignedWord cur;
SignedWord end;
if ((cur = lseek(handle, WordFactory.zero(), SEEK_CUR())).equal(WordFactory.signed(-1))) {
av = false;
} else if ((end = lseek(handle, WordFactory.zero(), SEEK_END())).equal(WordFactory.signed(-1))) {
av = false;
} else if (lseek(handle, cur, SEEK_SET()).equal(WordFactory.signed(-1))) {
av = false;
} else {
ret = end.subtract(cur);
av = true;
}
}
if (av) {
long r = ret.rawValue();
if (r > Integer.MAX_VALUE) {
r = Integer.MAX_VALUE;
}
return (int) r;
}
throw new IOException(lastErrorString(""));
}
use of org.graalvm.word.SignedWord 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 org.graalvm.word.SignedWord 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 org.graalvm.word.SignedWord 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;
}
}
use of org.graalvm.word.SignedWord in project graal by oracle.
the class SubstrateMemoryAccessProviderImpl method readPrimitiveConstant.
@Override
public JavaConstant readPrimitiveConstant(JavaKind kind, Constant baseConstant, long displacement, int bits) {
SignedWord offset = WordFactory.signed(displacement);
long rawValue;
if (baseConstant instanceof SubstrateObjectConstant) {
Object baseObject = ((SubstrateObjectConstant) baseConstant).getObject();
assert baseObject != null : "SubstrateObjectConstant does not wrap null value";
switch(bits) {
case Byte.SIZE:
rawValue = BarrieredAccess.readByte(baseObject, offset);
break;
case Short.SIZE:
rawValue = BarrieredAccess.readShort(baseObject, offset);
break;
case Integer.SIZE:
rawValue = BarrieredAccess.readInt(baseObject, offset);
break;
case Long.SIZE:
rawValue = BarrieredAccess.readLong(baseObject, offset);
break;
default:
throw shouldNotReachHere();
}
} else if (baseConstant instanceof PrimitiveConstant) {
PrimitiveConstant prim = (PrimitiveConstant) baseConstant;
if (!prim.getJavaKind().isNumericInteger()) {
return null;
}
Pointer basePointer = WordFactory.unsigned(prim.asLong());
if (basePointer.equal(0)) {
return null;
}
switch(bits) {
case Byte.SIZE:
rawValue = basePointer.readByte(offset);
break;
case Short.SIZE:
rawValue = basePointer.readShort(offset);
break;
case Integer.SIZE:
rawValue = basePointer.readInt(offset);
break;
case Long.SIZE:
rawValue = basePointer.readLong(offset);
break;
default:
throw shouldNotReachHere();
}
} else {
return null;
}
return toConstant(kind, rawValue);
}
Aggregations