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 0;
426              
427 0           not_there:
428 0               errno = ENOENT;
429                 return 0;
430             }
431              
432             MODULE = BSD::Resource PACKAGE = BSD::Resource
433              
434             PROTOTYPES: enable
435              
436             double
437             constant(name,arg)
438             char * name
439             int arg
440              
441             void
442             _getpriority(which = PRIO_PROCESS, who = 0)
443             int which
444             int who
445                 CODE:
446             {
447             int prio;
448              
449 6           ST(0) = sv_newmortal();
450 6           errno = 0; /* getpriority() can successfully return <= 0 */
451 6           prio = getpriority(which, who);
452 6           if (errno == 0)
453 6           sv_setiv(ST(0), prio);
454             else
455 0           ST(0) = &PL_sv_undef;
456             }
457              
458             void
459             _getrlimit(resource)
460             int resource
461                 PPCODE:
462             struct rlimit rl;
463 42           if (getrlimit(resource, &rl) == 0) {
464 42           EXTEND(sp, 2);
465 42           PUSHs(sv_2mortal(newSVnv((double)(rl.rlim_cur == RLIM_INFINITY ? -1.0 : rl.rlim_cur))));
466 42           PUSHs(sv_2mortal(newSVnv((double)(rl.rlim_max == RLIM_INFINITY ? -1.0 : rl.rlim_max))));
467             }
468              
469             void
470             _getrusage(who = RUSAGE_SELF)
471             int who
472                 PPCODE:
473             {
474             struct rusage ru;
475             #ifdef SOLARIS_PROCFS
476             Struct_psinfo  psi;
477             Struct_pstatus pst;
478             struct prusage pru;
479             pid_t  pid = getpid();
480             int    res, fd;
481             char psib[40], pstb[40], prub[40];
482             ru.ru_utime.tv_sec   = 0;
483             ru.ru_utime.tv_usec  = 0;
484             ru.ru_stime.tv_sec   = 0;
485             ru.ru_stime.tv_usec  = 0;
486                       ru.ru_maxrss = 0;
487                       ru.ru_ixrss = 0;
488             ru.ru_idrss    = 0;
489             ru.ru_isrss    = 0;
490             ru.ru_minflt   = 0;
491             ru.ru_majflt   = 0;
492             ru.ru_nswap    = 0;
493             ru.ru_inblock  = 0;
494             ru.ru_oublock  = 0;
495             ru.ru_msgsnd   = 0;
496             ru.ru_msgrcv   = 0;
497             ru.ru_nsignals = 0;
498                     ru.ru_nvcsw = 0;
499             ru.ru_nivcsw   = 0;
500             # ifndef SOLARIS_STRUCTURED_PROC
501             /* The time fields come okay from getrusage() but would be bad
502             * from PIOCUSAGE. Argh. */
503             res = getrusage(who, &ru);
504             if (res)
505             goto failed;
506             # endif
507             /* With 64-bit pids "/proc/18446744073709551616/psinfo" takes 34 bytes. */
508             sprintf(psib, "/proc/%d", pid);
509             sprintf(pstb, "/proc/%d", pid);
510             sprintf(prub, "/proc/%d", pid);
511             # ifdef SOLARIS_STRUCTURED_PROC
512             res = strlen(psib);
513             sprintf(psib + res, "/psinfo");
514             sprintf(pstb + res, "/status");
515             sprintf(prub + res, "/usage" );
516             # endif
517             fd = open(psib, O_RDONLY);
518             if (fd >= 0) {
519             # ifdef SOLARIS_STRUCTURED_PROC
520             res = read(fd, &psi, sizeof(psi));
521             if (res == sizeof(psi))
522             ru.ru_maxrss = psi.pr_rssize * 1024;
523             else
524             goto failed;
525             # else
526             res = ioctl(fd, PIOCPSINFO, &psi);
527             if (res != -1)
528             ru.ru_maxrss = psi.pr_byrssize;
529             else
530             goto failed;
531             # endif
532             close(fd);
533             } else
534             goto failed;
535             fd = open(pstb, O_RDONLY);
536             if (fd >= 0) {
537             # ifdef SOLARIS_STRUCTURED_PROC
538             res = read(fd, &pst, sizeof(pst));
539             res = res == sizeof(pst) ? 1 : 0;
540             # else
541             res = ioctl(fd, PIOCUSAGE, &pst);
542             res = res == -1 ? 0 : 1;
543             # endif
544             if (res) {
545             # ifdef SOLARIS_STRUCTURED_PROC
546             /* Structured proc seems to have okay values in struct psinfo but
547             * zero values from the earlier getrusage() so get the better ones. */
548             if (who == RUSAGE_SELF) {
549             ru.ru_utime.tv_sec = pst.pr_utime.tv_sec;
550             ru.ru_utime.tv_usec = pst.pr_utime.tv_nsec / 1000;
551             ru.ru_stime.tv_sec = pst.pr_stime.tv_sec;
552             ru.ru_stime.tv_usec = pst.pr_stime.tv_nsec / 1000;
553             } else if (who == RUSAGE_CHILDREN) {
554             ru.ru_utime.tv_sec = pst.pr_cutime.tv_sec;
555             ru.ru_utime.tv_usec = pst.pr_cutime.tv_nsec / 1000;
556             ru.ru_stime.tv_sec = pst.pr_cstime.tv_sec;
557             ru.ru_stime.tv_usec = pst.pr_cstime.tv_nsec / 1000;
558             }
559             # endif
560             /* Current values, not really integrals. */
561             ru.ru_idrss = pst.pr_brksize;
562             ru.ru_isrss = pst.pr_stksize;
563             } else
564             goto failed;
565             close(fd);
566             } else
567             goto failed;
568             fd = open(prub, O_RDONLY);
569             if (fd >= 0) {
570             # ifdef SOLARIS_STRUCTURED_PROC
571             res = read(fd, &pru, sizeof(pru));
572             res = res == sizeof(pru) ? 1 : 0;
573             # else
574             res = ioctl(fd, PIOCUSAGE, &pru);
575             res = res == -1 ? 0 : 1;
576             # endif
577             if (res) {
578             ru.ru_minflt = pru.pr_minf;
579             ru.ru_majflt = pru.pr_majf;
580             ru.ru_nswap = pru.pr_nswap;
581             ru.ru_inblock = pru.pr_inblk;
582             ru.ru_oublock = pru.pr_oublk;
583             ru.ru_msgsnd = pru.pr_msnd;
584             ru.ru_msgrcv = pru.pr_mrcv;
585             ru.ru_nsignals = pru.pr_sigs;
586             ru.ru_nvcsw = pru.pr_vctx;
587             ru.ru_nivcsw = pru.pr_ictx;
588             } else
589             goto failed;
590             close(fd);
591             } else
592             goto failed;
593             #else
594 7           if (getrusage(who, &ru))
595 7           goto failed;
596             #endif
597 7           EXTEND(sp, 16);
598 7           PUSHs(sv_2mortal(newSVnv(TV2DS(ru.ru_utime))));
599 7           PUSHs(sv_2mortal(newSVnv(TV2DS(ru.ru_stime))));
600 7           PUSHs(sv_2mortal(newSViv(ru.ru_maxrss)));
601 7           PUSHs(sv_2mortal(newSVnv(ru.ru_ixrss)));
602 7           PUSHs(sv_2mortal(newSVnv(ru.ru_idrss)));
603 7           PUSHs(sv_2mortal(newSVnv(ru.ru_isrss)));
604 7           PUSHs(sv_2mortal(newSVnv(ru.ru_minflt)));
605 7           PUSHs(sv_2mortal(newSVnv(ru.ru_majflt)));
606 7           PUSHs(sv_2mortal(newSVnv(ru.ru_nswap)));
607 7           PUSHs(sv_2mortal(newSVnv(ru.ru_inblock)));
608 7           PUSHs(sv_2mortal(newSVnv(ru.ru_oublock)));
609 7           PUSHs(sv_2mortal(newSVnv(ru.ru_msgsnd)));
610 7           PUSHs(sv_2mortal(newSVnv(ru.ru_msgrcv)));
611 7           PUSHs(sv_2mortal(newSVnv(ru.ru_nsignals)));
612 7           PUSHs(sv_2mortal(newSVnv(ru.ru_nvcsw)));
613 7           PUSHs(sv_2mortal(newSVnv(ru.ru_nivcsw)));
614 7           failed:
615             ;
616             }
617            
618             void
619             _setpriority(which = PRIO_PROCESS,who = 0,priority = PRIO_MAX/2)
620             int which
621             int who
622             int priority
623             CODE:
624             {
625 1           if (items == 2) {
626             /* if two arguments they are (which, priority),
627             * not (which, who). who defaults to 0. */
628             priority = who;
629             who = 0;
630             }
631 2           ST(0) = sv_newmortal();
632 2           ST(0) = (setpriority(which, who, priority) == 0) ?
633             &PL_sv_yes : &PL_sv_undef;
634             }
635            
636             void
637             _setrlimit(resource,soft,hard)
638             int resource
639             double soft
640             double hard
641             CODE:
642             {
643             struct rlimit rl;
644            
645 14           rl.rlim_cur = soft == -1.0 ? RLIM_INFINITY : (Rlim_t) soft;
646 14           rl.rlim_max = hard == -1.0 ? RLIM_INFINITY : (Rlim_t) hard;
647            
648 14           ST(0) = sv_newmortal();
649 14           ST(0) = (setrlimit(resource, &rl) == 0) ? &PL_sv_yes: &PL_sv_undef;
650             }
651            
652             HV *
653             _get_rlimits()
654             CODE:
655 2           RETVAL = newHV();
656             #if defined(RLIMIT_AIO_MEM) || defined(HAS_RLIMIT_AIO_MEM)
657             hv_store(RETVAL, "RLIMIT_AIO_MEM" , 14, newSViv(RLIMIT_AIO_MEM), 0);
658             #endif
659             #if defined(RLIMIT_AIO_OPS) || defined(HAS_RLIMIT_AIO_OPS)
660             hv_store(RETVAL, "RLIMIT_AIO_OPS" , 14, newSViv(RLIMIT_AIO_OPS), 0);
661             #endif
662             #if defined(RLIMIT_AS) || defined(HAS_RLIMIT_AS)
663 2           hv_store(RETVAL, "RLIMIT_AS" , 9, newSViv(RLIMIT_AS), 0);
664             #endif
665             #if defined(RLIMIT_CORE) || defined(HAS_RLIMIT_CORE)
666 2           hv_store(RETVAL, "RLIMIT_CORE" , 11, newSViv(RLIMIT_CORE), 0);
667             #endif
668             #if defined(RLIMIT_CPU) || defined(HAS_RLIMIT_CPU)
669 2           hv_store(RETVAL, "RLIMIT_CPU" , 10, newSViv(RLIMIT_CPU), 0);
670             #endif
671             #if defined(RLIMIT_DATA) || defined(HAS_RLIMIT_DATA)
672 2           hv_store(RETVAL, "RLIMIT_DATA" , 11, newSViv(RLIMIT_DATA), 0);
673             #endif
674             #if defined(RLIMIT_FSIZE) || defined(HAS_RLIMIT_FSIZE)
675 2           hv_store(RETVAL, "RLIMIT_FSIZE" , 12, newSViv(RLIMIT_FSIZE), 0);
676             #endif
677             #if defined(RLIMIT_LOCKS) || defined(HAS_RLIMIT_LOCKS)
678 2           hv_store(RETVAL, "RLIMIT_LOCKS" , 12, newSViv(RLIMIT_LOCKS), 0);
679             #endif
680             #if defined(RLIMIT_MEMLOCK) || defined(HAS_RLIMIT_MEMLOCK)
681 2           hv_store(RETVAL, "RLIMIT_MEMLOCK" , 14, newSViv(RLIMIT_MEMLOCK), 0);
682             #endif
683             #if defined(RLIMIT_NOFILE) || defined(HAS_RLIMIT_NOFILE)
684 2           hv_store(RETVAL, "RLIMIT_NOFILE" , 13, newSViv(RLIMIT_NOFILE), 0);
685             #endif
686             #if defined(RLIMIT_NPROC) || defined(HAS_RLIMIT_NPROC)
687 2           hv_store(RETVAL, "RLIMIT_NPROC" , 12, newSViv(RLIMIT_NPROC), 0);
688             #endif
689             #if defined(RLIMIT_OFILE) || defined(HAS_RLIMIT_OFILE)
690 2           hv_store(RETVAL, "RLIMIT_OFILE" , 12, newSViv(RLIMIT_OFILE), 0);
691             #endif
692             #if defined(RLIMIT_OPEN_MAX) || defined(HAS_RLIMIT_OPEN_MAX)
693 2           hv_store(RETVAL, "RLIMIT_OPEN_MAX" , 15, newSViv(RLIMIT_OPEN_MAX), 0);
694             #endif
695             #if defined(RLIMIT_RSS) || defined(HAS_RLIMIT_RSS)
696 2           hv_store(RETVAL, "RLIMIT_RSS" , 10, newSViv(RLIMIT_RSS), 0);
697             #endif
698             #if defined(RLIMIT_STACK) || defined(HAS_RLIMIT_STACK)
699 2           hv_store(RETVAL, "RLIMIT_STACK" , 12, newSViv(RLIMIT_STACK), 0);
700             #endif
701             #if defined(RLIMIT_TCACHE) || defined(HAS_RLIMIT_TCACHE)
702             hv_store(RETVAL, "RLIMIT_TCACHE" , 13, newSViv(RLIMIT_TCACHE), 0);
703             #endif
704             #if defined(RLIMIT_VMEM) || defined(HAS_RLIMIT_VMEM)
705 2           hv_store(RETVAL, "RLIMIT_VMEM" , 11, newSViv(RLIMIT_VMEM), 0);
706             #endif
707             OUTPUT:
708             RETVAL
709