xref: /sqlite-3.40.0/src/test_windirent.c (revision 7aa3ebee)
1 /*
2 ** 2015 November 30
3 **
4 ** The author disclaims copyright to this source code.  In place of
5 ** a legal notice, here is a blessing:
6 **
7 **    May you do good and not evil.
8 **    May you find forgiveness for yourself and forgive others.
9 **    May you share freely, never taking more than you give.
10 **
11 *************************************************************************
12 ** This file contains code to implement most of the opendir() family of
13 ** POSIX functions on Win32 using the MSVCRT.
14 */
15 
16 #if defined(_WIN32) && defined(_MSC_VER)
17 
18 #include "test_windirent.h"
19 
20 /*
21 ** Implementation of the POSIX opendir() function using the MSVCRT.
22 */
23 LPDIR opendir(
24   const char *dirname
25 ){
26   struct _finddata_t data;
27   LPDIR dirp = (LPDIR)sqlite3_malloc(sizeof(DIR));
28   SIZE_T namesize = sizeof(data.name) / sizeof(data.name[0]);
29 
30   if( dirp==NULL ) return NULL;
31   memset(dirp, 0, sizeof(DIR));
32 
33   /* TODO: Remove this if Unix-style root paths are not used. */
34   if( sqlite3_stricmp(dirname, "/")==0 ){
35     dirname = getenv("SystemDrive");
36   }
37 
38   _snprintf(data.name, namesize, "%s\\*", dirname);
39   dirp->d_handle = _findfirst(data.name, &data);
40 
41   if( dirp->d_handle==BAD_INTPTR_T ){
42     closedir(dirp);
43     return NULL;
44   }
45 
46   /* TODO: Remove this block to allow hidden and system files. */
47   if( data.attrib&_A_HIDDEN || data.attrib&_A_SYSTEM ){
48     if( _findnext(dirp->d_handle, &data)==-1 ){
49       closedir(dirp);
50       return NULL;
51     }
52   }
53 
54   dirp->d_first.d_attributes = data.attrib;
55   strncpy(dirp->d_first.d_name, data.name, NAME_MAX);
56   dirp->d_first.d_name[NAME_MAX] = '\0';
57 
58   return dirp;
59 }
60 
61 /*
62 ** Implementation of the POSIX readdir() function using the MSVCRT.
63 */
64 LPDIRENT readdir(
65   LPDIR dirp
66 ){
67   struct _finddata_t data;
68 
69   if( dirp==NULL ) return NULL;
70 
71   if( dirp->d_first.d_ino==0 ){
72     dirp->d_first.d_ino++;
73     dirp->d_next.d_ino++;
74 
75     return &dirp->d_first;
76   }
77 
78 next:
79 
80   if( _findnext(dirp->d_handle, &data)==-1 ) return NULL;
81 
82   /* TODO: Remove this block to allow hidden and system files. */
83   if( data.attrib&_A_HIDDEN ) goto next;
84   if( data.attrib&_A_SYSTEM ) goto next;
85 
86   dirp->d_next.d_ino++;
87   dirp->d_next.d_attributes = data.attrib;
88   strncpy(dirp->d_next.d_name, data.name, NAME_MAX);
89   dirp->d_next.d_name[NAME_MAX] = '\0';
90 
91   return &dirp->d_next;
92 }
93 
94 /*
95 ** Implementation of the POSIX readdir_r() function using the MSVCRT.
96 */
97 INT readdir_r(
98   LPDIR dirp,
99   LPDIRENT entry,
100   LPDIRENT *result
101 ){
102   struct _finddata_t data;
103 
104   if( dirp==NULL ) return EBADF;
105 
106   if( dirp->d_first.d_ino==0 ){
107     dirp->d_first.d_ino++;
108     dirp->d_next.d_ino++;
109 
110     entry->d_ino = dirp->d_first.d_ino;
111     entry->d_attributes = dirp->d_first.d_attributes;
112     strncpy(entry->d_name, dirp->d_first.d_name, NAME_MAX);
113     entry->d_name[NAME_MAX] = '\0';
114 
115     *result = entry;
116     return 0;
117   }
118 
119 next:
120 
121   if( _findnext(dirp->d_handle, &data)==-1 ){
122     *result = NULL;
123     return ENOENT;
124   }
125 
126   /* TODO: Remove this block to allow hidden and system files. */
127   if( data.attrib&_A_HIDDEN ) goto next;
128   if( data.attrib&_A_SYSTEM ) goto next;
129 
130   entry->d_ino = (ino_t)-1; /* not available */
131   entry->d_attributes = data.attrib;
132   strncpy(entry->d_name, data.name, NAME_MAX);
133   entry->d_name[NAME_MAX] = '\0';
134 
135   *result = entry;
136   return 0;
137 }
138 
139 /*
140 ** Implementation of the POSIX closedir() function using the MSVCRT.
141 */
142 INT closedir(
143   LPDIR dirp
144 ){
145   INT result = 0;
146 
147   if( dirp==NULL ) return EINVAL;
148 
149   if( dirp->d_handle!=NULL_INTPTR_T && dirp->d_handle!=BAD_INTPTR_T ){
150     result = _findclose(dirp->d_handle);
151   }
152 
153   sqlite3_free(dirp);
154   return result;
155 }
156 
157 #endif /* defined(WIN32) && defined(_MSC_VER) */
158