1

Is there a call, that can be used to ask the OS, when the current process started?

Of course, one could simply call gettimeofday() at start-up and refer to that once-recorded value through the life of the process, but is there another option?

Obviously, the OS keeps the record for each process (one can see it in the output of ps, for example). Can it be queried by the process itself (using C)?

An ideal solution would, of course, be cross-platform, but something (Free)BSD-specific is fine too. Thanks!

Update: I've come up with a BSD-specific implementation, that uses sysctl(3) to obtain the kern_proc structure of the current process and finds the ki_start field in there. If nobody suggests anything better in a few days, I'll post my own function here for posterity...

Mikhail T.
  • 3,043
  • 3
  • 29
  • 46
  • Well, yeah, _current_ time is easy... I need the time of the current process' start-up, though... – Mikhail T. Oct 15 '14 at 23:40
  • The best way to do this (pretty sure it will be OS-specific) is to use libkvm. It's the interface that the ps command uses get the information. You want to get the environment of the process, to get this look up the kvm_getenvv from function from the libkvm library. – D'Nabre Nov 05 '14 at 05:56

3 Answers3

1

You can look into the /proc/[process-id] folder.. Do a fstat() on it to get more info..

Haris
  • 12,120
  • 6
  • 43
  • 70
  • 1
    Although available for people, who need it, `/proc` is not even mounted by default on FreeBSD. – Mikhail T. Oct 15 '14 at 22:43
  • This is a FreeBSD question. You don't have /proc on FreeBSD (it's available for linux emulation, but not part of FreeBSD proper). – D'Nabre Nov 05 '14 at 05:37
  • Though I needed the proposed method to work on FreeBSD, if anyone were able to offer a more general cross-platform method, it would've been even nicer. Haris' suggestion is not bad -- I do look at just that (`/proc/PID`), when I wish to see, when the process started from command-line. It works on Linux, Solaris, and -- _usually_ -- on FreeBSD too. But since one can't rely on `/proc` being mounted on FreeBSD in all cases, it did not suit my needs for a program. – Mikhail T. Nov 06 '14 at 13:49
1

Ok, here is my own function -- it works on FreeBSD and is very likely to work on Open, Net, and DragonFly BSDs. Probably, on MacOS too. Feel free to take and adjust to taste -- the function caches the value in a static variable, which means, if your process forks after the function was called once, the child will have the parent's value. Also, I discard the microseconds part of timeval, but you may need it.

static void
getstarttime(struct timeval *ptv)
{
    static time_t   start; /* We cache this value */
    int             mib[4];
    size_t          len;
    struct kinfo_proc   kp;

    ptv->tv_usec = 0;   /* Not using microseconds at all */

    if (start != 0) {
        ptv->tv_sec = start;
        return;
    }
    ptv->tv_sec = 0;

    len = 4;
    if (sysctlnametomib("kern.proc.pid", mib, &len) != 0) {
        warn("Unable to obtain script start-time: %s",
            "sysctlnametomib");
        return;
    }
    mib[3] = getpid();
    len = sizeof(kp);
    if (sysctl(mib, 4, &kp, &len, NULL, 0) != 0) {
        warn("Unable to obtain script start-time: %s",
            "sysctl");
        return;
    }

    start = ptv->tv_sec = kp.ki_start.tv_sec;
}
Mikhail T.
  • 3,043
  • 3
  • 29
  • 46
1

Not sure standard this is for BSDs other than FreeBSD (only tested on FreeBSD 10.0, amd64). Took a lot of picking apart the source code ps, and other than just using a system library, it doing the same thing that Mikhail T.'s solution is doing. Though despite, the code being pretty rough (sort got caught up in figuring out how to do this 'properly' because 'it really shouldn't be that hard, right?', and 2+ hours later, this is what I have. Works wonderfully.

Remember to compile using the -lkvm flag to pull in libkvm (Kernel Data Library). The kinfo_proc is detailed in /usr/include/sys/user.h and has ever bit of information you ever wanted to know about a process. The example code below uses the current process, but it is just pulling the information based on PID. I've got in my scrap pieces of code what you need to pull out the process's environment variables and other stuff, just tell me if you want.

#include <fcntl.h>
#include <kvm.h>
#include <sys/sysctl.h>
#include <sys/user.h>


#include <unistd.h>
#include <stdio.h>
#include <time.h>

int main(int argc,char** args) {
    kvm_t* kd;

    // Get a handle to libkvm interface
    kd = kvm_open(NULL, "/dev/null", NULL, O_RDONLY, "error: ");

    pid_t pid;
    pid = getpid();

    struct kinfo_proc * kp;
    int p_count;

    // Get the kinfo_proc for this process by its pid
    kp = kvm_getprocs(kd, KERN_PROC_PID, pid, &p_count);

    printf("got %i kinfo_proc for pid %i\n", p_count, pid);

    time_t proc_start_time;
    proc_start_time = kp->ki_start.tv_sec;
    kvm_close(kd);

    printf("Process started at %s\n", ctime(&proc_start_time));
    return 0;
}

edit

Full source code for example including FreeBSD, NetBSD and Mac OS X (OpenBSD when I get a chance) can be found here: https://github.com/dnabre/misc/tree/master/proc_info

D'Nabre
  • 2,226
  • 16
  • 13
  • Thanks! Not sure, which method is "better", but this certainly works too. `` needs to be included before ``, though -- at least on FreeBSD-9.x. – Mikhail T. Nov 06 '14 at 13:43
  • Was on FreeBSD 10, did try to minimize the includes, so not terribly surprised of something like that. It exploded up to a like 3k lines then got cut back down as I dissect to ps, to understand the libkvm api. – D'Nabre Nov 06 '14 at 18:17
  • libkvm is common to most of the BSDs (not on OS X though, there's some mach-stuff to deal with I think). I'll up date the code (including your fix to the includes for FreeBSD-9.x) after I get a chance to test on NetBSD and OpenBSD. – D'Nabre Nov 07 '14 at 03:27
  • If you have an OS X development environment, see if my method (obtaining the kinfo_proc structure through sysctl()) works better there... Thanks. – Mikhail T. Nov 07 '14 at 19:08
  • @MikhailT. Yes, basically. The kinfo_proc is different, so just have change the line where you're pulling it out of the struct kproc_info. Two methods are doing basically the same thing. You're pulling the kproc_info out through a sysctl, I'm trying to use the kproc-specific apis. Here's your version tweaked for mac: http://pastebin.com/8qY4CpZT – D'Nabre Nov 07 '14 at 19:43
  • 1
    @MikhailT. See the github link added in answer for latest Mac version. – D'Nabre Dec 02 '14 at 05:48