@@ -276,6 +276,9 @@ static zend_result ps_files_write(ps_files *data, zend_string *key, zend_string
276276 return SUCCESS ;
277277}
278278
279+ /* Recursively remove expired session files. When dirdepth > 0 the
280+ * cleanup descends into subdirectories up to that many levels before
281+ * inspecting individual session files. */
279282static int ps_files_cleanup_dir (const zend_string * dirname , zend_long maxlifetime , size_t remaining_depth )
280283{
281284 DIR * dir ;
@@ -297,42 +300,55 @@ static int ps_files_cleanup_dir(const zend_string *dirname, zend_long maxlifetim
297300 return -1 ;
298301 }
299302
303+ /* Prepare buffer (dirname never changes) */
300304 memcpy (buf , ZSTR_VAL (dirname ), ZSTR_LEN (dirname ));
301305 buf [ZSTR_LEN (dirname )] = PHP_DIR_SEPARATOR ;
302306
307+ /* Only read the clock when we are about to compare mtimes at target depth */
303308 if (remaining_depth == 0 ) {
304309 time (& now );
305310 }
306311
307312 while ((entry = readdir (dir ))) {
313+ /* skip . and .. */
308314 if (entry -> d_name [0 ] == '.' &&
309315 (entry -> d_name [1 ] == '\0' ||
310316 (entry -> d_name [1 ] == '.' && entry -> d_name [2 ] == '\0' ))) {
311317 continue ;
312318 }
313- if (remaining_depth == 0 && strncmp (entry -> d_name , FILE_PREFIX , sizeof (FILE_PREFIX ) - 1 ) != 0 ) {
314- continue ;
315- }
316319 size_t entry_len = strlen (entry -> d_name );
320+ /* does it fit into our buffer? */
317321 if (ZSTR_LEN (dirname ) + 1 + entry_len >= MAXPATHLEN ) {
318322 continue ;
319323 }
324+ /* create the full path and NUL-terminate it */
320325 memcpy (buf + ZSTR_LEN (dirname ) + 1 , entry -> d_name , entry_len );
321326 buf [ZSTR_LEN (dirname ) + 1 + entry_len ] = '\0' ;
322- if (VCWD_STAT (buf , & sbuf ) != 0 ) {
323- continue ;
324- }
327+
325328 if (remaining_depth == 0 ) {
329+ /* target depth: delete expired session files */
330+ if (strncmp (entry -> d_name , FILE_PREFIX , sizeof (FILE_PREFIX ) - 1 ) != 0 ) {
331+ continue ;
332+ }
333+ if (VCWD_STAT (buf , & sbuf ) != 0 ) {
334+ continue ;
335+ }
326336 if ((now - sbuf .st_mtime ) > maxlifetime ) {
327337 VCWD_UNLINK (buf );
328338 nrdels ++ ;
329339 }
330- } else if (S_ISDIR (sbuf .st_mode )) {
331- zend_string * subdir = zend_string_init (buf , ZSTR_LEN (dirname ) + 1 + entry_len , 0 );
332- int n = ps_files_cleanup_dir (subdir , maxlifetime , remaining_depth - 1 );
333- zend_string_release (subdir );
334- if (n >= 0 ) {
335- nrdels += n ;
340+ } else {
341+ /* intermediate depth: recurse into subdirectories */
342+ if (VCWD_STAT (buf , & sbuf ) != 0 ) {
343+ continue ;
344+ }
345+ if (S_ISDIR (sbuf .st_mode )) {
346+ zend_string * subdir = zend_string_init (buf , ZSTR_LEN (dirname ) + 1 + entry_len , 0 );
347+ int n = ps_files_cleanup_dir (subdir , maxlifetime , remaining_depth - 1 );
348+ zend_string_release (subdir );
349+ if (n >= 0 ) {
350+ nrdels += n ;
351+ }
336352 }
337353 }
338354 }
0 commit comments