ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Linux-Clone/Clone.xs
Revision: 1.3
Committed: Thu Nov 2 07:31:16 2017 UTC (6 years, 6 months ago) by root
Branch: MAIN
CVS Tags: rel-1_1
Changes since 1.2: +58 -23 lines
Log Message:
1.1

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