forked from cirosantilli/cpp-cheat
-
Notifications
You must be signed in to change notification settings - Fork 0
/
clone.c.off
107 lines (79 loc) · 2.6 KB
/
clone.c.off
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/*
# clone
Create a new thread.
Interface for the `clone` Linux system call.
man clone
which allows you to:
- create threads
- create new processes. This is done with the POSIX `fork`. Linux also has a `fork` system call,
but it seems that it is a thin `clone` wrapper.
See also:
- http://stackoverflow.com/questions/4856255/the-difference-between-fork-vfork-exec-and-clone
- http://stackoverflow.com/questions/18904292/is-it-true-that-fork-calls-clone-internally
The difference is basically what is going to be shared between the two processes / threads.
glibc gives two wrappers:
- a raw system call wrapper
- a high level
# Raw wrapper
long clone(unsigned long flags,
void *child_stack,
void *ptid,
void *ctid,
struct pt_regs *regs);
TODO what is that pt_regs?
That struct contains register values... is it really arch dependent?
Also I don't see that anywhere on Linux source nor glibc... is it just an old API?
# High level wrapper
int clone(int (*fn)(void *), void *child_stack,
int flags, void *arg, ...
pid_t *ptid, struct user_desc *tls, pid_t *ctid);
The thread runs inside the given function.
Used to implement the POSIX `pthread` interface.
man 2 clone
TODO get working
*/
#define _GNU_SOURCE
#include <assert.h>
#include <sched.h> /* clone */
#include <stdio.h> /* perror */
#include <stdlib.h> /* EXIT_SUCCESS, EXIT_FAILURE, malloc, free */
/* Linux headers. */
#include <asm/ptrace.h>
int main() {
int i = 0;
const int STACK_SIZE = 1024;
char *stack_bottom;
char *stack_top;
/*pid_t pid = clone(*/
/*clone_fn,*/
/*SIGCHLD,*/
/*);*/
struct pt_regs regs;
stack_bottom = malloc(STACK_SIZE);
if (stack_bottom == NULL) {
perror("malloc");
exit(EXIT_FAILURE);
}
stack_top = stack_bottom + STACK_SIZE; /* Assume stack grows downward */
clone(
CLONE_VM, /* int flags */
stack_top, /* void* child_stack */
, /* void *ptid */
, /* void *ctid*/
, /* struct pt_regs *regs */
);
free(stack_bottom);
/*if (pid < 0) {*/
/*perror("clone");*/
/*exit(EXIT_FAILURE);*/
/*}*/
/*if (pid == 0) {*/
/*i++;*/
/*return EXIT_SUCCESS;*/
/*}*/
/*wait(&status);*/
//no more child process
/*assert(status == EXIT_SUCCESS);*/
assert(i == 1);
exit(EXIT_SUCCESS);
}