resolved conflicts for merge of f78109f6 to dalvik-dev

(git cherry-pick -m 1 8a6e388c11d8ee72a0af23e6091239e2f58bc968)

Change-Id: Ie07e5901d5a127b6d6840b05da5dfd5c2b967048
diff --git a/luni/src/main/native/ExecStrings.cpp b/luni/src/main/native/ExecStrings.cpp
new file mode 100644
index 0000000..aec84fe
--- /dev/null
+++ b/luni/src/main/native/ExecStrings.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ExecStrings"
+
+#include "ExecStrings.h"
+
+#include <stdlib.h>
+
+#include "cutils/log.h"
+#include "ScopedLocalRef.h"
+
+ExecStrings::ExecStrings(JNIEnv* env, jobjectArray java_string_array)
+    : env_(env), java_array_(java_string_array) {
+  if (java_array_ == NULL) {
+    return;
+  }
+
+  jsize length = env_->GetArrayLength(java_array_);
+  array_ = new char*[length + 1];
+  array_[length] = NULL;
+  for (jsize i = 0; i < length; ++i) {
+    ScopedLocalRef<jstring> java_string(env_, reinterpret_cast<jstring>(env_->GetObjectArrayElement(java_array_, i)));
+    // We need to pass these strings to const-unfriendly code.
+    char* string = const_cast<char*>(env_->GetStringUTFChars(java_string.get(), NULL));
+    array_[i] = string;
+  }
+}
+
+ExecStrings::~ExecStrings() {
+  if (array_ == NULL) {
+    return;
+  }
+
+  // Temporarily clear any pending exception so we can clean up.
+  jthrowable pending_exception = env_->ExceptionOccurred();
+  if (pending_exception != NULL) {
+    env_->ExceptionClear();
+  }
+
+  jsize length = env_->GetArrayLength(java_array_);
+  for (jsize i = 0; i < length; ++i) {
+    ScopedLocalRef<jstring> java_string(env_, reinterpret_cast<jstring>(env_->GetObjectArrayElement(java_array_, i)));
+    env_->ReleaseStringUTFChars(java_string.get(), array_[i]);
+  }
+  delete[] array_;
+
+  // Re-throw any pending exception.
+  if (pending_exception != NULL) {
+    if (env_->Throw(pending_exception) < 0) {
+      ALOGE("Error rethrowing exception!");
+    }
+  }
+}
+
+char** ExecStrings::get() {
+  return array_;
+}
diff --git a/luni/src/main/native/ExecStrings.h b/luni/src/main/native/ExecStrings.h
new file mode 100644
index 0000000..f8a1b15
--- /dev/null
+++ b/luni/src/main/native/ExecStrings.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "jni.h"
+
+class ExecStrings {
+ public:
+  ExecStrings(JNIEnv* env, jobjectArray java_string_array);
+
+  ~ExecStrings();
+
+  char** get();
+
+ private:
+  JNIEnv* env_;
+  jobjectArray java_array_;
+  char** array_;
+
+  // Disallow copy and assignment.
+  ExecStrings(const ExecStrings&);
+  void operator=(const ExecStrings&);
+};
diff --git a/luni/src/main/native/java_lang_ProcessManager.cpp b/luni/src/main/native/java_lang_ProcessManager.cpp
index 783fbd1..6556dc8 100644
--- a/luni/src/main/native/java_lang_ProcessManager.cpp
+++ b/luni/src/main/native/java_lang_ProcessManager.cpp
@@ -28,6 +28,8 @@
 
 #include "cutils/log.h"
 #include "jni.h"
+#include "ExecStrings.h"
+#include "JNIHelp.h"
 #include "JniConstants.h"
 #include "JNIHelp.h"
 #include "Portability.h"
@@ -208,8 +210,8 @@
                                  jobject inDescriptor, jobject outDescriptor, jobject errDescriptor,
                                  jboolean redirectErrorStream) {
 
-  // Copy commands into char*[].
-  char** commands = convertStrings(env, javaCommands);
+  ExecStrings commands(env, javaCommands);
+  ExecStrings environment(env, javaEnvironment);
 
   // Extract working directory string.
   const char* workingDirectory = NULL;
@@ -217,32 +219,14 @@
     workingDirectory = env->GetStringUTFChars(javaWorkingDirectory, NULL);
   }
 
-  // Convert environment array.
-  char** environment = convertStrings(env, javaEnvironment);
-
-  pid_t result = ExecuteProcess(env, commands, environment, workingDirectory,
+  pid_t result = ExecuteProcess(env, commands.get(), environment.get(), workingDirectory,
                                 inDescriptor, outDescriptor, errDescriptor, redirectErrorStream);
 
-  // Temporarily clear exception so we can clean up.
-  jthrowable exception = env->ExceptionOccurred();
-  env->ExceptionClear();
-
-  freeStrings(env, javaEnvironment, environment);
-
   // Clean up working directory string.
   if (javaWorkingDirectory != NULL) {
     env->ReleaseStringUTFChars(javaWorkingDirectory, workingDirectory);
   }
 
-  freeStrings(env, javaCommands, commands);
-
-  // Re-throw exception if present.
-  if (exception != NULL) {
-    if (env->Throw(exception) < 0) {
-      ALOGE("Error rethrowing exception!");
-    }
-  }
-
   return result;
 }
 
diff --git a/luni/src/main/native/libcore_io_Posix.cpp b/luni/src/main/native/libcore_io_Posix.cpp
index 1daa83d..7f40042 100644
--- a/luni/src/main/native/libcore_io_Posix.cpp
+++ b/luni/src/main/native/libcore_io_Posix.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "Posix"
 
 #include "AsynchronousSocketCloseMonitor.h"
+#include "ExecStrings.h"
 #include "JNIHelp.h"
 #include "JniConstants.h"
 #include "JniException.h"
@@ -493,12 +494,10 @@
         return;
     }
 
-    char** argv = convertStrings(env, javaArgv);
-    char** envp = convertStrings(env, javaEnvp);
-    execve(path.c_str(), argv, envp);
+    ExecStrings argv(env, javaArgv);
+    ExecStrings envp(env, javaEnvp);
+    execve(path.c_str(), argv.get(), envp.get());
 
-    freeStrings(env, javaArgv, argv);
-    freeStrings(env, javaEnvp, envp);
     throwErrnoException(env, "execve");
 }
 
@@ -508,10 +507,9 @@
         return;
     }
 
-    char** argv = convertStrings(env, javaArgv);
-    execv(path.c_str(), argv);
+    ExecStrings argv(env, javaArgv);
+    execv(path.c_str(), argv.get());
 
-    freeStrings(env, javaArgv, argv);
     throwErrnoException(env, "execv");
 }
 
diff --git a/luni/src/main/native/sub.mk b/luni/src/main/native/sub.mk
index 5627167..7d75804 100644
--- a/luni/src/main/native/sub.mk
+++ b/luni/src/main/native/sub.mk
@@ -5,6 +5,7 @@
 
 LOCAL_SRC_FILES := \
 	AsynchronousSocketCloseMonitor.cpp \
+	ExecStrings.cpp \
 	IcuUtilities.cpp \
 	JniException.cpp \
 	NetworkUtilities.cpp \