mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
87 lines
2.1 KiB
C++
87 lines
2.1 KiB
C++
// Copyright (c) FIRST and other WPILib contributors.
|
|
// Open Source Software; you can modify and/or share it under the terms of
|
|
// the WPILib BSD license file in the root directory of this project.
|
|
|
|
#include <poll.h>
|
|
#include <spawn.h>
|
|
#include <sys/syscall.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
|
|
#include <climits>
|
|
#include <cstdio>
|
|
#include <cstring>
|
|
#include <filesystem>
|
|
|
|
int main(int argc, char* argv[]) {
|
|
char path[PATH_MAX];
|
|
char dest[PATH_MAX];
|
|
std::memset(dest, 0, sizeof(dest)); // readlink does not null terminate!
|
|
pid_t pid = getpid();
|
|
std::snprintf(path, PATH_MAX, "/proc/%d/exe", pid);
|
|
int readlink_len = readlink(path, dest, PATH_MAX);
|
|
if (readlink_len < 0) {
|
|
std::perror("readlink");
|
|
return 1;
|
|
} else if (readlink_len == PATH_MAX) {
|
|
std::printf("Truncation occurred\n");
|
|
return 1;
|
|
}
|
|
|
|
std::filesystem::path exePath{dest};
|
|
if (exePath.empty()) {
|
|
return 1;
|
|
}
|
|
|
|
if (!exePath.has_stem()) {
|
|
return 1;
|
|
}
|
|
|
|
if (!exePath.has_parent_path()) {
|
|
return 1;
|
|
}
|
|
|
|
std::filesystem::path jarPath{exePath};
|
|
jarPath.replace_extension("jar");
|
|
std::filesystem::path parentPath{exePath.parent_path()};
|
|
|
|
if (!parentPath.has_parent_path()) {
|
|
return 1;
|
|
}
|
|
std::filesystem::path toolsFolder{parentPath.parent_path()};
|
|
|
|
std::filesystem::path Java = toolsFolder / "jdk" / "bin" / "java";
|
|
|
|
pid = 0;
|
|
std::string data = jarPath;
|
|
std::string jarArg = "-jar";
|
|
char* const arguments[] = {jarArg.data(), data.data(), nullptr};
|
|
|
|
int status =
|
|
posix_spawn(&pid, Java.c_str(), nullptr, nullptr, arguments, environ);
|
|
if (status != 0) {
|
|
char* home = std::getenv("JAVA_HOME");
|
|
std::string javaLocal = "java";
|
|
if (home != nullptr) {
|
|
std::filesystem::path javaHomePath{home};
|
|
javaHomePath /= "bin";
|
|
javaHomePath /= "java";
|
|
javaLocal = javaHomePath;
|
|
}
|
|
|
|
status = posix_spawn(&pid, javaLocal.c_str(), nullptr, nullptr, arguments,
|
|
environ);
|
|
if (status != 0) {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
int childPid = syscall(SYS_pidfd_open, pid, 0);
|
|
if (childPid <= 0) {
|
|
return 1;
|
|
}
|
|
|
|
struct pollfd pfd = {childPid, POLLIN, 0};
|
|
return poll(&pfd, 1, 3000);
|
|
}
|