File: dir.c

package info (click to toggle)
wily 0.13.33-3
  • links: PTS
  • area: main
  • in suites: slink
  • size: 1,500 kB
  • ctags: 1,720
  • sloc: ansic: 12,830; sh: 245; makefile: 188
file content (92 lines) | stat: -rw-r--r-- 1,893 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include "wily.h"
#include "data.h"

enum {
	MAXNAMES = 10240		/* initial number of names in a directory */
};

static int
mycmp (const void *a, const void *d) {
	return strcmp(*(char**)a, *(char**)d);
}

/* A few OS's have file systems that know which files in a directory are dirs. */
#ifdef DT_DIR
#define CHECKDIR(dp)	((dp)->d_type == DT_DIR)
#else
#define CHECKDIR(dp)	(0)
#endif

/* 
 * Read 'dirp', return null-terminated array of strings representing the
 * files in the directory.  Both the strings and the array need to be
 * freed later (use dirnames_free()).
 *
 * Returns 0 on error.
 */
char **
dirnames (DIR *dirp, char *path) {
	struct stat		statbuf;
	struct dirent	*direntp;
	char		*name;
	char		**list;
	int		nfiles;
	int		maxnames = MAXNAMES;

	/* Read the directory into a big buffer */

	rewinddir(dirp);	/* Workaround for possible FreeBSD bug. */

	list = (char**) salloc(maxnames * sizeof(char*));

	/* temporarily chdir so we can stat */
	if(chdir(path)) {
		diag(path, "couldn't chdir");
		return 0;
	}
	nfiles = 0;
	while ((direntp = readdir(dirp))) {
		name = direntp->d_name;
		if( name[0] == '.' &&  (!show_dot_files || name[1]=='\0')) {
			continue;
		}
		if (!(nfiles+2 < maxnames) ) {
			maxnames *= 2;
			list = (char**) srealloc(list, maxnames * sizeof(char*));
		}

		if (CHECKDIR(direntp) ||
				(stat(name, &statbuf) >= 0 && S_ISDIR(statbuf.st_mode))) {
			Path	buf;

			sprintf(buf, "%s/", name);
			list[nfiles++] = strdup(buf);
		} else {
			list[nfiles++] = strdup(name);
		}
	}
	/* return to wilydir */
	if(chdir(wilydir)) {
		diag(wilydir, "couldn't chdir back to wilydir [%s]", wilydir);
	}
	closedir(dirp);

	qsort(list, nfiles, sizeof(char*), mycmp);

	list[nfiles] = 0;
	return list;
}

/* Keep consistent with dirnames() */
void
dirnames_free(char**names) {
	char	**s;

	if(!names)
		return;
	for(s=names; *s; s++)
		free(*s);
	free(names);
}