@@ -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
{
@@ -2808,48 +2856,7 @@ int symlink(const char *target, const char *link)
2808
2856
if (wtarget [len ] == '/' )
2809
2857
wtarget [len ] = '\\' ;
2810
2858
2811
- /* create file symlink */
2812
- if (!CreateSymbolicLinkW (wlink , wtarget , symlink_file_flags )) {
2813
- errno = err_win_to_posix (GetLastError ());
2814
- return -1 ;
2815
- }
2816
-
2817
- /* convert to directory symlink if target exists */
2818
- switch (process_phantom_symlink (wtarget , wlink )) {
2819
- case PHANTOM_SYMLINK_RETRY : {
2820
- /* if target doesn't exist, add to phantom symlinks list */
2821
- wchar_t wfullpath [MAX_LONG_PATH ];
2822
- struct phantom_symlink_info * psi ;
2823
-
2824
- /* convert to absolute path to be independent of cwd */
2825
- len = GetFullPathNameW (wlink , MAX_LONG_PATH , wfullpath , NULL );
2826
- if (!len || len >= MAX_LONG_PATH ) {
2827
- errno = err_win_to_posix (GetLastError ());
2828
- return -1 ;
2829
- }
2830
-
2831
- /* over-allocate and fill phantom_symlink_info structure */
2832
- psi = xmalloc (sizeof (struct phantom_symlink_info )
2833
- + sizeof (wchar_t ) * (len + wcslen (wtarget ) + 2 ));
2834
- psi -> wlink = (wchar_t * )(psi + 1 );
2835
- wcscpy (psi -> wlink , wfullpath );
2836
- psi -> wtarget = psi -> wlink + len + 1 ;
2837
- wcscpy (psi -> wtarget , wtarget );
2838
-
2839
- EnterCriticalSection (& phantom_symlinks_cs );
2840
- psi -> next = phantom_symlinks ;
2841
- phantom_symlinks = psi ;
2842
- LeaveCriticalSection (& phantom_symlinks_cs );
2843
- break ;
2844
- }
2845
- case PHANTOM_SYMLINK_DIRECTORY :
2846
- /* if we created a dir symlink, process other phantom symlinks */
2847
- process_phantom_symlinks ();
2848
- break ;
2849
- default :
2850
- break ;
2851
- }
2852
- return 0 ;
2859
+ return create_phantom_symlink (wtarget , wlink );
2853
2860
}
2854
2861
2855
2862
#ifndef _WINNT_H
0 commit comments