1 /*
2  * This is the XS glue between libstatgrab and a Perl-API
3  * named Unix::Statgrab.
4  *
5  * This file and the compiled artifacts from it can be distributed
6  * under the same license as Perl 5 or the same license as
7  * libstatgrab based on your choice.
8  *
9  *  Copyright (C) 2004-2005 by Tassilo von Parseval
10  *  Copyright (C) 2012-2018 by Jens Rehsack
11  */
12 #include "EXTERN.h"
13 #include "perl.h"
14 #include "XSUB.h"
15 
16 #define NEED_newSVpvn_flags
17 
18 #include "ppport.h"
19 
20 #include <statgrab.h>
21 
22 #include "const-c.inc"
23 #include "config.h"
24 
25 const char *sg_host_info_names[] = {
26     "os_name", "os_release", "os_version", "platform", "hostname",
27     "bitwidth", "host_state", "ncpus", "maxcpus", "uptime", "systime"
28 };
29 
30 const char *sg_cpu_stat_names[] = {
31     "user", "kernel", "idle", "iowait", "swap", "nice", "total",
32     "context_switches", "voluntary_context_switches", "involuntary_context_switches",
33     "syscalls", "interrupts", "soft_interrupts", "systime"
34 };
35 
36 const char *sg_cpu_percent_names[] = {
37     "user", "kernel", "idle", "iowait", "swap", "nice", "time_taken"
38 };
39 
40 const char *sg_mem_stat_names[] = {
41     "total", "free", "used", "cache", "systime"
42 };
43 
44 const char *sg_load_stat_names[] = {
45     "min1", "min5", "min15", "systime"
46 };
47 
48 const char *sg_user_stat_names[] = {
49     "login_name", "record_id", "device", "hostname",
50     "pid", "login_time", "systime"
51 };
52 
53 const char *sg_swap_stat_names[] = {
54     "total", "free", "used", "systime"
55 };
56 
57 const char *sg_fs_stat_names[] = {
58     "device_name", "device_canonical", "fs_type", "mnt_point", "device_type", "size",
59     "used", "free", "avail", "total_inodes", "used_inodes", "free_inodes", "avail_inodes",
60     "io_size", "block_size", "total_blocks", "free_blocks", "used_blocks", "avail_blocks",
61     "systime"
62 };
63 
64 const char *sg_disk_io_stat_names[] = {
65     "disk_name", "read_bytes", "write_bytes", "systime"
66 };
67 
68 const char *sg_network_io_stat_names[] = {
69     "interface_name", "tx", "rx", "ipackets", "opackets",
70     "ierrors", "oerrors", "collisions", "systime"
71 };
72 
73 const char *sg_network_iface_stat_names[] = {
74     "interface_name", "speed", "factor", "duplex", "up", "systime"
75 };
76 
77 const char *sg_page_stat_names[] = {
78     "pages_pagein", "pages_pageout", "systime"
79 };
80 
81 const char *sg_process_stat_names[] = {
82     "process_name", "proctitle",
83     "pid", "parent", "pgid", "sessid", "uid", "euid", "gid", "egid",
84     "context_switches", "voluntary_context_switches", "involuntary_context_switches",
85     "proc_size", "proc_resident", "start_time", "time_spent", "cpu_percent",
86     "nice", "state", "systime"
87 };
88 
89 #ifndef lengthof
90 #define lengthof(x) (sizeof(x)/sizeof((x)[0]))
91 #endif
92 
93 #ifdef MATCH_UV_FIT_ULL
94 #define LUV UV
95 #else
96 #define LUV NV
97 #endif
98 
SAFE_STRLEN(const char * s)99 static STRLEN SAFE_STRLEN(const char *s)
100 {
101     return s ? strlen(s) : 0;
102 }
103 
104 #define sv_setpvn_IF(sv,str,len) (str)?sv_setpvn((sv),(str),(len)):((void)0)
105 
106 #define MAKE_AV_FROM_STRINGS(strings, av) do { \
107     size_t i; \
108     av = newAV(); \
109     av_extend(av, lengthof(strings)); \
110     for(i = 0; i < lengthof(strings); ++i) { \
111 	av_store(av, i, newSVpvn(strings[i], SAFE_STRLEN(strings[i]))); \
112     } \
113 } while(0)
114 
115 #define FETCH_ALL_ROWS(stats, FETCH_ROW, av, XV) do { \
116     size_t i, n; \
117     av = newAV(); \
118     av_extend(av, n = sg_get_nelements(stats)); \
119     for(i = 0; i < n; ++i) { \
120 	XV *row; \
121 	FETCH_ROW(stats, i, row); \
122 	av_store(av, i, newRV_noinc((SV *)row)); \
123     } \
124 } while(0)
125 
126 MODULE = Unix::Statgrab		PACKAGE = Unix::Statgrab
127 
128 INCLUDE: const-xs.inc
129 
130 BOOT:
131 {
132     /* sg_log_init(properties_pfx, env_name, argv0) */
133     sg_log_init("libstatgrab", "LIBSTATGRAB_LOG_PROPERTIES", NULL);
134     sg_init(1);
135 }
136 
137 void
get_error()138 get_error ()
139     PROTOTYPE:
140     CODE:
141     {
142 	sg_error_details *self = safemalloc(sizeof(sg_error_details));
143 
144 	if (SG_ERROR_NONE == sg_get_error_details(self))
145 	{
146 	    XSRETURN_UNDEF;
147 	}
148 
149 	EXTEND(SP, 1);
150 
151 	ST(0) = sv_newmortal();
152 	sv_setref_pv(ST(0), "Unix::Statgrab::sg_error_details", (void*)self);
153 	XSRETURN(1);
154     }
155 
156 int
157 drop_privileges ()
158     PROTOTYPE:
159     CODE:
160 	RETVAL = sg_drop_privileges() == 0;
161     OUTPUT:
162 	RETVAL
163 
164 void
get_host_info()165 get_host_info ()
166     PROTOTYPE:
167     CODE:
168     {
169 	sg_host_info *self;
170 	if ((self = sg_get_host_info_r(NULL)) == NULL)
171 	    XSRETURN_UNDEF;
172 
173 	EXTEND(SP, 1);
174 
175 	ST(0) = sv_newmortal();
176 	sv_setref_pv(ST(0), "Unix::Statgrab::sg_host_info", (void*)self);
177 	XSRETURN(1);
178     }
179 
180 void
get_cpu_stats()181 get_cpu_stats ()
182     PROTOTYPE:
183     CODE:
184     {
185 	sg_cpu_stats *self;
186 	if ((self = sg_get_cpu_stats_r(NULL)) == NULL)
187 	    XSRETURN_UNDEF;
188 
189 	EXTEND(SP, 1);
190 
191 	ST(0) = sv_newmortal();
192 	sv_setref_pv(ST(0), "Unix::Statgrab::sg_cpu_stats", (void*)self);
193 	XSRETURN(1);
194     }
195 
196 void
get_disk_io_stats()197 get_disk_io_stats ()
198     PROTOTYPE:
199     CODE:
200     {
201 	sg_disk_io_stats *self;
202 	if ((self = sg_get_disk_io_stats_r(NULL)) == NULL)
203 	    XSRETURN_UNDEF;
204 
205 	EXTEND(SP, 1);
206 
207 	ST(0) = sv_newmortal();
208 	sv_setref_pv(ST(0), "Unix::Statgrab::sg_disk_io_stats", (void*)self);
209 	XSRETURN(1);
210     }
211 
212 void
get_fs_stats()213 get_fs_stats ()
214     PROTOTYPE:
215     CODE:
216     {
217 	sg_fs_stats *self;
218 
219 	if ((self = sg_get_fs_stats_r(NULL)) == NULL)
220 	    XSRETURN_UNDEF;
221 
222 	EXTEND(SP, 1);
223 
224 	ST(0) = sv_newmortal();
225 	sv_setref_pv(ST(0), "Unix::Statgrab::sg_fs_stats", (void*)self);
226 	XSRETURN(1);
227     }
228 
229 void
get_load_stats()230 get_load_stats ()
231     PROTOTYPE:
232     CODE:
233     {
234 	sg_load_stats *self;
235 	if ((self = sg_get_load_stats_r(NULL)) == NULL)
236 	    XSRETURN_UNDEF;
237 
238 	EXTEND(SP, 1);
239 
240 	ST(0) = sv_newmortal();
241 	sv_setref_pv(ST(0), "Unix::Statgrab::sg_load_stats", (void*)self);
242 	XSRETURN(1);
243     }
244 
245 void
get_mem_stats()246 get_mem_stats ()
247     PROTOTYPE:
248     CODE:
249     {
250 	sg_mem_stats *self;
251 	if ((self = sg_get_mem_stats_r(NULL)) == NULL)
252 	    XSRETURN_UNDEF;
253 
254 	EXTEND(SP, 1);
255 
256 	ST(0) = sv_newmortal();
257 	sv_setref_pv(ST(0), "Unix::Statgrab::sg_mem_stats", (void*)self);
258 	XSRETURN(1);
259     }
260 
261 void
get_swap_stats()262 get_swap_stats ()
263     PROTOTYPE:
264     CODE:
265     {
266 	sg_swap_stats *self;
267 	if ((self = sg_get_swap_stats_r(NULL)) == NULL)
268 	    XSRETURN_UNDEF;
269 
270 	EXTEND(SP, 1);
271 
272 	ST(0) = sv_newmortal();
273 	sv_setref_pv(ST(0), "Unix::Statgrab::sg_swap_stats", (void*)self);
274 	XSRETURN(1);
275     }
276 
277 void
get_network_io_stats()278 get_network_io_stats ()
279     PROTOTYPE:
280     CODE:
281     {
282 	sg_network_io_stats *self;
283 
284 	if ((self = sg_get_network_io_stats_r(NULL)) == NULL)
285 	    XSRETURN_UNDEF;
286 
287 	EXTEND(SP, 1);
288 
289 	ST(0) = sv_newmortal();
290 	sv_setref_pv(ST(0), "Unix::Statgrab::sg_network_io_stats", (void*)self);
291 	XSRETURN(1);
292     }
293 
294 void
get_network_iface_stats()295 get_network_iface_stats ()
296     PROTOTYPE:
297     CODE:
298     {
299 	sg_network_iface_stats *self;
300 
301 	if ((self = sg_get_network_iface_stats_r(NULL)) == NULL)
302 	    XSRETURN_UNDEF;
303 
304 	EXTEND(SP, 1);
305 
306 	ST(0) = sv_newmortal();
307 	sv_setref_pv(ST(0), "Unix::Statgrab::sg_network_iface_stats", (void*)self);
308 	XSRETURN(1);
309     }
310 
311 void
get_page_stats()312 get_page_stats ()
313     PROTOTYPE:
314     CODE:
315     {
316 	sg_page_stats *self;
317 	if ((self = sg_get_page_stats_r(NULL)) == NULL)
318 	    XSRETURN_UNDEF;
319 
320 	EXTEND(SP, 1);
321 
322 	ST(0) = sv_newmortal();
323 	sv_setref_pv(ST(0), "Unix::Statgrab::sg_page_stats", (void*)self);
324 	XSRETURN(1);
325     }
326 
327 void
get_user_stats()328 get_user_stats ()
329     PROTOTYPE:
330     CODE:
331     {
332 	sg_user_stats *self;
333 	if ((self = sg_get_user_stats_r(NULL)) == NULL)
334 	    XSRETURN_UNDEF;
335 
336 	EXTEND(SP, 1);
337 
338 	ST(0) = sv_newmortal();
339 	sv_setref_pv(ST(0), "Unix::Statgrab::sg_user_stats", (void*)self);
340 	XSRETURN(1);
341     }
342 
343 void
get_process_stats()344 get_process_stats ()
345     PROTOTYPE:
346     CODE:
347     {
348 	sg_process_stats *self;
349 
350 	if ((self = sg_get_process_stats_r(NULL)) == NULL)
351 	    XSRETURN_UNDEF;
352 
353 	EXTEND(SP, 1);
354 
355 	ST(0) = sv_newmortal();
356 	sv_setref_pv(ST(0), "Unix::Statgrab::sg_process_stats", (void*)self);
357 	XSRETURN(1);
358     }
359 
360 MODULE = Unix::Statgrab	    PACKAGE = Unix::Statgrab::sg_error_details
361 
362 UV
363 error (self)
364 	sg_error_details *self;
365     CODE:
366 	RETVAL = self->error;
367     OUTPUT:
368 	RETVAL
369 
370 const char *
371 error_name(self)
372 	sg_error_details *self;
373     CODE:
374 	RETVAL = sg_str_error(self->error);
375     OUTPUT:
376 	RETVAL
377 
378 IV
379 errno_value (self)
380 	sg_error_details *self;
381     CODE:
382 	RETVAL = self->errno_value;
383     OUTPUT:
384 	RETVAL
385 
386 const char *
387 error_arg (self)
388 	sg_error_details *self;
389     CODE:
390 	RETVAL = self->error_arg;
391     OUTPUT:
392 	RETVAL
393 
394 void
strperror(self)395 strperror (self)
396 	sg_error_details *self;
397     CODE:
398     {
399 	char *buf = NULL;
400 	if(NULL == sg_strperror(&buf, self))
401 	    XSRETURN_UNDEF;
402 
403 	EXTEND(SP, 1);
404 
405 	ST(0) = newSVpv(buf, 0);
406 	free(buf);
407 	sv_2mortal(ST(0));
408 	XSRETURN(1);
409     }
410 
411 void
DESTROY(self)412 DESTROY (self)
413 	sg_error_details *self;
414     CODE:
415     {
416 	Safefree(self);
417     }
418 
419 MODULE = Unix::Statgrab	    PACKAGE = Unix::Statgrab::sg_host_info
420 
421 UV
422 entries (self)
423 	sg_host_info *self;
424     CODE:
425 	RETVAL = sg_get_nelements(self);
426     OUTPUT:
427 	RETVAL
428 
429 char *
430 os_name (self, num = 0)
431 	sg_host_info *self;
432 	UV num;
433     CODE:
434 	if (num >= sg_get_nelements(self))
435 	    XSRETURN_UNDEF;
436 	RETVAL = self[num].os_name;
437     OUTPUT:
438 	RETVAL
439 
440 char *
441 os_release (self, num = 0)
442 	sg_host_info *self;
443 	UV num;
444     CODE:
445 	if (num >= sg_get_nelements(self))
446 	    XSRETURN_UNDEF;
447 	RETVAL = self[num].os_release;
448     OUTPUT:
449 	RETVAL
450 
451 char *
452 os_version (self, num = 0)
453 	sg_host_info *self;
454 	UV num;
455     CODE:
456 	if (num >= sg_get_nelements(self))
457 	    XSRETURN_UNDEF;
458 	RETVAL = self[num].os_version;
459     OUTPUT:
460 	RETVAL
461 
462 char *
463 platform (self, num = 0)
464 	sg_host_info *self;
465 	UV num;
466     CODE:
467 	if (num >= sg_get_nelements(self))
468 	    XSRETURN_UNDEF;
469 	RETVAL = self[num].platform;
470     OUTPUT:
471 	RETVAL
472 
473 char *
474 hostname (self, num = 0)
475 	sg_host_info *self;
476 	UV num;
477     CODE:
478 	if (num >= sg_get_nelements(self))
479 	    XSRETURN_UNDEF;
480 	RETVAL = self[num].hostname;
481     OUTPUT:
482 	RETVAL
483 
484 UV
485 bitwidth (self, num = 0)
486 	sg_host_info *self;
487 	UV num;
488     CODE:
489 	if (num >= sg_get_nelements(self))
490 	    XSRETURN_UNDEF;
491 	RETVAL = self[num].bitwidth;
492     OUTPUT:
493 	RETVAL
494 
495 UV
496 host_state (self, num = 0)
497 	sg_host_info *self;
498 	UV num;
499     CODE:
500 	if (num >= sg_get_nelements(self))
501 	    XSRETURN_UNDEF;
502 	RETVAL = self[num].host_state;
503     OUTPUT:
504 	RETVAL
505 
506 UV
507 ncpus (self, num = 0)
508 	sg_host_info *self;
509 	UV num;
510     CODE:
511 	if (num >= sg_get_nelements(self))
512 	    XSRETURN_UNDEF;
513 	RETVAL = self[num].ncpus;
514     OUTPUT:
515 	RETVAL
516 
517 UV
518 maxcpus (self, num = 0)
519 	sg_host_info *self;
520 	UV num;
521     CODE:
522 	if (num >= sg_get_nelements(self))
523 	    XSRETURN_UNDEF;
524 	RETVAL = self[num].maxcpus;
525     OUTPUT:
526 	RETVAL
527 
528 IV
529 systime (self, num = 0)
530 	sg_host_info *self;
531 	UV num;
532     CODE:
533 	if (num >= sg_get_nelements(self))
534 	    XSRETURN_UNDEF;
535 	RETVAL = self[num].systime;
536     OUTPUT:
537 	RETVAL
538 
539 IV
540 uptime (self, num = 0)
541 	sg_host_info *self;
542 	UV num;
543     CODE:
544 	if (num >= sg_get_nelements(self))
545 	    XSRETURN_UNDEF;
546 	RETVAL = self[num].uptime;
547     OUTPUT:
548 	RETVAL
549 
550 void
551 colnames(self)
552 	sg_host_info *self;
553     PPCODE:
554         AV *retval;
555 	MAKE_AV_FROM_STRINGS(sg_host_info_names, retval);
556 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
557 	XSRETURN(1);
558 
559 #define HOST_INFO_ARRAY_ROW(self, entry, av) \
560     do { \
561 	av = newAV(); \
562 	av_extend(av, sizeof(sg_host_info_names)); \
563 	AvFILLp(av) = -1; \
564 	av_store(av, ++AvFILLp(av), newSVpvn(self[entry].os_name, SAFE_STRLEN(self[entry].os_name))); \
565 	av_store(av, ++AvFILLp(av), newSVpvn(self[entry].os_release, SAFE_STRLEN(self[entry].os_release))); \
566 	av_store(av, ++AvFILLp(av), newSVpvn(self[entry].os_version, SAFE_STRLEN(self[entry].os_version))); \
567 	av_store(av, ++AvFILLp(av), newSVpvn(self[entry].platform, SAFE_STRLEN(self[entry].platform))); \
568 	av_store(av, ++AvFILLp(av), newSVpvn(self[entry].hostname, SAFE_STRLEN(self[entry].hostname))); \
569 	av_store(av, ++AvFILLp(av), newSVuv(self[entry].bitwidth)); \
570 	av_store(av, ++AvFILLp(av), newSVuv(self[entry].host_state)); \
571 	av_store(av, ++AvFILLp(av), newSVuv(self[entry].ncpus)); \
572 	av_store(av, ++AvFILLp(av), newSVuv(self[entry].maxcpus)); \
573 	av_store(av, ++AvFILLp(av), newSViv(self[entry].uptime)); \
574 	av_store(av, ++AvFILLp(av), newSViv(self[entry].systime)); \
575     } while(0);
576 
577 #define HOST_INFO_HASH_ROW(self, entry, hv) \
578     do { \
579 	hv = newHV(); \
580 	hv_store(hv, sg_host_info_names[0], strlen(sg_host_info_names[0]), newSVpvn(self[entry].os_name, SAFE_STRLEN(self[entry].os_name)), 0); \
581 	hv_store(hv, sg_host_info_names[1], strlen(sg_host_info_names[1]), newSVpvn(self[entry].os_release, SAFE_STRLEN(self[entry].os_release)), 0); \
582 	hv_store(hv, sg_host_info_names[2], strlen(sg_host_info_names[2]), newSVpvn(self[entry].os_version, SAFE_STRLEN(self[entry].os_version)), 0); \
583 	hv_store(hv, sg_host_info_names[3], strlen(sg_host_info_names[3]), newSVpvn(self[entry].platform, SAFE_STRLEN(self[entry].platform)), 0); \
584 	hv_store(hv, sg_host_info_names[4], strlen(sg_host_info_names[4]), newSVpvn(self[entry].hostname, SAFE_STRLEN(self[entry].hostname)), 0); \
585 	hv_store(hv, sg_host_info_names[5], strlen(sg_host_info_names[5]), newSVuv(self[entry].bitwidth), 0); \
586 	hv_store(hv, sg_host_info_names[6], strlen(sg_host_info_names[6]), newSVuv(self[entry].host_state), 0); \
587 	hv_store(hv, sg_host_info_names[7], strlen(sg_host_info_names[7]), newSVuv(self[entry].ncpus), 0); \
588 	hv_store(hv, sg_host_info_names[8], strlen(sg_host_info_names[8]), newSVuv(self[entry].maxcpus), 0); \
589 	hv_store(hv, sg_host_info_names[9], strlen(sg_host_info_names[9]), newSViv(self[entry].uptime), 0); \
590 	hv_store(hv, sg_host_info_names[10], strlen(sg_host_info_names[10]), newSViv(self[entry].systime), 0); \
591     } while(0);
592 
593 void
594 fetchrow_arrayref(self, num = 0)
595 	sg_host_info *self;
596 	UV num;
597     PPCODE:
598         AV *retval;
599 	if (num >= sg_get_nelements(self))
600 	    XSRETURN_UNDEF;
601 	/* XXX add fill row macro here */
602 	HOST_INFO_ARRAY_ROW(self, num, retval);
603 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
604 	XSRETURN(1);
605 
606 void
607 fetchall_arrayref(self)
608 	sg_host_info *self;
609     PPCODE:
610         AV *retval;
611 	/* XXX add fill row macro here */
612 	FETCH_ALL_ROWS(self, HOST_INFO_ARRAY_ROW, retval, AV);
613 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
614 	XSRETURN(1);
615 
616 void
617 fetchrow_hashref(self, num = 0)
618 	sg_host_info *self;
619 	UV num;
620     PPCODE:
621         HV *retval;
622 	if (num >= sg_get_nelements(self))
623 	    XSRETURN_UNDEF;
624 	/* XXX add fill row macro here */
625 	HOST_INFO_HASH_ROW(self, num, retval);
626 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
627 	XSRETURN(1);
628 
629 void
630 fetchall_hashref(self)
631 	sg_host_info *self;
632     PPCODE:
633         AV *retval;
634 	/* XXX add fill row macro here */
635 	FETCH_ALL_ROWS(self, HOST_INFO_HASH_ROW, retval, HV);
636 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
637 	XSRETURN(1);
638 
639 void
DESTROY(self)640 DESTROY (self)
641 	sg_host_info *self;
642     CODE:
643     {
644 	sg_free_host_info(self);
645     }
646 
647 MODULE = Unix::Statgrab		PACKAGE = Unix::Statgrab::sg_cpu_stats
648 
649 UV
650 entries (self)
651 	sg_cpu_stats *self;
652     CODE:
653 	RETVAL = sg_get_nelements(self);
654     OUTPUT:
655 	RETVAL
656 
657 LUV
658 user (self, num = 0)
659 	sg_cpu_stats *self;
660 	UV num;
661     CODE:
662 	if (num >= sg_get_nelements(self))
663 	    XSRETURN_UNDEF;
664 	RETVAL = self[num].user;
665     OUTPUT:
666 	RETVAL
667 
668 LUV
669 kernel (self, num = 0)
670 	sg_cpu_stats *self;
671 	UV num;
672     CODE:
673 	if (num >= sg_get_nelements(self))
674 	    XSRETURN_UNDEF;
675 	RETVAL = self[num].kernel;
676     OUTPUT:
677 	RETVAL
678 
679 LUV
680 idle (self, num = 0)
681 	sg_cpu_stats *self;
682 	UV num;
683     CODE:
684 	if (num >= sg_get_nelements(self))
685 	    XSRETURN_UNDEF;
686 	RETVAL = self[num].idle;
687     OUTPUT:
688 	RETVAL
689 
690 LUV
691 iowait (self, num = 0)
692 	sg_cpu_stats *self;
693 	UV num;
694     CODE:
695 	if (num >= sg_get_nelements(self))
696 	    XSRETURN_UNDEF;
697 	RETVAL = self[num].iowait;
698     OUTPUT:
699 	RETVAL
700 
701 LUV
702 swap (self, num = 0)
703 	sg_cpu_stats *self;
704 	UV num;
705     CODE:
706 	if (num >= sg_get_nelements(self))
707 	    XSRETURN_UNDEF;
708 	RETVAL = self[num].swap;
709     OUTPUT:
710 	RETVAL
711 
712 LUV
713 nice (self, num = 0)
714 	sg_cpu_stats *self;
715 	UV num;
716     CODE:
717 	if (num >= sg_get_nelements(self))
718 	    XSRETURN_UNDEF;
719 	RETVAL = self[num].nice;
720     OUTPUT:
721 	RETVAL
722 
723 LUV
724 total (self, num = 0)
725 	sg_cpu_stats *self;
726 	UV num;
727     CODE:
728 	if (num >= sg_get_nelements(self))
729 	    XSRETURN_UNDEF;
730 	RETVAL = self[num].total;
731     OUTPUT:
732 	RETVAL
733 
734 LUV
735 context_switches (self, num = 0)
736 	sg_cpu_stats *self;
737 	UV num;
738     CODE:
739 	if (num >= sg_get_nelements(self))
740 	    XSRETURN_UNDEF;
741 	RETVAL = self[num].context_switches;
742     OUTPUT:
743 	RETVAL
744 
745 LUV
746 voluntary_context_switches (self, num = 0)
747 	sg_cpu_stats *self;
748 	UV num;
749     CODE:
750 	if (num >= sg_get_nelements(self))
751 	    XSRETURN_UNDEF;
752 	RETVAL = self[num].voluntary_context_switches;
753     OUTPUT:
754 	RETVAL
755 
756 LUV
757 involuntary_context_switches (self, num = 0)
758 	sg_cpu_stats *self;
759 	UV num;
760     CODE:
761 	if (num >= sg_get_nelements(self))
762 	    XSRETURN_UNDEF;
763 	RETVAL = self[num].involuntary_context_switches;
764     OUTPUT:
765 	RETVAL
766 
767 LUV
768 syscalls (self, num = 0)
769 	sg_cpu_stats *self;
770 	UV num;
771     CODE:
772 	if (num >= sg_get_nelements(self))
773 	    XSRETURN_UNDEF;
774 	RETVAL = self[num].syscalls;
775     OUTPUT:
776 	RETVAL
777 
778 LUV
779 interrupts (self, num = 0)
780 	sg_cpu_stats *self;
781 	UV num;
782     CODE:
783 	if (num >= sg_get_nelements(self))
784 	    XSRETURN_UNDEF;
785 	RETVAL = self[num].interrupts;
786     OUTPUT:
787 	RETVAL
788 
789 LUV
790 soft_interrupts (self, num = 0)
791 	sg_cpu_stats *self;
792 	UV num;
793     CODE:
794 	if (num >= sg_get_nelements(self))
795 	    XSRETURN_UNDEF;
796 	RETVAL = self[num].soft_interrupts;
797     OUTPUT:
798 	RETVAL
799 
800 IV
801 systime (self, num = 0)
802 	sg_cpu_stats *self;
803 	UV num;
804     CODE:
805 	if (num >= sg_get_nelements(self))
806 	    XSRETURN_UNDEF;
807 	RETVAL = self[num].systime;
808     OUTPUT:
809 	RETVAL
810 
811 void
812 colnames(self)
813 	sg_cpu_stats *self;
814     PPCODE:
815         AV *retval;
816 	MAKE_AV_FROM_STRINGS(sg_cpu_stat_names, retval);
817 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
818 	XSRETURN(1);
819 
820 #define CPU_STATS_ARRAY_ROW(self, entry, av) \
821     do { \
822 	SV **ary; \
823 	size_t j; \
824 	av = newAV(); \
825 	av_extend(av, lengthof(sg_cpu_stat_names)); \
826 	ary = AvARRAY(av); \
827 	AvFILLp(av) = lengthof(sg_cpu_stat_names)-1; \
828 	for( j = 0; j < lengthof(sg_cpu_stat_names); ++j ) \
829 	    ary[j] = newSV(0); \
830 	sv_setuv(ary[0], self[entry].user); \
831 	sv_setuv(ary[1], self[entry].kernel); \
832 	sv_setuv(ary[2], self[entry].idle); \
833 	sv_setuv(ary[3], self[entry].iowait); \
834 	sv_setuv(ary[4], self[entry].swap); \
835 	sv_setuv(ary[5], self[entry].nice); \
836 	sv_setuv(ary[6], self[entry].total); \
837 	sv_setuv(ary[7], self[entry].context_switches); \
838 	sv_setuv(ary[8], self[entry].voluntary_context_switches); \
839 	sv_setuv(ary[9], self[entry].involuntary_context_switches); \
840 	sv_setuv(ary[10], self[entry].syscalls); \
841 	sv_setuv(ary[11], self[entry].interrupts); \
842 	sv_setuv(ary[12], self[entry].soft_interrupts); \
843 	sv_setiv(ary[13], self[entry].systime); \
844     } while(0)
845 
846 #define CPU_STATS_HASH_ROW(self, entry, hv) \
847     do { \
848 	hv = newHV(); \
849 	hv_store(hv, sg_cpu_stat_names[0], strlen(sg_cpu_stat_names[0]), newSVuv(self[entry].user), 0); \
850 	hv_store(hv, sg_cpu_stat_names[1], strlen(sg_cpu_stat_names[1]), newSVuv(self[entry].kernel), 0); \
851 	hv_store(hv, sg_cpu_stat_names[2], strlen(sg_cpu_stat_names[2]), newSVuv(self[entry].idle), 0); \
852 	hv_store(hv, sg_cpu_stat_names[3], strlen(sg_cpu_stat_names[3]), newSVuv(self[entry].iowait), 0); \
853 	hv_store(hv, sg_cpu_stat_names[4], strlen(sg_cpu_stat_names[4]), newSVuv(self[entry].swap), 0); \
854 	hv_store(hv, sg_cpu_stat_names[5], strlen(sg_cpu_stat_names[5]), newSVuv(self[entry].nice), 0); \
855 	hv_store(hv, sg_cpu_stat_names[6], strlen(sg_cpu_stat_names[6]), newSVuv(self[entry].total), 0); \
856 	hv_store(hv, sg_cpu_stat_names[7], strlen(sg_cpu_stat_names[7]), newSVuv(self[entry].context_switches), 0); \
857 	hv_store(hv, sg_cpu_stat_names[8], strlen(sg_cpu_stat_names[8]), newSVuv(self[entry].voluntary_context_switches), 0); \
858 	hv_store(hv, sg_cpu_stat_names[9], strlen(sg_cpu_stat_names[9]), newSVuv(self[entry].involuntary_context_switches), 0); \
859 	hv_store(hv, sg_cpu_stat_names[10], strlen(sg_cpu_stat_names[10]), newSVuv(self[entry].syscalls), 0); \
860 	hv_store(hv, sg_cpu_stat_names[11], strlen(sg_cpu_stat_names[11]), newSVuv(self[entry].interrupts), 0); \
861 	hv_store(hv, sg_cpu_stat_names[12], strlen(sg_cpu_stat_names[12]), newSVuv(self[entry].soft_interrupts), 0); \
862 	hv_store(hv, sg_cpu_stat_names[13], strlen(sg_cpu_stat_names[13]), newSViv(self[entry].systime), 0); \
863     } while(0)
864 
865 void
866 fetchrow_arrayref(self, num = 0)
867 	sg_cpu_stats *self;
868 	UV num;
869     CODE:
870         AV *retval;
871 	if (num >= sg_get_nelements(self))
872 	    XSRETURN_UNDEF;
873 	/* XXX add fill row macro here */
874 	CPU_STATS_ARRAY_ROW(self, num, retval);
875 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
876 	XSRETURN(1);
877 
878 void
879 fetchall_arrayref(self)
880 	sg_cpu_stats *self;
881     CODE:
882         AV *retval;
883 	/* XXX add fill row macro here */
884 	FETCH_ALL_ROWS(self, CPU_STATS_ARRAY_ROW, retval, AV);
885 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
886 	XSRETURN(1);
887 
888 void
889 fetchrow_hashref(self, num = 0)
890 	sg_cpu_stats *self;
891 	UV num;
892     CODE:
893         HV *retval;
894 	if (num >= sg_get_nelements(self))
895 	    XSRETURN_UNDEF;
896 	/* XXX add fill row macro here */
897 	CPU_STATS_HASH_ROW(self, num, retval);
898 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
899 	XSRETURN(1);
900 
901 void
902 fetchall_hashref(self)
903 	sg_cpu_stats *self;
904     CODE:
905         AV *retval;
906 	/* XXX add fill row macro here */
907 	FETCH_ALL_ROWS(self, CPU_STATS_HASH_ROW, retval, HV);
908 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
909 	XSRETURN(1);
910 
911 
912 void
DESTROY(self)913 DESTROY (self)
914 	sg_cpu_stats *self;
915     CODE:
916     {
917 	sg_free_cpu_stats(self);
918     }
919 
920 void
get_cpu_stats_diff(now,last)921 get_cpu_stats_diff (now, last)
922 	sg_cpu_stats *now;
923 	sg_cpu_stats *last;
924     CODE:
925     {
926 	sg_cpu_stats *self;
927 	if ((self = sg_get_cpu_stats_diff_between(now, last, NULL)) == NULL)
928 	    XSRETURN_UNDEF;
929 
930 	EXTEND(SP, 1);
931 
932 	ST(0) = sv_newmortal();
933 	sv_setref_pv(ST(0), "Unix::Statgrab::sg_cpu_stats", (void*)self);
934 	XSRETURN(1);
935     }
936 
937 void
get_cpu_percents(of)938 get_cpu_percents (of)
939 	sg_cpu_stats *of;
940     CODE:
941     {
942 	sg_cpu_percents *self;
943 	if ((self = sg_get_cpu_percents_r(of, NULL)) == NULL)
944 	    XSRETURN_UNDEF;
945 
946 	EXTEND(SP, 1);
947 
948 	ST(0) = sv_newmortal();
949 	sv_setref_pv(ST(0), "Unix::Statgrab::sg_cpu_percents", (void*)self);
950 	XSRETURN(1);
951     }
952 
953 MODULE = Unix::Statgrab		PACKAGE = Unix::Statgrab::sg_cpu_percents
954 
955 UV
956 entries (self)
957 	sg_cpu_percents *self;
958     CODE:
959 	RETVAL = sg_get_nelements(self);
960     OUTPUT:
961 	RETVAL
962 
963 NV
964 user (self, num = 0)
965 	sg_cpu_percents *self;
966 	UV num;
967     CODE:
968 	if (num >= sg_get_nelements(self))
969 	    XSRETURN_UNDEF;
970 	RETVAL = self[num].user;
971     OUTPUT:
972 	RETVAL
973 
974 NV
975 kernel (self, num = 0)
976 	sg_cpu_percents *self;
977 	UV num;
978     CODE:
979 	if (num >= sg_get_nelements(self))
980 	    XSRETURN_UNDEF;
981 	RETVAL = self[num].kernel;
982     OUTPUT:
983 	RETVAL
984 
985 NV
986 idle (self, num = 0)
987 	sg_cpu_percents *self;
988 	UV num;
989     CODE:
990 	if (num >= sg_get_nelements(self))
991 	    XSRETURN_UNDEF;
992 	RETVAL = self[num].idle;
993     OUTPUT:
994 	RETVAL
995 
996 NV
997 iowait (self, num = 0)
998 	sg_cpu_percents *self;
999 	UV num;
1000     CODE:
1001 	if (num >= sg_get_nelements(self))
1002 	    XSRETURN_UNDEF;
1003 	RETVAL = self[num].iowait;
1004     OUTPUT:
1005 	RETVAL
1006 
1007 NV
1008 swap (self, num = 0)
1009 	sg_cpu_percents *self;
1010 	UV num;
1011     CODE:
1012 	if (num >= sg_get_nelements(self))
1013 	    XSRETURN_UNDEF;
1014 	RETVAL = self[num].swap;
1015     OUTPUT:
1016 	RETVAL
1017 
1018 NV
1019 nice (self, num = 0)
1020 	sg_cpu_percents *self;
1021 	UV num;
1022     CODE:
1023 	if (num >= sg_get_nelements(self))
1024 	    XSRETURN_UNDEF;
1025 	RETVAL = self[num].nice;
1026     OUTPUT:
1027 	RETVAL
1028 
1029 UV
1030 time_taken (self, num = 0)
1031 	sg_cpu_percents *self;
1032 	UV num;
1033     CODE:
1034 	if (num >= sg_get_nelements(self))
1035 	    XSRETURN_UNDEF;
1036 	RETVAL = self[num].time_taken;
1037     OUTPUT:
1038 	RETVAL
1039 
1040 void
1041 colnames(self)
1042 	sg_cpu_percents *self;
1043     PPCODE:
1044         AV *retval;
1045 	MAKE_AV_FROM_STRINGS(sg_cpu_percent_names, retval);
1046 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
1047 	XSRETURN(1);
1048 
1049 #define CPU_PERCENTS_ARRAY_ROW(self, entry, av) \
1050     do { \
1051 	SV **ary; \
1052 	size_t j; \
1053 	av = newAV(); \
1054 	av_extend(av, lengthof(sg_cpu_percent_names)); \
1055 	ary = AvARRAY(av); \
1056 	AvFILLp(av) = lengthof(sg_cpu_percent_names)-1; \
1057 	for( j = 0; j < lengthof(sg_cpu_percent_names); ++j ) \
1058 	    ary[j] = newSV(0); \
1059 	sv_setnv(ary[0], self[entry].user); \
1060 	sv_setnv(ary[1], self[entry].kernel); \
1061 	sv_setnv(ary[2], self[entry].idle); \
1062 	sv_setnv(ary[3], self[entry].iowait); \
1063 	sv_setnv(ary[4], self[entry].swap); \
1064 	sv_setnv(ary[5], self[entry].nice); \
1065 	sv_setiv(ary[6], self[entry].time_taken); \
1066     } while(0)
1067 
1068 #define CPU_PERCENTS_HASH_ROW(self, entry, hv) \
1069     do { \
1070 	hv = newHV(); \
1071 	hv_store(hv, sg_cpu_percent_names[0], strlen(sg_cpu_percent_names[0]), newSVnv(self[entry].user), 0); \
1072 	hv_store(hv, sg_cpu_percent_names[1], strlen(sg_cpu_percent_names[1]), newSVnv(self[entry].kernel), 0); \
1073 	hv_store(hv, sg_cpu_percent_names[2], strlen(sg_cpu_percent_names[2]), newSVnv(self[entry].idle), 0); \
1074 	hv_store(hv, sg_cpu_percent_names[3], strlen(sg_cpu_percent_names[3]), newSVnv(self[entry].iowait), 0); \
1075 	hv_store(hv, sg_cpu_percent_names[4], strlen(sg_cpu_percent_names[4]), newSVnv(self[entry].swap), 0); \
1076 	hv_store(hv, sg_cpu_percent_names[5], strlen(sg_cpu_percent_names[5]), newSVnv(self[entry].nice), 0); \
1077 	hv_store(hv, sg_cpu_percent_names[6], strlen(sg_cpu_percent_names[6]), newSViv(self[entry].time_taken), 0); \
1078     } while(0)
1079 
1080 void
1081 fetchrow_arrayref(self, num = 0)
1082 	sg_cpu_percents *self;
1083 	UV num;
1084     CODE:
1085         AV *retval;
1086 	if (num >= sg_get_nelements(self))
1087 	    XSRETURN_UNDEF;
1088 	/* XXX add fill row macro here */
1089 	CPU_PERCENTS_ARRAY_ROW(self, num, retval);
1090 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
1091 	XSRETURN(1);
1092 
1093 void
1094 fetchall_arrayref(self)
1095 	sg_cpu_percents *self;
1096     CODE:
1097         AV *retval;
1098 	/* XXX add fill row macro here */
1099 	FETCH_ALL_ROWS(self, CPU_PERCENTS_ARRAY_ROW, retval, AV);
1100 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
1101 	XSRETURN(1);
1102 
1103 void
1104 fetchrow_hashref(self, num = 0)
1105 	sg_cpu_percents *self;
1106 	UV num;
1107     CODE:
1108         HV *retval;
1109 	if (num >= sg_get_nelements(self))
1110 	    XSRETURN_UNDEF;
1111 	/* XXX add fill row macro here */
1112 	CPU_PERCENTS_HASH_ROW(self, num, retval);
1113 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
1114 	XSRETURN(1);
1115 
1116 void
1117 fetchall_hashref(self)
1118 	sg_cpu_percents *self;
1119     CODE:
1120         AV *retval;
1121 	/* XXX add fill row macro here */
1122 	FETCH_ALL_ROWS(self, CPU_PERCENTS_HASH_ROW, retval, HV);
1123 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
1124 	XSRETURN(1);
1125 
1126 void
DESTROY(self)1127 DESTROY (self)
1128 	sg_cpu_percents *self;
1129     CODE:
1130     {
1131 	sg_free_cpu_percents(self);
1132     }
1133 
1134 MODULE = Unix::Statgrab		PACKAGE = Unix::Statgrab::sg_disk_io_stats
1135 
1136 UV
1137 entries (self)
1138 	sg_disk_io_stats *self;
1139     CODE:
1140 	RETVAL = sg_get_nelements(self);
1141     OUTPUT:
1142 	RETVAL
1143 
1144 char *
1145 disk_name (self, num = 0)
1146 	sg_disk_io_stats *self;
1147 	UV num;
1148     CODE:
1149 	if (num >= sg_get_nelements(self))
1150 	    XSRETURN_UNDEF;
1151 	RETVAL = self[num].disk_name;
1152     OUTPUT:
1153 	RETVAL
1154 
1155 LUV
1156 read_bytes (self, num = 0)
1157 	sg_disk_io_stats *self;
1158 	UV num;
1159     CODE:
1160 	if (num >= sg_get_nelements(self))
1161 	    XSRETURN_UNDEF;
1162 	RETVAL = self[num].read_bytes;
1163     OUTPUT:
1164 	RETVAL
1165 
1166 LUV
1167 write_bytes (self, num = 0)
1168 	sg_disk_io_stats *self;
1169 	UV num;
1170     CODE:
1171 	if (num >= sg_get_nelements(self))
1172 	    XSRETURN_UNDEF;
1173 	RETVAL = self[num].write_bytes;
1174     OUTPUT:
1175 	RETVAL
1176 
1177 IV
1178 systime (self, num = 0)
1179 	sg_disk_io_stats *self;
1180 	UV num;
1181     CODE:
1182 	if (num >= sg_get_nelements(self))
1183 	    XSRETURN_UNDEF;
1184 	RETVAL = self[num].systime;
1185     OUTPUT:
1186 	RETVAL
1187 
1188 void
1189 colnames(self)
1190 	sg_disk_io_stats *self;
1191     PPCODE:
1192         AV *retval;
1193 	MAKE_AV_FROM_STRINGS(sg_disk_io_stat_names, retval);
1194 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
1195 	XSRETURN(1);
1196 
1197 #define DISK_IO_STATS_ARRAY_ROW(self, entry, av) \
1198     do { \
1199 	SV **ary; \
1200 	size_t j; \
1201 	av = newAV(); \
1202 	av_extend(av, lengthof(sg_disk_io_stat_names)); \
1203 	ary = AvARRAY(av); \
1204 	AvFILLp(av) = lengthof(sg_disk_io_stat_names)-1; \
1205 	for( j = 0; j < lengthof(sg_disk_io_stat_names); ++j ) \
1206 	    ary[j] = newSV(0); \
1207 	sv_setpvn_IF(ary[0], self[entry].disk_name, SAFE_STRLEN(self[entry].disk_name)); \
1208 	sv_setuv(ary[1], self[entry].read_bytes); \
1209 	sv_setuv(ary[2], self[entry].write_bytes); \
1210 	sv_setiv(ary[3], self[entry].systime); \
1211     } while(0)
1212 
1213 #define DISK_IO_STATS_HASH_ROW(self, entry, hv) \
1214     do { \
1215 	hv = newHV(); \
1216 	hv_store(hv, sg_disk_io_stat_names[0], strlen(sg_disk_io_stat_names[0]), newSVpvn(self[entry].disk_name, SAFE_STRLEN(self[entry].disk_name)), 0); \
1217 	hv_store(hv, sg_disk_io_stat_names[1], strlen(sg_disk_io_stat_names[1]), newSVuv(self[entry].read_bytes), 0); \
1218 	hv_store(hv, sg_disk_io_stat_names[2], strlen(sg_disk_io_stat_names[2]), newSVuv(self[entry].write_bytes), 0); \
1219 	hv_store(hv, sg_disk_io_stat_names[3], strlen(sg_disk_io_stat_names[3]), newSViv(self[entry].systime), 0); \
1220     } while(0)
1221 
1222 void
1223 fetchrow_arrayref(self, num = 0)
1224 	sg_disk_io_stats *self;
1225 	UV num;
1226     CODE:
1227         AV *retval;
1228 	if (num >= sg_get_nelements(self))
1229 	    XSRETURN_UNDEF;
1230 	/* XXX add fill row macro here */
1231 	DISK_IO_STATS_ARRAY_ROW(self, num, retval);
1232 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
1233 	XSRETURN(1);
1234 
1235 void
1236 fetchall_arrayref(self)
1237 	sg_disk_io_stats *self;
1238     CODE:
1239         AV *retval;
1240 	/* XXX add fill row macro here */
1241 	FETCH_ALL_ROWS(self, DISK_IO_STATS_ARRAY_ROW, retval, AV);
1242 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
1243 	XSRETURN(1);
1244 
1245 void
1246 fetchrow_hashref(self, num = 0)
1247 	sg_disk_io_stats *self;
1248 	UV num;
1249     CODE:
1250         HV *retval;
1251 	if (num >= sg_get_nelements(self))
1252 	    XSRETURN_UNDEF;
1253 	/* XXX add fill row macro here */
1254 	DISK_IO_STATS_HASH_ROW(self, num, retval);
1255 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
1256 	XSRETURN(1);
1257 
1258 void
1259 fetchall_hashref(self)
1260 	sg_disk_io_stats *self;
1261     CODE:
1262         AV *retval;
1263 	/* XXX add fill row macro here */
1264 	FETCH_ALL_ROWS(self, DISK_IO_STATS_HASH_ROW, retval, HV);
1265 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
1266 	XSRETURN(1);
1267 
1268 void
DESTROY(self)1269 DESTROY (self)
1270 	sg_disk_io_stats *self;
1271     CODE:
1272     {
1273 	sg_free_disk_io_stats(self);
1274     }
1275 
1276 void
get_disk_io_stats_diff(now,last)1277 get_disk_io_stats_diff (now, last)
1278 	sg_disk_io_stats *now;
1279 	sg_disk_io_stats *last;
1280     CODE:
1281     {
1282 	sg_disk_io_stats *self;
1283 
1284 	if ((self = sg_get_disk_io_stats_diff_between(now, last, NULL)) == NULL)
1285 	    XSRETURN_UNDEF;
1286 
1287 	EXTEND(SP, 1);
1288 
1289 	ST(0) = sv_newmortal();
1290 	sv_setref_pv(ST(0), "Unix::Statgrab::sg_disk_io_stats", (void*)self);
1291 	XSRETURN(1);
1292     }
1293 
1294 MODULE = Unix::Statgrab		PACKAGE = Unix::Statgrab::sg_fs_stats
1295 
1296 #ifndef HAVE_DEVICE_CANONICAL
1297 #define device_canonical device_name
1298 #endif
1299 
1300 UV
1301 entries (self)
1302 	sg_fs_stats *self;
1303     CODE:
1304 	RETVAL = sg_get_nelements(self);
1305     OUTPUT:
1306 	RETVAL
1307 
1308 char *
1309 device_name (self, num = 0)
1310 	sg_fs_stats *self;
1311 	UV num;
1312     CODE:
1313 	if (num >= sg_get_nelements(self))
1314 	    XSRETURN_UNDEF;
1315 	RETVAL = self[num].device_name;
1316     OUTPUT:
1317 	RETVAL
1318 
1319 char *
1320 device_canonical (self, num = 0)
1321 	sg_fs_stats *self;
1322 	UV num;
1323     CODE:
1324 	if (num >= sg_get_nelements(self))
1325 	    XSRETURN_UNDEF;
1326 	RETVAL = self[num].device_canonical;
1327     OUTPUT:
1328 	RETVAL
1329 
1330 char *
1331 fs_type (self, num = 0)
1332 	sg_fs_stats *self;
1333 	UV num;
1334     CODE:
1335 	if (num >= sg_get_nelements(self))
1336 	    XSRETURN_UNDEF;
1337 	RETVAL = self[num].fs_type;
1338     OUTPUT:
1339 	RETVAL
1340 
1341 char *
1342 mnt_point (self, num = 0)
1343 	sg_fs_stats *self;
1344 	UV num;
1345     CODE:
1346 	if (num >= sg_get_nelements(self))
1347 	    XSRETURN_UNDEF;
1348 	RETVAL = self[num].mnt_point;
1349     OUTPUT:
1350 	RETVAL
1351 
1352 UV
1353 device_type (self, num = 0)
1354 	sg_fs_stats *self;
1355 	UV num;
1356     CODE:
1357 	if (num >= sg_get_nelements(self))
1358 	    XSRETURN_UNDEF;
1359 	RETVAL = self[num].device_type;
1360     OUTPUT:
1361 	RETVAL
1362 
1363 LUV
1364 size (self, num = 0)
1365 	sg_fs_stats *self;
1366 	UV num;
1367     CODE:
1368 	if (num >= sg_get_nelements(self))
1369 	    XSRETURN_UNDEF;
1370 	RETVAL = self[num].size;
1371     OUTPUT:
1372 	RETVAL
1373 
1374 LUV
1375 used (self, num = 0)
1376 	sg_fs_stats *self;
1377 	UV num;
1378     CODE:
1379 	if (num >= sg_get_nelements(self))
1380 	    XSRETURN_UNDEF;
1381 	RETVAL = self[num].used;
1382     OUTPUT:
1383 	RETVAL
1384 
1385 LUV
1386 free (self, num = 0)
1387 	sg_fs_stats *self;
1388 	UV num;
1389     CODE:
1390 	if (num >= sg_get_nelements(self))
1391 	    XSRETURN_UNDEF;
1392 	RETVAL = self[num].free;
1393     OUTPUT:
1394 	RETVAL
1395 
1396 LUV
1397 avail (self, num = 0)
1398 	sg_fs_stats *self;
1399 	UV num;
1400     CODE:
1401 	if (num >= sg_get_nelements(self))
1402 	    XSRETURN_UNDEF;
1403 	RETVAL = self[num].avail;
1404     OUTPUT:
1405 	RETVAL
1406 
1407 LUV
1408 total_inodes (self, num = 0)
1409 	sg_fs_stats *self;
1410 	UV num;
1411     CODE:
1412 	if (num >= sg_get_nelements(self))
1413 	    XSRETURN_UNDEF;
1414 	RETVAL = self[num].total_inodes;
1415     OUTPUT:
1416 	RETVAL
1417 
1418 LUV
1419 used_inodes (self, num = 0)
1420 	sg_fs_stats *self;
1421 	UV num;
1422     CODE:
1423 	if (num >= sg_get_nelements(self))
1424 	    XSRETURN_UNDEF;
1425 	RETVAL = self[num].used_inodes;
1426     OUTPUT:
1427 	RETVAL
1428 
1429 LUV
1430 free_inodes (self, num = 0)
1431 	sg_fs_stats *self;
1432 	UV num;
1433     CODE:
1434 	if (num >= sg_get_nelements(self))
1435 	    XSRETURN_UNDEF;
1436 	RETVAL = self[num].free_inodes;
1437     OUTPUT:
1438 	RETVAL
1439 
1440 LUV
1441 avail_inodes (self, num = 0)
1442 	sg_fs_stats *self;
1443 	UV num;
1444     CODE:
1445 	if (num >= sg_get_nelements(self))
1446 	    XSRETURN_UNDEF;
1447 	RETVAL = self[num].avail_inodes;
1448     OUTPUT:
1449 	RETVAL
1450 
1451 LUV
1452 io_size (self, num = 0)
1453 	sg_fs_stats *self;
1454 	UV num;
1455     CODE:
1456 	if (num >= sg_get_nelements(self))
1457 	    XSRETURN_UNDEF;
1458 	RETVAL = self[num].io_size;
1459     OUTPUT:
1460 	RETVAL
1461 
1462 LUV
1463 block_size (self, num = 0)
1464 	sg_fs_stats *self;
1465 	UV num;
1466     CODE:
1467 	if (num >= sg_get_nelements(self))
1468 	    XSRETURN_UNDEF;
1469 	RETVAL = self[num].block_size;
1470     OUTPUT:
1471 	RETVAL
1472 
1473 LUV
1474 total_blocks (self, num = 0)
1475 	sg_fs_stats *self;
1476 	UV num;
1477     CODE:
1478 	if (num >= sg_get_nelements(self))
1479 	    XSRETURN_UNDEF;
1480 	RETVAL = self[num].total_blocks;
1481     OUTPUT:
1482 	RETVAL
1483 
1484 LUV
1485 free_blocks (self, num = 0)
1486 	sg_fs_stats *self;
1487 	UV num;
1488     CODE:
1489 	if (num >= sg_get_nelements(self))
1490 	    XSRETURN_UNDEF;
1491 	RETVAL = self[num].free_blocks;
1492     OUTPUT:
1493 	RETVAL
1494 
1495 LUV
1496 used_blocks (self, num = 0)
1497 	sg_fs_stats *self;
1498 	UV num;
1499     CODE:
1500 	if (num >= sg_get_nelements(self))
1501 	    XSRETURN_UNDEF;
1502 	RETVAL = self[num].used_blocks;
1503     OUTPUT:
1504 	RETVAL
1505 
1506 LUV
1507 avail_blocks (self, num = 0)
1508 	sg_fs_stats *self;
1509 	UV num;
1510     CODE:
1511 	if (num >= sg_get_nelements(self))
1512 	    XSRETURN_UNDEF;
1513 	RETVAL = self[num].avail_blocks;
1514     OUTPUT:
1515 	RETVAL
1516 
1517 IV
1518 systime (self, num = 0)
1519 	sg_fs_stats *self;
1520 	UV num;
1521     CODE:
1522 	if (num >= sg_get_nelements(self))
1523 	    XSRETURN_UNDEF;
1524 	RETVAL = self[num].systime;
1525     OUTPUT:
1526 	RETVAL
1527 
1528 void
1529 colnames(self)
1530 	sg_fs_stats *self;
1531     PPCODE:
1532         AV *retval;
1533 	MAKE_AV_FROM_STRINGS(sg_fs_stat_names, retval);
1534 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
1535 	XSRETURN(1);
1536 
1537 #define FS_STATS_ARRAY_ROW(self, entry, av) \
1538     do { \
1539 	SV **ary; \
1540 	size_t j; \
1541 	av = newAV(); \
1542 	av_extend(av, lengthof(sg_fs_stat_names)); \
1543 	ary = AvARRAY(av); \
1544 	AvFILLp(av) = lengthof(sg_fs_stat_names)-1; \
1545 	for( j = 0; j < lengthof(sg_fs_stat_names); ++j ) \
1546 	    ary[j] = newSV(0); \
1547 	sv_setpvn_IF(ary[0], self[entry].device_name, SAFE_STRLEN(self[entry].device_name)); \
1548 	sv_setpvn_IF(ary[1], self[entry].device_canonical, SAFE_STRLEN(self[entry].device_canonical)); \
1549 	sv_setpvn_IF(ary[2], self[entry].fs_type, SAFE_STRLEN(self[entry].fs_type)); \
1550 	sv_setpvn_IF(ary[3], self[entry].mnt_point, SAFE_STRLEN(self[entry].mnt_point)); \
1551 	sv_setuv(ary[4], self[entry].device_type); \
1552 	sv_setiv(ary[5], self[entry].size); \
1553 	sv_setiv(ary[6], self[entry].used); \
1554 	sv_setiv(ary[7], self[entry].free); \
1555 	sv_setiv(ary[8], self[entry].avail); \
1556 	sv_setiv(ary[9], self[entry].total_inodes); \
1557 	sv_setuv(ary[10], self[entry].used_inodes); \
1558 	sv_setuv(ary[11], self[entry].free_inodes); \
1559 	sv_setuv(ary[12], self[entry].avail_inodes); \
1560 	sv_setuv(ary[13], self[entry].io_size); \
1561 	sv_setuv(ary[14], self[entry].block_size); \
1562 	sv_setiv(ary[15], self[entry].total_blocks); \
1563 	sv_setiv(ary[16], self[entry].free_blocks); \
1564 	sv_setnv(ary[17], self[entry].used_blocks); \
1565 	sv_setiv(ary[18], self[entry].avail_blocks); \
1566 	sv_setiv(ary[19], self[entry].systime); \
1567     } while(0)
1568 
1569 #define FS_STATS_HASH_ROW(self, entry, hv) \
1570     do { \
1571 	hv = newHV(); \
1572 	hv_store(hv, sg_fs_stat_names[0], strlen(sg_fs_stat_names[0]), newSVpvn(self[entry].device_name, SAFE_STRLEN(self[entry].device_name)), 0); \
1573 	hv_store(hv, sg_fs_stat_names[1], strlen(sg_fs_stat_names[1]), newSVpvn(self[entry].device_canonical, SAFE_STRLEN(self[entry].device_canonical)), 0); \
1574 	hv_store(hv, sg_fs_stat_names[2], strlen(sg_fs_stat_names[2]), newSVpvn(self[entry].fs_type, SAFE_STRLEN(self[entry].fs_type)), 0); \
1575 	hv_store(hv, sg_fs_stat_names[3], strlen(sg_fs_stat_names[3]), newSVpvn(self[entry].mnt_point, SAFE_STRLEN(self[entry].mnt_point)), 0); \
1576 	hv_store(hv, sg_fs_stat_names[4], strlen(sg_fs_stat_names[4]), newSVuv(self[entry].device_type), 0); \
1577 	hv_store(hv, sg_fs_stat_names[5], strlen(sg_fs_stat_names[5]), newSVuv(self[entry].size), 0); \
1578 	hv_store(hv, sg_fs_stat_names[6], strlen(sg_fs_stat_names[6]), newSVuv(self[entry].used), 0); \
1579 	hv_store(hv, sg_fs_stat_names[7], strlen(sg_fs_stat_names[7]), newSVuv(self[entry].free), 0); \
1580 	hv_store(hv, sg_fs_stat_names[8], strlen(sg_fs_stat_names[8]), newSVuv(self[entry].avail), 0); \
1581 	hv_store(hv, sg_fs_stat_names[9], strlen(sg_fs_stat_names[9]), newSVuv(self[entry].total_inodes), 0); \
1582 	hv_store(hv, sg_fs_stat_names[10], strlen(sg_fs_stat_names[10]), newSVuv(self[entry].used_inodes), 0); \
1583 	hv_store(hv, sg_fs_stat_names[11], strlen(sg_fs_stat_names[11]), newSVuv(self[entry].free_inodes), 0); \
1584 	hv_store(hv, sg_fs_stat_names[12], strlen(sg_fs_stat_names[12]), newSVuv(self[entry].avail_inodes), 0); \
1585 	hv_store(hv, sg_fs_stat_names[13], strlen(sg_fs_stat_names[13]), newSVuv(self[entry].io_size), 0); \
1586 	hv_store(hv, sg_fs_stat_names[14], strlen(sg_fs_stat_names[14]), newSVuv(self[entry].block_size), 0); \
1587 	hv_store(hv, sg_fs_stat_names[15], strlen(sg_fs_stat_names[15]), newSVuv(self[entry].total_blocks), 0); \
1588 	hv_store(hv, sg_fs_stat_names[16], strlen(sg_fs_stat_names[16]), newSVuv(self[entry].free_blocks), 0); \
1589 	hv_store(hv, sg_fs_stat_names[17], strlen(sg_fs_stat_names[17]), newSVuv(self[entry].used_blocks), 0); \
1590 	hv_store(hv, sg_fs_stat_names[18], strlen(sg_fs_stat_names[18]), newSVuv(self[entry].avail_blocks), 0); \
1591 	hv_store(hv, sg_fs_stat_names[19], strlen(sg_fs_stat_names[19]), newSViv(self[entry].systime), 0); \
1592     } while(0)
1593 
1594 void
1595 fetchrow_arrayref(self, num = 0)
1596 	sg_fs_stats *self;
1597 	UV num;
1598     CODE:
1599         AV *retval;
1600 	if (num >= sg_get_nelements(self))
1601 	    XSRETURN_UNDEF;
1602 	/* XXX add fill row macro here */
1603 	FS_STATS_ARRAY_ROW(self, num, retval);
1604 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
1605 	XSRETURN(1);
1606 
1607 void
1608 fetchall_arrayref(self)
1609 	sg_fs_stats *self;
1610     CODE:
1611         AV *retval;
1612 	/* XXX add fill row macro here */
1613 	FETCH_ALL_ROWS(self, FS_STATS_ARRAY_ROW, retval, AV);
1614 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
1615 	XSRETURN(1);
1616 
1617 void
1618 fetchrow_hashref(self, num = 0)
1619 	sg_fs_stats *self;
1620 	UV num;
1621     CODE:
1622         HV *retval;
1623 	if (num >= sg_get_nelements(self))
1624 	    XSRETURN_UNDEF;
1625 	/* XXX add fill row macro here */
1626 	FS_STATS_HASH_ROW(self, num, retval);
1627 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
1628 	XSRETURN(1);
1629 
1630 void
1631 fetchall_hashref(self)
1632 	sg_fs_stats *self;
1633     CODE:
1634         AV *retval;
1635 	/* XXX add fill row macro here */
1636 	FETCH_ALL_ROWS(self, FS_STATS_HASH_ROW, retval, HV);
1637 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
1638 	XSRETURN(1);
1639 
1640 void
DESTROY(self)1641 DESTROY (self)
1642 	sg_fs_stats *self;
1643     CODE:
1644     {
1645 	sg_free_fs_stats(self);
1646     }
1647 
1648 void
get_fs_stats_diff(now,last)1649 get_fs_stats_diff (now, last)
1650 	sg_fs_stats *now;
1651 	sg_fs_stats *last;
1652     CODE:
1653     {
1654 	sg_fs_stats *self;
1655 
1656 	if ((self = sg_get_fs_stats_diff_between(now, last, NULL)) == NULL)
1657 	    XSRETURN_UNDEF;
1658 
1659 	EXTEND(SP, 1);
1660 
1661 	ST(0) = sv_newmortal();
1662 	sv_setref_pv(ST(0), "Unix::Statgrab::sg_fs_stats", (void*)self);
1663 	XSRETURN(1);
1664     }
1665 
1666 #undef device_canonical
1667 
1668 MODULE = Unix::Statgrab	    PACKAGE = Unix::Statgrab::sg_load_stats
1669 
1670 UV
1671 entries (self)
1672 	sg_load_stats *self;
1673     CODE:
1674 	RETVAL = sg_get_nelements(self);
1675     OUTPUT:
1676 	RETVAL
1677 
1678 NV
1679 min1 (self, num = 0)
1680 	sg_load_stats *self;
1681 	UV num;
1682     CODE:
1683 	if (num >= sg_get_nelements(self))
1684 	    XSRETURN_UNDEF;
1685 	RETVAL = self[num].min1;
1686     OUTPUT:
1687 	RETVAL
1688 
1689 NV
1690 min5 (self, num = 0)
1691 	sg_load_stats *self;
1692 	UV num;
1693     CODE:
1694 	if (num >= sg_get_nelements(self))
1695 	    XSRETURN_UNDEF;
1696 	RETVAL = self[num].min5;
1697     OUTPUT:
1698 	RETVAL
1699 
1700 NV
1701 min15 (self, num = 0)
1702 	sg_load_stats *self;
1703 	UV num;
1704     CODE:
1705 	if (num >= sg_get_nelements(self))
1706 	    XSRETURN_UNDEF;
1707 	RETVAL = self[num].min15;
1708     OUTPUT:
1709 	RETVAL
1710 
1711 IV
1712 systime (self, num = 0)
1713 	sg_load_stats *self;
1714 	UV num;
1715     CODE:
1716 	if (num >= sg_get_nelements(self))
1717 	    XSRETURN_UNDEF;
1718 	RETVAL = self[num].systime;
1719     OUTPUT:
1720 	RETVAL
1721 
1722 void
1723 colnames(self)
1724 	sg_load_stats *self;
1725     PPCODE:
1726         AV *retval;
1727 	MAKE_AV_FROM_STRINGS(sg_load_stat_names, retval);
1728 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
1729 	XSRETURN(1);
1730 
1731 #define LOAD_STATS_ARRAY_ROW(self, entry, av) \
1732     do { \
1733 	SV **ary; \
1734 	size_t j; \
1735 	av = newAV(); \
1736 	av_extend(av, lengthof(sg_load_stat_names)); \
1737 	ary = AvARRAY(av); \
1738 	AvFILLp(av) = lengthof(sg_load_stat_names)-1; \
1739 	for( j = 0; j < lengthof(sg_load_stat_names); ++j ) \
1740 	    ary[j] = newSV(0); \
1741 	sv_setnv(ary[0], self[entry].min1); \
1742 	sv_setnv(ary[1], self[entry].min5); \
1743 	sv_setnv(ary[2], self[entry].min15); \
1744 	sv_setiv(ary[3], self[entry].systime); \
1745     } while(0)
1746 
1747 #define LOAD_STATS_HASH_ROW(self, entry, hv) \
1748     do { \
1749 	hv = newHV(); \
1750 	hv_store(hv, sg_load_stat_names[0], strlen(sg_load_stat_names[0]), newSVnv(self[entry].min1), 0); \
1751 	hv_store(hv, sg_load_stat_names[1], strlen(sg_load_stat_names[1]), newSVnv(self[entry].min5), 0); \
1752 	hv_store(hv, sg_load_stat_names[2], strlen(sg_load_stat_names[2]), newSVnv(self[entry].min15), 0); \
1753 	hv_store(hv, sg_load_stat_names[3], strlen(sg_load_stat_names[3]), newSViv(self[entry].systime), 0); \
1754     } while(0)
1755 
1756 void
1757 fetchrow_arrayref(self, num = 0)
1758 	sg_load_stats *self;
1759 	UV num;
1760     CODE:
1761         AV *retval;
1762 	if (num >= sg_get_nelements(self))
1763 	    XSRETURN_UNDEF;
1764 	/* XXX add fill row macro here */
1765 	LOAD_STATS_ARRAY_ROW(self, num, retval);
1766 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
1767 	XSRETURN(1);
1768 
1769 void
1770 fetchall_arrayref(self)
1771 	sg_load_stats *self;
1772     CODE:
1773         AV *retval;
1774 	/* XXX add fill row macro here */
1775 	FETCH_ALL_ROWS(self, LOAD_STATS_ARRAY_ROW, retval, AV);
1776 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
1777 	XSRETURN(1);
1778 
1779 void
1780 fetchrow_hashref(self, num = 0)
1781 	sg_load_stats *self;
1782 	UV num;
1783     CODE:
1784         HV *retval;
1785 	if (num >= sg_get_nelements(self))
1786 	    XSRETURN_UNDEF;
1787 	/* XXX add fill row macro here */
1788 	LOAD_STATS_HASH_ROW(self, num, retval);
1789 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
1790 	XSRETURN(1);
1791 
1792 void
1793 fetchall_hashref(self)
1794 	sg_load_stats *self;
1795     CODE:
1796         AV *retval;
1797 	/* XXX add fill row macro here */
1798 	FETCH_ALL_ROWS(self, LOAD_STATS_HASH_ROW, retval, HV);
1799 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
1800 	XSRETURN(1);
1801 
1802 void
DESTROY(self)1803 DESTROY (self)
1804 	sg_load_stats *self;
1805     CODE:
1806     {
1807 	sg_free_load_stats(self);
1808     }
1809 
1810 MODULE = Unix::Statgrab	    PACKAGE = Unix::Statgrab::sg_mem_stats
1811 
1812 UV
1813 entries (self)
1814 	sg_mem_stats *self;
1815     CODE:
1816 	RETVAL = sg_get_nelements(self);
1817     OUTPUT:
1818 	RETVAL
1819 
1820 LUV
1821 total (self, num = 0)
1822 	sg_mem_stats *self;
1823 	UV num;
1824     CODE:
1825 	if (num >= sg_get_nelements(self))
1826 	    XSRETURN_UNDEF;
1827 	RETVAL = self[num].total;
1828     OUTPUT:
1829 	RETVAL
1830 
1831 LUV
1832 free (self, num = 0)
1833 	sg_mem_stats *self;
1834 	UV num;
1835     CODE:
1836 	if (num >= sg_get_nelements(self))
1837 	    XSRETURN_UNDEF;
1838 	RETVAL = self[num].free;
1839     OUTPUT:
1840 	RETVAL
1841 
1842 LUV
1843 used (self, num = 0)
1844 	sg_mem_stats *self;
1845 	UV num;
1846     CODE:
1847 	if (num >= sg_get_nelements(self))
1848 	    XSRETURN_UNDEF;
1849 	RETVAL = self[num].used;
1850     OUTPUT:
1851 	RETVAL
1852 
1853 LUV
1854 cache (self, num = 0)
1855 	sg_mem_stats *self;
1856 	UV num;
1857     CODE:
1858 	if (num >= sg_get_nelements(self))
1859 	    XSRETURN_UNDEF;
1860 	RETVAL = self[num].cache;
1861     OUTPUT:
1862 	RETVAL
1863 
1864 IV
1865 systime (self, num = 0)
1866 	sg_mem_stats *self;
1867 	UV num;
1868     CODE:
1869 	if (num >= sg_get_nelements(self))
1870 	    XSRETURN_UNDEF;
1871 	RETVAL = self[num].systime;
1872     OUTPUT:
1873 	RETVAL
1874 
1875 void
1876 colnames(self)
1877 	sg_mem_stats *self;
1878     PPCODE:
1879         AV *retval;
1880 	MAKE_AV_FROM_STRINGS(sg_mem_stat_names, retval);
1881 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
1882 	XSRETURN(1);
1883 
1884 #define MEM_STATS_ARRAY_ROW(self, entry, av) \
1885     do { \
1886 	SV **ary; \
1887 	size_t j; \
1888 	av = newAV(); \
1889 	av_extend(av, lengthof(sg_mem_stat_names)); \
1890 	ary = AvARRAY(av); \
1891 	AvFILLp(av) = lengthof(sg_mem_stat_names)-1; \
1892 	for( j = 0; j < lengthof(sg_mem_stat_names); ++j ) \
1893 	    ary[j] = newSV(0); \
1894 	sv_setuv(ary[0], self[entry].total); \
1895 	sv_setuv(ary[1], self[entry].free); \
1896 	sv_setuv(ary[2], self[entry].used); \
1897 	sv_setuv(ary[3], self[entry].cache); \
1898 	sv_setiv(ary[4], self[entry].systime); \
1899     } while(0)
1900 
1901 #define MEM_STATS_HASH_ROW(self, entry, hv) \
1902     do { \
1903 	hv = newHV(); \
1904 	hv_store(hv, sg_mem_stat_names[0], strlen(sg_mem_stat_names[0]), newSVuv(self[entry].total), 0); \
1905 	hv_store(hv, sg_mem_stat_names[1], strlen(sg_mem_stat_names[1]), newSVuv(self[entry].free), 0); \
1906 	hv_store(hv, sg_mem_stat_names[2], strlen(sg_mem_stat_names[2]), newSVuv(self[entry].used), 0); \
1907 	hv_store(hv, sg_mem_stat_names[3], strlen(sg_mem_stat_names[3]), newSVuv(self[entry].cache), 0); \
1908 	hv_store(hv, sg_mem_stat_names[4], strlen(sg_mem_stat_names[4]), newSViv(self[entry].systime), 0); \
1909     } while(0)
1910 
1911 void
1912 fetchrow_arrayref(self, num = 0)
1913 	sg_mem_stats *self;
1914 	UV num;
1915     CODE:
1916         AV *retval;
1917 	if (num >= sg_get_nelements(self))
1918 	    XSRETURN_UNDEF;
1919 	/* XXX add fill row macro here */
1920 	MEM_STATS_ARRAY_ROW(self, num, retval);
1921 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
1922 	XSRETURN(1);
1923 
1924 void
1925 fetchall_arrayref(self)
1926 	sg_mem_stats *self;
1927     CODE:
1928         AV *retval;
1929 	/* XXX add fill row macro here */
1930 	FETCH_ALL_ROWS(self, MEM_STATS_ARRAY_ROW, retval, AV);
1931 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
1932 	XSRETURN(1);
1933 
1934 void
1935 fetchrow_hashref(self, num = 0)
1936 	sg_mem_stats *self;
1937 	UV num;
1938     CODE:
1939         HV *retval;
1940 	if (num >= sg_get_nelements(self))
1941 	    XSRETURN_UNDEF;
1942 	/* XXX add fill row macro here */
1943 	MEM_STATS_HASH_ROW(self, num, retval);
1944 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
1945 	XSRETURN(1);
1946 
1947 void
1948 fetchall_hashref(self)
1949 	sg_mem_stats *self;
1950     CODE:
1951         AV *retval;
1952 	/* XXX add fill row macro here */
1953 	FETCH_ALL_ROWS(self, MEM_STATS_HASH_ROW, retval, HV);
1954 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
1955 	XSRETURN(1);
1956 
1957 void
DESTROY(self)1958 DESTROY (self)
1959 	sg_mem_stats *self;
1960     CODE:
1961     {
1962 	sg_free_mem_stats(self);
1963     }
1964 
1965 MODULE = Unix::Statgrab     PACKAGE = Unix::Statgrab::sg_swap_stats
1966 
1967 UV
1968 entries (self)
1969 	sg_swap_stats *self;
1970     CODE:
1971 	RETVAL = sg_get_nelements(self);
1972     OUTPUT:
1973 	RETVAL
1974 
1975 LUV
1976 total (self, num = 0)
1977 	sg_swap_stats *self;
1978 	UV num;
1979     CODE:
1980 	if (num >= sg_get_nelements(self))
1981 	    XSRETURN_UNDEF;
1982 	RETVAL = self[num].total;
1983     OUTPUT:
1984 	RETVAL
1985 
1986 LUV
1987 free (self, num = 0)
1988 	sg_swap_stats *self;
1989 	UV num;
1990     CODE:
1991 	if (num >= sg_get_nelements(self))
1992 	    XSRETURN_UNDEF;
1993 	RETVAL = self[num].free;
1994     OUTPUT:
1995 	RETVAL
1996 
1997 LUV
1998 used (self, num = 0)
1999 	sg_swap_stats *self;
2000 	UV num;
2001     CODE:
2002 	if (num >= sg_get_nelements(self))
2003 	    XSRETURN_UNDEF;
2004 	RETVAL = self[num].used;
2005     OUTPUT:
2006 	RETVAL
2007 
2008 IV
2009 systime (self, num = 0)
2010 	sg_swap_stats *self;
2011 	UV num;
2012     CODE:
2013 	if (num >= sg_get_nelements(self))
2014 	    XSRETURN_UNDEF;
2015 	RETVAL = self[num].systime;
2016     OUTPUT:
2017 	RETVAL
2018 
2019 void
2020 colnames(self)
2021 	sg_swap_stats *self;
2022     PPCODE:
2023         AV *retval;
2024 	MAKE_AV_FROM_STRINGS(sg_swap_stat_names, retval);
2025 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
2026 	XSRETURN(1);
2027 
2028 #define SWAP_STATS_ARRAY_ROW(self, entry, av) \
2029     do { \
2030 	SV **ary; \
2031 	size_t j; \
2032 	av = newAV(); \
2033 	av_extend(av, lengthof(sg_swap_stat_names)); \
2034 	ary = AvARRAY(av); \
2035 	AvFILLp(av) = lengthof(sg_swap_stat_names)-1; \
2036 	for( j = 0; j < lengthof(sg_swap_stat_names); ++j ) \
2037 	    ary[j] = newSV(0); \
2038 	sv_setuv(ary[0], self[entry].total); \
2039 	sv_setuv(ary[1], self[entry].free); \
2040 	sv_setuv(ary[2], self[entry].used); \
2041 	sv_setiv(ary[3], self[entry].systime); \
2042     } while(0)
2043 
2044 #define SWAP_STATS_HASH_ROW(self, entry, hv) \
2045     do { \
2046 	hv = newHV(); \
2047 	hv_store(hv, sg_swap_stat_names[0], strlen(sg_swap_stat_names[0]), newSVuv(self[entry].total), 0); \
2048 	hv_store(hv, sg_swap_stat_names[1], strlen(sg_swap_stat_names[1]), newSVuv(self[entry].free), 0); \
2049 	hv_store(hv, sg_swap_stat_names[2], strlen(sg_swap_stat_names[2]), newSVuv(self[entry].used), 0); \
2050 	hv_store(hv, sg_swap_stat_names[3], strlen(sg_swap_stat_names[3]), newSViv(self[entry].systime), 0); \
2051     } while(0)
2052 
2053 void
2054 fetchrow_arrayref(self, num = 0)
2055 	sg_swap_stats *self;
2056 	UV num;
2057     CODE:
2058         AV *retval;
2059 	if (num >= sg_get_nelements(self))
2060 	    XSRETURN_UNDEF;
2061 	/* XXX add fill row macro here */
2062 	SWAP_STATS_ARRAY_ROW(self, num, retval);
2063 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
2064 	XSRETURN(1);
2065 
2066 void
2067 fetchall_arrayref(self)
2068 	sg_swap_stats *self;
2069     CODE:
2070         AV *retval;
2071 	/* XXX add fill row macro here */
2072 	FETCH_ALL_ROWS(self, SWAP_STATS_ARRAY_ROW, retval, AV);
2073 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
2074 	XSRETURN(1);
2075 
2076 void
2077 fetchrow_hashref(self, num = 0)
2078 	sg_swap_stats *self;
2079 	UV num;
2080     CODE:
2081         HV *retval;
2082 	if (num >= sg_get_nelements(self))
2083 	    XSRETURN_UNDEF;
2084 	/* XXX add fill row macro here */
2085 	SWAP_STATS_HASH_ROW(self, num, retval);
2086 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
2087 	XSRETURN(1);
2088 
2089 void
2090 fetchall_hashref(self)
2091 	sg_swap_stats *self;
2092     CODE:
2093         AV *retval;
2094 	/* XXX add fill row macro here */
2095 	FETCH_ALL_ROWS(self, SWAP_STATS_HASH_ROW, retval, HV);
2096 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
2097 	XSRETURN(1);
2098 
2099 void
DESTROY(self)2100 DESTROY (self)
2101 	sg_swap_stats *self;
2102     CODE:
2103     {
2104 	sg_free_swap_stats(self);
2105     }
2106 
2107 MODULE = Unix::Statgrab     PACKAGE = Unix::Statgrab::sg_network_io_stats
2108 
2109 UV
2110 entries (self)
2111 	sg_network_io_stats *self;
2112     CODE:
2113 	RETVAL = sg_get_nelements(self);
2114     OUTPUT:
2115 	RETVAL
2116 
2117 char *
2118 interface_name (self, num = 0)
2119 	sg_network_io_stats *self;
2120 	UV num;
2121     CODE:
2122 	if (num >= sg_get_nelements(self))
2123 	    XSRETURN_UNDEF;
2124 	RETVAL = self[num].interface_name;
2125     OUTPUT:
2126 	RETVAL
2127 
2128 LUV
2129 tx (self, num = 0)
2130 	sg_network_io_stats *self;
2131 	UV num;
2132     CODE:
2133 	if (num >= sg_get_nelements(self))
2134 	    XSRETURN_UNDEF;
2135 	RETVAL = self[num].tx;
2136     OUTPUT:
2137 	RETVAL
2138 
2139 LUV
2140 rx (self, num = 0)
2141 	sg_network_io_stats *self;
2142 	UV num;
2143     CODE:
2144 	if (num >= sg_get_nelements(self))
2145 	    XSRETURN_UNDEF;
2146 	RETVAL = self[num].rx;
2147     OUTPUT:
2148 	RETVAL
2149 
2150 LUV
2151 ipackets (self, num = 0)
2152 	sg_network_io_stats *self;
2153 	UV num;
2154     CODE:
2155 	if (num >= sg_get_nelements(self))
2156 	    XSRETURN_UNDEF;
2157 	RETVAL = self[num].ipackets;
2158     OUTPUT:
2159 	RETVAL
2160 
2161 LUV
2162 opackets (self, num = 0)
2163 	sg_network_io_stats *self;
2164 	UV num;
2165     CODE:
2166 	if (num >= sg_get_nelements(self))
2167 	    XSRETURN_UNDEF;
2168 	RETVAL = self[num].opackets;
2169     OUTPUT:
2170 	RETVAL
2171 
2172 LUV
2173 ierrors (self, num = 0)
2174 	sg_network_io_stats *self;
2175 	UV num;
2176     CODE:
2177 	if (num >= sg_get_nelements(self))
2178 	    XSRETURN_UNDEF;
2179 	RETVAL = self[num].ierrors;
2180     OUTPUT:
2181 	RETVAL
2182 
2183 LUV
2184 oerrors (self, num = 0)
2185 	sg_network_io_stats *self;
2186 	UV num;
2187     CODE:
2188 	if (num >= sg_get_nelements(self))
2189 	    XSRETURN_UNDEF;
2190 	RETVAL = self[num].oerrors;
2191     OUTPUT:
2192 	RETVAL
2193 
2194 LUV
2195 collisions (self, num = 0)
2196 	sg_network_io_stats *self;
2197 	UV num;
2198     CODE:
2199 	if (num >= sg_get_nelements(self))
2200 	    XSRETURN_UNDEF;
2201 	RETVAL = self[num].collisions;
2202     OUTPUT:
2203 	RETVAL
2204 
2205 UV
2206 systime (self, num = 0)
2207 	sg_network_io_stats *self;
2208 	UV num;
2209     CODE:
2210 	if (num >= sg_get_nelements(self))
2211 	    XSRETURN_UNDEF;
2212 	RETVAL = self[num].systime;
2213     OUTPUT:
2214 	RETVAL
2215 
2216 void
2217 colnames(self)
2218 	sg_network_io_stats *self;
2219     PPCODE:
2220         AV *retval;
2221 	MAKE_AV_FROM_STRINGS(sg_network_io_stat_names, retval);
2222 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
2223 	XSRETURN(1);
2224 
2225 #define NETWORK_IO_STATS_ARRAY_ROW(self, entry, av) \
2226     do { \
2227 	SV **ary; \
2228 	size_t j; \
2229 	av = newAV(); \
2230 	av_extend(av, lengthof(sg_network_io_stat_names)); \
2231 	ary = AvARRAY(av); \
2232 	AvFILLp(av) = lengthof(sg_network_io_stat_names)-1; \
2233 	for( j = 0; j < lengthof(sg_network_io_stat_names); ++j ) \
2234 	    ary[j] = newSV(0); \
2235 	sv_setpvn_IF(ary[0], self[entry].interface_name, SAFE_STRLEN(self[entry].interface_name)); \
2236 	sv_setuv(ary[1], self[entry].tx); \
2237 	sv_setuv(ary[2], self[entry].rx); \
2238 	sv_setuv(ary[3], self[entry].ipackets); \
2239 	sv_setuv(ary[4], self[entry].opackets); \
2240 	sv_setuv(ary[5], self[entry].ierrors); \
2241 	sv_setuv(ary[6], self[entry].oerrors); \
2242 	sv_setuv(ary[7], self[entry].collisions); \
2243 	sv_setiv(ary[8], self[entry].systime); \
2244     } while(0)
2245 
2246 #define NETWORK_IO_STATS_HASH_ROW(self, entry, hv) \
2247     do { \
2248 	hv = newHV(); \
2249 	hv_store(hv, sg_network_io_stat_names[0], strlen(sg_network_io_stat_names[0]), newSVpvn(self[entry].interface_name, SAFE_STRLEN(self[entry].interface_name)), 0); \
2250 	hv_store(hv, sg_network_io_stat_names[1], strlen(sg_network_io_stat_names[1]), newSVuv(self[entry].tx), 0); \
2251 	hv_store(hv, sg_network_io_stat_names[2], strlen(sg_network_io_stat_names[2]), newSVuv(self[entry].rx), 0); \
2252 	hv_store(hv, sg_network_io_stat_names[3], strlen(sg_network_io_stat_names[3]), newSVuv(self[entry].ipackets), 0); \
2253 	hv_store(hv, sg_network_io_stat_names[4], strlen(sg_network_io_stat_names[4]), newSVuv(self[entry].opackets), 0); \
2254 	hv_store(hv, sg_network_io_stat_names[5], strlen(sg_network_io_stat_names[5]), newSVuv(self[entry].ierrors), 0); \
2255 	hv_store(hv, sg_network_io_stat_names[6], strlen(sg_network_io_stat_names[6]), newSVuv(self[entry].oerrors), 0); \
2256 	hv_store(hv, sg_network_io_stat_names[7], strlen(sg_network_io_stat_names[7]), newSVuv(self[entry].collisions), 0); \
2257 	hv_store(hv, sg_network_io_stat_names[8], strlen(sg_network_io_stat_names[8]), newSViv(self[entry].systime), 0); \
2258     } while(0)
2259 
2260 void
2261 fetchrow_arrayref(self, num = 0)
2262 	sg_network_io_stats *self;
2263 	UV num;
2264     CODE:
2265         AV *retval;
2266 	if (num >= sg_get_nelements(self))
2267 	    XSRETURN_UNDEF;
2268 	/* XXX add fill row macro here */
2269 	NETWORK_IO_STATS_ARRAY_ROW(self, num, retval);
2270 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
2271 	XSRETURN(1);
2272 
2273 void
2274 fetchall_arrayref(self)
2275 	sg_network_io_stats *self;
2276     CODE:
2277         AV *retval;
2278 	/* XXX add fill row macro here */
2279 	FETCH_ALL_ROWS(self, NETWORK_IO_STATS_ARRAY_ROW, retval, AV);
2280 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
2281 	XSRETURN(1);
2282 
2283 void
2284 fetchrow_hashref(self, num = 0)
2285 	sg_network_io_stats *self;
2286 	UV num;
2287     CODE:
2288         HV *retval;
2289 	if (num >= sg_get_nelements(self))
2290 	    XSRETURN_UNDEF;
2291 	/* XXX add fill row macro here */
2292 	NETWORK_IO_STATS_HASH_ROW(self, num, retval);
2293 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
2294 	XSRETURN(1);
2295 
2296 void
2297 fetchall_hashref(self)
2298 	sg_network_io_stats *self;
2299     CODE:
2300         AV *retval;
2301 	/* XXX add fill row macro here */
2302 	FETCH_ALL_ROWS(self, NETWORK_IO_STATS_HASH_ROW, retval, HV);
2303 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
2304 	XSRETURN(1);
2305 
2306 void
DESTROY(self)2307 DESTROY (self)
2308 	sg_network_io_stats *self;
2309     CODE:
2310     {
2311 	sg_free_network_io_stats(self);
2312     }
2313 
2314 void
get_network_io_stats_diff(now,last)2315 get_network_io_stats_diff (now, last)
2316 	sg_network_io_stats *now;
2317 	sg_network_io_stats *last;
2318     CODE:
2319     {
2320 	sg_network_io_stats *self;
2321 
2322 	if ((self = sg_get_network_io_stats_diff_between(now, last, NULL)) == NULL)
2323 	    XSRETURN_UNDEF;
2324 
2325 	EXTEND(SP, 1);
2326 
2327 	ST(0) = sv_newmortal();
2328 	sv_setref_pv(ST(0), "Unix::Statgrab::sg_network_io_stats", (void*)self);
2329 	XSRETURN(1);
2330     }
2331 
2332 MODULE = Unix::Statgrab     PACKAGE = Unix::Statgrab::sg_network_iface_stats
2333 
2334 UV
2335 entries (self)
2336 	sg_network_iface_stats *self;
2337     CODE:
2338 	RETVAL = sg_get_nelements(self);
2339     OUTPUT:
2340 	RETVAL
2341 
2342 char *
2343 interface_name (self, num = 0)
2344 	sg_network_iface_stats *self;
2345 	UV num;
2346     CODE:
2347 	if (num >= sg_get_nelements(self))
2348 	    XSRETURN_UNDEF;
2349 	RETVAL = self[num].interface_name;
2350     OUTPUT:
2351 	RETVAL
2352 
2353 LUV
2354 speed (self, num = 0)
2355 	sg_network_iface_stats *self;
2356 	UV num;
2357     CODE:
2358 	if (num >= sg_get_nelements(self))
2359 	    XSRETURN_UNDEF;
2360 	RETVAL = self[num].speed;
2361     OUTPUT:
2362 	RETVAL
2363 
2364 LUV
2365 factor (self, num = 0)
2366 	sg_network_iface_stats *self;
2367 	UV num;
2368     CODE:
2369 	if (num >= sg_get_nelements(self))
2370 	    XSRETURN_UNDEF;
2371 	RETVAL = self[num].factor;
2372     OUTPUT:
2373 	RETVAL
2374 
2375 UV
2376 duplex (self, num = 0)
2377 	sg_network_iface_stats *self;
2378 	UV num;
2379     CODE:
2380 	if (num >= sg_get_nelements(self))
2381 	    XSRETURN_UNDEF;
2382 	RETVAL = self[num].duplex;
2383     OUTPUT:
2384 	RETVAL
2385 
2386 UV
2387 up (self, num = 0)
2388 	sg_network_iface_stats *self;
2389 	UV num;
2390     CODE:
2391 	if (num >= sg_get_nelements(self))
2392 	    XSRETURN_UNDEF;
2393 	RETVAL = self[num].up;
2394     OUTPUT:
2395 	RETVAL
2396 
2397 IV
2398 systime (self, num = 0)
2399 	sg_network_iface_stats *self;
2400 	UV num;
2401     CODE:
2402 	if (num >= sg_get_nelements(self))
2403 	    XSRETURN_UNDEF;
2404 	RETVAL = self[num].systime;
2405     OUTPUT:
2406 	RETVAL
2407 
2408 void
2409 colnames(self)
2410 	sg_network_iface_stats *self;
2411     PPCODE:
2412         AV *retval;
2413 	MAKE_AV_FROM_STRINGS(sg_network_iface_stat_names, retval);
2414 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
2415 	XSRETURN(1);
2416 
2417 #define NETWORK_IFACE_STATS_ARRAY_ROW(self, entry, av) \
2418     do { \
2419 	SV **ary; \
2420 	size_t j; \
2421 	av = newAV(); \
2422 	av_extend(av, lengthof(sg_network_iface_stat_names)); \
2423 	ary = AvARRAY(av); \
2424 	AvFILLp(av) = lengthof(sg_network_iface_stat_names)-1; \
2425 	for( j = 0; j < lengthof(sg_network_iface_stat_names); ++j ) \
2426 	    ary[j] = newSV(0); \
2427 	sv_setpvn_IF(ary[0], self[entry].interface_name, SAFE_STRLEN(self[entry].interface_name)); \
2428 	sv_setuv(ary[1], self[entry].speed); \
2429 	sv_setuv(ary[2], self[entry].factor); \
2430 	sv_setuv(ary[3], self[entry].duplex); \
2431 	sv_setuv(ary[4], self[entry].up); \
2432 	sv_setiv(ary[5], self[entry].systime); \
2433     } while(0)
2434 
2435 #define NETWORK_IFACE_STATS_HASH_ROW(self, entry, hv) \
2436     do { \
2437 	hv = newHV(); \
2438 	hv_store(hv, sg_network_iface_stat_names[0], strlen(sg_network_iface_stat_names[0]), newSVpvn(self[entry].interface_name, SAFE_STRLEN(self[entry].interface_name)), 0); \
2439 	hv_store(hv, sg_network_iface_stat_names[1], strlen(sg_network_iface_stat_names[1]), newSVuv(self[entry].speed), 0); \
2440 	hv_store(hv, sg_network_iface_stat_names[2], strlen(sg_network_iface_stat_names[2]), newSVuv(self[entry].factor), 0); \
2441 	hv_store(hv, sg_network_iface_stat_names[3], strlen(sg_network_iface_stat_names[3]), newSVuv(self[entry].duplex), 0); \
2442 	hv_store(hv, sg_network_iface_stat_names[4], strlen(sg_network_iface_stat_names[4]), newSVuv(self[entry].up), 0); \
2443 	hv_store(hv, sg_network_iface_stat_names[5], strlen(sg_network_iface_stat_names[5]), newSViv(self[entry].systime), 0); \
2444     } while(0)
2445 
2446 void
2447 fetchrow_arrayref(self, num = 0)
2448 	sg_network_iface_stats *self;
2449 	UV num;
2450     CODE:
2451         AV *retval;
2452 	if (num >= sg_get_nelements(self))
2453 	    XSRETURN_UNDEF;
2454 	/* XXX add fill row macro here */
2455 	NETWORK_IFACE_STATS_ARRAY_ROW(self, num, retval);
2456 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
2457 	XSRETURN(1);
2458 
2459 void
2460 fetchall_arrayref(self)
2461 	sg_network_iface_stats *self;
2462     CODE:
2463         AV *retval;
2464 	/* XXX add fill row macro here */
2465 	FETCH_ALL_ROWS(self, NETWORK_IFACE_STATS_ARRAY_ROW, retval, AV);
2466 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
2467 	XSRETURN(1);
2468 
2469 void
2470 fetchrow_hashref(self, num = 0)
2471 	sg_network_iface_stats *self;
2472 	UV num;
2473     CODE:
2474         HV *retval;
2475 	if (num >= sg_get_nelements(self))
2476 	    XSRETURN_UNDEF;
2477 	/* XXX add fill row macro here */
2478 	NETWORK_IFACE_STATS_HASH_ROW(self, num, retval);
2479 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
2480 	XSRETURN(1);
2481 
2482 void
2483 fetchall_hashref(self)
2484 	sg_network_iface_stats *self;
2485     CODE:
2486         AV *retval;
2487 	/* XXX add fill row macro here */
2488 	FETCH_ALL_ROWS(self, NETWORK_IFACE_STATS_HASH_ROW, retval, HV);
2489 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
2490 	XSRETURN(1);
2491 
2492 void
DESTROY(self)2493 DESTROY (self)
2494 	sg_network_iface_stats *self;
2495     CODE:
2496     {
2497 	sg_free_network_iface_stats(self);
2498     }
2499 
2500 MODULE = Unix::Statgrab	    PACKAGE = Unix::Statgrab::sg_page_stats
2501 
2502 UV
2503 entries (self)
2504 	sg_page_stats *self;
2505     CODE:
2506 	RETVAL = sg_get_nelements(self);
2507     OUTPUT:
2508 	RETVAL
2509 
2510 LUV
2511 pages_pagein (self, num = 0)
2512 	sg_page_stats *self;
2513 	UV num;
2514     CODE:
2515 	if (num >= sg_get_nelements(self))
2516 	    XSRETURN_UNDEF;
2517 	RETVAL = self[num].pages_pagein;
2518     OUTPUT:
2519 	RETVAL
2520 
2521 LUV
2522 pages_pageout (self, num = 0)
2523 	sg_page_stats *self;
2524 	UV num;
2525     CODE:
2526 	if (num >= sg_get_nelements(self))
2527 	    XSRETURN_UNDEF;
2528 	RETVAL = self[num].pages_pageout;
2529     OUTPUT:
2530 	RETVAL
2531 
2532 UV
2533 systime (self, num = 0)
2534 	sg_page_stats *self;
2535 	UV num;
2536     CODE:
2537 	if (num >= sg_get_nelements(self))
2538 	    XSRETURN_UNDEF;
2539 	RETVAL = self[num].systime;
2540     OUTPUT:
2541 	RETVAL
2542 
2543 void
2544 colnames(self)
2545 	sg_page_stats *self;
2546     PPCODE:
2547         AV *retval;
2548 	MAKE_AV_FROM_STRINGS(sg_page_stat_names, retval);
2549 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
2550 	XSRETURN(1);
2551 
2552 #define PAGE_STATS_ARRAY_ROW(self, entry, av) \
2553     do { \
2554 	SV **ary; \
2555 	size_t j; \
2556 	av = newAV(); \
2557 	av_extend(av, lengthof(sg_page_stat_names)); \
2558 	ary = AvARRAY(av); \
2559 	AvFILLp(av) = lengthof(sg_page_stat_names)-1; \
2560 	for( j = 0; j < lengthof(sg_page_stat_names); ++j ) \
2561 	    ary[j] = newSV(0); \
2562 	sv_setuv(ary[0], self[entry].pages_pagein); \
2563 	sv_setuv(ary[1], self[entry].pages_pageout); \
2564 	sv_setiv(ary[2], self[entry].systime); \
2565     } while(0)
2566 
2567 #define PAGE_STATS_HASH_ROW(self, entry, hv) \
2568     do { \
2569 	hv = newHV(); \
2570 	hv_store(hv, sg_page_stat_names[0], strlen(sg_page_stat_names[0]), newSVuv(self[entry].pages_pagein), 0); \
2571 	hv_store(hv, sg_page_stat_names[1], strlen(sg_page_stat_names[1]), newSVuv(self[entry].pages_pageout), 0); \
2572 	hv_store(hv, sg_page_stat_names[2], strlen(sg_page_stat_names[2]), newSViv(self[entry].systime), 0); \
2573     } while(0)
2574 
2575 void
2576 fetchrow_arrayref(self, num = 0)
2577 	sg_page_stats *self;
2578 	UV num;
2579     CODE:
2580         AV *retval;
2581 	if (num >= sg_get_nelements(self))
2582 	    XSRETURN_UNDEF;
2583 	/* XXX add fill row macro here */
2584 	PAGE_STATS_ARRAY_ROW(self, num, retval);
2585 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
2586 	XSRETURN(1);
2587 
2588 void
2589 fetchall_arrayref(self)
2590 	sg_page_stats *self;
2591     CODE:
2592         AV *retval;
2593 	/* XXX add fill row macro here */
2594 	FETCH_ALL_ROWS(self, PAGE_STATS_ARRAY_ROW, retval, AV);
2595 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
2596 	XSRETURN(1);
2597 
2598 void
2599 fetchrow_hashref(self, num = 0)
2600 	sg_page_stats *self;
2601 	UV num;
2602     CODE:
2603         HV *retval;
2604 	if (num >= sg_get_nelements(self))
2605 	    XSRETURN_UNDEF;
2606 	/* XXX add fill row macro here */
2607 	PAGE_STATS_HASH_ROW(self, num, retval);
2608 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
2609 	XSRETURN(1);
2610 
2611 void
2612 fetchall_hashref(self)
2613 	sg_page_stats *self;
2614     CODE:
2615         AV *retval;
2616 	/* XXX add fill row macro here */
2617 	FETCH_ALL_ROWS(self, PAGE_STATS_HASH_ROW, retval, HV);
2618 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
2619 	XSRETURN(1);
2620 
2621 void
DESTROY(self)2622 DESTROY (self)
2623 	sg_page_stats *self;
2624     CODE:
2625     {
2626 	sg_free_page_stats(self);
2627     }
2628 
2629 void
get_page_stats_diff(now,last)2630 get_page_stats_diff (now, last)
2631 	sg_page_stats *now;
2632 	sg_page_stats *last;
2633     CODE:
2634     {
2635 	sg_page_stats *self;
2636 	if ((self = sg_get_page_stats_diff_between(now, last, NULL)) == NULL)
2637 	    XSRETURN_UNDEF;
2638 
2639 	EXTEND(SP, 1);
2640 
2641 	ST(0) = sv_newmortal();
2642 	sv_setref_pv(ST(0), "Unix::Statgrab::sg_page_stats", (void*)self);
2643 	XSRETURN(1);
2644     }
2645 
2646 MODULE = Unix::Statgrab     PACKAGE = Unix::Statgrab::sg_user_stats
2647 
2648 UV
2649 entries (self)
2650 	sg_user_stats *self;
2651     CODE:
2652 	RETVAL = sg_get_nelements(self);
2653     OUTPUT:
2654 	RETVAL
2655 
2656 char *
2657 login_name (self, num = 0)
2658 	sg_user_stats *self;
2659 	UV num;
2660     CODE:
2661 	if (num >= sg_get_nelements(self))
2662 	    XSRETURN_UNDEF;
2663 	RETVAL = self[num].login_name;
2664     OUTPUT:
2665 	RETVAL
2666 
2667 void
2668 record_id (self, num = 0)
2669 	sg_user_stats *self;
2670 	UV num;
2671     CODE:
2672     {
2673 	if (num >= sg_get_nelements(self))
2674 	    XSRETURN_UNDEF;
2675 
2676 	EXTEND(SP, 1);
2677 
2678 	ST(0) = newSVpvn_flags(self[num].record_id, self[num].record_id_size, SVs_TEMP);
2679 	XSRETURN(1);
2680     }
2681 
2682 char *
2683 device (self, num = 0)
2684 	sg_user_stats *self;
2685 	UV num;
2686     CODE:
2687 	if (num >= sg_get_nelements(self))
2688 	    XSRETURN_UNDEF;
2689 	RETVAL = self[num].device;
2690     OUTPUT:
2691 	RETVAL
2692 
2693 char *
2694 hostname (self, num = 0)
2695 	sg_user_stats *self;
2696 	UV num;
2697     CODE:
2698 	if (num >= sg_get_nelements(self))
2699 	    XSRETURN_UNDEF;
2700 	RETVAL = self[num].hostname;
2701     OUTPUT:
2702 	RETVAL
2703 
2704 IV
2705 pid (self, num = 0)
2706 	sg_user_stats *self;
2707 	UV num;
2708     CODE:
2709 	if (num >= sg_get_nelements(self))
2710 	    XSRETURN_UNDEF;
2711 	RETVAL = self[num].pid;
2712     OUTPUT:
2713 	RETVAL
2714 
2715 IV
2716 login_time (self, num = 0)
2717 	sg_user_stats *self;
2718 	UV num;
2719     CODE:
2720 	if (num >= sg_get_nelements(self))
2721 	    XSRETURN_UNDEF;
2722 	RETVAL = self[num].login_time;
2723     OUTPUT:
2724 	RETVAL
2725 
2726 IV
2727 systime (self, num = 0)
2728 	sg_user_stats *self;
2729 	UV num;
2730     CODE:
2731 	if (num >= sg_get_nelements(self))
2732 	    XSRETURN_UNDEF;
2733 	RETVAL = self[num].systime;
2734     OUTPUT:
2735 	RETVAL
2736 
2737 void
2738 colnames(self)
2739 	sg_user_stats *self;
2740     PPCODE:
2741         AV *retval;
2742 	MAKE_AV_FROM_STRINGS(sg_user_stat_names, retval);
2743 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
2744 	XSRETURN(1);
2745 
2746 #define USER_STATS_ARRAY_ROW(self, entry, av) \
2747     do { \
2748 	SV **ary; \
2749 	size_t j; \
2750 	av = newAV(); \
2751 	av_extend(av, lengthof(sg_user_stat_names)); \
2752 	ary = AvARRAY(av); \
2753 	AvFILLp(av) = lengthof(sg_user_stat_names)-1; \
2754 	for( j = 0; j < lengthof(sg_user_stat_names); ++j ) \
2755 	    ary[j] = newSV(0); \
2756 	sv_setpvn_IF(ary[0], self[entry].login_name, SAFE_STRLEN(self[entry].login_name)); \
2757 	sv_setpvn_IF(ary[1], self[entry].record_id, self[entry].record_id_size); \
2758 	sv_setpvn_IF(ary[2], self[entry].device, SAFE_STRLEN(self[entry].device)); \
2759 	sv_setpvn_IF(ary[3], self[entry].hostname, SAFE_STRLEN(self[entry].hostname)); \
2760 	sv_setiv(ary[4], self[entry].pid); \
2761 	sv_setiv(ary[5], self[entry].login_time); \
2762 	sv_setiv(ary[6], self[entry].systime); \
2763     } while(0)
2764 
2765 #define USER_STATS_HASH_ROW(self, entry, hv) \
2766     do { \
2767 	hv = newHV(); \
2768 	hv_store(hv, sg_user_stat_names[0], strlen(sg_user_stat_names[0]), newSVpvn(self[entry].login_name, SAFE_STRLEN(self[entry].login_name)), 0); \
2769 	hv_store(hv, sg_user_stat_names[1], strlen(sg_user_stat_names[1]), newSVpvn(self[entry].record_id, self[entry].record_id_size), 0); \
2770 	hv_store(hv, sg_user_stat_names[2], strlen(sg_user_stat_names[2]), newSVpvn(self[entry].device, SAFE_STRLEN(self[entry].device)), 0); \
2771 	hv_store(hv, sg_user_stat_names[3], strlen(sg_user_stat_names[3]), newSVpvn(self[entry].hostname, SAFE_STRLEN(self[entry].hostname)), 0); \
2772 	hv_store(hv, sg_user_stat_names[4], strlen(sg_user_stat_names[4]), newSViv(self[entry].pid), 0); \
2773 	hv_store(hv, sg_user_stat_names[5], strlen(sg_user_stat_names[5]), newSViv(self[entry].login_time), 0); \
2774 	hv_store(hv, sg_user_stat_names[6], strlen(sg_user_stat_names[6]), newSViv(self[entry].systime), 0); \
2775     } while(0)
2776 
2777 void
2778 fetchrow_arrayref(self, num = 0)
2779 	sg_user_stats *self;
2780 	UV num;
2781     CODE:
2782         AV *retval;
2783 	if (num >= sg_get_nelements(self))
2784 	    XSRETURN_UNDEF;
2785 	/* XXX add fill row macro here */
2786 	USER_STATS_ARRAY_ROW(self, num, retval);
2787 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
2788 	XSRETURN(1);
2789 
2790 void
2791 fetchall_arrayref(self)
2792 	sg_user_stats *self;
2793     CODE:
2794         AV *retval;
2795 	/* XXX add fill row macro here */
2796 	FETCH_ALL_ROWS(self, USER_STATS_ARRAY_ROW, retval, AV);
2797 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
2798 	XSRETURN(1);
2799 
2800 void
2801 fetchrow_hashref(self, num = 0)
2802 	sg_user_stats *self;
2803 	UV num;
2804     CODE:
2805         HV *retval;
2806 	if (num >= sg_get_nelements(self))
2807 	    XSRETURN_UNDEF;
2808 	/* XXX add fill row macro here */
2809 	USER_STATS_HASH_ROW(self, num, retval);
2810 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
2811 	XSRETURN(1);
2812 
2813 void
2814 fetchall_hashref(self)
2815 	sg_user_stats *self;
2816     CODE:
2817         AV *retval;
2818 	/* XXX add fill row macro here */
2819 	FETCH_ALL_ROWS(self, USER_STATS_HASH_ROW, retval, HV);
2820 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
2821 	XSRETURN(1);
2822 
2823 void
DESTROY(self)2824 DESTROY (self)
2825 	sg_user_stats *self;
2826     CODE:
2827     {
2828 	sg_free_user_stats(self);
2829     }
2830 
2831 MODULE = Unix::Statgrab	    PACKAGE = Unix::Statgrab::sg_process_stats
2832 
2833 UV
2834 entries (self)
2835 	sg_process_stats *self;
2836     CODE:
2837 	RETVAL = sg_get_nelements(self);
2838     OUTPUT:
2839 	RETVAL
2840 
2841 char *
2842 process_name (self, num = 0)
2843 	sg_process_stats *self;
2844 	UV num;
2845     CODE:
2846 	if (num >= sg_get_nelements(self))
2847 	    XSRETURN_UNDEF;
2848 	RETVAL = self[num].process_name;
2849     OUTPUT:
2850 	RETVAL
2851 
2852 char *
2853 proctitle (self, num = 0)
2854 	sg_process_stats *self;
2855 	UV num;
2856     CODE:
2857 	if (num >= sg_get_nelements(self))
2858 	    XSRETURN_UNDEF;
2859 	RETVAL = self[num].proctitle;
2860     OUTPUT:
2861 	RETVAL
2862 
2863 IV
2864 pid (self, num = 0)
2865 	sg_process_stats *self;
2866 	UV num;
2867     CODE:
2868 	if (num >= sg_get_nelements(self))
2869 	    XSRETURN_UNDEF;
2870 	RETVAL = self[num].pid;
2871     OUTPUT:
2872 	RETVAL
2873 
2874 IV
2875 parent (self, num = 0)
2876 	sg_process_stats *self;
2877 	UV num;
2878     CODE:
2879 	if (num >= sg_get_nelements(self))
2880 	    XSRETURN_UNDEF;
2881 	RETVAL = self[num].parent;
2882     OUTPUT:
2883 	RETVAL
2884 
2885 IV
2886 pgid (self, num = 0)
2887 	sg_process_stats *self;
2888 	UV num;
2889     CODE:
2890 	if (num >= sg_get_nelements(self))
2891 	    XSRETURN_UNDEF;
2892 	RETVAL = self[num].pgid;
2893     OUTPUT:
2894 	RETVAL
2895 
2896 IV
2897 sessid (self, num = 0)
2898 	sg_process_stats *self;
2899 	UV num;
2900     CODE:
2901 	if (num >= sg_get_nelements(self))
2902 	    XSRETURN_UNDEF;
2903 	RETVAL = self[num].sessid;
2904     OUTPUT:
2905 	RETVAL
2906 
2907 IV
2908 uid (self, num = 0)
2909 	sg_process_stats *self;
2910 	UV num;
2911     CODE:
2912 	if (num >= sg_get_nelements(self))
2913 	    XSRETURN_UNDEF;
2914 	RETVAL = self[num].uid;
2915     OUTPUT:
2916 	RETVAL
2917 
2918 IV
2919 euid (self, num = 0)
2920 	sg_process_stats *self;
2921 	UV num;
2922     CODE:
2923 	if (num >= sg_get_nelements(self))
2924 	    XSRETURN_UNDEF;
2925 	RETVAL = self[num].euid;
2926     OUTPUT:
2927 	RETVAL
2928 
2929 IV
2930 gid (self, num = 0)
2931 	sg_process_stats *self;
2932 	UV num;
2933     CODE:
2934 	if (num >= sg_get_nelements(self))
2935 	    XSRETURN_UNDEF;
2936 	RETVAL = self[num].gid;
2937     OUTPUT:
2938 	RETVAL
2939 
2940 IV
2941 egid (self, num = 0)
2942 	sg_process_stats *self;
2943 	UV num;
2944     CODE:
2945 	if (num >= sg_get_nelements(self))
2946 	    XSRETURN_UNDEF;
2947 	RETVAL = self[num].egid;
2948     OUTPUT:
2949 	RETVAL
2950 
2951 LUV
2952 context_switches (self, num = 0)
2953 	sg_process_stats *self;
2954 	UV num;
2955     CODE:
2956 	if (num >= sg_get_nelements(self))
2957 	    XSRETURN_UNDEF;
2958 	RETVAL = self[num].context_switches;
2959     OUTPUT:
2960 	RETVAL
2961 
2962 LUV
2963 voluntary_context_switches (self, num = 0)
2964 	sg_process_stats *self;
2965 	UV num;
2966     CODE:
2967 	if (num >= sg_get_nelements(self))
2968 	    XSRETURN_UNDEF;
2969 	RETVAL = self[num].voluntary_context_switches;
2970     OUTPUT:
2971 	RETVAL
2972 
2973 LUV
2974 involuntary_context_switches (self, num = 0)
2975 	sg_process_stats *self;
2976 	UV num;
2977     CODE:
2978 	if (num >= sg_get_nelements(self))
2979 	    XSRETURN_UNDEF;
2980 	RETVAL = self[num].involuntary_context_switches;
2981     OUTPUT:
2982 	RETVAL
2983 
2984 LUV
2985 proc_size (self, num = 0)
2986 	sg_process_stats *self;
2987 	UV num;
2988     CODE:
2989 	if (num >= sg_get_nelements(self))
2990 	    XSRETURN_UNDEF;
2991 	RETVAL = self[num].proc_size;
2992     OUTPUT:
2993 	RETVAL
2994 
2995 LUV
2996 proc_resident (self, num = 0)
2997 	sg_process_stats *self;
2998 	UV num;
2999     CODE:
3000 	if (num >= sg_get_nelements(self))
3001 	    XSRETURN_UNDEF;
3002 	RETVAL = self[num].proc_resident;
3003     OUTPUT:
3004 	RETVAL
3005 
3006 IV
3007 start_time (self, num = 0)
3008 	sg_process_stats *self;
3009 	UV num;
3010     CODE:
3011 	if (num >= sg_get_nelements(self))
3012 	    XSRETURN_UNDEF;
3013 	RETVAL = self[num].start_time;
3014     OUTPUT:
3015 	RETVAL
3016 
3017 IV
3018 time_spent (self, num = 0)
3019 	sg_process_stats *self;
3020 	UV num;
3021     CODE:
3022 	if (num >= sg_get_nelements(self))
3023 	    XSRETURN_UNDEF;
3024 	RETVAL = self[num].time_spent;
3025     OUTPUT:
3026 	RETVAL
3027 
3028 LUV
3029 cpu_percent (self, num = 0)
3030 	sg_process_stats *self;
3031 	UV num;
3032     CODE:
3033 	if (num >= sg_get_nelements(self))
3034 	    XSRETURN_UNDEF;
3035 	RETVAL = self[num].cpu_percent;
3036     OUTPUT:
3037 	RETVAL
3038 
3039 IV
3040 nice (self, num = 0)
3041 	sg_process_stats *self;
3042 	UV num;
3043     CODE:
3044 	if (num >= sg_get_nelements(self))
3045 	    XSRETURN_UNDEF;
3046 	RETVAL = self[num].nice;
3047     OUTPUT:
3048 	RETVAL
3049 
3050 UV
3051 state (self, num = 0)
3052 	sg_process_stats *self;
3053 	UV num;
3054     CODE:
3055 	if (num >= sg_get_nelements(self))
3056 	    XSRETURN_UNDEF;
3057 	RETVAL = self[num].state;
3058     OUTPUT:
3059 	RETVAL
3060 
3061 IV
3062 systime (self, num = 0)
3063 	sg_process_stats *self;
3064 	UV num;
3065     CODE:
3066 	if (num >= sg_get_nelements(self))
3067 	    XSRETURN_UNDEF;
3068 	RETVAL = self[num].systime;
3069     OUTPUT:
3070 	RETVAL
3071 
3072 void
3073 colnames(self)
3074 	sg_process_stats *self;
3075     PPCODE:
3076         AV *retval;
3077 	MAKE_AV_FROM_STRINGS(sg_process_stat_names, retval);
3078 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
3079 	XSRETURN(1);
3080 
3081 #define PROCESS_STATS_ARRAY_ROW(self, entry, av) \
3082     do { \
3083 	SV **ary; \
3084 	size_t j; \
3085 	av = newAV(); \
3086 	av_extend(av, lengthof(sg_process_stat_names)); \
3087 	ary = AvARRAY(av); \
3088 	AvFILLp(av) = lengthof(sg_process_stat_names)-1; \
3089 	for( j = 0; j < lengthof(sg_process_stat_names); ++j ) \
3090 	    ary[j] = newSV(0); \
3091 	sv_setpvn_IF(ary[0], self[entry].process_name, SAFE_STRLEN(self[entry].process_name)); \
3092 	sv_setpvn_IF(ary[1], self[entry].proctitle, SAFE_STRLEN(self[entry].proctitle)); \
3093 	sv_setiv(ary[2], self[entry].pid); \
3094 	sv_setiv(ary[3], self[entry].parent); \
3095 	sv_setiv(ary[4], self[entry].pgid); \
3096 	sv_setiv(ary[5], self[entry].sessid); \
3097 	sv_setiv(ary[6], self[entry].uid); \
3098 	sv_setiv(ary[7], self[entry].euid); \
3099 	sv_setiv(ary[8], self[entry].gid); \
3100 	sv_setiv(ary[9], self[entry].egid); \
3101 	sv_setuv(ary[10], self[entry].context_switches); \
3102 	sv_setuv(ary[11], self[entry].voluntary_context_switches); \
3103 	sv_setuv(ary[12], self[entry].involuntary_context_switches); \
3104 	sv_setuv(ary[13], self[entry].proc_size); \
3105 	sv_setuv(ary[14], self[entry].proc_resident); \
3106 	sv_setiv(ary[15], self[entry].start_time); \
3107 	sv_setiv(ary[16], self[entry].time_spent); \
3108 	sv_setnv(ary[17], self[entry].cpu_percent); \
3109 	sv_setiv(ary[18], self[entry].nice); \
3110 	sv_setuv(ary[19], self[entry].state); \
3111 	sv_setiv(ary[20], self[entry].systime); \
3112     } while(0)
3113 
3114 #define PROCESS_STATS_HASH_ROW(self, entry, hv) \
3115     do { \
3116 	hv = newHV(); \
3117 	hv_store(hv, sg_process_stat_names[0], strlen(sg_process_stat_names[0]), newSVpvn(self[entry].process_name, SAFE_STRLEN(self[entry].process_name)), 0); \
3118 	hv_store(hv, sg_process_stat_names[1], strlen(sg_process_stat_names[1]), newSVpvn(self[entry].proctitle, SAFE_STRLEN(self[entry].proctitle)), 0); \
3119 	hv_store(hv, sg_process_stat_names[2], strlen(sg_process_stat_names[2]), newSViv(self[entry].pid), 0); \
3120 	hv_store(hv, sg_process_stat_names[3], strlen(sg_process_stat_names[3]), newSViv(self[entry].parent), 0); \
3121 	hv_store(hv, sg_process_stat_names[4], strlen(sg_process_stat_names[4]), newSViv(self[entry].pgid), 0); \
3122 	hv_store(hv, sg_process_stat_names[5], strlen(sg_process_stat_names[5]), newSViv(self[entry].sessid), 0); \
3123 	hv_store(hv, sg_process_stat_names[6], strlen(sg_process_stat_names[6]), newSViv(self[entry].uid), 0); \
3124 	hv_store(hv, sg_process_stat_names[7], strlen(sg_process_stat_names[7]), newSViv(self[entry].euid), 0); \
3125 	hv_store(hv, sg_process_stat_names[8], strlen(sg_process_stat_names[8]), newSViv(self[entry].gid), 0); \
3126 	hv_store(hv, sg_process_stat_names[9], strlen(sg_process_stat_names[9]), newSViv(self[entry].egid), 0); \
3127 	hv_store(hv, sg_process_stat_names[10], strlen(sg_process_stat_names[10]), newSVuv(self[entry].context_switches), 0); \
3128 	hv_store(hv, sg_process_stat_names[11], strlen(sg_process_stat_names[11]), newSVuv(self[entry].voluntary_context_switches), 0); \
3129 	hv_store(hv, sg_process_stat_names[12], strlen(sg_process_stat_names[12]), newSVuv(self[entry].involuntary_context_switches), 0); \
3130 	hv_store(hv, sg_process_stat_names[13], strlen(sg_process_stat_names[13]), newSVuv(self[entry].proc_size), 0); \
3131 	hv_store(hv, sg_process_stat_names[14], strlen(sg_process_stat_names[14]), newSVuv(self[entry].proc_resident), 0); \
3132 	hv_store(hv, sg_process_stat_names[15], strlen(sg_process_stat_names[15]), newSViv(self[entry].start_time), 0); \
3133 	hv_store(hv, sg_process_stat_names[16], strlen(sg_process_stat_names[16]), newSViv(self[entry].time_spent), 0); \
3134 	hv_store(hv, sg_process_stat_names[17], strlen(sg_process_stat_names[17]), newSVnv(self[entry].cpu_percent), 0); \
3135 	hv_store(hv, sg_process_stat_names[18], strlen(sg_process_stat_names[18]), newSViv(self[entry].nice), 0); \
3136 	hv_store(hv, sg_process_stat_names[19], strlen(sg_process_stat_names[19]), newSVuv(self[entry].state), 0); \
3137 	hv_store(hv, sg_process_stat_names[20], strlen(sg_process_stat_names[20]), newSViv(self[entry].systime), 0); \
3138     } while(0)
3139 
3140 void
3141 fetchrow_arrayref(self, num = 0)
3142 	sg_process_stats *self;
3143 	UV num;
3144     CODE:
3145         AV *retval;
3146 	if (num >= sg_get_nelements(self))
3147 	    XSRETURN_UNDEF;
3148 	/* XXX add fill row macro here */
3149 	PROCESS_STATS_ARRAY_ROW(self, num, retval);
3150 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
3151 	XSRETURN(1);
3152 
3153 void
3154 fetchall_arrayref(self)
3155 	sg_process_stats *self;
3156     CODE:
3157         AV *retval;
3158 	/* XXX add fill row macro here */
3159 	FETCH_ALL_ROWS(self, PROCESS_STATS_ARRAY_ROW, retval, AV);
3160 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
3161 	XSRETURN(1);
3162 
3163 void
3164 fetchrow_hashref(self, num = 0)
3165 	sg_process_stats *self;
3166 	UV num;
3167     CODE:
3168         HV *retval;
3169 	if (num >= sg_get_nelements(self))
3170 	    XSRETURN_UNDEF;
3171 	/* XXX add fill row macro here */
3172 	PROCESS_STATS_HASH_ROW(self, num, retval);
3173 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
3174 	XSRETURN(1);
3175 
3176 void
3177 fetchall_hashref(self)
3178 	sg_process_stats *self;
3179     CODE:
3180         AV *retval;
3181 	/* XXX add fill row macro here */
3182 	FETCH_ALL_ROWS(self, PROCESS_STATS_HASH_ROW, retval, HV);
3183 	ST(0) = sv_2mortal (newRV_noinc ((SV *)retval));
3184 	XSRETURN(1);
3185 
3186 void
DESTROY(self)3187 DESTROY (self)
3188 	sg_process_stats *self;
3189     CODE:
3190     {
3191 	sg_free_process_stats(self);
3192     }
3193