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