@@ -429,6 +429,54 @@ static void process_phantom_symlinks(void)
429429 LeaveCriticalSection (& phantom_symlinks_cs );
430430}
431431
432+ static int create_phantom_symlink (wchar_t * wtarget , wchar_t * wlink )
433+ {
434+ int len ;
435+
436+ /* create file symlink */
437+ if (!CreateSymbolicLinkW (wlink , wtarget , symlink_file_flags )) {
438+ errno = err_win_to_posix (GetLastError ());
439+ return -1 ;
440+ }
441+
442+ /* convert to directory symlink if target exists */
443+ switch (process_phantom_symlink (wtarget , wlink )) {
444+ case PHANTOM_SYMLINK_RETRY : {
445+ /* if target doesn't exist, add to phantom symlinks list */
446+ wchar_t wfullpath [MAX_LONG_PATH ];
447+ struct phantom_symlink_info * psi ;
448+
449+ /* convert to absolute path to be independent of cwd */
450+ len = GetFullPathNameW (wlink , MAX_LONG_PATH , wfullpath , NULL );
451+ if (!len || len >= MAX_LONG_PATH ) {
452+ errno = err_win_to_posix (GetLastError ());
453+ return -1 ;
454+ }
455+
456+ /* over-allocate and fill phantom_symlink_info structure */
457+ psi = xmalloc (sizeof (struct phantom_symlink_info ) +
458+ sizeof (wchar_t ) * (len + wcslen (wtarget ) + 2 ));
459+ psi -> wlink = (wchar_t * )(psi + 1 );
460+ wcscpy (psi -> wlink , wfullpath );
461+ psi -> wtarget = psi -> wlink + len + 1 ;
462+ wcscpy (psi -> wtarget , wtarget );
463+
464+ EnterCriticalSection (& phantom_symlinks_cs );
465+ psi -> next = phantom_symlinks ;
466+ phantom_symlinks = psi ;
467+ LeaveCriticalSection (& phantom_symlinks_cs );
468+ break ;
469+ }
470+ case PHANTOM_SYMLINK_DIRECTORY :
471+ /* if we created a dir symlink, process other phantom symlinks */
472+ process_phantom_symlinks ();
473+ break ;
474+ default :
475+ break ;
476+ }
477+ return 0 ;
478+ }
479+
432480/* Normalizes NT paths as returned by some low-level APIs. */
433481static wchar_t * normalize_ntpath (wchar_t * wbuf )
434482{
@@ -2831,48 +2879,7 @@ int symlink(const char *target, const char *link)
28312879 if (wtarget [len ] == '/' )
28322880 wtarget [len ] = '\\' ;
28332881
2834- /* create file symlink */
2835- if (!CreateSymbolicLinkW (wlink , wtarget , symlink_file_flags )) {
2836- errno = err_win_to_posix (GetLastError ());
2837- return -1 ;
2838- }
2839-
2840- /* convert to directory symlink if target exists */
2841- switch (process_phantom_symlink (wtarget , wlink )) {
2842- case PHANTOM_SYMLINK_RETRY : {
2843- /* if target doesn't exist, add to phantom symlinks list */
2844- wchar_t wfullpath [MAX_LONG_PATH ];
2845- struct phantom_symlink_info * psi ;
2846-
2847- /* convert to absolute path to be independent of cwd */
2848- len = GetFullPathNameW (wlink , MAX_LONG_PATH , wfullpath , NULL );
2849- if (!len || len >= MAX_LONG_PATH ) {
2850- errno = err_win_to_posix (GetLastError ());
2851- return -1 ;
2852- }
2853-
2854- /* over-allocate and fill phantom_symlink_info structure */
2855- psi = xmalloc (sizeof (struct phantom_symlink_info )
2856- + sizeof (wchar_t ) * (len + wcslen (wtarget ) + 2 ));
2857- psi -> wlink = (wchar_t * )(psi + 1 );
2858- wcscpy (psi -> wlink , wfullpath );
2859- psi -> wtarget = psi -> wlink + len + 1 ;
2860- wcscpy (psi -> wtarget , wtarget );
2861-
2862- EnterCriticalSection (& phantom_symlinks_cs );
2863- psi -> next = phantom_symlinks ;
2864- phantom_symlinks = psi ;
2865- LeaveCriticalSection (& phantom_symlinks_cs );
2866- break ;
2867- }
2868- case PHANTOM_SYMLINK_DIRECTORY :
2869- /* if we created a dir symlink, process other phantom symlinks */
2870- process_phantom_symlinks ();
2871- break ;
2872- default :
2873- break ;
2874- }
2875- return 0 ;
2882+ return create_phantom_symlink (wtarget , wlink );
28762883}
28772884
28782885#ifndef _WINNT_H
0 commit comments