6

I am new to OpenBSD. I have worked on Linux before. I am looking for the directory where I can find the information about the processes running currently. In Linux, we have /proc directory where the entire list is present. But I can not find a similar setup in OpenBSD 4.6. I know there are commands like ps, top and sysctl but I want to get that information through a C code.

iqstatic
  • 2,322
  • 3
  • 21
  • 39

2 Answers2

2

procfs in the BSDs is either deprecated or removed altogether, sorry. That being said, it's also quite usual to have the sources for your system under /usr/src, so you can look at them if you really need to. Or you can just browse them on the web, eg http://bxr.su/o/bin/ps/ps.c

cnst
  • 25,870
  • 6
  • 90
  • 122
loreb
  • 1,327
  • 1
  • 7
  • 6
  • I had already checked the /usr/src folder and even that is empty. I have also had a look at the source code for ps and top commands but couldnt figure it out how the process information is fetched. – iqstatic Dec 10 '13 at 06:09
  • I searched and found that there is a header proc.h present in /usr/include/sys directory which consists of a structure proc which fetches the running process information. I think i can make use of that to solve my purpose :) – iqstatic Dec 10 '13 at 06:50
  • @IqbalTariq ps uses `kvm_getprocs()`; about proc.h, isn't it a **kernel** header? (PS if bandwidth is not a problem you'd better upgrade; 4.6 is four years old...) – loreb Dec 10 '13 at 15:40
  • I have mounted procfs using mount_procfs /proc /proc command and it is showing a linux like procfs. Now my task is to parse the /proc directory and show the list of running processes with their PIDs just like ps command. Any idea? – iqstatic Dec 16 '13 at 07:35
  • I don't have OpenBSD installed -- much less 4.6 -- yet just looking at the mount_procfs(8) **strongly** suggests an idea... keep in mind that openbsd people are put an insane amount of dedication to keep their manpages in good shape. And never forget that /proc on BSD was never appreciated, so it's not the best source of information. – loreb Dec 16 '13 at 15:58
  • Thats right!!! I rolled back to my previous approach of parsing the struct proc in proc.h (kernel header) but i dont know how to get the process list from LIST_ENTRY(proc) p_list. – iqstatic Dec 17 '13 at 06:24
1

You can use sysctl to get the running processes in an array of kinfo_proc structures, this type is defined in:

/usr/include/sys/sysctl.h

The top command uses a function named getprocs that works this way, it's defined in:

/usr/src/usr.bin/top/machine.c

The next utility outputs information of all running processes using a slightly modified version of getprocs:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <kvm.h>
#include <sys/sysctl.h>

#define TRUE  1
#define FALSE 0

struct kinfo_proc * getprocs( int * count, int threads )
{
    struct kinfo_proc * procbase = NULL ;
    unsigned int maxslp ;
    size_t size = sizeof( maxslp ) ;
    int maxslp_mib[] = { CTL_VM, VM_MAXSLP } ;
    int mib[6] =
    {
        CTL_KERN,
        KERN_PROC,
        threads ? KERN_PROC_KTHREAD | KERN_PROC_SHOW_THREADS : KERN_PROC_KTHREAD,
        0,
        sizeof( struct kinfo_proc ),
        0
    } ;

    if( sysctl( maxslp_mib, 2, &maxslp, &size, NULL, 0 ) == -1 )
    {
        perror( "list" ) ;
        return NULL ;
    }

    retry:

    if( sysctl( mib, 6, NULL, &size, NULL, 0 ) == -1 )
    {
        perror( "list" ) ;
        return NULL ;
    }

    size = 5 * size / 4 ;           /* extra slop */
    procbase = (struct kinfo_proc *)malloc( size ) ;
    if( procbase == NULL )
    {
        perror( "list" ) ;
        return NULL ;
    }

    mib[5] = (int)( size / sizeof( struct kinfo_proc ) ) ;
    if( sysctl( mib, 6, procbase, &size, NULL, 0 ) )
    {
        if( errno == ENOMEM )
        {
            free( procbase ) ;
            goto retry;
        }
        perror( "list" ) ;
        return NULL ;
    }

    *count = (int)( size / sizeof( struct kinfo_proc ) ) ;
    return procbase ;
}

int showinfo( int threads )
{
    struct kinfo_proc * list, * proc ;
    int count, i ;
    if( ( list = getprocs( &count, threads ) ) == NULL )
    {
        return 1 ;
    }
    proc = list ;
    if( threads )
    {
        for( i = 0 ; i < count ; ++i, ++proc )
        {
            if( proc->p_tid != -1 )
            {
                printf( "%s: pid: %d (tid: %d)\n", proc->p_comm, proc->p_pid, proc->p_tid ) ;
            }
        }
    }
    else
    {
        for( i = 0 ; i < count ; ++i, ++proc )
        {
            printf( "%s: pid: %d\n", proc->p_comm, proc->p_pid ) ;
        }
    }
    return 0 ;
}

int main( int argc, char * argv[] )
{
    if( argc == 1 )
    {
        return showinfo( FALSE ) ;
    }
    else if( argc == 2 && ( !strcmp( argv[1], "-t" ) || !strcmp( argv[1], "--threads" ) ) )
    {
        return showinfo( TRUE ) ;
    }
    else
    {
        printf( "Usage:\n" ) ;
        printf( "      list [-h] [-t]\n\n" ) ;
        printf( "Options:\n" ) ;
        printf( "      -h, --help            Print this information\n" ) ;
        printf( "      -t, --threads         Show threads\n\n" ) ;
        return 0 ;
    }
}