xref: /plan9/sys/src/cmd/unix/drawterm/libc/nsec.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 static uvlong order = (uvlong) 0x0001020304050607ULL;
5*8ccd4a63SDavid du Colombier 
6*8ccd4a63SDavid du Colombier static void
be2vlong(vlong * to,uchar * f)7*8ccd4a63SDavid du Colombier be2vlong(vlong *to, uchar *f)
8*8ccd4a63SDavid du Colombier {
9*8ccd4a63SDavid du Colombier 	uchar *t, *o;
10*8ccd4a63SDavid du Colombier 	int i;
11*8ccd4a63SDavid du Colombier 
12*8ccd4a63SDavid du Colombier 	t = (uchar*)to;
13*8ccd4a63SDavid du Colombier 	o = (uchar*)&order;
14*8ccd4a63SDavid du Colombier 	for(i = 0; i < 8; i++)
15*8ccd4a63SDavid du Colombier 		t[o[i]] = f[i];
16*8ccd4a63SDavid du Colombier }
17*8ccd4a63SDavid du Colombier 
18*8ccd4a63SDavid du Colombier /*
19*8ccd4a63SDavid du Colombier  *  After a fork with fd's copied, both fd's are pointing to
20*8ccd4a63SDavid du Colombier  *  the same Chan structure.  Since the offset is kept in the Chan
21*8ccd4a63SDavid du Colombier  *  structure, the seek's and read's in the two processes can
22*8ccd4a63SDavid du Colombier  *  compete at moving the offset around.  Hence the retry loop.
23*8ccd4a63SDavid du Colombier  *
24*8ccd4a63SDavid du Colombier  *  Since the bintime version doesn't need a seek, it doesn't
25*8ccd4a63SDavid du Colombier  *  have the loop.
26*8ccd4a63SDavid du Colombier  */
27*8ccd4a63SDavid du Colombier vlong
nsec(void)28*8ccd4a63SDavid du Colombier nsec(void)
29*8ccd4a63SDavid du Colombier {
30*8ccd4a63SDavid du Colombier 	char b[12+1];
31*8ccd4a63SDavid du Colombier 	static int f = -1;
32*8ccd4a63SDavid du Colombier 	static int usebintime;
33*8ccd4a63SDavid du Colombier 	int retries;
34*8ccd4a63SDavid du Colombier 	vlong t;
35*8ccd4a63SDavid du Colombier 
36*8ccd4a63SDavid du Colombier 	if(f < 0){
37*8ccd4a63SDavid du Colombier 		usebintime = 1;
38*8ccd4a63SDavid du Colombier 		f = open("/dev/bintime", OREAD|OCEXEC);
39*8ccd4a63SDavid du Colombier 		if(f < 0){
40*8ccd4a63SDavid du Colombier 			usebintime = 0;
41*8ccd4a63SDavid du Colombier 			f = open("/dev/nsec", OREAD|OCEXEC);
42*8ccd4a63SDavid du Colombier 			if(f < 0)
43*8ccd4a63SDavid du Colombier 				return 0;
44*8ccd4a63SDavid du Colombier 		}
45*8ccd4a63SDavid du Colombier 	}
46*8ccd4a63SDavid du Colombier 
47*8ccd4a63SDavid du Colombier 	if(usebintime){
48*8ccd4a63SDavid du Colombier 		if(read(f, b, sizeof(uvlong)) < 0)
49*8ccd4a63SDavid du Colombier 			goto error;
50*8ccd4a63SDavid du Colombier 		be2vlong(&t, (uchar*)b);
51*8ccd4a63SDavid du Colombier 		return t;
52*8ccd4a63SDavid du Colombier 	} else {
53*8ccd4a63SDavid du Colombier 		for(retries = 0; retries < 100; retries++){
54*8ccd4a63SDavid du Colombier 			if(seek(f, 0, 0) >= 0 && read(f, b, sizeof(b)-1) >= 0){
55*8ccd4a63SDavid du Colombier 				b[sizeof(b)-1] = 0;
56*8ccd4a63SDavid du Colombier 				return strtoll(b, 0, 0);
57*8ccd4a63SDavid du Colombier 			}
58*8ccd4a63SDavid du Colombier 		}
59*8ccd4a63SDavid du Colombier 	}
60*8ccd4a63SDavid du Colombier 
61*8ccd4a63SDavid du Colombier error:
62*8ccd4a63SDavid du Colombier 	close(f);
63*8ccd4a63SDavid du Colombier 	f = -1;
64*8ccd4a63SDavid du Colombier 	return 0;
65*8ccd4a63SDavid du Colombier }
66