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