ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Linux-Clone/Clone.xs
Revision: 1.4
Committed: Tue Nov 7 18:15:29 2017 UTC (6 years, 6 months ago) by root
Branch: MAIN
CVS Tags: rel-1_2
Changes since 1.3: +31 -24 lines
Log Message:
1.2

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 #include <unistd.h>
12 #include <sys/syscall.h>
13
14 #ifdef __has_include
15 #if !__has_include("linux/kcmp.h") // use "" as GCC wrongly expands macros
16 #undef SYS_kcmp
17 #endif
18 #endif
19
20 #ifdef SYS_kcmp
21 #include "linux/kcmp.h"
22 #define kcmp(pid1,pid2,type,idx1,idx2) \
23 syscall (SYS_kcmp, (pid_t)pid1, (pid_t)pid2, \
24 (int)type, (unsigned long)idx1, (unsigned long)idx2)
25 #else
26 #define kcmp(pid1,pid2,type,idx1,idx2) \
27 (errno = ENOSYS, -1)
28 #endif
29
30 /* from schmorp.h */
31 static int
32 s_fileno (SV *fh, int wr)
33 {
34 dTHX;
35 SvGETMAGIC (fh);
36
37 if (SvROK (fh))
38 {
39 fh = SvRV (fh);
40 SvGETMAGIC (fh);
41 }
42
43 if (SvTYPE (fh) == SVt_PVGV)
44 return PerlIO_fileno (wr ? IoOFP (sv_2io (fh)) : IoIFP (sv_2io (fh)));
45
46 if (SvOK (fh) && (SvIV (fh) >= 0) && (SvIV (fh) < 0x7fffffffL))
47 return SvIV (fh);
48
49 return -1;
50 }
51
52 static int
53 clone_cb (void *arg)
54 {
55 dSP;
56
57 PUSHMARK (SP);
58
59 PUTBACK;
60 int count = call_sv (sv_2mortal ((SV *)arg), G_SCALAR);
61 SPAGAIN;
62 int retval = count ? SvIV (POPs) : 0;
63 PUTBACK;
64
65 return retval;
66 }
67
68 MODULE = Linux::Clone PACKAGE = Linux::Clone
69
70 PROTOTYPES: ENABLE
71
72 BOOT:
73 HV *stash = gv_stashpv ("Linux::Clone", 1);
74
75 static const struct {
76 const char *name;
77 IV iv;
78 } *civ, const_iv[] = {
79 # define const_iv(name) { # name, (IV)name },
80 # define const_iv_clone(name) { # name, (IV) CLONE_ ## name },
81 # ifdef CLONE_FILES
82 const_iv_clone (FILES)
83 # endif
84 # ifdef CLONE_FS
85 const_iv_clone (FS)
86 # endif
87 # ifdef CLONE_NEWNS
88 const_iv_clone (NEWNS)
89 # endif
90 # ifdef CLONE_VM
91 const_iv_clone (VM)
92 # endif
93 # ifdef CLONE_THREAD
94 const_iv_clone (THREAD)
95 # endif
96 # ifdef CLONE_SIGHAND
97 const_iv_clone (SIGHAND)
98 # endif
99 # ifdef CLONE_SYSVSEM
100 const_iv_clone (SYSVSEM)
101 # endif
102 # ifdef CLONE_NEWUTS
103 const_iv_clone (NEWUTS)
104 # endif
105 # ifdef CLONE_NEWIPC
106 const_iv_clone (NEWIPC)
107 # endif
108 # ifdef CLONE_NEWNET
109 const_iv_clone (NEWNET)
110 # endif
111 # ifdef CLONE_PTRACE
112 const_iv_clone (PTRACE)
113 # endif
114 # ifdef CLONE_VFORK
115 const_iv_clone (VFORK)
116 # endif
117 # ifdef CLONE_SETTLS
118 const_iv_clone (SETTLS)
119 # endif
120 # ifdef CLONE_PARENT_SETTID
121 const_iv_clone (PARENT_SETTID)
122 # endif
123 # ifdef CLONE_CHILD_CLEARTID
124 const_iv_clone (CHILD_CLEARTID)
125 # endif
126 # ifdef CLONE_DETACHED
127 const_iv_clone (DETACHED)
128 # endif
129 # ifdef CLONE_UNTRACED
130 const_iv_clone (UNTRACED)
131 # endif
132 # ifdef CLONE_CHILD_SETTID
133 const_iv_clone (CHILD_SETTID)
134 # endif
135 # ifdef CLONE_NEWUSER
136 const_iv_clone (NEWUSER)
137 # endif
138 # ifdef CLONE_NEWPID
139 const_iv_clone (NEWPID)
140 # endif
141 # ifdef CLONE_IO
142 const_iv_clone (IO)
143 # endif
144 # ifdef CLONE_NEWCGROUP
145 const_iv_clone (NEWCGROUP)
146 # endif
147 # ifdef SYS_kcmp
148 const_iv (KCMP_FILE)
149 const_iv (KCMP_VM)
150 const_iv (KCMP_FILES)
151 const_iv (KCMP_FS)
152 const_iv (KCMP_SIGHAND)
153 const_iv (KCMP_IO)
154 const_iv (KCMP_SYSVSEM)
155 const_iv (KCMP_FILE)
156 # endif
157 };
158
159 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ > const_iv; civ--)
160 newCONSTSUB (stash, (char *)civ[-1].name, newSViv (civ[-1].iv));
161
162 int
163 clone (SV *sub, IV stacksize, int flags, SV *ptid = 0, SV *tls = &PL_sv_undef)
164 CODE:
165 {
166 if (!stacksize)
167 stacksize = 4 << 20;
168
169 pid_t ptid_;
170 char *stack_ptr = mmap (0, stacksize, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_GROWSDOWN | MAP_STACK, -1, 0);
171
172 #ifndef __hppa
173 stack_ptr += stacksize - 16; /* be safe and put the sp at 16 bytes below the end */
174 #endif
175
176 RETVAL = -1;
177 if (stack_ptr != (void *)-1)
178 {
179 SV *my_sub = newSVsv (sub);
180
181 RETVAL = clone (clone_cb, (void *)stack_ptr, flags, (void *)my_sub, &ptid, SvOK (tls) ? SvPV_nolen (tls) : 0, 0);
182
183 if (ptid) sv_setiv (ptid, (IV)ptid_);
184
185 if ((flags & (CLONE_VM | CLONE_VFORK)) != CLONE_VM)
186 {
187 int old_errno = errno;
188 munmap (stack_ptr, stacksize);
189 errno = old_errno;
190 }
191 }
192 }
193 OUTPUT:
194 RETVAL
195
196 int
197 unshare (int flags)
198
199 int
200 setns (SV *fh_or_fd, int nstype = 0)
201 C_ARGS: s_fileno (fh_or_fd, 0), nstype
202
203 int
204 pivot_root (SV *new_root, SV *old_root)
205 CODE:
206 RETVAL = syscall (SYS_pivot_root,
207 (const char *)SvPVbyte_nolen (new_root),
208 (const char *)SvPVbyte_nolen (old_root));
209 OUTPUT:
210 RETVAL
211
212 int
213 kcmp (IV pid1, IV pid2, IV type, UV idx1 = 0, UV idx2 = 0)
214