coreutils

General Software Utilities
git clone http://git.omkov.net/coreutils
Log | Tree | Refs | README | LICENCE | Download

coreutils/src/time.c (86 lines, 2.1 KiB) -rw-r--r-- blame download

012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
// time.c, version 1.0.1
// OMKOV coreutils implementation of POSIX time
// Copyright (C) 2020, Jakob Wakeling
// MIT Licence

#include "util/error.h"
#include "util/optget.h"

#include <sys/times.h>
#include <sys/wait.h>
#include <unistd.h>

#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <time.h>

#define VERSION "1.0.1"

static struct lop lops[] = {
	{ "help",    ARG_NUL, 256 },
	{ "version", ARG_NUL, 257 },
	{ NULL, 0, 0 }
};

static bool pflag;

static void hlp(void);
static void ver(void);

int main(int ac, char *av[]) { (void)ac; A0 = av[0];
	struct opt opt = OPTGET_INIT; opt.str = "p"; opt.lops = lops;
	for (int o; (o = optget(&opt, av, 0)) != -1;) switch (o) {
	case 'p': { pflag = true; break; }
	case 256: { hlp(); return 0; }
	case 257: { ver(); return 0; }
	default: { return 1; }
	}
	
	struct tms tm; clock_t cl = times(&tm);
	
	pid_t pid = fork();
	if (pid == -1) { error(1, "%s", serr()); }
	else if (pid == 0) { 
		execvp(av[opt.ind], &av[opt.ind]);
		warn("%s: %s", av[opt.ind], serr());
		return errno = ENOENT ? 127 : 126;
	}
	
	int status; waitpid(pid, &status, 0);
	cl = times(&tm) - cl;
	
	double tick = (double)sysconf(_SC_CLK_TCK);
	double real = (double)cl / tick;
	double user = (double)(tm.tms_utime + tm.tms_cutime) / tick;
	double sys  = (double)(tm.tms_stime + tm.tms_cstime) / tick;
	
	if (pflag) {
		fprintf(stderr, "real %0.2f\n", real);
		fprintf(stderr, "user %0.2f\n", user);
		fprintf(stderr, "sys %0.2f\n", sys);
	}
	else {
		fprintf(stderr, "real  %0.2fs\n", real);
		fprintf(stderr, "user  %0.2fs\n", user);
		fprintf(stderr, "sys   %0.2fs\n", sys);
	}
	
	return WEXITSTATUS(status);
}

static void hlp(void) {
	puts("time - time a simple command\n");
	puts("usage: time [-p] command [argument...]\n");
	puts("options:");
	puts("  -p            Use portable format");
	puts("  --help        Display help information");
	puts("  --version     Display version information");
}

static void ver(void) {
	puts("OMKOV coreutils time, version " VERSION);
	puts("Copyright (C) 2020, Jakob Wakeling");
	puts("MIT Licence (https://opensource.org/licenses/MIT)");
}