aboutsummaryrefslogtreecommitdiff
path: root/libc/bionic/clone.cpp
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2013-11-19 13:31:58 -0800
committerElliott Hughes <enh@google.com>2013-11-19 14:08:54 -0800
commit36d6188f8cd8b948fb797f11d9620d63d0c2215a (patch)
tree86b3162cac031151b2ae44b4d554fce4f9456147 /libc/bionic/clone.cpp
parent318e86ed887e04e593f3db9b84b402d5501ced9b (diff)
downloadbionic-36d6188f8cd8b948fb797f11d9620d63d0c2215a.tar.gz
Clean up forking and cloning.
The kernel now maintains the pthread_internal_t::tid field for us, and __clone was only used in one place so let's inline it so we don't have to leave such a dangerous function lying around. Also rename files to match their content and remove some useless #includes. Change-Id: I24299fb4a940e394de75f864ee36fdabbd9438f9
Diffstat (limited to 'libc/bionic/clone.cpp')
-rw-r--r--libc/bionic/clone.cpp63
1 files changed, 63 insertions, 0 deletions
diff --git a/libc/bionic/clone.cpp b/libc/bionic/clone.cpp
new file mode 100644
index 000000000..1d997fed7
--- /dev/null
+++ b/libc/bionic/clone.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define __GNU_SOURCE 1
+#include <sched.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+extern "C" pid_t __bionic_clone(uint32_t flags, void* child_stack, int* parent_tid, void* tls, int* child_tid, int (*fn)(void*), void* arg);
+extern "C" void __exit(int status);
+
+// Called from the __bionic_clone assembler to call the thread function then exit.
+extern "C" void __bionic_clone_entry(int (*fn)(void*), void* arg) {
+ int status = (*fn)(arg);
+ __exit(status);
+}
+
+int clone(int (*fn)(void*), void* child_stack, int flags, void* arg, ...) {
+ int* parent_tid = NULL;
+ void* new_tls = NULL;
+ int* child_tid = NULL;
+
+ // Extract any optional parameters required by the flags.
+ va_list args;
+ va_start(args, arg);
+ if ((flags & (CLONE_PARENT_SETTID|CLONE_SETTLS|CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID)) != 0) {
+ parent_tid = va_arg(args, int*);
+ }
+ if ((flags & (CLONE_SETTLS|CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID)) != 0) {
+ new_tls = va_arg(args, void*);
+ }
+ if ((flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID)) != 0) {
+ child_tid = va_arg(args, int*);
+ }
+ va_end(args);
+
+ return __bionic_clone(flags, child_stack, parent_tid, new_tls, child_tid, fn, arg);
+}