ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Linux-Clone/Clone.xs
Revision: 1.1
Committed: Mon Nov 28 05:43:03 2011 UTC (12 years, 5 months ago) by root
Branch: MAIN
CVS Tags: rel-0_01
Log Message:
0.01

File Contents

# Content
1 #include "EXTERN.h"
2 #include "perl.h"
3 #include "XSUB.h"
4
5 #include <sys/errno.h>
6 #include <sys/mman.h>
7
8 #undef _GNU_SOURCE
9 #define _GNU_SOURCE
10 #include <sched.h>
11
12 static int
13 clone_cb (void *arg)
14 {
15 dSP;
16
17 PUSHMARK (SP);
18
19 PUTBACK;
20 int count = call_sv (sv_2mortal ((SV *)arg), G_SCALAR);
21 SPAGAIN;
22 int retval = count ? SvIV (POPs) : 0;
23 PUTBACK;
24
25 return retval;
26 }
27
28 MODULE = Linux::Clone PACKAGE = Linux::Clone
29
30 PROTOTYPES: ENABLE
31
32 BOOT:
33 HV *stash = gv_stashpv ("Linux::Clone", 1);
34
35 static const struct {
36 const char *name;
37 IV iv;
38 } *civ, const_iv[] = {
39 # define const_iv(name) { # name, (IV) CLONE_ ## name },
40 # ifdef CLONE_FILES
41 const_iv (FILES)
42 # endif
43 # ifdef CLONE_FS
44 const_iv (FS)
45 # endif
46 # ifdef CLONE_NEWNS
47 const_iv (NEWNS)
48 # endif
49 # ifdef CLONE_VM
50 const_iv (VM)
51 # endif
52 # ifdef CLONE_THREAD
53 const_iv (THREAD)
54 # endif
55 # ifdef CLONE_SIGHAND
56 const_iv (SIGHAND)
57 # endif
58 # ifdef CLONE_SYSVSEM
59 const_iv (SYSVSEM)
60 # endif
61 # ifdef CLONE_NEWUTS
62 const_iv (NEWUTS)
63 # endif
64 # ifdef CLONE_NEWIPC
65 const_iv (NEWIPC)
66 # endif
67 # ifdef CLONE_NEWNET
68 const_iv (NEWNET)
69 # endif
70 # ifdef CLONE_PTRACE
71 const_iv (PTRACE)
72 # endif
73 # ifdef CLONE_VFORK
74 const_iv (VFORK)
75 # endif
76 # ifdef CLONE_SETTLS
77 const_iv (SETTLS)
78 # endif
79 # ifdef CLONE_PARENT_SETTID
80 const_iv (PARENT_SETTID)
81 # endif
82 # ifdef CLONE_CHILD_CLEARTID
83 const_iv (CHILD_CLEARTID)
84 # endif
85 # ifdef CLONE_DETACHED
86 const_iv (DETACHED)
87 # endif
88 # ifdef CLONE_UNTRACED
89 const_iv (UNTRACED)
90 # endif
91 # ifdef CLONE_CHILD_SETTID
92 const_iv (CHILD_SETTID)
93 # endif
94 # ifdef CLONE_NEWUSER
95 const_iv (NEWUSER)
96 # endif
97 # ifdef CLONE_NEWPID
98 const_iv (NEWPID)
99 # endif
100 # ifdef CLONE_IO
101 const_iv (IO)
102 # endif
103 };
104
105 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ > const_iv; civ--)
106 newCONSTSUB (stash, (char *)civ[-1].name, newSViv (civ[-1].iv));
107
108 int
109 unshare (int flags)
110 CODE:
111 RETVAL = unshare (flags);
112 OUTPUT:
113 RETVAL
114
115 int
116 clone (SV *sub, IV stacksize, int flags, SV *ptid = 0, SV *tls = &PL_sv_undef)
117 CODE:
118 {
119 if (!stacksize)
120 stacksize = 4 << 20;
121
122 pid_t ptid_;
123 char *stack_ptr = mmap (0, stacksize, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_GROWSDOWN | MAP_STACK, -1, 0);
124
125 #ifndef __hppa
126 stack_ptr += stacksize - 16; /* be safe and put the sp at 16 bytes below the end */
127 #endif
128
129 RETVAL = -1;
130 if (stack_ptr != (void *)-1)
131 {
132 SV *my_sub = newSVsv (sub);
133
134 RETVAL = clone (clone_cb, (void *)stack_ptr, flags, (void *)my_sub, &ptid, SvOK (tls) ? SvPV_nolen (tls) : 0, 0);
135
136 if (ptid) sv_setiv (ptid, (IV)ptid_);
137
138 if ((flags & (CLONE_VM | CLONE_VFORK)) != CLONE_VM)
139 {
140 int old_errno = errno;
141 munmap (stack_ptr, stacksize);
142 errno = old_errno;
143 }
144 }
145 }
146 OUTPUT:
147 RETVAL
148