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