1 /* Modified for use in WIN32CL port of ZXID,
2  * 15.9.2010, by Sampo Kellomaki (sampo@zxid.org) */
3 /*
4 
5     Implementation of POSIX directory browsing functions and types for Win32.
6 
7     Author:  Kevlin Henney (kevlin@acm.org, kevlin@curbralan.com)
8     History: Created March 1997. Updated June 2003.
9     Rights:  See end of file.
10 
11 */
12 
13 /*#include <dirent.h>*/
14 #include <errno.h>
15 #include <io.h> /* _findfirst and _findnext set errno iff they return -1 */
16 #include <stdlib.h>
17 #include <string.h>
18 
19 #ifdef __cplusplus
20 extern "C"
21 {
22 #endif
23 
24 struct dirent {
25   char* d_name;
26 };
27 
28 struct DIR
29 {
30     long                handle; /* -1 for failed rewind */
31     struct _finddata_t  info;
32     struct dirent       result; /* d_name null iff first time */
33     char                *name;  /* null-terminated char string */
34 };
35 typedef struct DIR DIR;
36 
zx_win23_opendir(const char * name)37 DIR *zx_win23_opendir(const char *name)
38 {
39     DIR *dir = 0;
40 
41     if(name && name[0])
42     {
43         size_t base_length = strlen(name);
44         const char *all = /* search pattern must end with suitable wildcard */
45             strchr("/\\", name[base_length - 1]) ? "*" : "/*";
46 
47         if((dir = (DIR *) malloc(sizeof *dir)) != 0 &&
48            (dir->name = (char *) malloc(base_length + strlen(all) + 1)) != 0)
49         {
50             strcat(strcpy(dir->name, name), all);
51 
52             if((dir->handle = (long) _findfirst(dir->name, &dir->info)) != -1)
53             {
54                 dir->result.d_name = 0;
55             }
56             else /* rollback */
57             {
58                 free(dir->name);
59                 free(dir);
60                 dir = 0;
61             }
62         }
63         else /* rollback */
64         {
65             free(dir);
66             dir   = 0;
67             errno = ENOMEM;
68         }
69     }
70     else
71     {
72         errno = EINVAL;
73     }
74 
75     return dir;
76 }
77 
78 /* Called by: */
zx_win23_closedir(DIR * dir)79 int zx_win23_closedir(DIR *dir)
80 {
81     int result = -1;
82 
83     if(dir)
84     {
85         if(dir->handle != -1)
86         {
87             result = _findclose(dir->handle);
88         }
89 
90         free(dir->name);
91         free(dir);
92     }
93 
94     if(result == -1) /* map all errors to EBADF */
95     {
96         errno = EBADF;
97     }
98 
99     return result;
100 }
101 
zx_win23_readdir(DIR * dir)102 struct dirent *zx_win23_readdir(DIR *dir)
103 {
104     struct dirent *result = 0;
105 
106     if(dir && dir->handle != -1)
107     {
108         if(!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1)
109         {
110             result         = &dir->result;
111             result->d_name = dir->info.name;
112         }
113     }
114     else
115     {
116         errno = EBADF;
117     }
118 
119     return result;
120 }
121 
122 /* Called by: */
zx_win23_rewinddir(DIR * dir)123 void zx_win23_rewinddir(DIR *dir)
124 {
125     if(dir && dir->handle != -1)
126     {
127         _findclose(dir->handle);
128         dir->handle = (long) _findfirst(dir->name, &dir->info);
129         dir->result.d_name = 0;
130     }
131     else
132     {
133         errno = EBADF;
134     }
135 }
136 
137 #ifdef __cplusplus
138 }
139 #endif
140 
141 /*
142 
143     Copyright Kevlin Henney, 1997, 2003. All rights reserved.
144 
145     Permission to use, copy, modify, and distribute this software and its
146     documentation for any purpose is hereby granted without fee, provided
147     that this copyright and permissions notice appear in all copies and
148     derivatives.
149 
150     This software is supplied "as is" without express or implied warranty.
151 
152     But that said, if there are any problems please get in touch.
153 
154 */
155