Do not needlessly cast the return value of calloc/malloc.
[videolan:libdvdread.git] / msvc / contrib / dirent / dirent.c
1 /*
2
3     Implementation of POSIX directory browsing functions and types for Win32.
4
5     Kevlin Henney (mailto:kevlin@acm.org), March 1997.
6
7     Copyright Kevlin Henney, 1997. All rights reserved.
8
9     Permission to use, copy, modify, and distribute this software and its
10     documentation for any purpose is hereby granted without fee, provided
11     that this copyright and permissions notice appear in all copies and
12     derivatives, and that no charge may be made for the software and its
13     documentation except to cover cost of distribution.
14
15     This software is supplied "as is" without express or implied warranty.
16
17     But that said, if there are any problems please get in touch.
18
19 */
20
21 #include <dirent.h>
22 #include <errno.h>
23 #include <io.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #ifndef DIR
28
29 struct DIR
30 {
31     long                handle; /* -1 for failed rewind */
32     struct _finddata_t  info;
33     struct dirent       result; /* d_name null iff first time */
34     char                *name;  /* NTBS */
35 };
36
37 #endif
38
39 DIR *opendir(const char *name)
40 {
41     DIR *dir = 0;
42
43     if(name && name[0])
44     {
45         size_t base_length = strlen(name);
46         const char *all = /* the root directory is a special case... */
47             strchr("/\\", name[base_length - 1]) ? "*" : "/*";
48
49         if((dir = malloc(sizeof *dir)) != 0 &&
50            (dir->name = malloc(base_length + strlen(all) + 1)) != 0)
51         {
52             strcat(strcpy(dir->name, name), all);
53
54             if((dir->handle = _findfirst(dir->name, &dir->info)) != -1)
55             {
56                 dir->result.d_name = 0;
57             }
58             else /* rollback */
59             {
60                 free(dir->name);
61                 free(dir);
62                 dir = 0;
63             }
64         }
65         else /* rollback */
66         {
67             free(dir);
68             dir   = 0;
69             errno = ENOMEM;
70         }
71     }
72     else
73     {
74         errno = EINVAL;
75     }
76
77     return dir;
78 }
79
80 int closedir(DIR *dir)
81 {
82     int result = -1;
83
84     if(dir)
85     {
86         if(dir->handle != -1)
87         {
88             result = _findclose(dir->handle);
89         }
90
91         free(dir->name);
92         free(dir);
93     }
94
95     if(result == -1) /* map all errors to EBADF */
96     {
97         errno = EBADF;
98     }
99
100     return result;
101 }
102
103 struct dirent *readdir(DIR *dir)
104 {
105     struct dirent *result = 0;
106
107     if(dir && dir->handle != -1)
108     {
109         if(!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1)
110         {
111             result         = &dir->result;
112             result->d_name = dir->info.name;
113         }
114     }
115     else
116     {
117         errno = EBADF;
118     }
119
120     return result;
121 }
122
123 void rewinddir(DIR *dir)
124 {
125     if(dir && dir->handle != -1)
126     {
127         _findclose(dir->handle);
128         dir->handle = _findfirst(dir->name, &dir->info);
129         dir->result.d_name = 0;
130     }
131     else
132     {
133         errno = EBADF;
134     }
135 }