1/***********************************************************************
2*                                                                      *
3*               This software is part of the ast package               *
4*          Copyright (c) 1985-2012 AT&T Intellectual Property          *
5*                      and is licensed under the                       *
6*                 Eclipse Public License, Version 1.0                  *
7*                    by AT&T Intellectual Property                     *
8*                                                                      *
9*                A copy of the License is available at                 *
10*          http://www.eclipse.org/org/documents/epl-v10.html           *
11*         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12*                                                                      *
13*              Information and Software Systems Research               *
14*                            AT&T Research                             *
15*                           Florham Park NJ                            *
16*                                                                      *
17*                 Glenn Fowler <gsf@research.att.com>                  *
18*                  David Korn <dgk@research.att.com>                   *
19*                   Phong Vo <kpv@research.att.com>                    *
20*                                                                      *
21***********************************************************************/
22#pragma prototyped
23/*
24 * opendir, closedir
25 *
26 * open|close directory stream
27 *
28 * POSIX compatible directory stream access routines:
29 *
30 *	#include <sys/types.h>
31 *	#include <dirent.h>
32 *
33 * NOTE: readdir() returns a pointer to struct dirent
34 */
35
36#include "dirlib.h"
37
38#if _dir_ok
39
40NoN(opendir)
41
42#else
43
44static const char id_dir[] = "\n@(#)$Id: directory (AT&T Research) 1993-04-01 $\0\n";
45
46static DIR*	freedirp;		/* always keep one dirp */
47
48DIR*
49opendir(register const char* path)
50{
51	register DIR*	dirp = 0;
52	register int	fd;
53	struct stat	st;
54
55	if ((fd = open(path, O_RDONLY|O_cloexec)) < 0) return(0);
56	if (fstat(fd, &st) < 0 ||
57	   !S_ISDIR(st.st_mode) && (errno = ENOTDIR) ||
58#if !O_cloexec
59	   fcntl(fd, F_SETFD, FD_CLOEXEC) ||
60#endif
61	   !(dirp = freedirp ? freedirp :
62#if defined(_DIR_PRIVATE_) || _ptr_dd_buf
63	   newof(0, DIR, 1, DIRBLKSIZ)
64#else
65	   newof(0, DIR, 1, 0)
66#endif
67		))
68	{
69		close(fd);
70		if (dirp)
71		{
72			if (!freedirp) freedirp = dirp;
73			else free(dirp);
74		}
75		return(0);
76	}
77	freedirp = 0;
78	dirp->dd_fd = fd;
79	dirp->dd_loc = dirp->dd_size = 0;	/* refill needed */
80#if defined(_DIR_PRIVATE_) || _ptr_dd_buf
81	dirp->dd_buf = (void*)((char*)dirp + sizeof(DIR));
82#endif
83	return(dirp);
84}
85
86void
87closedir(register DIR* dirp)
88{
89	if (dirp)
90	{
91		close(dirp->dd_fd);
92		if (!freedirp) freedirp = dirp;
93		else free(dirp);
94	}
95}
96
97#endif
98