1/***********************************************************************
2*                                                                      *
3*               This software is part of the ast package               *
4*          Copyright (c) 1985-2011 AT&T Intellectual Property          *
5*                      and is licensed under the                       *
6*                  Common Public License, Version 1.0                  *
7*                    by AT&T Intellectual Property                     *
8*                                                                      *
9*                A copy of the License is available at                 *
10*            http://www.opensource.org/licenses/cpl1.0.txt             *
11*         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
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)) < 0) return(0);
56	if (fstat(fd, &st) < 0 ||
57	   !S_ISDIR(st.st_mode) && (errno = ENOTDIR) ||
58	   fcntl(fd, F_SETFD, FD_CLOEXEC) ||
59	   !(dirp = freedirp ? freedirp :
60#if defined(_DIR_PRIVATE_) || _ptr_dd_buf
61	   newof(0, DIR, 1, DIRBLKSIZ)
62#else
63	   newof(0, DIR, 1, 0)
64#endif
65		))
66	{
67		close(fd);
68		if (dirp)
69		{
70			if (!freedirp) freedirp = dirp;
71			else free(dirp);
72		}
73		return(0);
74	}
75	freedirp = 0;
76	dirp->dd_fd = fd;
77	dirp->dd_loc = dirp->dd_size = 0;	/* refill needed */
78#if defined(_DIR_PRIVATE_) || _ptr_dd_buf
79	dirp->dd_buf = (void*)((char*)dirp + sizeof(DIR));
80#endif
81	return(dirp);
82}
83
84void
85closedir(register DIR* dirp)
86{
87	if (dirp)
88	{
89		close(dirp->dd_fd);
90		if (!freedirp) freedirp = dirp;
91		else free(dirp);
92	}
93}
94
95#endif
96