ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Linux-Clone/Clone.xs
Revision: 1.7
Committed: Sat Sep 3 23:56:10 2022 UTC (20 months, 2 weeks ago) by root
Branch: MAIN
Changes since 1.6: +14 -0 lines
Log Message:
*** empty log message ***

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