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