ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Linux-Clone/Clone.xs
Revision: 1.1
Committed: Mon Nov 28 05:43:03 2011 UTC (12 years, 5 months ago) by root
Branch: MAIN
CVS Tags: rel-0_01
Log Message:
0.01

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    
12     static int
13     clone_cb (void *arg)
14     {
15     dSP;
16    
17     PUSHMARK (SP);
18    
19     PUTBACK;
20     int count = call_sv (sv_2mortal ((SV *)arg), G_SCALAR);
21     SPAGAIN;
22     int retval = count ? SvIV (POPs) : 0;
23     PUTBACK;
24    
25     return retval;
26     }
27    
28     MODULE = Linux::Clone PACKAGE = Linux::Clone
29    
30     PROTOTYPES: ENABLE
31    
32     BOOT:
33     HV *stash = gv_stashpv ("Linux::Clone", 1);
34    
35     static const struct {
36     const char *name;
37     IV iv;
38     } *civ, const_iv[] = {
39     # define const_iv(name) { # name, (IV) CLONE_ ## name },
40     # ifdef CLONE_FILES
41     const_iv (FILES)
42     # endif
43     # ifdef CLONE_FS
44     const_iv (FS)
45     # endif
46     # ifdef CLONE_NEWNS
47     const_iv (NEWNS)
48     # endif
49     # ifdef CLONE_VM
50     const_iv (VM)
51     # endif
52     # ifdef CLONE_THREAD
53     const_iv (THREAD)
54     # endif
55     # ifdef CLONE_SIGHAND
56     const_iv (SIGHAND)
57     # endif
58     # ifdef CLONE_SYSVSEM
59     const_iv (SYSVSEM)
60     # endif
61     # ifdef CLONE_NEWUTS
62     const_iv (NEWUTS)
63     # endif
64     # ifdef CLONE_NEWIPC
65     const_iv (NEWIPC)
66     # endif
67     # ifdef CLONE_NEWNET
68     const_iv (NEWNET)
69     # endif
70     # ifdef CLONE_PTRACE
71     const_iv (PTRACE)
72     # endif
73     # ifdef CLONE_VFORK
74     const_iv (VFORK)
75     # endif
76     # ifdef CLONE_SETTLS
77     const_iv (SETTLS)
78     # endif
79     # ifdef CLONE_PARENT_SETTID
80     const_iv (PARENT_SETTID)
81     # endif
82     # ifdef CLONE_CHILD_CLEARTID
83     const_iv (CHILD_CLEARTID)
84     # endif
85     # ifdef CLONE_DETACHED
86     const_iv (DETACHED)
87     # endif
88     # ifdef CLONE_UNTRACED
89     const_iv (UNTRACED)
90     # endif
91     # ifdef CLONE_CHILD_SETTID
92     const_iv (CHILD_SETTID)
93     # endif
94     # ifdef CLONE_NEWUSER
95     const_iv (NEWUSER)
96     # endif
97     # ifdef CLONE_NEWPID
98     const_iv (NEWPID)
99     # endif
100     # ifdef CLONE_IO
101     const_iv (IO)
102     # endif
103     };
104    
105     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));
107    
108     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)
117     CODE:
118     {
119     if (!stacksize)
120     stacksize = 4 << 20;
121    
122     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);
124    
125     #ifndef __hppa
126     stack_ptr += stacksize - 16; /* be safe and put the sp at 16 bytes below the end */
127     #endif
128    
129     RETVAL = -1;
130     if (stack_ptr != (void *)-1)
131     {
132     SV *my_sub = newSVsv (sub);
133    
134     RETVAL = clone (clone_cb, (void *)stack_ptr, flags, (void *)my_sub, &ptid, SvOK (tls) ? SvPV_nolen (tls) : 0, 0);
135    
136     if (ptid) sv_setiv (ptid, (IV)ptid_);
137    
138     if ((flags & (CLONE_VM | CLONE_VFORK)) != CLONE_VM)
139     {
140     int old_errno = errno;
141     munmap (stack_ptr, stacksize);
142     errno = old_errno;
143     }
144     }
145     }
146     OUTPUT:
147     RETVAL
148