1 | /** @file
|
---|
2 | Open a directory.
|
---|
3 |
|
---|
4 | Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
|
---|
5 | This program and the accompanying materials
|
---|
6 | are licensed and made available under the terms and conditions of the BSD License
|
---|
7 | which accompanies this distribution. The full text of the license may be found at
|
---|
8 | http://opensource.org/licenses/bsd-license.php
|
---|
9 |
|
---|
10 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
---|
11 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
---|
12 |
|
---|
13 | Copyright (c) 1983, 1993
|
---|
14 | The Regents of the University of California. All rights reserved.
|
---|
15 |
|
---|
16 | Redistribution and use in source and binary forms, with or without
|
---|
17 | modification, are permitted provided that the following conditions
|
---|
18 | are met:
|
---|
19 | 1. Redistributions of source code must retain the above copyright
|
---|
20 | notice, this list of conditions and the following disclaimer.
|
---|
21 | 2. Redistributions in binary form must reproduce the above copyright
|
---|
22 | notice, this list of conditions and the following disclaimer in the
|
---|
23 | documentation and/or other materials provided with the distribution.
|
---|
24 | 3. Neither the name of the University nor the names of its contributors
|
---|
25 | may be used to endorse or promote products derived from this software
|
---|
26 | without specific prior written permission.
|
---|
27 |
|
---|
28 | THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
---|
29 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
---|
30 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
---|
31 | ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
---|
32 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
---|
33 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
---|
34 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
---|
35 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
---|
36 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
---|
37 | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
---|
38 | SUCH DAMAGE.
|
---|
39 |
|
---|
40 | NetBSD: opendir.c,v 1.33 2008/01/10 09:49:04 elad Exp
|
---|
41 | opendir.c 8.7 (Berkeley) 12/10/94
|
---|
42 | **/
|
---|
43 | #include <sys/cdefs.h>
|
---|
44 |
|
---|
45 | #include <namespace.h>
|
---|
46 | #include <reentrant.h>
|
---|
47 | #include <extern.h>
|
---|
48 | #include <sys/param.h>
|
---|
49 | //#include <sys/mount.h>
|
---|
50 | #include <sys/stat.h>
|
---|
51 |
|
---|
52 | #include <assert.h>
|
---|
53 | #include <dirent.h>
|
---|
54 | #include <errno.h>
|
---|
55 | #include <fcntl.h>
|
---|
56 | #include <stdlib.h>
|
---|
57 | #include <string.h>
|
---|
58 | #include <unistd.h>
|
---|
59 |
|
---|
60 | #define MAXITERATIONS 100
|
---|
61 |
|
---|
62 | /*
|
---|
63 | * Open a directory.
|
---|
64 | */
|
---|
65 | DIR *
|
---|
66 | opendir(const char *name)
|
---|
67 | {
|
---|
68 | _DIAGASSERT(name != NULL);
|
---|
69 |
|
---|
70 | return (__opendir2(name, DTF_HIDEW|DTF_NODUP));
|
---|
71 | }
|
---|
72 |
|
---|
73 | DIR *
|
---|
74 | __opendir2(const char *name, int flags)
|
---|
75 | {
|
---|
76 | DIR *dirp = NULL;
|
---|
77 | int fd;
|
---|
78 | int serrno;
|
---|
79 | struct stat sb;
|
---|
80 | int incr;
|
---|
81 |
|
---|
82 | _DIAGASSERT(name != NULL);
|
---|
83 |
|
---|
84 | if ((fd = open(name, O_RDONLY | O_NONBLOCK, 0)) == -1 ||
|
---|
85 | fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
|
---|
86 | goto error;
|
---|
87 | if (fstat(fd, &sb) || !S_ISDIR(sb.st_mode)) {
|
---|
88 | errno = ENOTDIR;
|
---|
89 | goto error;
|
---|
90 | }
|
---|
91 | if ((dirp = (DIR *)malloc(sizeof(DIR))) == NULL)
|
---|
92 | goto error;
|
---|
93 | dirp->dd_buf = NULL;
|
---|
94 |
|
---|
95 | /*
|
---|
96 | * If the machine's page size is an exact multiple of DIRBLKSIZ,
|
---|
97 | * use a buffer that is cluster boundary aligned.
|
---|
98 | * Hopefully this can be a big win someday by allowing page trades
|
---|
99 | * to user space to be done by getdirentries()
|
---|
100 | */
|
---|
101 | incr = DIRBLKSIZ;
|
---|
102 |
|
---|
103 | dirp->dd_len = incr;
|
---|
104 | dirp->dd_buf = malloc((size_t)dirp->dd_len);
|
---|
105 | if (dirp->dd_buf == NULL)
|
---|
106 | goto error;
|
---|
107 | dirp->dd_seek = 0;
|
---|
108 | flags &= ~DTF_REWIND;
|
---|
109 |
|
---|
110 | dirp->dd_loc = 0;
|
---|
111 | dirp->dd_fd = fd;
|
---|
112 | dirp->dd_flags = flags;
|
---|
113 |
|
---|
114 | /*
|
---|
115 | * Set up seek point for rewinddir.
|
---|
116 | */
|
---|
117 | #ifdef _REENTRANT
|
---|
118 | if (__isthreaded) {
|
---|
119 | if ((dirp->dd_lock = malloc(sizeof(mutex_t))) == NULL)
|
---|
120 | goto error;
|
---|
121 | mutex_init((mutex_t *)dirp->dd_lock, NULL);
|
---|
122 | }
|
---|
123 | #endif
|
---|
124 | dirp->dd_internal = NULL;
|
---|
125 | return (dirp);
|
---|
126 | error:
|
---|
127 | serrno = errno;
|
---|
128 | if (dirp && dirp->dd_buf)
|
---|
129 | free(dirp->dd_buf);
|
---|
130 | if (dirp)
|
---|
131 | free(dirp);
|
---|
132 | if (fd != -1)
|
---|
133 | (void)close(fd);
|
---|
134 | errno = serrno;
|
---|
135 | return NULL;
|
---|
136 | }
|
---|