modules/jdk.packager/src/main/native/library/common/PosixPlatform.cpp

Print this page

        

*** 42,60 **** --- 42,154 ---- #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;