in dotnet/tools/common/manifest.c [164:224]
void CreateLinkIfNeeded(const char *target, const char *toCreate)
{
BOOL result;
DWORD error;
DWORD flag;
if (!PathFileExists(target))
{
printf("File %s does not exist\n", target);
exit(-1);
}
/* The file is linked by the calling script */
if (strstr(toCreate, "manifest_prep.exe") != NULL)
return;
_chmod(toCreate, _S_IREAD | _S_IWRITE);
unlink(toCreate);
/* Try hard linking first (except mono.exe) */
if (strstr(toCreate, "mono.exe") == NULL)
{
result = CreateHardLink(toCreate, target, NULL);
if (result)
return;
error = GetLastError();
if (error == ERROR_ALREADY_EXISTS)
{
/*printf("%s does exist after unlink. Ignoring error. \n", toCreate);*/
return;
}
}
/* Fall back to symbolic linking */
flag = SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
retry:
result = CreateSymbolicLinkA(toCreate, target, flag);
if (!result)
{
error = GetLastError();
if (error == 87 && flag != 0)
{
printf("SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE seems not supported\n");
flag = 0;
goto retry;
}
if (error != ERROR_ALREADY_EXISTS)
{
/* For uknown to me reasons, sometimes the link function failes even if long paths are enabled. */
if (error == ERROR_PATH_NOT_FOUND && PathFileExistsA(target))
{
/*printf("Target file %s does exists. Ignoring error. \n", target);*/
return;
}
printf("Error %d on linking %s to %s\n", error, toCreate, target);
exit(-1);
}
}
}