modules/fxpackager/src/main/native/library/common/PosixPlatform.cpp
Print this page
*** 34,59 ****
#include "PosixPlatform.h"
#ifdef POSIX
#include "PlatformString.h"
#include <assert.h>
#include <stdbool.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/sysctl.h>
!
#include <dlfcn.h>
PosixPlatform::PosixPlatform(void) {
}
PosixPlatform::~PosixPlatform(void) {
}
void PosixPlatform::SetCurrentDirectory(TString Value) {
chdir(StringToFileSystemString(Value));
}
Module PosixPlatform::LoadLibrary(TString FileName) {
--- 34,83 ----
#include "PosixPlatform.h"
#ifdef POSIX
#include "PlatformString.h"
+ #include "FilePath.h"
#include <assert.h>
#include <stdbool.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/sysctl.h>
! #include <iostream>
#include <dlfcn.h>
+ #include <signal.h>
PosixPlatform::PosixPlatform(void) {
}
PosixPlatform::~PosixPlatform(void) {
}
+ MessageResponse PosixPlatform::ShowResponseMessage(TString title, TString description) {
+ MessageResponse result = mrCancel;
+
+ printf("%s %s (Y/N)\n", PlatformString(title).toPlatformString(), PlatformString(description).toPlatformString());
+ fflush(stdout);
+
+ std::string input;
+ std::cin >> input;
+
+ if (input == "Y") {
+ result = mrOK;
+ }
+
+ return result;
+ }
+
+ //MessageResponse PosixPlatform::ShowResponseMessageB(TString description) {
+ // TString appname = GetModuleFileName();
+ // appname = FilePath::ExtractFileName(appname);
+ // return ShowResponseMessage(appname, description);
+ //}
+
void PosixPlatform::SetCurrentDirectory(TString Value) {
chdir(StringToFileSystemString(Value));
}
Module PosixPlatform::LoadLibrary(TString FileName) {
*** 76,81 ****
--- 100,274 ----
std::vector<TString> PosixPlatform::FilterOutRuntimeDependenciesForPlatform(std::vector<TString> Imports) {
std::vector<TString> result;
return result;
}
+ Process* PosixPlatform::CreateProcess() {
+ return new PosixProcess();
+ }
+
+ //--------------------------------------------------------------------------------------------------
+
+
+ PosixProcess::PosixProcess() : Process() {
+ FChildPID = 0;
+ FRunning = false;
+ }
+
+ PosixProcess::~PosixProcess() {
+ Terminate();
+ }
+
+ void PosixProcess::Cleanup() {
+ #ifdef MAC
+ sigaction(SIGINT, &savintr, (struct sigaction *)0);
+ sigaction(SIGQUIT, &savequit, (struct sigaction *)0);
+ sigprocmask(SIG_SETMASK, &saveblock, (sigset_t *)0);
+ #endif //MAC
+ }
+
+ bool PosixProcess::IsRunning() {
+ bool result = false;
+
+ if (kill(FChildPID, 0) == 0) {
+ result = true;
+ }
+
+ return result;
+ }
+
+ bool PosixProcess::Terminate() {
+ bool result = false;
+
+ if (IsRunning() == true && FRunning == true) {
+ FRunning = false;
+ Cleanup();
+ int status = kill(FChildPID, SIGTERM);
+
+ if (status == 0) {
+ result = true;
+ }
+ else {
+ #ifdef DEBUG
+ if (errno == EINVAL)
+ printf("Kill error: The value of the sig argument is an invalid or unsupported signal number.");
+ else if (errno == EPERM)
+ printf("Kill error: The process does not have permission to send the signal to any receiving process.");
+ else if (errno == ESRCH)
+ printf("Kill error: No process or process group can be found corresponding to that specified by pid.");
+ #endif //DEBUG
+ if (IsRunning() == true) {
+ status = kill(FChildPID, SIGKILL);
+
+ if (status == 0) {
+ result = true;
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+
+ bool PosixProcess::Execute(const TString Application, const std::vector<TString> Arguments, bool AWait) {
+ bool result = false;
+
+ if (FRunning == false) {
+ FRunning = true;
+
+ struct sigaction sa;
+ sa.sa_handler = SIG_IGN;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ #ifdef MAC
+ sigemptyset(&savintr.sa_mask);
+ sigemptyset(&savequit.sa_mask);
+ sigaction(SIGINT, &sa, &savintr);
+ sigaction(SIGQUIT, &sa, &savequit);
+ sigaddset(&sa.sa_mask, SIGCHLD);
+ sigprocmask(SIG_BLOCK, &sa.sa_mask, &saveblock);
+ #endif //MAC
+ FChildPID = fork();
+
+ // PID returned by vfork is 0 for the child process and the PID of the child
+ // process for the parent.
+ if (FChildPID == -1) {
+ // Error
+ TString message = PlatformString::Format(_T("Error: Unable to create process %s"), Application.data());
+ throw Exception(message);
+ }
+ else if (FChildPID == 0) {
+ Cleanup();
+ TString command = Application;
+
+ for (std::vector<TString>::const_iterator iterator = Arguments.begin(); iterator != Arguments.end(); iterator++) {
+ command += TString(_T(" ")) + *iterator;
+ }
+ #ifdef DEBUG
+ printf("%s\n", command.data());
+ #endif //DEBUG
+ execl("/bin/sh", "sh", "-c", command.data(), (char *)0);
+ _exit(127);
+ } else {
+ if (AWait == true) {
+ Wait();
+ Cleanup();
+ FRunning = false;
+ result = true;
+ }
+ else {
+ result = true;
+ }
+ }
+ }
+
+ return result;
+ }
+
+ bool PosixProcess::Wait() {
+ bool result = false;
+
+ int status;
+ pid_t wpid;
+
+ //TODO Use waitpid instead of wait
+ #ifdef LINUX
+ wait();
+ #endif
+ #ifdef MAC
+ wpid = wait(&status);
+ #endif
+
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
+ if (errno != EINTR){
+ status = -1;
+ }
+ }
+
+ #ifdef DEBUG
+ if (WIFEXITED(status)) {
+ printf("child exited, status=%d\n", WEXITSTATUS(status));
+ } else if (WIFSIGNALED(status)) {
+ printf("child killed (signal %d)\n", WTERMSIG(status));
+ } else if (WIFSTOPPED(status)) {
+ printf("child stopped (signal %d)\n", WSTOPSIG(status));
+ #ifdef WIFCONTINUED // Not all implementations support this
+ } else if (WIFCONTINUED(status)) {
+ printf("child continued\n");
+ #endif //WIFCONTINUED
+ } else { // Non-standard case -- may never happen
+ printf("Unexpected status (0x%x)\n", status);
+ }
+ #endif //DEBUG
+
+ if (wpid != -1) {
+ result = true;
+ }
+
+ return result;
+ }
+
+ TProcessID PosixProcess::GetProcessID() {
+ return FChildPID;
+ }
+
#endif //POSIX