8026487: PPC64: Implement 'os::fork_and_exec' on AIX
authorsimonis
Wed, 16 Oct 2013 10:52:41 +0200
changeset 22837 feba5d4126b8
parent 22836 e7e511228518
child 22838 82c7497fbad4
8026487: PPC64: Implement 'os::fork_and_exec' on AIX Reviewed-by: kvn, twisti
hotspot/src/os/aix/vm/os_aix.cpp
--- a/hotspot/src/os/aix/vm/os_aix.cpp	Sun Sep 15 15:28:58 2013 +0200
+++ b/hotspot/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()