Merge change 2077 into donut

* changes:
  adb: adbd no longer disables OOM and now sets children's OOM adjustment to zero
diff --git a/include/cutils/native_handle.h b/include/cutils/native_handle.h
index 2b64893..8a44b72 100644
--- a/include/cutils/native_handle.h
+++ b/include/cutils/native_handle.h
@@ -17,12 +17,55 @@
 #ifndef NATIVE_HANDLE_H_
 #define NATIVE_HANDLE_H_
 
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
 typedef struct
 {
-    int version;        /* sizeof(native_handle) */
+    int version;        /* sizeof(native_handle_t) */
     int numFds;         /* number of file-descriptors at &data[0] */
     int numInts;        /* number of ints at &data[numFds] */
     int data[0];        /* numFds + numInts ints */
-} native_handle;
+} native_handle_t;
+
+
+/* keep the old definition for backward source-compatibility */
+typedef native_handle_t native_handle;
+
+/*
+ * native_handle_close
+ * 
+ * closes the file descriptors contained in this native_handle_t
+ * 
+ * return 0 on success, or a negative error code on failure
+ * 
+ */
+int native_handle_close(const native_handle_t* h);
+
+
+/*
+ * native_handle_create
+ * 
+ * creates a native_handle_t and initializes it. must be destroyed with
+ * native_handle_delete().
+ * 
+ */
+native_handle_t* native_handle_create(int numFds, int numInts);
+
+/*
+ * native_handle_delete
+ * 
+ * frees a native_handle_t allocated with native_handle_create().
+ * This ONLY frees the memory allocated for the native_handle_t, but doesn't
+ * close the file descriptors; which can be achieved with native_handle_close().
+ * 
+ * return 0 on success, or a negative error code on failure
+ * 
+ */
+int native_handle_delete(native_handle_t* h);
+
+
+__END_DECLS
 
 #endif /* NATIVE_HANDLE_H_ */
diff --git a/init/init.c b/init/init.c
index b350569..0c1ad3f 100644
--- a/init/init.c
+++ b/init/init.c
@@ -193,7 +193,8 @@
     }
 
     if ((!(svc->flags & SVC_ONESHOT)) && dynamic_args) {
-        ERROR("service '%s' must be one-shot to use dynamic args, disabling\n", svc->args[0]);
+        ERROR("service '%s' must be one-shot to use dynamic args, disabling\n",
+               svc->args[0]);
         svc->flags |= SVC_DISABLED;
         return;
     }
@@ -258,42 +259,18 @@
             execve(svc->args[0], (char**) svc->args, (char**) ENV);
         else {
             char *arg_ptrs[SVC_MAXARGS+1];
-            int arg_idx;
+            int arg_idx = svc->nargs;
             char *tmp = strdup(dynamic_args);
-            char *p = tmp;
+            char *next = tmp;
+            char *bword;
 
             /* Copy the static arguments */
-            for (arg_idx = 0; arg_idx < svc->nargs; arg_idx++) {
-                arg_ptrs[arg_idx] = svc->args[arg_idx];
-            }
+            memcpy(arg_ptrs, svc->args, (svc->nargs * sizeof(char *)));
 
-            int done = 0;
-            while(!done) {
-
-                if (arg_idx == SVC_MAXARGS) 
+            while((bword = strsep(&next, " "))) {
+                arg_ptrs[arg_idx++] = bword;
+                if (arg_idx == SVC_MAXARGS)
                     break;
-
-                /* Advance over any leading whitespace */
-                if (*p == ' ') {
-                    for (p; *p != ' '; p++);
-                    p++;
-                }
-                /* Locate next argument */
-                char *q = p;
-                while(1) {
-                    if (*q == ' ') {
-                        *q = '\0';
-                        break;
-                    } else if (*q == '\0') {
-                        done = 1;
-                        break;
-                    }
-                    q++;
-                }
-                arg_ptrs[arg_idx++] = p;
-
-                q++; // Advance q to the next string
-                p = q;
             }
             arg_ptrs[arg_idx] = '\0';
             execve(svc->args[0], (char**) arg_ptrs, (char**) ENV);
@@ -462,7 +439,6 @@
         svc = service_find_by_name(name);
     else {
         tmp = strdup(name);
-        strcpy(tmp, name);
         args = strchr(tmp, ':');
         *args = '\0';
         args++;
@@ -802,7 +778,7 @@
     svc = service_find_by_keychord(id);
     if (svc) {
         INFO("starting service %s from keychord\n", svc->name);
-        service_start(svc, NULL);   
+        service_start(svc, NULL);
     } else {
         ERROR("service for keychord %d not found\n", id);
     }
diff --git a/libcutils/Android.mk b/libcutils/Android.mk
index f5e49f5..18d0ee3 100644
--- a/libcutils/Android.mk
+++ b/libcutils/Android.mk
@@ -20,6 +20,7 @@
 	array.c \
 	hashmap.c \
 	atomic.c \
+        native_handle.c \
 	buffer.c \
 	socket_inaddr_any_server.c \
 	socket_local_client.c \
diff --git a/libcutils/native_handle.c b/libcutils/native_handle.c
new file mode 100644
index 0000000..4089968
--- /dev/null
+++ b/libcutils/native_handle.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2007 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 "NativeHandle"
+
+#include <stdint.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <cutils/log.h>
+#include <cutils/native_handle.h>
+
+native_handle_t* native_handle_create(int numFds, int numInts)
+{
+    native_handle_t* h = malloc(
+            sizeof(native_handle_t) + sizeof(int)*(numFds+numInts));
+
+    h->version = sizeof(native_handle_t);
+    h->numFds = numFds;
+    h->numInts = numInts;
+    return h;
+}
+
+int native_handle_delete(native_handle_t* h)
+{
+    if (h) {
+        if (h->version != sizeof(native_handle_t))
+            return -EINVAL;
+        free(h);
+    }
+    return 0;
+}
+
+int native_handle_close(const native_handle_t* h)
+{
+    if (h->version != sizeof(native_handle_t))
+        return -EINVAL;
+
+    const int numFds = h->numFds;
+    int i;
+    for (i=0 ; i<numFds ; i++) {
+        close(h->data[i]);
+    }
+    return 0;
+}