@@ -352,26 +352,40 @@ int git_futils_mkdir_withperf(
352352 * tail = '\0' ;
353353 st .st_mode = 0 ;
354354
355- /* make directory */
356- perfdata -> mkdir_calls ++ ;
355+ /* See what's going on with this path component */
356+ perfdata -> stat_calls ++ ;
357+
358+ if (p_lstat (make_path .ptr , & st ) < 0 ) {
359+ perfdata -> mkdir_calls ++ ;
357360
358- if (p_mkdir (make_path .ptr , mode ) < 0 ) {
359- int tmp_errno = giterr_system_last ();
361+ if (errno != ENOENT || p_mkdir (make_path .ptr , mode ) < 0 ) {
362+ giterr_set (GITERR_OS , "Failed to make directory '%s'" , make_path .ptr );
363+ error = GIT_EEXISTS ;
364+ goto done ;
365+ }
366+
367+ giterr_clear ();
368+ } else {
369+ /* with exclusive create, existing dir is an error */
370+ if ((flags & GIT_MKDIR_EXCL ) != 0 ) {
371+ giterr_set (GITERR_INVALID , "Failed to make directory '%s': directory exists" , make_path .ptr );
372+ error = GIT_EEXISTS ;
373+ goto done ;
374+ }
360375
361- /* ignore error if not at end or if directory already exists */
362- if (lastch == '\0' ) {
376+ if (S_ISLNK (st .st_mode )) {
363377 perfdata -> stat_calls ++ ;
364378
365- if ( p_stat ( make_path . ptr , & st ) < 0 || ! S_ISDIR ( st . st_mode )) {
366- giterr_system_set ( tmp_errno );
379+ /* Re-stat the target, make sure it's a directory */
380+ if ( p_stat ( make_path . ptr , & st ) < 0 ) {
367381 giterr_set (GITERR_OS , "Failed to make directory '%s'" , make_path .ptr );
382+ error = GIT_EEXISTS ;
368383 goto done ;
369384 }
370385 }
371386
372- /* with exclusive create, existing dir is an error */
373- if ((flags & GIT_MKDIR_EXCL ) != 0 ) {
374- giterr_set (GITERR_OS , "Directory already exists '%s'" , make_path .ptr );
387+ if (!S_ISDIR (st .st_mode )) {
388+ giterr_set (GITERR_INVALID , "Failed to make directory '%s': directory exists" , make_path .ptr );
375389 error = GIT_EEXISTS ;
376390 goto done ;
377391 }
0 commit comments