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