Fix the creation of the dumpdir directory in stress_floppy Makefile
[ltp-debian.git] / lib / cloner.c
blob93cdc436ccc490b0f272e3a9529bf6e159c447ef
1 /*
2 * Copyright (c) International Business Machines Corp., 2009
3 * Some wrappers for clone functionality. Thrown together by Serge Hallyn
4 * <serue@us.ibm.com> based on existing clone usage in ltp.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
14 * the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #ifndef _GNU_SOURCE
21 #define _GNU_SOURCE
22 #endif
24 #include <stdio.h>
25 #include <errno.h>
26 #include <unistd.h> /* fork, getpid, sleep */
27 #include <string.h>
28 #include <stdlib.h> /* exit */
29 #include <sched.h> /* clone */
30 #include "test.h"
32 #undef clone /* we want to use clone() */
34 /* copied from several other files under ltp */
35 #if defined (__s390__) || (__s390x__)
36 #define clone __clone
37 extern int __clone(int(void*),void*,int,void*);
38 #elif defined(__ia64__)
39 #define clone2 __clone2
40 /* Prototype provided by David Mosberger */
41 extern int __clone2(int (*fn) (void *arg), void *child_stack_base,
42 size_t child_stack_size, int flags, void *arg,
43 pid_t *parent_tid, void *tls, pid_t *child_tid);
44 #endif
46 /***********************************************************************
47 * ltp_clone: wrapper for clone to hide the architecture dependencies.
48 * 1. hppa takes bottom of stack and no stacksize (stack grows up)
49 * 2. __ia64__ takes bottom of stack and uses clone2
50 * 3. all others take top of stack (stack grows down)
51 ***********************************************************************/
52 int
53 ltp_clone(unsigned long clone_flags, int (*fn)(void *arg), void *arg,
54 size_t stack_size, void *stack)
56 int ret;
58 #if defined(__hppa__)
59 ret = clone(fn, stack, clone_flags, arg);
60 #elif defined(__ia64__)
61 ret = clone2(fn, stack, stack_size, clone_flags, arg, NULL, NULL, NULL);
62 #else
63 ret = clone(fn, (stack ? stack + stack_size - 1 : NULL),
64 clone_flags, arg);
65 #endif
67 return ret;
70 /***********************************************************************
71 * ltp_clone_malloc: also does the memory allocation for clone with a
72 * caller-specified size.
73 ***********************************************************************/
74 int
75 ltp_clone_malloc(unsigned long clone_flags, int (*fn)(void *arg), void *arg,
76 size_t stack_size)
78 int ret;
79 void *stack = malloc(stack_size);
80 int saved_errno;
82 if (!stack)
83 return -1;
85 ret = ltp_clone(clone_flags, fn, arg, stack_size, stack);
87 if (ret == -1) {
88 saved_errno = errno;
89 free(stack);
90 errno = saved_errno;
93 return ret;
96 /***********************************************************************
97 * ltp_clone_quick: calls ltp_clone_malloc with predetermined stack size.
98 * Experience thus far suggests that one page is often insufficient,
99 * while 4*getpagesize() seems adequate.
100 ***********************************************************************/
102 ltp_clone_quick(unsigned long clone_flags, int (*fn)(void *arg), void *arg)
104 size_t stack_size = getpagesize() * 4;
106 return ltp_clone_malloc(clone_flags, fn, arg, stack_size);