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

# User Rev Content
1 root 1.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 root 1.3 #include <unistd.h>
12     #include <sys/syscall.h>
13    
14 root 1.6 #include <sched.h>
15    
16     #include <sys/ioctl.h>
17     #include <net/if.h>
18    
19 root 1.7 #include <linux/nsfs.h>
20    
21 root 1.4 #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 root 1.3 #ifdef SYS_kcmp
28 root 1.4 #include "linux/kcmp.h"
29 root 1.3 #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 root 1.1
37 root 1.2 /* 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 root 1.1 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 root 1.4 # define const_iv(name) { # name, (IV)name },
87     # define const_iv_clone(name) { # name, (IV) CLONE_ ## name },
88 root 1.6 # ifdef CSIGNAL
89     const_iv (CSIGNAL)
90     # endif
91 root 1.1 # ifdef CLONE_FILES
92 root 1.4 const_iv_clone (FILES)
93 root 1.1 # endif
94     # ifdef CLONE_FS
95 root 1.4 const_iv_clone (FS)
96 root 1.1 # endif
97     # ifdef CLONE_NEWNS
98 root 1.4 const_iv_clone (NEWNS)
99 root 1.1 # endif
100     # ifdef CLONE_VM
101 root 1.4 const_iv_clone (VM)
102 root 1.1 # endif
103     # ifdef CLONE_THREAD
104 root 1.4 const_iv_clone (THREAD)
105 root 1.1 # endif
106     # ifdef CLONE_SIGHAND
107 root 1.4 const_iv_clone (SIGHAND)
108 root 1.1 # endif
109     # ifdef CLONE_SYSVSEM
110 root 1.4 const_iv_clone (SYSVSEM)
111 root 1.1 # endif
112     # ifdef CLONE_NEWUTS
113 root 1.4 const_iv_clone (NEWUTS)
114 root 1.1 # endif
115     # ifdef CLONE_NEWIPC
116 root 1.4 const_iv_clone (NEWIPC)
117 root 1.1 # endif
118     # ifdef CLONE_NEWNET
119 root 1.4 const_iv_clone (NEWNET)
120 root 1.1 # endif
121     # ifdef CLONE_PTRACE
122 root 1.4 const_iv_clone (PTRACE)
123 root 1.1 # endif
124     # ifdef CLONE_VFORK
125 root 1.4 const_iv_clone (VFORK)
126 root 1.1 # endif
127     # ifdef CLONE_SETTLS
128 root 1.4 const_iv_clone (SETTLS)
129 root 1.1 # endif
130     # ifdef CLONE_PARENT_SETTID
131 root 1.4 const_iv_clone (PARENT_SETTID)
132 root 1.1 # endif
133     # ifdef CLONE_CHILD_CLEARTID
134 root 1.4 const_iv_clone (CHILD_CLEARTID)
135 root 1.1 # endif
136     # ifdef CLONE_DETACHED
137 root 1.4 const_iv_clone (DETACHED)
138 root 1.1 # endif
139     # ifdef CLONE_UNTRACED
140 root 1.4 const_iv_clone (UNTRACED)
141 root 1.1 # endif
142     # ifdef CLONE_CHILD_SETTID
143 root 1.4 const_iv_clone (CHILD_SETTID)
144 root 1.1 # endif
145     # ifdef CLONE_NEWUSER
146 root 1.4 const_iv_clone (NEWUSER)
147 root 1.1 # endif
148     # ifdef CLONE_NEWPID
149 root 1.4 const_iv_clone (NEWPID)
150 root 1.1 # endif
151     # ifdef CLONE_IO
152 root 1.4 const_iv_clone (IO)
153 root 1.1 # endif
154 root 1.2 # ifdef CLONE_NEWCGROUP
155 root 1.4 const_iv_clone (NEWCGROUP)
156 root 1.3 # endif
157 root 1.5 # ifdef CLONE_PIDFD
158     const_iv_clone (PIDFD)
159     # endif
160 root 1.3 # 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 root 1.2 # endif
170 root 1.7 # 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 root 1.1 };
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 root 1.2 if (!stacksize)
192 root 1.1 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 root 1.6 OUTPUT: RETVAL
219 root 1.1
220 root 1.2 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 root 1.3
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 root 1.6 OUTPUT: RETVAL
234 root 1.3
235     int
236     kcmp (IV pid1, IV pid2, IV type, UV idx1 = 0, UV idx2 = 0)
237    
238 root 1.6 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