xref: /plan9/sys/src/cmd/unix/drawterm/libc/time.c (revision 8ccd4a6360d974db7bd7bbd4f37e7018419ea908)
1*8ccd4a63SDavid du Colombier #include <u.h>
2*8ccd4a63SDavid du Colombier #include <libc.h>
3*8ccd4a63SDavid du Colombier 
4*8ccd4a63SDavid du Colombier 
5*8ccd4a63SDavid du Colombier /*
6*8ccd4a63SDavid du Colombier  *  After a fork with fd's copied, both fd's are pointing to
7*8ccd4a63SDavid du Colombier  *  the same Chan structure.  Since the offset is kept in the Chan
8*8ccd4a63SDavid du Colombier  *  structure, the seek's and read's in the two processes can
9*8ccd4a63SDavid du Colombier  *  compete at moving the offset around.  Hence the unusual loop
10*8ccd4a63SDavid du Colombier  *  in the middle of this routine.
11*8ccd4a63SDavid du Colombier  */
12*8ccd4a63SDavid du Colombier static long
oldtime(long * tp)13*8ccd4a63SDavid du Colombier oldtime(long *tp)
14*8ccd4a63SDavid du Colombier {
15*8ccd4a63SDavid du Colombier 	char b[20];
16*8ccd4a63SDavid du Colombier 	static int f = -1;
17*8ccd4a63SDavid du Colombier 	int i, retries;
18*8ccd4a63SDavid du Colombier 	long t;
19*8ccd4a63SDavid du Colombier 
20*8ccd4a63SDavid du Colombier 	memset(b, 0, sizeof(b));
21*8ccd4a63SDavid du Colombier 	for(retries = 0; retries < 100; retries++){
22*8ccd4a63SDavid du Colombier 		if(f < 0)
23*8ccd4a63SDavid du Colombier 			f = open("/dev/time", OREAD|OCEXEC);
24*8ccd4a63SDavid du Colombier 		if(f < 0)
25*8ccd4a63SDavid du Colombier 			break;
26*8ccd4a63SDavid du Colombier 		if(seek(f, 0, 0) < 0 || (i = read(f, b, sizeof(b))) < 0){
27*8ccd4a63SDavid du Colombier 			close(f);
28*8ccd4a63SDavid du Colombier 			f = -1;
29*8ccd4a63SDavid du Colombier 		} else {
30*8ccd4a63SDavid du Colombier 			if(i != 0)
31*8ccd4a63SDavid du Colombier 				break;
32*8ccd4a63SDavid du Colombier 		}
33*8ccd4a63SDavid du Colombier 	}
34*8ccd4a63SDavid du Colombier 	t = atol(b);
35*8ccd4a63SDavid du Colombier 	if(tp)
36*8ccd4a63SDavid du Colombier 		*tp = t;
37*8ccd4a63SDavid du Colombier 	return t;
38*8ccd4a63SDavid du Colombier }
39*8ccd4a63SDavid du Colombier 
40*8ccd4a63SDavid du Colombier long
time(long * tp)41*8ccd4a63SDavid du Colombier time(long *tp)
42*8ccd4a63SDavid du Colombier {
43*8ccd4a63SDavid du Colombier 	vlong t;
44*8ccd4a63SDavid du Colombier 
45*8ccd4a63SDavid du Colombier 	t = nsec()/((vlong)1000000000);
46*8ccd4a63SDavid du Colombier 	if(t == 0)
47*8ccd4a63SDavid du Colombier 		t = oldtime(0);
48*8ccd4a63SDavid du Colombier 	if(tp != nil)
49*8ccd4a63SDavid du Colombier 		*tp = t;
50*8ccd4a63SDavid du Colombier 	return t;
51*8ccd4a63SDavid du Colombier }
52