@@ -458,6 +458,54 @@ static void process_phantom_symlinks(void)
458458 LeaveCriticalSection (& phantom_symlinks_cs );
459459}
460460
461+ static int create_phantom_symlink (wchar_t * wtarget , wchar_t * wlink )
462+ {
463+ int len ;
464+
465+ /* create file symlink */
466+ if (!CreateSymbolicLinkW (wlink , wtarget , symlink_file_flags )) {
467+ errno = err_win_to_posix (GetLastError ());
468+ return -1 ;
469+ }
470+
471+ /* convert to directory symlink if target exists */
472+ switch (process_phantom_symlink (wtarget , wlink )) {
473+ case PHANTOM_SYMLINK_RETRY : {
474+ /* if target doesn't exist, add to phantom symlinks list */
475+ wchar_t wfullpath [MAX_LONG_PATH ];
476+ struct phantom_symlink_info * psi ;
477+
478+ /* convert to absolute path to be independent of cwd */
479+ len = GetFullPathNameW (wlink , MAX_LONG_PATH , wfullpath , NULL );
480+ if (!len || len >= MAX_LONG_PATH ) {
481+ errno = err_win_to_posix (GetLastError ());
482+ return -1 ;
483+ }
484+
485+ /* over-allocate and fill phantom_symlink_info structure */
486+ psi = xmalloc (sizeof (struct phantom_symlink_info ) +
487+ sizeof (wchar_t ) * (len + wcslen (wtarget ) + 2 ));
488+ psi -> wlink = (wchar_t * )(psi + 1 );
489+ wcscpy (psi -> wlink , wfullpath );
490+ psi -> wtarget = psi -> wlink + len + 1 ;
491+ wcscpy (psi -> wtarget , wtarget );
492+
493+ EnterCriticalSection (& phantom_symlinks_cs );
494+ psi -> next = phantom_symlinks ;
495+ phantom_symlinks = psi ;
496+ LeaveCriticalSection (& phantom_symlinks_cs );
497+ break ;
498+ }
499+ case PHANTOM_SYMLINK_DIRECTORY :
500+ /* if we created a dir symlink, process other phantom symlinks */
501+ process_phantom_symlinks ();
502+ break ;
503+ default :
504+ break ;
505+ }
506+ return 0 ;
507+ }
508+
461509/* Normalizes NT paths as returned by some low-level APIs. */
462510static wchar_t * normalize_ntpath (wchar_t * wbuf )
463511{
@@ -2911,48 +2959,7 @@ int symlink(const char *target, const char *link)
29112959 if (wtarget [len ] == '/' )
29122960 wtarget [len ] = '\\' ;
29132961
2914- /* create file symlink */
2915- if (!CreateSymbolicLinkW (wlink , wtarget , symlink_file_flags )) {
2916- errno = err_win_to_posix (GetLastError ());
2917- return -1 ;
2918- }
2919-
2920- /* convert to directory symlink if target exists */
2921- switch (process_phantom_symlink (wtarget , wlink )) {
2922- case PHANTOM_SYMLINK_RETRY : {
2923- /* if target doesn't exist, add to phantom symlinks list */
2924- wchar_t wfullpath [MAX_LONG_PATH ];
2925- struct phantom_symlink_info * psi ;
2926-
2927- /* convert to absolute path to be independent of cwd */
2928- len = GetFullPathNameW (wlink , MAX_LONG_PATH , wfullpath , NULL );
2929- if (!len || len >= MAX_LONG_PATH ) {
2930- errno = err_win_to_posix (GetLastError ());
2931- return -1 ;
2932- }
2933-
2934- /* over-allocate and fill phantom_symlink_info structure */
2935- psi = xmalloc (sizeof (struct phantom_symlink_info )
2936- + sizeof (wchar_t ) * (len + wcslen (wtarget ) + 2 ));
2937- psi -> wlink = (wchar_t * )(psi + 1 );
2938- wcscpy (psi -> wlink , wfullpath );
2939- psi -> wtarget = psi -> wlink + len + 1 ;
2940- wcscpy (psi -> wtarget , wtarget );
2941-
2942- EnterCriticalSection (& phantom_symlinks_cs );
2943- psi -> next = phantom_symlinks ;
2944- phantom_symlinks = psi ;
2945- LeaveCriticalSection (& phantom_symlinks_cs );
2946- break ;
2947- }
2948- case PHANTOM_SYMLINK_DIRECTORY :
2949- /* if we created a dir symlink, process other phantom symlinks */
2950- process_phantom_symlinks ();
2951- break ;
2952- default :
2953- break ;
2954- }
2955- return 0 ;
2962+ return create_phantom_symlink (wtarget , wlink );
29562963}
29572964
29582965#ifndef _WINNT_H
0 commit comments