@@ -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
{
@@ -2781,48 +2829,7 @@ int symlink(const char *target, const char *link)
2781
2829
if (wtarget [len ] == '/' )
2782
2830
wtarget [len ] = '\\' ;
2783
2831
2784
- /* create file symlink */
2785
- if (!CreateSymbolicLinkW (wlink , wtarget , symlink_file_flags )) {
2786
- errno = err_win_to_posix (GetLastError ());
2787
- return -1 ;
2788
- }
2789
-
2790
- /* convert to directory symlink if target exists */
2791
- switch (process_phantom_symlink (wtarget , wlink )) {
2792
- case PHANTOM_SYMLINK_RETRY : {
2793
- /* if target doesn't exist, add to phantom symlinks list */
2794
- wchar_t wfullpath [MAX_LONG_PATH ];
2795
- struct phantom_symlink_info * psi ;
2796
-
2797
- /* convert to absolute path to be independent of cwd */
2798
- len = GetFullPathNameW (wlink , MAX_LONG_PATH , wfullpath , NULL );
2799
- if (!len || len >= MAX_LONG_PATH ) {
2800
- errno = err_win_to_posix (GetLastError ());
2801
- return -1 ;
2802
- }
2803
-
2804
- /* over-allocate and fill phantom_symlink_info structure */
2805
- psi = xmalloc (sizeof (struct phantom_symlink_info )
2806
- + sizeof (wchar_t ) * (len + wcslen (wtarget ) + 2 ));
2807
- psi -> wlink = (wchar_t * )(psi + 1 );
2808
- wcscpy (psi -> wlink , wfullpath );
2809
- psi -> wtarget = psi -> wlink + len + 1 ;
2810
- wcscpy (psi -> wtarget , wtarget );
2811
-
2812
- EnterCriticalSection (& phantom_symlinks_cs );
2813
- psi -> next = phantom_symlinks ;
2814
- phantom_symlinks = psi ;
2815
- LeaveCriticalSection (& phantom_symlinks_cs );
2816
- break ;
2817
- }
2818
- case PHANTOM_SYMLINK_DIRECTORY :
2819
- /* if we created a dir symlink, process other phantom symlinks */
2820
- process_phantom_symlinks ();
2821
- break ;
2822
- default :
2823
- break ;
2824
- }
2825
- return 0 ;
2832
+ return create_phantom_symlink (wtarget , wlink );
2826
2833
}
2827
2834
2828
2835
#ifndef _WINNT_H
0 commit comments