use of org.graalvm.nativeimage.PinnedObject in project graal by oracle.
the class Target_com_sun_security_auth_module_UnixSystem method getUnixInfo.
@Substitute
void getUnixInfo() {
int realUid = Unistd.getuid();
Word pwsize = WordFactory.signed(Unistd.sysconf(Unistd._SC_GETPW_R_SIZE_MAX()));
if (pwsize.lessThan(0)) {
// indicates no definitive bound: try different sizes
pwsize = WordFactory.signed(1024);
}
CCharPointer pwbuf = LibC.malloc(pwsize);
try {
passwd pwent = StackValue.get(SizeOf.get(passwd.class));
passwdPointer p = StackValue.get(SizeOf.get(passwdPointer.class));
int result;
do {
if (pwbuf.isNull()) {
throw new OutOfMemoryError("Native heap");
}
p.write(WordFactory.nullPointer());
result = Pwd.getpwuid_r(realUid, pwent, pwbuf, pwsize, p);
if (result == Errno.ERANGE()) {
pwsize = pwsize.add(pwsize);
pwbuf = LibC.realloc(pwbuf, pwsize);
} else if (result < 0 && result != Errno.EINTR()) {
throw new RuntimeException("getpwuid_r error: " + Errno.errno());
}
} while (result != 0);
this.uid = pwent.pw_uid();
this.gid = pwent.pw_gid();
this.username = CTypeConversion.toJavaString(pwent.pw_name());
} finally {
LibC.free(pwbuf);
}
int ngroups = Unistd.getgroups(0, WordFactory.nullPointer());
int[] groupIds = new int[ngroups];
try (PinnedObject pinnedGroupIds = PinnedObject.create(groupIds)) {
ngroups = Unistd.getgroups(groupIds.length, pinnedGroupIds.addressOfArrayElement(0));
}
this.groups = new long[ngroups];
for (int i = 0; i < this.groups.length; i++) {
this.groups[i] = groupIds[i];
}
}
use of org.graalvm.nativeimage.PinnedObject 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.nativeimage.PinnedObject in project graal by oracle.
the class PosixJavaLangSubstitutions method doForkAndExec.
@SuppressWarnings("try")
static int doForkAndExec(CCharPointer file, CCharPointer dir, CCharPointerPointer argv, CCharPointerPointer envp, int[] stdioFds, int failFd) {
final int buflen = SizeOf.get(dirent.class) + Limits.PATH_MAX() + 1;
final boolean haveProcFs = Platform.includedIn(Platform.LINUX.class);
try (// only this thread will exist in the child and garbage collection is not possible.
PinnedObject bufferPin = PinnedObject.create(new byte[buflen]);
CCharPointerHolder procFdsPath = haveProcFs ? CTypeConversion.toCString("/proc/self/fd/") : null;
CCharPointerHolder searchPaths = CTypeConversion.toCString(System.getenv("PATH"));
CCharPointerHolder searchPathSeparator = CTypeConversion.toCString(":");
NoAllocationVerifier v = NoAllocationVerifier.factory("fragile state after fork()")) {
CCharPointer procFdsPathPtr = (procFdsPath != null) ? procFdsPath.get() : WordFactory.nullPointer();
return uninterruptibleForkAndExec(file, dir, argv, envp, stdioFds, failFd, bufferPin.addressOfArrayElement(0), buflen, procFdsPathPtr, searchPaths.get(), searchPathSeparator.get());
}
}
use of org.graalvm.nativeimage.PinnedObject in project graal by oracle.
the class JavaUtilZipSubstitutions method inflateBytes.
// Inflater.c-Java_java_util_zip_Inflater_inflateBytes(JNIEnv *env, jobject this, jlong addr,
@SuppressWarnings("hiding")
@Substitute
private int inflateBytes(long addr, byte[] b, int off, int len) throws DataFormatException {
z_stream strm = WordFactory.pointer(addr);
try (PinnedObject pinned_in_buf = PinnedObject.create(this.buf);
PinnedObject pinned_out_buf = PinnedObject.create(b)) {
strm.set_next_in(pinned_in_buf.addressOfArrayElement(this.off));
strm.set_next_out(pinned_out_buf.addressOfArrayElement(off));
strm.set_avail_in(this.len);
strm.set_avail_out(len);
int ret = ZLib.inflate(strm, ZLib.Z_PARTIAL_FLUSH());
if (ret == ZLib.Z_STREAM_END()) {
this.finished = true;
return Util_java_util_zip_Inflater.update(this, len, strm);
} else if (ret == ZLib.Z_OK()) {
return Util_java_util_zip_Inflater.update(this, len, strm);
} else if (ret == ZLib.Z_NEED_DICT()) {
needDict = true;
Util_java_util_zip_Inflater.update(this, len, strm);
return 0;
} else if (ret == ZLib.Z_BUF_ERROR()) {
return 0;
} else if (ret == ZLib.Z_DATA_ERROR()) {
throw new DataFormatException(CTypeConversion.toJavaString(strm.msg()));
} else if (ret == ZLib.Z_MEM_ERROR()) {
throw new OutOfMemoryError();
} else {
throw new InternalError();
}
}
}
use of org.graalvm.nativeimage.PinnedObject in project graal by oracle.
the class JNIThreadLocalPinnedObjects method pinArrayAndGetAddress.
public static <T extends PointerBase> T pinArrayAndGetAddress(Object array) {
PinnedObject pin = PinnedObject.create(array);
pinnedObjectsListHead.set(new PinnedObjectListNode(pin, pinnedObjectsListHead.get()));
return pin.addressOfArrayElement(0);
}
Aggregations