@@ -425,6 +425,54 @@ static void process_phantom_symlinks(void)
425
425
LeaveCriticalSection (& phantom_symlinks_cs );
426
426
}
427
427
428
+ static int create_phantom_symlink (wchar_t * wtarget , wchar_t * wlink )
429
+ {
430
+ int len ;
431
+
432
+ /* create file symlink */
433
+ if (!CreateSymbolicLinkW (wlink , wtarget , symlink_file_flags )) {
434
+ errno = err_win_to_posix (GetLastError ());
435
+ return -1 ;
436
+ }
437
+
438
+ /* convert to directory symlink if target exists */
439
+ switch (process_phantom_symlink (wtarget , wlink )) {
440
+ case PHANTOM_SYMLINK_RETRY : {
441
+ /* if target doesn't exist, add to phantom symlinks list */
442
+ wchar_t wfullpath [MAX_LONG_PATH ];
443
+ struct phantom_symlink_info * psi ;
444
+
445
+ /* convert to absolute path to be independent of cwd */
446
+ len = GetFullPathNameW (wlink , MAX_LONG_PATH , wfullpath , NULL );
447
+ if (!len || len >= MAX_LONG_PATH ) {
448
+ errno = err_win_to_posix (GetLastError ());
449
+ return -1 ;
450
+ }
451
+
452
+ /* over-allocate and fill phantom_symlink_info structure */
453
+ psi = xmalloc (sizeof (struct phantom_symlink_info ) +
454
+ sizeof (wchar_t ) * (len + wcslen (wtarget ) + 2 ));
455
+ psi -> wlink = (wchar_t * )(psi + 1 );
456
+ wcscpy (psi -> wlink , wfullpath );
457
+ psi -> wtarget = psi -> wlink + len + 1 ;
458
+ wcscpy (psi -> wtarget , wtarget );
459
+
460
+ EnterCriticalSection (& phantom_symlinks_cs );
461
+ psi -> next = phantom_symlinks ;
462
+ phantom_symlinks = psi ;
463
+ LeaveCriticalSection (& phantom_symlinks_cs );
464
+ break ;
465
+ }
466
+ case PHANTOM_SYMLINK_DIRECTORY :
467
+ /* if we created a dir symlink, process other phantom symlinks */
468
+ process_phantom_symlinks ();
469
+ break ;
470
+ default :
471
+ break ;
472
+ }
473
+ return 0 ;
474
+ }
475
+
428
476
/* Normalizes NT paths as returned by some low-level APIs. */
429
477
static wchar_t * normalize_ntpath (wchar_t * wbuf )
430
478
{
@@ -2682,48 +2730,7 @@ int symlink(const char *target, const char *link)
2682
2730
if (wtarget [len ] == '/' )
2683
2731
wtarget [len ] = '\\' ;
2684
2732
2685
- /* create file symlink */
2686
- if (!CreateSymbolicLinkW (wlink , wtarget , symlink_file_flags )) {
2687
- errno = err_win_to_posix (GetLastError ());
2688
- return -1 ;
2689
- }
2690
-
2691
- /* convert to directory symlink if target exists */
2692
- switch (process_phantom_symlink (wtarget , wlink )) {
2693
- case PHANTOM_SYMLINK_RETRY : {
2694
- /* if target doesn't exist, add to phantom symlinks list */
2695
- wchar_t wfullpath [MAX_LONG_PATH ];
2696
- struct phantom_symlink_info * psi ;
2697
-
2698
- /* convert to absolute path to be independent of cwd */
2699
- len = GetFullPathNameW (wlink , MAX_LONG_PATH , wfullpath , NULL );
2700
- if (!len || len >= MAX_LONG_PATH ) {
2701
- errno = err_win_to_posix (GetLastError ());
2702
- return -1 ;
2703
- }
2704
-
2705
- /* over-allocate and fill phantom_symlink_info structure */
2706
- psi = xmalloc (sizeof (struct phantom_symlink_info )
2707
- + sizeof (wchar_t ) * (len + wcslen (wtarget ) + 2 ));
2708
- psi -> wlink = (wchar_t * )(psi + 1 );
2709
- wcscpy (psi -> wlink , wfullpath );
2710
- psi -> wtarget = psi -> wlink + len + 1 ;
2711
- wcscpy (psi -> wtarget , wtarget );
2712
-
2713
- EnterCriticalSection (& phantom_symlinks_cs );
2714
- psi -> next = phantom_symlinks ;
2715
- phantom_symlinks = psi ;
2716
- LeaveCriticalSection (& phantom_symlinks_cs );
2717
- break ;
2718
- }
2719
- case PHANTOM_SYMLINK_DIRECTORY :
2720
- /* if we created a dir symlink, process other phantom symlinks */
2721
- process_phantom_symlinks ();
2722
- break ;
2723
- default :
2724
- break ;
2725
- }
2726
- return 0 ;
2733
+ return create_phantom_symlink (wtarget , wlink );
2727
2734
}
2728
2735
2729
2736
#ifndef _WINNT_H
0 commit comments