# HG changeset patch # User simonis # Date 1381913561 -7200 # Node ID 3068270ba47636d5a2ff6de75d31e70b8fb3a327 # Parent abe03600372aaa6d0396921e81fcc6255e8e7912 8026487: PPC64: Implement 'os::fork_and_exec' on AIX Reviewed-by: kvn, twisti diff -r abe03600372a -r 3068270ba476 src/os/aix/vm/os_aix.cpp --- a/src/os/aix/vm/os_aix.cpp Sun Sep 15 15:28:58 2013 +0200 +++ b/src/os/aix/vm/os_aix.cpp Wed Oct 16 10:52:41 2013 +0200 @@ -227,8 +227,12 @@ } julong os::Aix::available_memory() { - Unimplemented(); - return 0; + os::Aix::meminfo_t mi; + if (os::Aix::get_meminfo(&mi)) { + return mi.real_free; + } else { + return 0xFFFFFFFFFFFFFFFFLL; + } } julong os::physical_memory() { @@ -5060,8 +5064,56 @@ // Unlike system(), this function can be called from signal handler. It // doesn't block SIGINT et al. int os::fork_and_exec(char* cmd) { - Unimplemented(); - return 0; + char * argv[4] = {"sh", "-c", cmd, NULL}; + + pid_t pid = fork(); + + if (pid < 0) { + // fork failed + return -1; + + } else if (pid == 0) { + // child process + + // try to be consistent with system(), which uses "/usr/bin/sh" on AIX + execve("/usr/bin/sh", argv, environ); + + // execve failed + _exit(-1); + + } else { + // copied from J2SE ..._waitForProcessExit() in UNIXProcess_md.c; we don't + // care about the actual exit code, for now. + + int status; + + // Wait for the child process to exit. This returns immediately if + // the child has already exited. */ + while (waitpid(pid, &status, 0) < 0) { + switch (errno) { + case ECHILD: return 0; + case EINTR: break; + default: return -1; + } + } + + if (WIFEXITED(status)) { + // The child exited normally; get its exit code. + return WEXITSTATUS(status); + } else if (WIFSIGNALED(status)) { + // The child exited because of a signal + // The best value to return is 0x80 + signal number, + // because that is what all Unix shells do, and because + // it allows callers to distinguish between process exit and + // process death by signal. + return 0x80 + WTERMSIG(status); + } else { + // Unknown exit code; pass it through + return status; + } + } + // Remove warning. + return -1; } // is_headless_jre()