Skip to content

Commit

Permalink
[libc/cmds] Fix time command hour wrapping problem
Browse files Browse the repository at this point in the history
  • Loading branch information
ghaerr committed Sep 15, 2023
1 parent c00b057 commit 0a0b148
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 59 deletions.
43 changes: 27 additions & 16 deletions elkscmd/misc_utils/time.c
Original file line number Diff line number Diff line change
@@ -1,61 +1,72 @@
/* time command - modified from BSD 4.2 by Greg Haerr*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/times.h>
#include <sys/wait.h>

static void printt(char * s, long us)
/* return current time in microseconds */
clock_t time_usecs(void)
{
struct timeval tv;

if (gettimeofday(&tv, (void *)0) < 0)
return 0;

return (tv.tv_sec * 1000000LL + tv.tv_usec);
}

static void print_time(char * s, clock_t us)
{
long mins, secs;

if (us < 1000L && us > 499L) /* round up to 1/1000 second*/
us = 1000L;
mins = us / 60000000L;
if (us < 1000 && us > 499) /* round up to 1/1000 second*/
us = 1000;
mins = us / 60000000LL;
if (mins)
us -= mins * 60000000L;
us -= mins * 60000000LL;

secs = us / 1000000L;
if (secs)
us -= secs * 1000000L;
us -= secs * 1000000LL;

fprintf(stderr, "%s\t%lum%lu.%03lus\n", s, mins, secs, us/1000);
fprintf(stderr, "%s\t%lum%lu.%03lus\n", s, mins, secs, (long)us/1000);

}


int main(int argc, char **argv)
{
int status, p;
struct tms end, start;
clock_t start, end;

if(argc <= 1) {
fprintf(stderr, "Usage: time <program ...>\n");
exit(0);
return 0;
}

times(&start);
start = time_usecs();
p = fork();
if(p == -1) {
fprintf(stderr, "Try again.\n");
exit(1);
perror(NULL);
return 1;
}
if(p == 0) {
execvp(argv[1], &argv[1]);
perror(argv[1]);
exit(1);
return 1;
}
signal(SIGINT, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
while (waitpid(p, &status, 0) != p)
continue;
if((status&0377) != 0)
fprintf(stderr,"Command terminated abnormally.\n");
times(&end);
end = time_usecs();
fprintf(stderr, "\n");
printt("Real", end.tms_cstime - start.tms_cstime);
print_time("Real", end - start);
exit(status>>8);
}
4 changes: 0 additions & 4 deletions libc/include/sys/times.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@ struct tms {
clock_t tms_cstime;
};

__BEGIN_DECLS

clock_t times (struct tms *tp);

__END_DECLS

#endif
13 changes: 2 additions & 11 deletions libc/include/time.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@

#include <features.h>
#include <sys/types.h>
#include <stdint.h>
#include <stddef.h>

#ifndef _CLOCK_T
#define _CLOCK_T
typedef long clock_t;
#endif
typedef int64_t clock_t;

#define CLOCKS_PER_SEC 100
#define CLK_TCK 100 /* That must be the same as HZ ???? */
Expand Down Expand Up @@ -42,11 +40,6 @@ struct timezone {
//extern int daylight;
extern long timezone;

__BEGIN_DECLS

int stime (time_t* __tptr);

clock_t clock(void);
time_t time(time_t * __tp);
#ifndef __HAS_NO_FLOATS__
double difftime(time_t __time2, time_t __time1);
Expand All @@ -66,6 +59,4 @@ void __tm_conv(struct tm *tmbuf, const time_t *timep, time_t offset);
void __asctime(char *buffer, const struct tm *ptm);
#endif

__END_DECLS

#endif
2 changes: 1 addition & 1 deletion libc/system/out.mk
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
include $(TOPDIR)/libc/Makefile.inc

DEFINES += -DL_execl -DL_execle -DL_execlp -DL_execlpe \
-DL_sleep -DL_usleep -DL_times
-DL_sleep -DL_usleep

ifneq "$(VPATH)" ""
dir = $(VPATH)/
Expand Down
45 changes: 18 additions & 27 deletions libc/system/times.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,29 @@
#include <sys/time.h>
#include <sys/times.h>

#if 0 /* system call not implemented*/

/*
* Library version of 'times' since ELKS doesn't implement the system call.
* Note: this routine returns the system clock time in microseconds,
* not the accumulated CPU time(s) nor in CLK_TCKs.
* Thus, it should not be used and has been removed from compilation.
*/
clock_t times(struct tms *tp)
{
long rv;
__times(tp, &rv);
return rv;
}
struct timeval tv;

#else
if (gettimeofday(&tv, (void *)0) < 0)
return -1;

/* library version of 'times' since ELKS doesn't implement it*/
clock_t times(struct tms *tp)
{
struct timeval tv;
if (tp) {
clock_t usecs = tv.tv_sec * 1000000LL + tv.tv_usec;

if (gettimeofday(&tv, (void *)0) < 0)
return -1;
/* return user and system same since ELKS doesn't implement*/
tp->tms_utime = usecs;
tp->tms_stime = usecs;
tp->tms_cutime = usecs;
tp->tms_cstime = usecs;
}

if (tp) {
/* scale down to one hour period to fit in long*/
unsigned long usecs = (tv.tv_sec % 3600) * 1000000L + tv.tv_usec;

/* return user and system same since ELKS doesn't implement*/
tp->tms_utime = usecs;
tp->tms_stime = usecs;
tp->tms_cutime = usecs;
tp->tms_cstime = usecs;
}

return tv.tv_sec;
return tv.tv_sec;
}

#endif
#endif /* L_times*/

0 comments on commit 0a0b148

Please sign in to comment.