xref: /original-bsd/lib/libc/gen/opendir.c (revision a95f03a8)
1 /*
2  * Copyright (c) 1983 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #if defined(LIBC_SCCS) && !defined(lint)
9 static char sccsid[] = "@(#)opendir.c	5.12 (Berkeley) 03/14/92";
10 #endif /* LIBC_SCCS and not lint */
11 
12 #include <sys/param.h>
13 #include <dirent.h>
14 #include <fcntl.h>
15 #include <stdlib.h>
16 #include <unistd.h>
17 
18 long _rewinddir;
19 
20 /*
21  * open a directory.
22  */
23 DIR *
24 opendir(name)
25 	const char *name;
26 {
27 	register DIR *dirp;
28 	register int fd;
29 
30 	if ((fd = open(name, 0)) == -1)
31 		return NULL;
32 	if (fcntl(fd, F_SETFD, 1) == -1 ||
33 	    (dirp = (DIR *)malloc(sizeof(DIR))) == NULL) {
34 		close (fd);
35 		return NULL;
36 	}
37 	/*
38 	 * If CLBYTES is an exact multiple of DIRBLKSIZ, use a CLBYTES
39 	 * buffer that it cluster boundary aligned.
40 	 * Hopefully this can be a big win someday by allowing page trades
41 	 * to user space to be done by getdirentries()
42 	 */
43 	if ((CLBYTES % DIRBLKSIZ) == 0) {
44 		dirp->dd_buf = malloc(CLBYTES);
45 		dirp->dd_len = CLBYTES;
46 	} else {
47 		dirp->dd_buf = malloc(DIRBLKSIZ);
48 		dirp->dd_len = DIRBLKSIZ;
49 	}
50 	if (dirp->dd_buf == NULL) {
51 		close (fd);
52 		return NULL;
53 	}
54 	dirp->dd_fd = fd;
55 	dirp->dd_loc = 0;
56 	dirp->dd_seek = 0;
57 	/*
58 	 * Set up seek point for rewinddir.
59 	 */
60 	_rewinddir = telldir(dirp);
61 	return dirp;
62 }
63