File Coverage

Resource.xs
Criterion Covered Total %
statement 90 97 92.8
branch n/a
condition n/a
subroutine n/a
pod n/a
total 90 97 92.8


line stmt bran cond sub pod time code
1             /*
2             * Copyright (c) 1995-2003 Jarkko Hietaniemi. All rights reserved.
3             * This program is free software; you can redistribute it and/or
4              * modify it under the same terms as Perl itself.
5              *
6              * Resource.xs
7              *
8              */
9            
10             #include "EXTERN.h"
11             #include "perl.h"
12             #include "XSUB.h"
13            
14             #if (PERL_VERSION < 4) || ((PERL_VERSION == 4) && (PERL_SUBVERSION <= 4))
15             #define PL_sv_undef sv_undef
16             #define PL_sv_yes sv_yes
17             #endif
18            
19             #if defined(__hpux) && !defined(_INCLUDE_XOPEN_SOURCE_EXTENDED)
20             #define _INCLUDE_XOPEN_SOURCE_EXTENDED
21             #endif
22            
23             /* if this fails your vendor has failed you and Perl cannot help. */
24             #include <sys/resource.h>
25              
26             #if defined(__sun__) && defined(__svr4__) && !defined(SOLARIS_NO_PROCFS)
27             # define SOLARIS
28             # define SOLARIS_PROCFS
29             # ifdef I_SYS_RUSAGE
30             # include <sys/rusage.h>
31             /* Some old Solarises have no RUSAGE_* defined in <sys/resource.h>.
32              * There is <sys/rusage.h> which has but this file is very non-standard.
33              * More the fun, the file itself warns will not be there for long. */
34             # define part_of_sec tv_nsec
35             # endif
36             /* Solaris uses timerstruc_t in struct rusage. According to the <sys/time.h>
37              * in old Solarises tv_nsec in the timerstruc_t is nanoseconds (and the name
38              * also supports that theory) BUT getrusage() seems after all to tick
39              * microseconds, not nano. */
40             # define part_in_sec 0.000001
41             #
42             /* Newer Solarises (5.5 onwards) have much better support for rusage-kinda
43              * things via the proc interface. */
44             # define _STRUCTURED_PROC 1
45             # include <sys/procfs.h>
46             # include <fcntl.h>
47              
48             # ifdef PIOCUSAGE
49             # undef SOLARIS_STRUCTURED_PROC
50             # else
51             # define SOLARIS_STRUCTURED_PROC
52             # endif
53              
54             # ifdef SOLARIS_STRUCTURED_PROC
55             # define Struct_psinfo struct psinfo
56             # define Struct_pstatus struct pstatus
57             # else
58             # define Struct_psinfo struct prpsinfo
59             # define Struct_pstatus struct prstatus
60             # endif
61             #endif
62              
63             #ifdef SOLARIS_NO_PROCFS
64             # define SOLARIS
65             # undef SOLARIS_PROCFS
66             # define TRY_GETRUSAGE_SYS_SYSCALL
67             #endif
68              
69             #ifdef I_SYS_TIME
70             # include <sys/time.h>
71             #endif
72              
73             #ifdef I_SYS_SELECT
74             # include <sys/select.h> /* struct timeval might be hidden in here */
75             #endif
76              
77             #ifndef part_of_sec
78             #define part_of_sec tv_usec
79             #define part_in_sec 0.000001
80             #endif
81              
82             #define IDM ((double)part_in_sec)
83             #define TV2DS(tv) ((double)tv.tv_sec+(double)tv.part_of_sec*part_in_sec)
84              
85             #ifndef HAS_GETRUSAGE
86             # if defined(RUSAGE_SELF) || defined(SOLARIS)
87             # define HAS_GETRUSAGE
88             # endif
89             #endif
90              
91             #if defined(OS2) && !defined(PRIO_PROCESS)
92             # define PRIO_PROCESS 0 /* This argument is ignored anyway. */
93             #endif
94              
95             #if defined(__hpux) && defined(RLIMIT_NLIMITS)
96             /* there is getrusage() in HPUX but only as an indirect syscall */
97             # define TRY_GETRUSAGE_AS_SYSCALL
98             /* some rlimits exist (but are officially unsupported by HP) */
99             # define RLIMIT_CPU 0
100             # define RLIMIT_FSIZE 1
101             # define RLIMIT_DATA 2
102             # define RLIMIT_STACK 3
103             # define RLIMIT_CORE 4
104             # define RLIMIT_RSS 5
105             # define RLIMIT_NOFILE 6
106             # define RLIMIT_OPEN_MAX RLIMIT_NOFILE
107             # define RLIM_NLIMITS 7
108             # define RLIM_INFINITY 0x7fffffff
109             #endif
110            
111             #ifdef __linux__
112             /* enums without #defines, how wonderful */
113             # ifndef PRIO_PROCESS
114             # define PRIO_PROCESS PRIO_PROCESS
115             # endif
116             # ifndef PRIO_PGRP
117             # define PRIO_PGRP PRIO_PGRP
118             # endif
119             # ifndef PRIO_USER
120             # define PRIO_USER PRIO_USER
121             # endif
122             #endif
123              
124             #if !defined(RLIMIT_OPEN_MAX) && defined(RLIMIT_NOFILE)
125             # define RLIMIT_OPEN_MAX RLIMIT_NOFILE
126             #endif
127              
128             #if !defined(RLIMIT_NOFILE) && defined(RLIMIT_OPEN_MAX)
129             # define RLIMIT_NOFILE RLIMIT_OPEN_MAX
130             #endif
131              
132             #if !defined(RLIMIT_OFILE) && defined(RLIMIT_NOFILE)
133             # define RLIMIT_OFILE RLIMIT_NOFILE
134             #endif
135              
136             #if !defined(RLIMIT_VMEM) && defined(RLIMIT_AS)
137             # define RLIMIT_VMEM RLIMIT_AS
138             #else
139             # if !defined(RLIMIT_AS) && defined(RLIMIT_VMEM)
140             # define RLIMIT_AS RLIMIT_VMEM
141             # endif
142             #endif
143              
144             #ifdef TRY_GETRUSAGE_AS_SYSCALL
145             # include <sys/syscall.h>
146             # if defined(SYS_GETRUSAGE)
147             # define getrusage(a, b) syscall(SYS_GETRUSAGE, (a), (b))
148             # define HAS_GETRUSAGE
149             # endif
150             #endif
151              
152             #ifndef Rlim_t
153             # ifdef Quad_t
154             # define Rlim_t Quad_t
155             # else
156             # define Rlim_t unsigned long
157             # endif
158             #endif
159              
160             #if defined(RLIM_INFINITY) /* this is the only one we can count on (?) */
161             #define HAS_GETRLIMIT
162             #define HAS_SETRLIMIT
163             #endif
164              
165             #ifndef PRIO_MAX
166             # define PRIO_MAX 20
167             #endif
168              
169             #ifndef PRIO_MIN
170             # define PRIO_MIN -20
171             #endif
172              
173             #if defined(PRIO_USER)
174             #ifndef HAS_GETPRIORITY
175             #define HAS_GETPRIORITY
176             #endif
177             #ifndef HAS_SETPRIORITY
178             #define HAS_SETPRIORITY
179             #endif
180             #endif
181              
182             #ifndef HAS_GETPRIORITY
183             #define _getpriority(a,b) not_here("getpriority")
184             #endif
185              
186             #ifndef HAS_GETRLIMIT
187             #define _getrlimit(a,b) not_here("getrlimit")
188             #endif
189              
190             #ifndef HAS_GETRUSAGE
191             #define _getrusage(a,b) not_here("getrusage")
192             #endif
193              
194             #ifndef HAS_SETPRIORITY
195             #define _setpriority(a,b,c) not_here("setpriority")
196             #endif
197              
198             #ifndef HAS_SETRLIMIT
199             #define _setrlimit(a,b) not_here("setrlimit")
200             #endif
201              
202             static int
203             not_here(s)
204             char *s;
205             {
206             croak("BSD::Resource::%s not implemented on this architecture", s);
207             return -1;
208             }
209            
210             static double
211             constant(name, arg)
212             char *name;
213             int arg;
214             {
215 48               errno = 0;
216 48               switch (*name) {
217                 case 'E':
218 14           if (strEQ(name, "EINVAL"))
219             #ifdef EINVAL
220             return EINVAL;
221             #else
222             goto not_there;
223             #endif
224 7           if (strEQ(name, "ENOENT"))
225             #ifdef ENOENT
226             return ENOENT;
227             #else
228             goto not_there;
229             #endif
230                   break;
231                 case 'P':
232 2           if (strnEQ(name, "PRIO_", 5)) {
233 2           if (strEQ(name, "PRIO_MIN"))
234             #if defined(PRIO_MIN) || defined(HAS_PRIO_MIN)
235             return PRIO_MIN;
236             #else
237             goto not_there;
238             #endif
239 2           if (strEQ(name, "PRIO_MAX"))
240             #if defined(PRIO_MAX) || defined(HAS_PRIO_MAX)
241             return PRIO_MAX;
242             #else
243             goto not_there;
244             #endif
245 2           if (strEQ(name, "PRIO_USER"))
246             #if defined(PRIO_USER) || defined(HAS_PRIO_USER)
247             return PRIO_USER;
248             #else
249             goto not_there;
250             #endif
251 2           if (strEQ(name, "PRIO_PGRP"))
252             #if defined(PRIO_PGRP) || defined(HAS_PRIO_PGRP)
253             return PRIO_PGRP;
254             #else
255             goto not_there;
256             #endif
257 2           if (strEQ(name, "PRIO_PROCESS"))
258             #if defined(PRIO_PROCESS) || defined(HAS_PRIO_PROCESS)
259             return PRIO_PROCESS;
260             #else
261             goto not_there;
262             #endif
263             }
264                 goto not_there;
265                 case 'R':
266 32           if (strnEQ(name, "RLIM", 4)) {
267 29           if (strEQ(name, "RLIMIT_AIO_MEM"))
268             #if defined(RLIMIT_AIO_MEM) || defined(HAS_RLIMIT_AIO_MEM)
269             return RLIMIT_AIO_MEM;
270             #else
271 29           goto not_there;
272             #endif
273 29           if (strEQ(name, "RLIMIT_AIO_OPS"))
274             #if defined(RLIMIT_AIO_OPS) || defined(HAS_RLIMIT_AIO_OPS)
275             return RLIMIT_AIO_OPS;
276             #else
277 29           goto not_there;
278             #endif
279 29           if (strEQ(name, "RLIMIT_AS"))
280             #if defined(RLIMIT_AS) || defined(HAS_RLIMIT_AS)
281             return RLIMIT_AS;
282             #else
283             goto not_there;
284             #endif
285 27           if (strEQ(name, "RLIMIT_CORE"))
286             #if defined(RLIMIT_CORE) || defined(HAS_RLIMIT_CORE)
287             return RLIMIT_CORE;
288             #else
289             goto not_there;
290             #endif
291 25           if (strEQ(name, "RLIMIT_CPU"))
292             #if defined(RLIMIT_CPU) || defined(HAS_RLIMIT_CPU)
293             return RLIMIT_CPU;
294             #else
295             goto not_there;
296             #endif
297 23           if (strEQ(name, "RLIMIT_DATA"))
298             #if defined(RLIMIT_DATA) || defined(HAS_RLIMIT_DATA)
299             return RLIMIT_DATA;
300             #else
301             goto not_there;
302             #endif
303 21           if (strEQ(name, "RLIMIT_FSIZE"))
304             #if defined(RLIMIT_FSIZE) || defined(HAS_RLIMIT_FSIZE)
305             return RLIMIT_FSIZE;
306             #else
307             goto not_there;
308             #endif
309 19           if (strEQ(name, "RLIMIT_LOCKS"))
310             #if defined(RLIMIT_LOCKS) || defined(HAS_RLIMIT_LOCKS)
311             return RLIMIT_LOCKS;
312             #else
313             goto not_there;
314             #endif
315 17           if (strEQ(name, "RLIMIT_MEMLOCK"))
316             #if defined(RLIMIT_MEMLOCK) || defined(HAS_RLIMIT_MEMLOCK)
317             return RLIMIT_MEMLOCK;
318             #else
319             goto not_there;
320             #endif
321 15           if (strEQ(name, "RLIMIT_NOFILE"))
322             #if defined(RLIMIT_NOFILE) || defined(HAS_RLIMIT_NOFILE)
323             return RLIMIT_NOFILE;
324             #else
325             goto not_there;
326             #endif
327 13           if (strEQ(name, "RLIMIT_NPROC"))
328             #if defined(RLIMIT_NPROC) || defined(HAS_RLIMIT_NPROC)
329             return RLIMIT_NPROC;
330             #else
331             goto not_there;
332             #endif
333 11           if (strEQ(name, "RLIMIT_OFILE"))
334             #if defined(RLIMIT_OFILE) || defined(HAS_RLIMIT_OFILE)
335             return RLIMIT_OFILE;
336             #else
337             goto not_there;
338             #endif
339 9           if (strEQ(name, "RLIMIT_OPEN_MAX"))
340             #if defined(RLIMIT_OPEN_MAX) || defined(HAS_RLIMIT_OPEN_MAX)
341             return RLIMIT_OPEN_MAX;
342             #else
343             goto not_there;
344             #endif
345 7           if (strEQ(name, "RLIMIT_RSS"))
346             #if defined(RLIMIT_RSS) || defined(HAS_RLIMIT_RSS)
347             return RLIMIT_RSS;
348             #else
349             goto not_there;
350             #endif
351 5           if (strEQ(name, "RLIMIT_STACK"))
352             #if defined(RLIMIT_STACK) || defined(HAS_RLIMIT_STACK)
353             return RLIMIT_STACK;
354             #else
355             goto not_there;
356             #endif
357 3           if (strEQ(name, "RLIMIT_TCACHE"))
358             #if defined(RLIMIT_TCACHE) || defined(HAS_RLIMIT_TCACHE)
359             return RLIMIT_TCACHE;
360             #else
361 3           goto not_there;
362             #endif
363 3           if (strEQ(name, "RLIMIT_VMEM"))
364             #if defined(RLIMIT_VMEM) || defined(HAS_RLIMIT_VMEM)
365             return RLIMIT_VMEM;
366             #else
367             goto not_there;
368             #endif
369 1           if (strEQ(name, "RLIM_INFINITY"))
370             #if defined(RLIM_INFINITY) || defined(HAS_RLIM_INFINITY)
371             return -1.0; /* trust me */
372             #else
373             goto not_there;
374             #endif
375 0           if (strEQ(name, "RLIM_NLIMITS"))
376             #if defined(RLIM_NLIMITS) || defined(HAS_RLIM_NLIMITS)
377             return RLIM_NLIMITS;
378             #else
379             goto not_there;
380             #endif
381 0           if (strEQ(name, "RLIM_SAVED_CUR"))
382             #if defined(RLIM_SAVED_CUR) || defined(HAS_RLIM_SAVED_CUR)
383             return RLIM_SAVED_CUR;
384             #else
385             goto not_there;
386             #endif
387 0           if (strEQ(name, "RLIM_SAVED_MAX"))
388             #if defined(RLIM_SAVED_MAX) || defined(HAS_RLIM_SAVED_MAX)
389             return RLIM_SAVED_MAX;
390             #else
391             goto not_there;
392             #endif
393             break;
394             }
395 3           if (strnEQ(name, "RUSAGE_", 7)) {
396 3           if (strEQ(name, "RUSAGE_BOTH"))
397             #if defined(RUSAGE_BOTH) || defined(HAS_RUSAGE_BOTH)
398             return RUSAGE_BOTH;
399             #else
400 3           goto not_there;
401             #endif
402 3           if (strEQ(name, "RUSAGE_CHILDREN"))
403             #if defined(RUSAGE_CHILDREN) || defined(HAS_RUSAGE_CHILDREN)
404             return RUSAGE_CHILDREN;
405             #else
406             goto not_there;
407             #endif
408 2           if (strEQ(name, "RUSAGE_SELF"))
409             #if defined(RUSAGE_SELF) || defined(HAS_RUSAGE_SELF)
410             return RUSAGE_SELF;
411             #else
412             goto not_there;
413             #endif
414 0           if (strEQ(name, "RUSAGE_THREAD"))
415             #if defined(RUSAGE_THREAD) || defined(HAS_RUSAGE_THREAD)
416             return RUSAGE_THREAD;
417             #else
418 7           goto not_there;
419             #endif
420             break;
421             }
422                 }
423              
424 7               errno = EINVAL;
425                 return