--- old/modules/jdk.packager/src/main/native/library/common/PosixPlatform.cpp 2017-07-05 12:50:52.000000000 -0700 +++ new/modules/jdk.packager/src/main/native/library/common/PosixPlatform.cpp 2017-07-05 12:50:52.000000000 -0700 @@ -44,6 +44,11 @@ #include #include #include +#include +#include +#include +#include +#include #include #include #include @@ -53,6 +58,95 @@ } 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) {