1717
1818#include "flb_tests_internal.h"
1919
20+ #ifdef _WIN32
21+ # define FLB_UNLINK _unlink
22+ # define FLB_RMDIR _rmdir
23+ #else
24+ # define FLB_UNLINK unlink
25+ # define FLB_RMDIR rmdir
26+ #endif
27+
2028static int mkpath (const char * p ) {
29+ #if FLB_SYSTEM_WINDOWS
30+ if (_mkdir (p ) == 0 ) {
31+ return 0 ;
32+ }
33+ #else
2134 if (mkdir (p , 0777 ) == 0 ) {
2235 return 0 ;
2336 }
37+ #endif
2438 if (errno == EEXIST ) {
2539 return 0 ;
2640 }
2741 return -1 ;
2842}
2943
30- static void tmpdir_for (char * out , size_t n , const char * name ) {
44+ static void join_path (char * out , size_t cap , const char * a , const char * b )
45+ {
46+ #ifdef _WIN32
47+ _snprintf (out , cap , "%s\\%s" , a , b );
48+ #else
49+ snprintf (out , cap , "%s/%s" , a , b );
50+ #endif
51+ out [cap - 1 ] = '\0' ;
52+ }
53+
54+ static void tmpdir_for (char * out , size_t n , const char * name )
55+ {
56+ #ifdef _WIN32
57+ DWORD pid = GetCurrentProcessId ();
58+ _snprintf (out , n , "C:\\Windows\\Temp\\flb-dlq-%s-%lu" , name , (unsigned long ) pid );
59+ #else
3160 snprintf (out , n , "/tmp/flb-dlq-%s-%ld" , name , (long ) getpid ());
61+ #endif
62+ out [n - 1 ] = '\0' ;
3263 mkpath (out );
3364}
3465
@@ -90,35 +121,67 @@ static int buf_contains(const void *hay, size_t hlen,
90121 return 0 ;
91122}
92123
93- /* find the most recent *.flb file in dir; write full path into out */
94- static int find_latest_flb (const char * dir , char * out , size_t out_sz )
124+ #if FLB_SYSTEM_WINDOWS
125+ static int find_latest_flb_win32 (const char * dir , char * out , size_t out_sz )
95126{
127+ WIN32_FIND_DATAA ffd ;
128+ HANDLE h = INVALID_HANDLE_VALUE ;
129+ char pattern [1024 ];
130+ ULONGLONG best_ts = 0ULL ;
131+ char best_name [MAX_PATH ] = {0 };
132+
133+ _snprintf (pattern , sizeof (pattern ), "%s\\*.flb" , dir );
134+ pattern [sizeof (pattern )- 1 ] = '\0' ;
135+
136+ h = FindFirstFileA (pattern , & ffd );
137+ if (h == INVALID_HANDLE_VALUE ) {
138+ return -1 ;
139+ }
140+
141+ do {
142+ if (ffd .dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
143+ continue ;
144+ }
145+ ULONGLONG ts = (((ULONGLONG )ffd .ftLastWriteTime .dwHighDateTime ) << 32 ) |
146+ (ULONGLONG )ffd .ftLastWriteTime .dwLowDateTime ;
147+ if (ts >= best_ts ) {
148+ best_ts = ts ;
149+ strncpy (best_name , ffd .cFileName , sizeof (best_name )- 1 );
150+ best_name [sizeof (best_name )- 1 ] = '\0' ;
151+ }
152+ } while (FindNextFileA (h , & ffd ));
153+
154+ FindClose (h );
155+
156+ if (best_name [0 ] == '\0' ) {
157+ return -1 ;
158+ }
159+
160+ join_path (out , out_sz , dir , best_name );
161+ return 0 ;
162+ }
163+ #else
164+ static int find_latest_flb_unix (const char * dir , char * out , size_t out_sz )
165+ {
166+ DIR * d = opendir (dir );
96167 struct dirent * e ;
97168 time_t best_t = 0 ;
98169 char best_path [1024 ] = {0 };
99170 struct stat st ;
100171 char full [1024 ];
101- size_t len = 0 ;
102- DIR * d = opendir (dir );
103172
104- if (!d ) {
105- return -1 ;
106- }
173+ if (!d ) return -1 ;
107174
108175 while ((e = readdir (d )) != NULL ) {
109- len = strlen (e -> d_name );
110- if (len < 5 ) {
111- continue ;
112- }
113- if (strcmp (e -> d_name + (len - 4 ), ".flb" ) != 0 ) {
114- continue ;
115- }
176+ size_t len = strlen (e -> d_name );
177+ if (len < 5 ) continue ;
178+ if (strcmp (e -> d_name + (len - 4 ), ".flb" ) != 0 ) continue ;
116179
117- snprintf (full , sizeof (full ), "%s/%s" , dir , e -> d_name );
180+ join_path (full , sizeof (full ), dir , e -> d_name );
118181 if (stat (full , & st ) == 0 ) {
119182 if (st .st_mtime >= best_t ) {
120183 best_t = st .st_mtime ;
121- strncpy (best_path , full , sizeof (best_path ) - 1 );
184+ strncpy (best_path , full , sizeof (best_path )- 1 );
122185 }
123186 }
124187 }
@@ -131,6 +194,17 @@ static int find_latest_flb(const char *dir, char *out, size_t out_sz)
131194 out [out_sz - 1 ] = '\0' ;
132195 return 0 ;
133196}
197+ #endif
198+
199+ /* find the most recent *.flb file in dir; write full path into out */
200+ static int find_latest_flb (const char * dir , char * out , size_t out_sz )
201+ {
202+ #if FLB_SYSTEM_WINDOWS
203+ return find_latest_flb_win32 (dir , out , out_sz );
204+ #else
205+ return find_latest_flb_unix (dir , out , out_sz );
206+ #endif
207+ }
134208
135209static void free_ctx (struct flb_config * ctx )
136210{
@@ -195,37 +269,81 @@ static void rmdir_stream_dir(const char *root, const char *stream_name)
195269}
196270
197271/* Minimal POSIX rm -rf for the whole temp tree after CIO is gone */
198- static void rm_rf_best_effort (const char * root )
272+ #if FLB_SYSTEM_WINDOWS
273+ static void rm_rf_best_effort_win32 (const char * root )
274+ {
275+ WIN32_FIND_DATAA ffd ;
276+ HANDLE h = INVALID_HANDLE_VALUE ;
277+ char pattern [1024 ], p [1024 ];
278+
279+ _snprintf (pattern , sizeof (pattern ), "%s\\*" ,
280+ root ? root : "" );
281+ pattern [sizeof (pattern )- 1 ] = '\0' ;
282+
283+ h = FindFirstFileA (pattern , & ffd );
284+ if (h == INVALID_HANDLE_VALUE ) {
285+ /* try removing root itself */
286+ (void ) FLB_RMDIR (root );
287+ return ;
288+ }
289+
290+ do {
291+ const char * name = ffd .cFileName ;
292+ if (!strcmp (name , "." ) || !strcmp (name , ".." )) continue ;
293+
294+ join_path (p , sizeof (p ), root , name );
295+
296+ if (ffd .dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
297+ rm_rf_best_effort_win32 (p );
298+ }
299+ else {
300+ /* clear read-only if needed */
301+ if (ffd .dwFileAttributes & FILE_ATTRIBUTE_READONLY ) {
302+ SetFileAttributesA (p ,
303+ ffd .dwFileAttributes & ~FILE_ATTRIBUTE_READONLY );
304+ }
305+ (void ) DeleteFileA (p );
306+ }
307+ } while (FindNextFileA (h , & ffd ));
308+
309+ FindClose (h );
310+ (void ) FLB_RMDIR (root );
311+ }
312+ #else
313+ static void rm_rf_best_effort_unix (const char * root )
199314{
200- DIR * d ;
315+ DIR * d = opendir ( root ) ;
201316 struct dirent * e ;
202317 char p [1024 ];
203318 struct stat st ;
204319
205- if (!root ) { return ; }
206-
207- d = opendir (root );
208320 if (!d ) {
209- (void ) rmdir (root );
321+ (void ) FLB_RMDIR (root );
210322 return ;
211323 }
212324 while ((e = readdir (d )) != NULL ) {
213- if (!strcmp (e -> d_name , "." ) || !strcmp (e -> d_name , ".." )) {
214- continue ;
215- }
216- snprintf (p , sizeof (p ), "%s/%s" , root , e -> d_name );
217- if (lstat (p , & st ) != 0 ) {
218- continue ;
219- }
325+ if (!strcmp (e -> d_name , "." ) || !strcmp (e -> d_name , ".." )) continue ;
326+ join_path (p , sizeof (p ), root , e -> d_name );
327+ if (lstat (p , & st ) != 0 ) continue ;
220328 if (S_ISDIR (st .st_mode )) {
221- rm_rf_best_effort (p );
329+ rm_rf_best_effort_unix (p );
222330 }
223331 else {
224- (void ) unlink (p );
332+ (void ) FLB_UNLINK (p );
225333 }
226334 }
227335 closedir (d );
228- (void ) rmdir (root );
336+ (void ) FLB_RMDIR (root );
337+ }
338+ #endif
339+
340+ static void rm_rf_best_effort (const char * root )
341+ {
342+ #if FLB_SYSTEM_WINDOWS
343+ rm_rf_best_effort_win32 (root );
344+ #else
345+ rm_rf_best_effort_unix (root );
346+ #endif
229347}
230348
231349static void test_cleanup_with_cio (struct flb_config * ctx , const char * root )
0 commit comments