modules/jdk.packager/src/main/native/library/common/PosixPlatform.cpp
Print this page
@@ -42,19 +42,113 @@
#include <assert.h>
#include <stdbool.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/sysctl.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <limits.h>
+#include <pwd.h>
#include <iostream>
#include <dlfcn.h>
#include <signal.h>
PosixPlatform::PosixPlatform(void) {
}
PosixPlatform::~PosixPlatform(void) {
+ if (!SingleInstanceFile.empty()) {
+ unlink(SingleInstanceFile.c_str());
+ }
+}
+
+bool PosixPlatform::mkdirs(const char* path) {
+ char* p = NULL;
+ char tmp_path[PATH_MAX] = {0};
+
+ if (strlen(path) > (sizeof(tmp_path) - 1)) {
+ // too long name
+ return false;
+ }
+
+ strcpy(tmp_path, path);
+
+ errno = 0;
+ for (p = tmp_path + 1; *p; ++p) {
+ if (*p == '/') {
+ *p = '\0';
+ if (mkdir(tmp_path, S_IRWXU) != 0) {
+ if (errno != EEXIST) {
+ return false;
+ }
+ }
+ *p = '/';
+ }
+ }
+
+ if (mkdir(tmp_path, S_IRWXU) != 0) {
+ if (errno != EEXIST) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool PosixPlatform::getTmpDir(char* path, int len) {
+ struct passwd* pw = getpwuid(getuid());
+ const char* homedir = pw->pw_dir;
+ snprintf(path, len-1 , "%s%s", homedir, getTmpDirString());
+ struct stat sb;
+ if (stat(path, &sb) != 0 || !S_ISDIR(sb.st_mode)) {
+ // the dir doesn't exist
+ if (!mkdirs(path)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+// returns true if another instance is already running.
+// if false, we need to continue regular launch.
+bool PosixPlatform::CheckForSingleInstance(TString appName) {
+ char tmpDir[PATH_MAX] = {0};
+ if (!getTmpDir(tmpDir, PATH_MAX)) {
+ printf("Unable to check for single instance.\n");
+ return false;
+ }
+
+ char lock_file[PATH_MAX] = {0};
+ snprintf(lock_file, PATH_MAX-1, "%s/%s", tmpDir, appName.c_str());
+ SingleInstanceFile = lock_file;
+ int pid_file = open(lock_file, O_CREAT | O_RDWR, 0666);
+ int rc = flock(pid_file, LOCK_EX | LOCK_NB);
+
+ if (rc) {
+ if (EWOULDBLOCK == errno) {
+ // another instance is running
+ pid_t pid = 0;
+ read(pid_file, (void*)&pid, sizeof(pid_t));
+ printf("Another instance is running PID: %d\n", pid);
+ if (pid != 0) {
+ singleInstanceProcessId = pid;
+ SingleInstanceFile.clear();
+ return true;
+ }
+ } else {
+ printf("Unable to check for single instance.\n");
+ }
+ } else {
+ // It is the first instance.
+ pid_t pid = getpid();
+ write(pid_file, (void*)&pid, sizeof(pid_t));
+ }
+
+ return false;
}
MessageResponse PosixPlatform::ShowResponseMessage(TString title, TString description) {
MessageResponse result = mrCancel;