This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
3503ad92b18f6315893eb19b35b8571fcb1b1ed9
[perl5.git] / ext / IPC / SysV / SysV.xs
1 #include "EXTERN.h"
2 #include "perl.h"
3 #include "XSUB.h"
4
5 #include <sys/types.h>
6 #ifdef __linux__
7 #include <asm/page.h>
8 #endif
9 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
10 #include <sys/ipc.h>
11 #ifdef HAS_MSG
12 #include <sys/msg.h>
13 #endif
14 #ifdef HAS_SEM
15 #include <sys/sem.h>
16 #endif
17 #ifdef HAS_SHM
18 #ifdef PERL_SCO5
19 #include <sys/sysmacros.h>
20 #endif
21 #include <sys/shm.h>
22 # ifndef HAS_SHMAT_PROTOTYPE
23     extern Shmat_t shmat _((int, char *, int));
24 # endif
25 #endif
26 #endif
27
28 /* Required in BSDI to get PAGE_SIZE definition for SHMLBA.
29  * Ugly.  More beautiful solutions welcome.
30  * Shouting at BSDI sounds quite beautiful. */
31 #ifdef __bsdi__
32 #   include <vm/vm_param.h>
33 #endif
34
35 MODULE=IPC::SysV        PACKAGE=IPC::Msg::stat
36
37 PROTOTYPES: ENABLE
38
39 void
40 pack(obj)
41     SV  * obj
42 PPCODE:
43 {
44     SV *sv;
45     struct msqid_ds ds;
46     AV *list = (AV*)SvRV(obj);
47     sv = *av_fetch(list,0,TRUE); ds.msg_perm.uid = SvIV(sv);
48     sv = *av_fetch(list,1,TRUE); ds.msg_perm.gid = SvIV(sv);
49     sv = *av_fetch(list,4,TRUE); ds.msg_perm.mode = SvIV(sv);
50     sv = *av_fetch(list,6,TRUE); ds.msg_qbytes = SvIV(sv);
51     ST(0) = sv_2mortal(newSVpv((char *)&ds,sizeof(ds)));
52     XSRETURN(1);
53 }
54
55 void
56 unpack(obj,buf)
57     SV * obj
58     SV * buf
59 PPCODE:
60 {
61     STRLEN len;
62     SV **sv_ptr;
63     struct msqid_ds *ds = (struct msqid_ds *)SvPV(buf,len);
64     AV *list = (AV*)SvRV(obj);
65     if (len != sizeof(*ds)) {
66         croak("Bad arg length for %s, length is %d, should be %d",
67                     "IPC::Msg::stat",
68                     len, sizeof(*ds));
69     }
70     sv_ptr = av_fetch(list,0,TRUE);
71     sv_setiv(*sv_ptr, ds->msg_perm.uid);
72     sv_ptr = av_fetch(list,1,TRUE);
73     sv_setiv(*sv_ptr, ds->msg_perm.gid);
74     sv_ptr = av_fetch(list,2,TRUE);
75     sv_setiv(*sv_ptr, ds->msg_perm.cuid);
76     sv_ptr = av_fetch(list,3,TRUE);
77     sv_setiv(*sv_ptr, ds->msg_perm.cgid);
78     sv_ptr = av_fetch(list,4,TRUE);
79     sv_setiv(*sv_ptr, ds->msg_perm.mode);
80     sv_ptr = av_fetch(list,5,TRUE);
81     sv_setiv(*sv_ptr, ds->msg_qnum);
82     sv_ptr = av_fetch(list,6,TRUE);
83     sv_setiv(*sv_ptr, ds->msg_qbytes);
84     sv_ptr = av_fetch(list,7,TRUE);
85     sv_setiv(*sv_ptr, ds->msg_lspid);
86     sv_ptr = av_fetch(list,8,TRUE);
87     sv_setiv(*sv_ptr, ds->msg_lrpid);
88     sv_ptr = av_fetch(list,9,TRUE);
89     sv_setiv(*sv_ptr, ds->msg_stime);
90     sv_ptr = av_fetch(list,10,TRUE);
91     sv_setiv(*sv_ptr, ds->msg_rtime);
92     sv_ptr = av_fetch(list,11,TRUE);
93     sv_setiv(*sv_ptr, ds->msg_ctime);
94     XSRETURN(1);
95 }
96
97 MODULE=IPC::SysV        PACKAGE=IPC::Semaphore::stat
98
99 void
100 unpack(obj,ds)
101     SV * obj
102     SV * ds
103 PPCODE:
104 {
105     STRLEN len;
106     AV *list = (AV*)SvRV(obj);
107     struct semid_ds *data = (struct semid_ds *)SvPV(ds,len);
108     if(!sv_isa(obj, "IPC::Semaphore::stat"))
109         croak("method %s not called a %s object",
110                 "unpack","IPC::Semaphore::stat");
111     if (len != sizeof(*data)) {
112         croak("Bad arg length for %s, length is %d, should be %d",
113                     "IPC::Semaphore::stat",
114                     len, sizeof(*data));
115     }
116     sv_setiv(*av_fetch(list,0,TRUE), data[0].sem_perm.uid);
117     sv_setiv(*av_fetch(list,1,TRUE), data[0].sem_perm.gid);
118     sv_setiv(*av_fetch(list,2,TRUE), data[0].sem_perm.cuid);
119     sv_setiv(*av_fetch(list,3,TRUE), data[0].sem_perm.cgid);
120     sv_setiv(*av_fetch(list,4,TRUE), data[0].sem_perm.mode);
121     sv_setiv(*av_fetch(list,5,TRUE), data[0].sem_ctime);
122     sv_setiv(*av_fetch(list,6,TRUE), data[0].sem_otime);
123     sv_setiv(*av_fetch(list,7,TRUE), data[0].sem_nsems);
124     XSRETURN(1);
125 }
126
127 void
128 pack(obj)
129     SV  * obj
130 PPCODE:
131 {
132     SV **sv_ptr;
133     SV *sv;
134     struct semid_ds ds;
135     AV *list = (AV*)SvRV(obj);
136     if(!sv_isa(obj, "IPC::Semaphore::stat"))
137         croak("method %s not called a %s object",
138                 "pack","IPC::Semaphore::stat");
139     if((sv_ptr = av_fetch(list,0,TRUE)) && (sv = *sv_ptr))
140         ds.sem_perm.uid = SvIV(*sv_ptr);
141     if((sv_ptr = av_fetch(list,1,TRUE)) && (sv = *sv_ptr))
142         ds.sem_perm.gid = SvIV(*sv_ptr);
143     if((sv_ptr = av_fetch(list,2,TRUE)) && (sv = *sv_ptr))
144         ds.sem_perm.cuid = SvIV(*sv_ptr);
145     if((sv_ptr = av_fetch(list,3,TRUE)) && (sv = *sv_ptr))
146         ds.sem_perm.cgid = SvIV(*sv_ptr);
147     if((sv_ptr = av_fetch(list,4,TRUE)) && (sv = *sv_ptr))
148         ds.sem_perm.mode = SvIV(*sv_ptr);
149     if((sv_ptr = av_fetch(list,5,TRUE)) && (sv = *sv_ptr))
150         ds.sem_ctime = SvIV(*sv_ptr);
151     if((sv_ptr = av_fetch(list,6,TRUE)) && (sv = *sv_ptr))
152         ds.sem_otime = SvIV(*sv_ptr);
153     if((sv_ptr = av_fetch(list,7,TRUE)) && (sv = *sv_ptr))
154         ds.sem_nsems = SvIV(*sv_ptr);
155     ST(0) = sv_2mortal(newSVpv((char *)&ds,sizeof(ds)));
156     XSRETURN(1);
157 }
158
159 MODULE=IPC::SysV        PACKAGE=IPC::SysV
160
161 int
162 ftok(path, id)
163         char *          path
164         int             id
165     CODE:
166 #if defined(HAS_SEM) || defined(HAS_SHM)
167         key_t k = ftok(path, id);
168         ST(0) = k == (key_t) -1 ? &PL_sv_undef : sv_2mortal(newSViv(k));
169 #else
170         DIE(no_func, "ftok");
171 #endif
172
173 int
174 SHMLBA()
175     CODE:
176 #ifdef SHMLBA
177     ST(0) = sv_2mortal(newSViv(SHMLBA));
178 #else
179     croak("SHMLBA is not defined on this architecture");
180 #endif
181
182 BOOT:
183 {
184     HV *stash = gv_stashpvn("IPC::SysV", 9, TRUE);
185     /*
186      * constant subs for IPC::SysV
187      */
188      struct { char *n; I32 v; } IPC__SysV__const[] = {
189 #ifdef GETVAL
190         {"GETVAL", GETVAL},
191 #endif
192 #ifdef GETPID
193         {"GETPID", GETPID},
194 #endif
195 #ifdef GETNCNT
196         {"GETNCNT", GETNCNT},
197 #endif
198 #ifdef GETZCNT
199         {"GETZCNT", GETZCNT},
200 #endif
201 #ifdef GETALL
202         {"GETALL", GETALL},
203 #endif
204 #ifdef IPC_ALLOC
205         {"IPC_ALLOC", IPC_ALLOC},
206 #endif
207 #ifdef IPC_CREAT
208         {"IPC_CREAT", IPC_CREAT},
209 #endif
210 #ifdef IPC_EXCL
211         {"IPC_EXCL", IPC_EXCL},
212 #endif
213 #ifdef IPC_GETACL
214         {"IPC_GETACL", IPC_EXCL},
215 #endif
216 #ifdef IPC_LOCKED
217         {"IPC_LOCKED", IPC_LOCKED},
218 #endif
219 #ifdef IPC_M
220         {"IPC_M", IPC_M},
221 #endif
222 #ifdef IPC_NOERROR
223         {"IPC_NOERROR", IPC_NOERROR},
224 #endif
225 #ifdef IPC_NOWAIT
226         {"IPC_NOWAIT", IPC_NOWAIT},
227 #endif
228 #ifdef IPC_PRIVATE
229         {"IPC_PRIVATE", IPC_PRIVATE},
230 #endif
231 #ifdef IPC_R
232         {"IPC_R", IPC_R},
233 #endif
234 #ifdef IPC_RMID
235         {"IPC_RMID", IPC_RMID},
236 #endif
237 #ifdef IPC_SET
238         {"IPC_SET", IPC_SET},
239 #endif
240 #ifdef IPC_SETACL
241         {"IPC_SETACL", IPC_SETACL},
242 #endif
243 #ifdef IPC_SETLABEL
244         {"IPC_SETLABEL", IPC_SETLABEL},
245 #endif
246 #ifdef IPC_STAT
247         {"IPC_STAT", IPC_STAT},
248 #endif
249 #ifdef IPC_W
250         {"IPC_W", IPC_W},
251 #endif
252 #ifdef IPC_WANTED
253         {"IPC_WANTED", IPC_WANTED},
254 #endif
255 #ifdef MSG_NOERROR
256         {"MSG_NOERROR", MSG_NOERROR},
257 #endif
258 #ifdef MSG_FWAIT
259         {"MSG_FWAIT", MSG_FWAIT},
260 #endif
261 #ifdef MSG_LOCKED
262         {"MSG_LOCKED", MSG_LOCKED},
263 #endif
264 #ifdef MSG_MWAIT
265         {"MSG_MWAIT", MSG_MWAIT},
266 #endif
267 #ifdef MSG_WAIT
268         {"MSG_WAIT", MSG_WAIT},
269 #endif
270 #ifdef MSG_R
271         {"MSG_R", MSG_R},
272 #endif
273 #ifdef MSG_RWAIT
274         {"MSG_RWAIT", MSG_RWAIT},
275 #endif
276 #ifdef MSG_STAT
277         {"MSG_STAT", MSG_STAT},
278 #endif
279 #ifdef MSG_W
280         {"MSG_W", MSG_W},
281 #endif
282 #ifdef MSG_WWAIT
283         {"MSG_WWAIT", MSG_WWAIT},
284 #endif
285 #ifdef SEM_A
286         {"SEM_A", SEM_A},
287 #endif
288 #ifdef SEM_ALLOC
289         {"SEM_ALLOC", SEM_ALLOC},
290 #endif
291 #ifdef SEM_DEST
292         {"SEM_DEST", SEM_DEST},
293 #endif
294 #ifdef SEM_ERR
295         {"SEM_ERR", SEM_ERR},
296 #endif
297 #ifdef SEM_R
298         {"SEM_R", SEM_R},
299 #endif
300 #ifdef SEM_ORDER
301         {"SEM_ORDER", SEM_ORDER},
302 #endif
303 #ifdef SEM_UNDO
304         {"SEM_UNDO", SEM_UNDO},
305 #endif
306 #ifdef SETVAL
307         {"SETVAL", SETVAL},
308 #endif
309 #ifdef SETALL
310         {"SETALL", SETALL},
311 #endif
312 #ifdef SHM_CLEAR
313         {"SHM_CLEAR", SHM_CLEAR},
314 #endif
315 #ifdef SHM_COPY
316         {"SHM_COPY", SHM_COPY},
317 #endif
318 #ifdef SHM_DCACHE
319         {"SHM_DCACHE", SHM_DCACHE},
320 #endif
321 #ifdef SHM_DEST
322         {"SHM_DEST", SHM_DEST},
323 #endif
324 #ifdef SHM_ECACHE
325         {"SHM_ECACHE", SHM_ECACHE},
326 #endif
327 #ifdef SHM_FMAP
328         {"SHM_FMAP", SHM_FMAP},
329 #endif
330 #ifdef SHM_ICACHE
331         {"SHM_ICACHE", SHM_ICACHE},
332 #endif
333 #ifdef SHM_INIT
334         {"SHM_INIT", SHM_INIT},
335 #endif
336 #ifdef SHM_LOCK
337         {"SHM_LOCK", SHM_LOCK},
338 #endif
339 #ifdef SHM_LOCKED
340         {"SHM_LOCKED", SHM_LOCKED},
341 #endif
342 #ifdef SHM_MAP
343         {"SHM_MAP", SHM_MAP},
344 #endif
345 #ifdef SHM_NOSWAP
346         {"SHM_NOSWAP", SHM_NOSWAP},
347 #endif
348 #ifdef SHM_RDONLY
349         {"SHM_RDONLY", SHM_RDONLY},
350 #endif
351 #ifdef SHM_REMOVED
352         {"SHM_REMOVED", SHM_REMOVED},
353 #endif
354 #ifdef SHM_RND
355         {"SHM_RND", SHM_RND},
356 #endif
357 #ifdef SHM_SHARE_MMU
358         {"SHM_SHARE_MMU", SHM_SHARE_MMU},
359 #endif
360 #ifdef SHM_SHATTR
361         {"SHM_SHATTR", SHM_SHATTR},
362 #endif
363 #ifdef SHM_SIZE
364         {"SHM_SIZE", SHM_SIZE},
365 #endif
366 #ifdef SHM_UNLOCK
367         {"SHM_UNLOCK", SHM_UNLOCK},
368 #endif
369 #ifdef SHM_W
370         {"SHM_W", SHM_W},
371 #endif
372 #ifdef S_IRUSR
373         {"S_IRUSR", S_IRUSR},
374 #endif
375 #ifdef S_IWUSR
376         {"S_IWUSR", S_IWUSR},
377 #endif
378 #ifdef S_IRWXU
379         {"S_IRWXU", S_IRWXU},
380 #endif
381 #ifdef S_IRGRP
382         {"S_IRGRP", S_IRGRP},
383 #endif
384 #ifdef S_IWGRP
385         {"S_IWGRP", S_IWGRP},
386 #endif
387 #ifdef S_IRWXG
388         {"S_IRWXG", S_IRWXG},
389 #endif
390 #ifdef S_IROTH
391         {"S_IROTH", S_IROTH},
392 #endif
393 #ifdef S_IWOTH
394         {"S_IWOTH", S_IWOTH},
395 #endif
396 #ifdef S_IRWXO
397         {"S_IRWXO", S_IRWXO},
398 #endif
399         {Nullch,0}};
400     char *name;
401     int i;
402
403     for(i = 0 ; name = IPC__SysV__const[i].n ; i++) {
404         newCONSTSUB(stash,name, newSViv(IPC__SysV__const[i].v));
405     }
406 }
407