xref: /plan9/sys/src/cmd/unix/drawterm/libc/dirfstat.c (revision 8ccd4a6360d974db7bd7bbd4f37e7018419ea908)
1*8ccd4a63SDavid du Colombier #include <u.h>
2*8ccd4a63SDavid du Colombier #include <libc.h>
3*8ccd4a63SDavid du Colombier #include <fcall.h>
4*8ccd4a63SDavid du Colombier 
5*8ccd4a63SDavid du Colombier enum
6*8ccd4a63SDavid du Colombier {
7*8ccd4a63SDavid du Colombier 	DIRSIZE	= STATFIXLEN + 16 * 4		/* enough for encoded stat buf + some reasonable strings */
8*8ccd4a63SDavid du Colombier };
9*8ccd4a63SDavid du Colombier 
10*8ccd4a63SDavid du Colombier Dir*
dirfstat(int fd)11*8ccd4a63SDavid du Colombier dirfstat(int fd)
12*8ccd4a63SDavid du Colombier {
13*8ccd4a63SDavid du Colombier 	Dir *d;
14*8ccd4a63SDavid du Colombier 	uchar *buf;
15*8ccd4a63SDavid du Colombier 	int n, nd, i;
16*8ccd4a63SDavid du Colombier 
17*8ccd4a63SDavid du Colombier 	nd = DIRSIZE;
18*8ccd4a63SDavid du Colombier 	for(i=0; i<2; i++){	/* should work by the second try */
19*8ccd4a63SDavid du Colombier 		d = malloc(sizeof(Dir) + BIT16SZ + nd);
20*8ccd4a63SDavid du Colombier 		if(d == nil)
21*8ccd4a63SDavid du Colombier 			return nil;
22*8ccd4a63SDavid du Colombier 		buf = (uchar*)&d[1];
23*8ccd4a63SDavid du Colombier 		n = fstat(fd, buf, BIT16SZ+nd);
24*8ccd4a63SDavid du Colombier 		if(n < BIT16SZ){
25*8ccd4a63SDavid du Colombier 			free(d);
26*8ccd4a63SDavid du Colombier 			return nil;
27*8ccd4a63SDavid du Colombier 		}
28*8ccd4a63SDavid du Colombier 		nd = GBIT16(buf);	/* upper bound on size of Dir + strings */
29*8ccd4a63SDavid du Colombier 		if(nd <= n){
30*8ccd4a63SDavid du Colombier 			convM2D(buf, n, d, (char*)&d[1]);
31*8ccd4a63SDavid du Colombier 			return d;
32*8ccd4a63SDavid du Colombier 		}
33*8ccd4a63SDavid du Colombier 		/* else sizeof(Dir)+BIT16SZ+nd is plenty */
34*8ccd4a63SDavid du Colombier 		free(d);
35*8ccd4a63SDavid du Colombier 	}
36*8ccd4a63SDavid du Colombier 	return nil;
37*8ccd4a63SDavid du Colombier }
38