Yes, albeit I am not sure how reliable it is. c has some built in libraries you can use for this. I chose to do it in Rust but you can probably look up the parts you need. TLDR spawning a child process and rusage
extern crate nix;
use std::process::Command;
use std::process::Output;
use libc::{c_long, rusage, suseconds_t, timeval, time_t, getrusage, RUSAGE_CHILDREN};
pub fn execute_cmd(bash_cmd: String) -> (u64, Output) {
let mut usage = rusage {
ru_utime: timeval{ tv_sec: 0 as time_t, tv_usec: 0 as suseconds_t, },
ru_stime: timeval{ tv_sec: 0 as time_t, tv_usec: 0 as suseconds_t, },
ru_maxrss: 0 as c_long,
ru_ixrss: 0 as c_long,
ru_idrss: 0 as c_long,
ru_isrss: 0 as c_long,
ru_minflt: 0 as c_long,
ru_majflt: 0 as c_long,
ru_nswap: 0 as c_long,
ru_inblock: 0 as c_long,
ru_oublock: 0 as c_long,
ru_msgsnd: 0 as c_long,
ru_msgrcv: 0 as c_long,
ru_nsignals: 0 as c_long,
ru_nvcsw: 0 as c_long,
ru_nivcsw: 0 as c_long,
};
let _result = nix::sys::wait::waitpid(None, None);
let output = Command::new(bash_cmd.clone())
.output()
.expect("Failed to execute cmd");
unsafe { getrusage( RUSAGE_CHILDREN, (&mut usage) as *mut rusage); }
let user_secs = usage.ru_utime.tv_sec as u64;
let user_usecs = usage.ru_utime.tv_usec as u64;
let sys_secs = usage.ru_stime.tv_sec as u64;
let sys_usecs = usage.ru_stime.tv_usec as u64;
let user_time = (user_secs * 1_000_000) + user_usecs;
let sys_time = (sys_secs * 1_000_000) + sys_usecs;
return (user_time + sys_time, output);
}