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