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