たまにはCプログラムでも。ただのストップウォッチには興味ありませんですか、そうですか。
% gcc -Os -o stopwatch stopwatch.c % stopwatch 5 / 0:00:03.9
↑くるくる回る。
sleepコマンドの代わりにすると、待ち時間がわかって良いかも? でもそれだけ。
なお引数なしだとカウントアップします。
ソースは以下。# 工夫も何もないが…
cygwin, Linux, Mac OS X、BSDなどで動く気がします。
/* stopwatch.c */ #define _BSD_SOURCE #include <stdio.h> #include <stdlib.h> #include <sys/time.h> //#define USE_SELECT struct timeval m; char rc[] = "|/-\\"; #ifdef USE_SELECT int usleep(unsigned long u) { struct timeval w = {0,u}; int ret = select(0,0,0,0,&w); if (ret < 0) perror("select"); return ret; } #endif int display(struct timeval *v, int s) { printf("%c%3d:%02d:%02d.%01d \r", rc[v->tv_usec/(1000000/s)%4], v->tv_sec/3600, v->tv_sec/60%60, v->tv_sec%60, v->tv_usec/100000); fflush(stdout); } int countup() { struct timeval v; gettimeofday(&v, NULL); timersub(&v, &m, &v); display(&v, 4); printf("\t\t\t\t%7d\r", 100000 - v.tv_usec%100000); return 100000 - v.tv_usec%100000; } int sw() { struct timeval v; gettimeofday(&v, NULL); timersub(&m, &v, &v); if (v.tv_sec < 0 || v.tv_sec == 0 && v.tv_usec < 10000) return -1; display(&v, 8); printf("\t\t\t\t%7d\r", v.tv_usec%100000); return v.tv_usec%100000; } int main(int argc, char** argv) { int w; gettimeofday(&m, NULL); if (argc > 1) { m.tv_sec += atoi(argv[1]); while ((w = sw()) >= 0) usleep(w); } else while (1) usleep(countup()); printf("\n"); return 0; }
usleepなんて関数ない!って怒られる人は #define USE_SELECT すると、selectシステムコールをusleepの代わりとして使います。誤差蓄積防止用に差分値の0.1秒以下の桁を渡しています。
ちなみにtimersub関数は BSD由来のマクロで、POSIXにはありません。最近のLinux(というかglibc)では#define _BSD_SOURCE しないと使えなくなっています。