@@ -424,6 +424,54 @@ static void process_phantom_symlinks(void)
424424 LeaveCriticalSection (& phantom_symlinks_cs );
425425}
426426
427+ static int create_phantom_symlink (wchar_t * wtarget , wchar_t * wlink )
428+ {
429+ int len ;
430+
431+ /* create file symlink */
432+ if (!CreateSymbolicLinkW (wlink , wtarget , symlink_file_flags )) {
433+ errno = err_win_to_posix (GetLastError ());
434+ return -1 ;
435+ }
436+
437+ /* convert to directory symlink if target exists */
438+ switch (process_phantom_symlink (wtarget , wlink )) {
439+ case PHANTOM_SYMLINK_RETRY : {
440+ /* if target doesn't exist, add to phantom symlinks list */
441+ wchar_t wfullpath [MAX_LONG_PATH ];
442+ struct phantom_symlink_info * psi ;
443+
444+ /* convert to absolute path to be independent of cwd */
445+ len = GetFullPathNameW (wlink , MAX_LONG_PATH , wfullpath , NULL );
446+ if (!len || len >= MAX_LONG_PATH ) {
447+ errno = err_win_to_posix (GetLastError ());
448+ return -1 ;
449+ }
450+
451+ /* over-allocate and fill phantom_symlink_info structure */
452+ psi = xmalloc (sizeof (struct phantom_symlink_info ) +
453+ sizeof (wchar_t ) * (len + wcslen (wtarget ) + 2 ));
454+ psi -> wlink = (wchar_t * )(psi + 1 );
455+ wcscpy (psi -> wlink , wfullpath );
456+ psi -> wtarget = psi -> wlink + len + 1 ;
457+ wcscpy (psi -> wtarget , wtarget );
458+
459+ EnterCriticalSection (& phantom_symlinks_cs );
460+ psi -> next = phantom_symlinks ;
461+ phantom_symlinks = psi ;
462+ LeaveCriticalSection (& phantom_symlinks_cs );
463+ break ;
464+ }
465+ case PHANTOM_SYMLINK_DIRECTORY :
466+ /* if we created a dir symlink, process other phantom symlinks */
467+ process_phantom_symlinks ();
468+ break ;
469+ default :
470+ break ;
471+ }
472+ return 0 ;
473+ }
474+
427475/* Normalizes NT paths as returned by some low-level APIs. */
428476static wchar_t * normalize_ntpath (wchar_t * wbuf )
429477{
@@ -2501,48 +2549,7 @@ int symlink(const char *target, const char *link)
25012549 if (wtarget [len ] == '/' )
25022550 wtarget [len ] = '\\' ;
25032551
2504- /* create file symlink */
2505- if (!CreateSymbolicLinkW (wlink , wtarget , symlink_file_flags )) {
2506- errno = err_win_to_posix (GetLastError ());
2507- return -1 ;
2508- }
2509-
2510- /* convert to directory symlink if target exists */
2511- switch (process_phantom_symlink (wtarget , wlink )) {
2512- case PHANTOM_SYMLINK_RETRY : {
2513- /* if target doesn't exist, add to phantom symlinks list */
2514- wchar_t wfullpath [MAX_LONG_PATH ];
2515- struct phantom_symlink_info * psi ;
2516-
2517- /* convert to absolute path to be independent of cwd */
2518- len = GetFullPathNameW (wlink , MAX_LONG_PATH , wfullpath , NULL );
2519- if (!len || len >= MAX_LONG_PATH ) {
2520- errno = err_win_to_posix (GetLastError ());
2521- return -1 ;
2522- }
2523-
2524- /* over-allocate and fill phantom_symlink_info structure */
2525- psi = xmalloc (sizeof (struct phantom_symlink_info )
2526- + sizeof (wchar_t ) * (len + wcslen (wtarget ) + 2 ));
2527- psi -> wlink = (wchar_t * )(psi + 1 );
2528- wcscpy (psi -> wlink , wfullpath );
2529- psi -> wtarget = psi -> wlink + len + 1 ;
2530- wcscpy (psi -> wtarget , wtarget );
2531-
2532- EnterCriticalSection (& phantom_symlinks_cs );
2533- psi -> next = phantom_symlinks ;
2534- phantom_symlinks = psi ;
2535- LeaveCriticalSection (& phantom_symlinks_cs );
2536- break ;
2537- }
2538- case PHANTOM_SYMLINK_DIRECTORY :
2539- /* if we created a dir symlink, process other phantom symlinks */
2540- process_phantom_symlinks ();
2541- break ;
2542- default :
2543- break ;
2544- }
2545- return 0 ;
2552+ return create_phantom_symlink (wtarget , wlink );
25462553}
25472554
25482555#ifndef _WINNT_H
0 commit comments