@@ -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
{
@@ -2744,48 +2792,7 @@ int symlink(const char *target, const char *link)
2744
2792
if (wtarget [len ] == '/' )
2745
2793
wtarget [len ] = '\\' ;
2746
2794
2747
- /* create file symlink */
2748
- if (!CreateSymbolicLinkW (wlink , wtarget , symlink_file_flags )) {
2749
- errno = err_win_to_posix (GetLastError ());
2750
- return -1 ;
2751
- }
2752
-
2753
- /* convert to directory symlink if target exists */
2754
- switch (process_phantom_symlink (wtarget , wlink )) {
2755
- case PHANTOM_SYMLINK_RETRY : {
2756
- /* if target doesn't exist, add to phantom symlinks list */
2757
- wchar_t wfullpath [MAX_LONG_PATH ];
2758
- struct phantom_symlink_info * psi ;
2759
-
2760
- /* convert to absolute path to be independent of cwd */
2761
- len = GetFullPathNameW (wlink , MAX_LONG_PATH , wfullpath , NULL );
2762
- if (!len || len >= MAX_LONG_PATH ) {
2763
- errno = err_win_to_posix (GetLastError ());
2764
- return -1 ;
2765
- }
2766
-
2767
- /* over-allocate and fill phantom_symlink_info structure */
2768
- psi = xmalloc (sizeof (struct phantom_symlink_info )
2769
- + sizeof (wchar_t ) * (len + wcslen (wtarget ) + 2 ));
2770
- psi -> wlink = (wchar_t * )(psi + 1 );
2771
- wcscpy (psi -> wlink , wfullpath );
2772
- psi -> wtarget = psi -> wlink + len + 1 ;
2773
- wcscpy (psi -> wtarget , wtarget );
2774
-
2775
- EnterCriticalSection (& phantom_symlinks_cs );
2776
- psi -> next = phantom_symlinks ;
2777
- phantom_symlinks = psi ;
2778
- LeaveCriticalSection (& phantom_symlinks_cs );
2779
- break ;
2780
- }
2781
- case PHANTOM_SYMLINK_DIRECTORY :
2782
- /* if we created a dir symlink, process other phantom symlinks */
2783
- process_phantom_symlinks ();
2784
- break ;
2785
- default :
2786
- break ;
2787
- }
2788
- return 0 ;
2795
+ return create_phantom_symlink (wtarget , wlink );
2789
2796
}
2790
2797
2791
2798
#ifndef _WINNT_H
0 commit comments