ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Linux-Clone/Clone.xs
Revision: 1.5
Committed: Mon Jul 25 10:59:29 2022 UTC (21 months, 3 weeks ago) by root
Branch: MAIN
Changes since 1.4: +3 -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.4 #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 root 1.3 #ifdef SYS_kcmp
21 root 1.4 #include "linux/kcmp.h"
22 root 1.3 #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 root 1.1
30 root 1.2 /* 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 root 1.1 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 root 1.4 # define const_iv(name) { # name, (IV)name },
80     # define const_iv_clone(name) { # name, (IV) CLONE_ ## name },
81 root 1.1 # ifdef CLONE_FILES
82 root 1.4 const_iv_clone (FILES)
83 root 1.1 # endif
84     # ifdef CLONE_FS
85 root 1.4 const_iv_clone (FS)
86 root 1.1 # endif
87     # ifdef CLONE_NEWNS
88 root 1.4 const_iv_clone (NEWNS)
89 root 1.1 # endif
90     # ifdef CLONE_VM
91 root 1.4 const_iv_clone (VM)
92 root 1.1 # endif
93     # ifdef CLONE_THREAD
94 root 1.4 const_iv_clone (THREAD)
95 root 1.1 # endif
96     # ifdef CLONE_SIGHAND
97 root 1.4 const_iv_clone (SIGHAND)
98 root 1.1 # endif
99     # ifdef CLONE_SYSVSEM
100 root 1.4 const_iv_clone (SYSVSEM)
101 root 1.1 # endif
102     # ifdef CLONE_NEWUTS
103 root 1.4 const_iv_clone (NEWUTS)
104 root 1.1 # endif
105     # ifdef CLONE_NEWIPC
106 root 1.4 const_iv_clone (NEWIPC)
107 root 1.1 # endif
108     # ifdef CLONE_NEWNET
109 root 1.4 const_iv_clone (NEWNET)
110 root 1.1 # endif
111     # ifdef CLONE_PTRACE
112 root 1.4 const_iv_clone (PTRACE)
113 root 1.1 # endif
114     # ifdef CLONE_VFORK
115 root 1.4 const_iv_clone (VFORK)
116 root 1.1 # endif
117     # ifdef CLONE_SETTLS
118 root 1.4 const_iv_clone (SETTLS)
119 root 1.1 # endif
120     # ifdef CLONE_PARENT_SETTID
121 root 1.4 const_iv_clone (PARENT_SETTID)
122 root 1.1 # endif
123     # ifdef CLONE_CHILD_CLEARTID
124 root 1.4 const_iv_clone (CHILD_CLEARTID)
125 root 1.1 # endif
126     # ifdef CLONE_DETACHED
127 root 1.4 const_iv_clone (DETACHED)
128 root 1.1 # endif
129     # ifdef CLONE_UNTRACED
130 root 1.4 const_iv_clone (UNTRACED)
131 root 1.1 # endif
132     # ifdef CLONE_CHILD_SETTID
133 root 1.4 const_iv_clone (CHILD_SETTID)
134 root 1.1 # endif
135     # ifdef CLONE_NEWUSER
136 root 1.4 const_iv_clone (NEWUSER)
137 root 1.1 # endif
138     # ifdef CLONE_NEWPID
139 root 1.4 const_iv_clone (NEWPID)
140 root 1.1 # endif
141     # ifdef CLONE_IO
142 root 1.4 const_iv_clone (IO)
143 root 1.1 # endif
144 root 1.2 # ifdef CLONE_NEWCGROUP
145 root 1.4 const_iv_clone (NEWCGROUP)
146 root 1.3 # endif
147 root 1.5 # ifdef CLONE_PIDFD
148     const_iv_clone (PIDFD)
149     # endif
150 root 1.3 # ifdef SYS_kcmp
151     const_iv (KCMP_FILE)
152     const_iv (KCMP_VM)
153     const_iv (KCMP_FILES)
154     const_iv (KCMP_FS)
155     const_iv (KCMP_SIGHAND)
156     const_iv (KCMP_IO)
157     const_iv (KCMP_SYSVSEM)
158     const_iv (KCMP_FILE)
159 root 1.2 # endif
160 root 1.1 };
161    
162     for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ > const_iv; civ--)
163     newCONSTSUB (stash, (char *)civ[-1].name, newSViv (civ[-1].iv));
164    
165     int
166     clone (SV *sub, IV stacksize, int flags, SV *ptid = 0, SV *tls = &PL_sv_undef)
167     CODE:
168     {
169 root 1.2 if (!stacksize)
170 root 1.1 stacksize = 4 << 20;
171    
172     pid_t ptid_;
173     char *stack_ptr = mmap (0, stacksize, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_GROWSDOWN | MAP_STACK, -1, 0);
174    
175     #ifndef __hppa
176     stack_ptr += stacksize - 16; /* be safe and put the sp at 16 bytes below the end */
177     #endif
178    
179     RETVAL = -1;
180     if (stack_ptr != (void *)-1)
181     {
182     SV *my_sub = newSVsv (sub);
183    
184     RETVAL = clone (clone_cb, (void *)stack_ptr, flags, (void *)my_sub, &ptid, SvOK (tls) ? SvPV_nolen (tls) : 0, 0);
185    
186     if (ptid) sv_setiv (ptid, (IV)ptid_);
187    
188     if ((flags & (CLONE_VM | CLONE_VFORK)) != CLONE_VM)
189     {
190     int old_errno = errno;
191     munmap (stack_ptr, stacksize);
192     errno = old_errno;
193     }
194     }
195     }
196     OUTPUT:
197     RETVAL
198    
199 root 1.2 int
200     unshare (int flags)
201    
202     int
203     setns (SV *fh_or_fd, int nstype = 0)
204     C_ARGS: s_fileno (fh_or_fd, 0), nstype
205 root 1.3
206     int
207     pivot_root (SV *new_root, SV *old_root)
208     CODE:
209     RETVAL = syscall (SYS_pivot_root,
210     (const char *)SvPVbyte_nolen (new_root),
211     (const char *)SvPVbyte_nolen (old_root));
212     OUTPUT:
213     RETVAL
214    
215     int
216     kcmp (IV pid1, IV pid2, IV type, UV idx1 = 0, UV idx2 = 0)
217