< prev index next >

src/jdk.jpackage/unix/native/libapplauncher/PosixPlatform.cpp

Print this page




   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #include "PosixPlatform.h"
  27 
  28 #ifdef POSIX
  29 
  30 #include "PlatformString.h"
  31 #include "FilePath.h"
  32 #include "Helpers.h"
  33 
  34 #include <assert.h>
  35 #include <stdbool.h>
  36 #include <sys/types.h>
  37 #include <unistd.h>
  38 #include <sys/sysctl.h>
  39 #include <sys/file.h>
  40 #include <sys/stat.h>
  41 #ifdef LINUX
  42 #include <sys/wait.h>
  43 #endif
  44 #include <errno.h>
  45 #include <limits.h>
  46 #include <pwd.h>
  47 #include <iostream>
  48 #include <algorithm>
  49 #include <dlfcn.h>
  50 #include <signal.h>
  51 

  52 
  53 PosixPlatform::PosixPlatform(void) {
  54 }
  55 
  56 PosixPlatform::~PosixPlatform(void) {
  57 }
  58 
  59 TString PosixPlatform::GetTempDirectory() {
  60     struct passwd* pw = getpwuid(getuid());
  61     TString homedir(pw->pw_dir);
  62     homedir += getTmpDirString();
  63     if (!FilePath::DirectoryExists(homedir)) {
  64         if (!FilePath::CreateDirectory(homedir, false)) {
  65             homedir.clear();
  66         }
  67     }
  68 
  69     return homedir;
  70 }
  71 


  97     return result;
  98 }
  99 
 100 void PosixPlatform::SetCurrentDirectory(TString Value) {
 101     chdir(StringToFileSystemString(Value));
 102 }
 103 
 104 Module PosixPlatform::LoadLibrary(TString FileName) {
 105     return dlopen(StringToFileSystemString(FileName), RTLD_LAZY);
 106 }
 107 
 108 void PosixPlatform::FreeLibrary(Module AModule) {
 109     dlclose(AModule);
 110 }
 111 
 112 Procedure PosixPlatform::GetProcAddress(Module AModule,
 113         std::string MethodName) {
 114     return dlsym(AModule, PlatformString(MethodName));
 115 }
 116 
 117 std::vector<std::string> PosixPlatform::GetLibraryImports(
 118        const TString FileName) {
 119  std::vector<TString> result;









































 120  return result;
 121 }
 122 
 123 std::vector<TString> PosixPlatform::FilterOutRuntimeDependenciesForPlatform(
 124        std::vector<TString> Imports) {
 125  std::vector<TString> result;















 126  return result;
 127 }
 128 
 129 Process* PosixPlatform::CreateProcess() {
 130     return new PosixProcess();
 131 }
 132 
 133 PosixProcess::PosixProcess() : Process() {
 134     FChildPID = 0;
 135     FRunning = false;
 136     FOutputHandle = 0;
 137     FInputHandle = 0;
 138 }
 139 
 140 PosixProcess::~PosixProcess() {
 141     Terminate();
 142 }
 143 
 144 void PosixProcess::Cleanup() {
 145     if (FOutputHandle != 0) {
 146         close(FOutputHandle);
 147         FOutputHandle = 0;
 148     }
 149 
 150     if (FInputHandle != 0) {
 151         close(FInputHandle);
 152         FInputHandle = 0;
 153     }
 154 
 155 #ifdef MAC
 156     sigaction(SIGINT, &savintr, (struct sigaction *)0);
 157     sigaction(SIGQUIT, &savequit, (struct sigaction *)0);
 158     sigprocmask(SIG_SETMASK, &saveblock, (sigset_t *)0);
 159 #endif //MAC
 160 }
 161 
 162 bool PosixProcess::ReadOutput() {
 163     bool result = false;
 164 
 165     if (FOutputHandle != 0 && IsRunning() == true) {
 166         char buffer[4096] = {0};
 167 
 168         ssize_t count = read(FOutputHandle, buffer, sizeof(buffer));
 169 
 170         if (count == -1) {
 171             if (errno == EINTR) {
 172                 // continue;
 173             } else {
 174                 perror("read");
 175                 exit(1);
 176             }
 177         } else if (count == 0) {
 178             // break;
 179         } else {
 180             if (buffer[count - 1] == EOF) {
 181                 buffer[count - 1] = '\0';
 182             }
 183 
 184             std::list<TString> output = Helpers::StringToArray(buffer);
 185             FOutput.splice(FOutput.end(), output, output.begin(), output.end());
 186             result = true;
 187         }
 188     }


 216                 printf("Kill error: The value of the sig argument is an invalid or unsupported signal number.");
 217             } else if (errno == EPERM) {
 218                 printf("Kill error: The process does not have permission to send the signal to any receiving process.");
 219             } else if (errno == ESRCH) {
 220                 printf("Kill error: No process or process group can be found corresponding to that specified by pid.");
 221             }
 222 #endif // DEBUG
 223             if (IsRunning() == true) {
 224                 status = kill(FChildPID, SIGKILL);
 225 
 226                 if (status == 0) {
 227                     result = true;
 228                 }
 229             }
 230         }
 231     }
 232 
 233     return result;
 234 }
 235 
 236 #define PIPE_READ 0
 237 #define PIPE_WRITE 1
 238 
 239 bool PosixProcess::Execute(const TString Application,
 240         const std::vector<TString> Arguments, bool AWait) {
 241     bool result = false;
 242 
 243     if (FRunning == false) {
 244         FRunning = true;
 245 
 246         int handles[2];
 247 
 248         if (pipe(handles) == -1) {
 249             return false;
 250         }
 251 
 252         struct sigaction sa;
 253         sa.sa_handler = SIG_IGN;
 254         sigemptyset(&sa.sa_mask);
 255         sa.sa_flags = 0;
 256 #ifdef MAC
 257         sigemptyset(&savintr.sa_mask);
 258         sigemptyset(&savequit.sa_mask);
 259         sigaction(SIGINT, &sa, &savintr);
 260         sigaction(SIGQUIT, &sa, &savequit);
 261         sigaddset(&sa.sa_mask, SIGCHLD);
 262         sigprocmask(SIG_BLOCK, &sa.sa_mask, &saveblock);
 263 #endif // MAC
 264         FChildPID = fork();
 265 
 266         // PID returned by vfork is 0 for the child process and the
 267         // PID of the child process for the parent.
 268         if (FChildPID == -1) {
 269             // Error
 270             TString message = PlatformString::Format(
 271                     _T("Error: Unable to create process %s"),
 272                     Application.data());
 273             throw Exception(message);
 274         }
 275         else if (FChildPID == 0) {
 276             Cleanup();
 277             TString command = Application;
 278 
 279             for (std::vector<TString>::const_iterator iterator =
 280                     Arguments.begin(); iterator != Arguments.end();
 281                     iterator++) {
 282                 command += TString(_T(" ")) + *iterator;
 283             }
 284 #ifdef DEBUG
 285             printf("%s\n", command.data());
 286 #endif // DEBUG
 287 
 288             dup2(handles[PIPE_READ], STDIN_FILENO);
 289             dup2(handles[PIPE_WRITE], STDOUT_FILENO);
 290 
 291             close(handles[PIPE_READ]);
 292             close(handles[PIPE_WRITE]);
 293 
 294             execl("/bin/sh", "sh", "-c", command.data(), (char *)0);
 295 
 296             _exit(127);
 297         } else {
 298             FOutputHandle = handles[PIPE_READ];
 299             FInputHandle = handles[PIPE_WRITE];
 300 
 301             if (AWait == true) {
 302                 ReadOutput();
 303                 Wait();
 304                 Cleanup();
 305                 FRunning = false;
 306                 result = true;
 307             }
 308             else {
 309                 result = true;
 310             }
 311         }
 312     }
 313 
 314     return result;
 315 }
 316 
 317 bool PosixProcess::Wait() {
 318     bool result = false;
 319 
 320     int status = 0;
 321     pid_t wpid = 0;
 322 
 323 #ifdef LINUX
 324     wpid = wait(&status);
 325 #endif
 326 #ifdef MAC
 327     wpid = wait(&status);
 328 #endif
 329 
 330     if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
 331         if (errno != EINTR){
 332             status = -1;
 333         }
 334     }
 335 
 336 #ifdef DEBUG
 337     if (WIFEXITED(status)) {
 338         printf("child exited, status=%d\n", WEXITSTATUS(status));
 339     } else if (WIFSIGNALED(status)) {
 340         printf("child killed (signal %d)\n", WTERMSIG(status));
 341     } else if (WIFSTOPPED(status)) {
 342         printf("child stopped (signal %d)\n", WSTOPSIG(status));
 343 #ifdef WIFCONTINUED // Not all implementations support this
 344     } else if (WIFCONTINUED(status)) {
 345         printf("child continued\n");
 346 #endif // WIFCONTINUED
 347     } else { // Non-standard case -- may never happen
 348         printf("Unexpected status (0x%x)\n", status);
 349     }
 350 #endif // DEBUG
 351 


 353         result = true;
 354     }
 355 
 356     return result;
 357 }
 358 
 359 TProcessID PosixProcess::GetProcessID() {
 360     return FChildPID;
 361 }
 362 
 363 void PosixProcess::SetInput(TString Value) {
 364     if (FInputHandle != 0) {
 365         write(FInputHandle, Value.data(), Value.size());
 366     }
 367 }
 368 
 369 std::list<TString> PosixProcess::GetOutput() {
 370     ReadOutput();
 371     return Process::GetOutput();
 372 }
 373 
 374 #endif // POSIX


   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #include "PosixPlatform.h"
  27 


  28 #include "PlatformString.h"
  29 #include "FilePath.h"
  30 #include "Helpers.h"
  31 
  32 #include <assert.h>
  33 #include <stdbool.h>
  34 #include <sys/types.h>
  35 #include <unistd.h>
  36 #include <sys/sysctl.h>
  37 #include <sys/file.h>
  38 #include <sys/stat.h>

  39 #include <sys/wait.h>

  40 #include <errno.h>
  41 #include <limits.h>
  42 #include <pwd.h>
  43 #include <iostream>
  44 #include <algorithm>
  45 #include <dlfcn.h>
  46 #include <signal.h>
  47 
  48 using namespace std;
  49 
  50 PosixPlatform::PosixPlatform(void) {
  51 }
  52 
  53 PosixPlatform::~PosixPlatform(void) {
  54 }
  55 
  56 TString PosixPlatform::GetTempDirectory() {
  57     struct passwd* pw = getpwuid(getuid());
  58     TString homedir(pw->pw_dir);
  59     homedir += getTmpDirString();
  60     if (!FilePath::DirectoryExists(homedir)) {
  61         if (!FilePath::CreateDirectory(homedir, false)) {
  62             homedir.clear();
  63         }
  64     }
  65 
  66     return homedir;
  67 }
  68 


  94     return result;
  95 }
  96 
  97 void PosixPlatform::SetCurrentDirectory(TString Value) {
  98     chdir(StringToFileSystemString(Value));
  99 }
 100 
 101 Module PosixPlatform::LoadLibrary(TString FileName) {
 102     return dlopen(StringToFileSystemString(FileName), RTLD_LAZY);
 103 }
 104 
 105 void PosixPlatform::FreeLibrary(Module AModule) {
 106     dlclose(AModule);
 107 }
 108 
 109 Procedure PosixPlatform::GetProcAddress(Module AModule,
 110         std::string MethodName) {
 111     return dlsym(AModule, PlatformString(MethodName));
 112 }
 113 
 114 Process* PosixPlatform::CreateProcess() {
 115     return new PosixProcess();
 116 }
 117 
 118 void PosixPlatform::addPlatformDependencies(JavaLibrary *pJavaLibrary) {
 119 }
 120 
 121 void Platform::CopyString(char *Destination,
 122         size_t NumberOfElements, const char *Source) {
 123     strncpy(Destination, Source, NumberOfElements);
 124 
 125     if (NumberOfElements > 0) {
 126         Destination[NumberOfElements - 1] = '\0';
 127     }
 128 }
 129 
 130 void Platform::CopyString(wchar_t *Destination,
 131         size_t NumberOfElements, const wchar_t *Source) {
 132     wcsncpy(Destination, Source, NumberOfElements);
 133 
 134     if (NumberOfElements > 0) {
 135         Destination[NumberOfElements - 1] = '\0';
 136     }
 137 }
 138 
 139 // Owner must free the return value.
 140 
 141 MultibyteString Platform::WideStringToMultibyteString(
 142         const wchar_t* value) {
 143     MultibyteString result;
 144     size_t count = 0;
 145 
 146     if (value == NULL) {
 147         return result;
 148     }
 149 
 150     count = wcstombs(NULL, value, 0);
 151     if (count > 0) {
 152         result.data = new char[count + 1];
 153         result.data[count] = '\0';
 154         result.length = count;
 155         wcstombs(result.data, value, count);
 156     }
 157 
 158     return result;
 159 }
 160 
 161 // Owner must free the return value.
 162 
 163 WideString Platform::MultibyteStringToWideString(const char* value) {
 164     WideString result;
 165     size_t count = 0;
 166 
 167     if (value == NULL) {
 168         return result;
 169     }
 170 
 171     count = mbstowcs(NULL, value, 0);
 172     if (count > 0) {
 173         result.data = new wchar_t[count + 1];
 174         result.data[count] = '\0';
 175         result.length = count;
 176         mbstowcs(result.data, value, count);
 177     }
 178 
 179     return result;
 180 }
 181 
 182 void PosixPlatform::InitStreamLocale(wios *stream) {
 183     // Nothing to do for POSIX platforms.
 184 }
 185 
 186 PosixProcess::PosixProcess() : Process() {
 187     FChildPID = 0;
 188     FRunning = false;
 189     FOutputHandle = 0;
 190     FInputHandle = 0;
 191 }
 192 
 193 PosixProcess::~PosixProcess() {
 194     Terminate();
 195 }
 196 


















 197 bool PosixProcess::ReadOutput() {
 198     bool result = false;
 199 
 200     if (FOutputHandle != 0 && IsRunning() == true) {
 201         char buffer[4096] = {0};
 202 
 203         ssize_t count = read(FOutputHandle, buffer, sizeof (buffer));
 204 
 205         if (count == -1) {
 206             if (errno == EINTR) {
 207                 // continue;
 208             } else {
 209                 perror("read");
 210                 exit(1);
 211             }
 212         } else if (count == 0) {
 213             // break;
 214         } else {
 215             if (buffer[count - 1] == EOF) {
 216                 buffer[count - 1] = '\0';
 217             }
 218 
 219             std::list<TString> output = Helpers::StringToArray(buffer);
 220             FOutput.splice(FOutput.end(), output, output.begin(), output.end());
 221             result = true;
 222         }
 223     }


 251                 printf("Kill error: The value of the sig argument is an invalid or unsupported signal number.");
 252             } else if (errno == EPERM) {
 253                 printf("Kill error: The process does not have permission to send the signal to any receiving process.");
 254             } else if (errno == ESRCH) {
 255                 printf("Kill error: No process or process group can be found corresponding to that specified by pid.");
 256             }
 257 #endif // DEBUG
 258             if (IsRunning() == true) {
 259                 status = kill(FChildPID, SIGKILL);
 260 
 261                 if (status == 0) {
 262                     result = true;
 263                 }
 264             }
 265         }
 266     }
 267 
 268     return result;
 269 }
 270 

















































































 271 bool PosixProcess::Wait() {
 272     bool result = false;
 273 
 274     int status = 0;
 275     pid_t wpid = 0;
 276 




 277     wpid = wait(&status);


 278     if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
 279         if (errno != EINTR) {
 280             status = -1;
 281         }
 282     }
 283 
 284 #ifdef DEBUG
 285     if (WIFEXITED(status)) {
 286         printf("child exited, status=%d\n", WEXITSTATUS(status));
 287     } else if (WIFSIGNALED(status)) {
 288         printf("child killed (signal %d)\n", WTERMSIG(status));
 289     } else if (WIFSTOPPED(status)) {
 290         printf("child stopped (signal %d)\n", WSTOPSIG(status));
 291 #ifdef WIFCONTINUED // Not all implementations support this
 292     } else if (WIFCONTINUED(status)) {
 293         printf("child continued\n");
 294 #endif // WIFCONTINUED
 295     } else { // Non-standard case -- may never happen
 296         printf("Unexpected status (0x%x)\n", status);
 297     }
 298 #endif // DEBUG
 299 


 301         result = true;
 302     }
 303 
 304     return result;
 305 }
 306 
 307 TProcessID PosixProcess::GetProcessID() {
 308     return FChildPID;
 309 }
 310 
 311 void PosixProcess::SetInput(TString Value) {
 312     if (FInputHandle != 0) {
 313         write(FInputHandle, Value.data(), Value.size());
 314     }
 315 }
 316 
 317 std::list<TString> PosixProcess::GetOutput() {
 318     ReadOutput();
 319     return Process::GetOutput();
 320 }


< prev index next >