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