mescc: Mes C Library: Support GNU Awk: Implement atof.
[mes.git] / lib / dirent / opendir.c
1 /* -*-comment-start: "//";comment-end:""-*-
2  * GNU Mes --- Maxwell Equations of Software
3  * Copyright (C) 1991-1996,98,2000,2001 Free Software Foundation, Inc.
4  * Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
5  *
6  * This file is part of GNU Mes.
7  *
8  * GNU Mes is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or (at
11  * your option) any later version.
12  *
13  * GNU Mes is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 // Taken from GNU C Library 2.2.5
23
24 #include <mes/lib.h>
25 #include <errno.h>
26 #include <limits.h>
27 #include <stddef.h>
28 #include <stdlib.h>
29 #include <dirent.h>
30 #include <fcntl.h>
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <unistd.h>
34 #include <stdio.h>
35
36 #include <dirstream.h>
37
38 /* Open a directory stream on NAME.  */
39 DIR *
40 opendir (char const *name)
41 {
42   DIR *dirp;
43   struct stat statbuf;
44   int fd;
45   size_t allocation;
46   int save_errno;
47
48   if (name[0] == '\0')
49     {
50       /* POSIX.1-1990 says an empty name gets ENOENT;
51          but `open' might like it fine.  */
52       errno = ENOENT;
53       return 0;
54     }
55
56   fd = open (name, O_RDONLY | O_DIRECTORY);
57   if (fd < 0)
58     return 0;
59
60   if (fstat (fd, &statbuf) < 0)
61     goto lose;
62
63   if (fcntl (fd, F_SETFD, FD_CLOEXEC) < 0)
64     goto lose;
65
66   allocation = statbuf.st_blksize;
67
68   dirp = (DIR *) calloc (1, sizeof (DIR) + allocation);
69   if (!dirp)
70   lose:
71     {
72       save_errno = errno;
73       close (fd);
74       errno = save_errno;
75       return 0;
76     }
77   dirp->data = (char *) (dirp + 1);
78   dirp->allocation = allocation;
79   dirp->fd = fd;
80
81   return dirp;
82 }