I have the following C code:
#include <glibtop.h>
#include <glibtop/procwd.h>
#include <glibtop/proclist.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <glib.h>
#include <unistd.h>
int main(int argc, char **argv)
{
glibtop_proclist buf;
glibtop_proc_wd buf2;
char **dirs, **dir;
pid_t *pids;
glibtop_init();
pids = glibtop_get_proclist(&buf, GLIBTOP_KERN_PROC_ALL, 0);
int i;
printf("Processes: %ld\n", buf.number);
for (i = 0; i < buf.number; i++) {
pid_t pid = pids[i];
dirs = glibtop_get_proc_wd(&buf2, pid);
g_print("Process %u:\n"
" - root: '%s'\n"
" - exe: '%s'\n"
" - working directories:\n",
(unsigned)pid, buf2.root, buf2.exe);
for (dir = dirs; *dir; ++dir)
g_print(" - '%s'\n", *dir);
g_strfreev(dirs);
}
glibtop_close();
return 0;
}
It will print the path, executable and working directories of every running process, and will output something that looks like this:
Process 7994:
- root: '/proc/7056/fdinfo'
- exe: '/opt/google/chrome/chrome'
- working directories:
- '/proc/7056/fdinfo'
Process 8016:
- root: '/'
- exe: '/usr/bin/konsole'
- working directories:
- '/home/cbwood'
Process 8035:
- root: '/'
- exe: '/usr/bin/bash'
- working directories:
- '/home/cbwood/Projects/raku-GLib-Top'
Process 8318:
- root: '/proc/7056/fdinfo'
- exe: '/opt/google/chrome/chrome'
- working directories:
- '/proc/7056/fdinfo'
It runs perfectly, with no issues or segfaults.
Here is the standalone version of the NativeCall-enabled raku version:
use NativeCall;
constant pid_t := int32;
# cw: This works for latest ubuntu. Replace the location of your libgtop, here!
constant gtop is export ='gtop-2.0',v11;
constant GLIBTOP_KERN_PROC_ALL is export = 0;
sub glibtop_init
returns Pointer
is native(gtop)
is export
{ * }
sub glibtop_close
is native(gtop)
is export
{ * }
class glibtop_proclist is repr<CStruct> is export {
has uint64 $.flags is rw;
has uint64 $.number is rw;
has uint64 $.total is rw;
has uint64 $.size is rw;
}
# cw: 216 determined from constants
class glibtop_proc_wd is repr<CStruct> is export {
has uint64 $.flags;
has uint32 $.number;
HAS uint8 @!root[216] is CArray;
HAS uint8 @!exe[216] is CArray;
submethod BUILD {
# @!root[$_] = 0 for 215;
# @!exe[$_] = 0 for 215;
}
method root ($encoding = 'utf8') {
my @r = @!root[^216];
nativecast( Str, CArray[uint8].new(@r) );
}
method exe ($encoding = 'utf8') {
my @e = @!exe[^216];
nativecast( Str, CArray[uint8].new(@e) );
}
}
sub glibtop_get_proclist (
glibtop_proclist $buf,
int64 $which,
int64 $arg
)
returns CArray[pid_t]
is native(gtop)
is export
{ * }
sub glibtop_get_proc_wd (glibtop_proc_wd $buf, pid_t $pid)
returns CArray[ CArray[uint8] ]
is native(gtop)
is export
{ * }
multi sub CStringArrayToArray (CArray[Str] $sa) is export {
CArrayToArray($sa)
}
multi sub CArrayToArray(CArray $ca) is export {
return Nil unless $ca;
my ($i, @a) = (0);
while $ca[$i] {
@a.push: $ca[$i].clone;
$i++;
}
@a;
}
sub MAIN {
glibtop_init();
my uint64 ($w, $a) = (GLIBTOP_KERN_PROC_ALL, 0);
my @pids = CArrayToArray(
glibtop_get_proclist(
(my $buf = glibtop_proclist.new),
$w,
$a
)
);
say("Processes: { $buf.number }");
for @pids {
my pid_t $p = $_;
my $dirs = glibtop_get_proc_wd(
(my $buf2 = glibtop_proc_wd.new),
$p
);
say qq:to/OUTPUT/
Process #{ $p }:
- root: { $buf2.root}
- exe: { $buf2.exe }
- working directories:
{ @dirs.join("\n - ") }
OUTPUT
glibtop_close();
}
It does not and will segfault WAY before it gets to pid 1000. What I can get of it looks like this:
Process #6:
- root:
- exe:
** (process:8702): WARNING **: 11:29:05.948: Could not read link /proc/8/root : Permission denied
** (process:8702): WARNING **: 11:29:05.948: Could not read link /proc/8/exe : Permission denied
** (process:8702): WARNING **: 11:29:05.948: Could not read link /proc/8/cwd : Permission denied
** (process:8702): WARNING **: 11:29:05.948: Could not read link /proc/8/task/8/cwd : Permission denied
free(): invalid pointer
./p6gtkexec: line 72: 8702 Aborted (core dumped) ${EXEC} --stagestats ${EXTRAS} ${INCLUDES} "$@"
Could someone please take a look at this and tell me what I might need to changed?
For the record, the CStructs involved have been SIZE verified against C. That doesn't mean that they are completely cleared from suspicion.
Thanks in advance to anyone who can take this up!