Skip to content

Commit

Permalink
Replace symlinkat call with getcwd/chdir/symlink/chdir to fix Conda b…
Browse files Browse the repository at this point in the history
…uild using macOS 10.9 SDK
  • Loading branch information
milot-mirdita committed Feb 10, 2020
1 parent 28e83e8 commit 2a829ae
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 3 deletions.
36 changes: 33 additions & 3 deletions src/commons/FileUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,18 +186,48 @@ void FileUtil::symlinkAlias(const std::string &file, const std::string &alias) {
if (symlinkExists(pathToAlias) == true){
FileUtil::remove(pathToAlias.c_str());
}

if (symlinkat(base.c_str(), dirfd(dir), alias.c_str()) != 0) {
// symlinkat is not available in Conda macOS
// Conda uses the macOS 10.9 SDK, and symlinkat was introduced in 10.10
// We emulate symlinkat by manipulating the CWD instead
std::string oldWd = FileUtil::getCurrentWorkingDirectory();
if (chdir(path.c_str()) != 0) {
Debug(Debug::ERROR) << "Could not change working directory to " << path << "\n";
EXIT(EXIT_FAILURE);
}
if (symlink(base.c_str(), alias.c_str()) != 0) {
Debug(Debug::ERROR) << "Could not create symlink of " << file << "!\n";
EXIT(EXIT_FAILURE);
}

if (chdir(oldWd.c_str()) != 0) {
Debug(Debug::ERROR) << "Could not change working directory to " << oldWd << "\n";
EXIT(EXIT_FAILURE);
}
if (closedir(dir) != 0) {
Debug(Debug::ERROR) << "Error closing directory " << path << "!\n";
EXIT(EXIT_FAILURE);
}
}

std::string FileUtil::getCurrentWorkingDirectory() {
// CWD can be larger than PATH_MAX and allocating enough memory is somewhat tricky
char* wd = NULL;
size_t bufferSize = PATH_MAX;
do {
if (wd != NULL) {
free(wd);
bufferSize *= 2;
}
wd = getcwd(NULL, bufferSize);
if (wd == NULL && errno != ERANGE && errno != 0) {
Debug(Debug::ERROR) << "Could not get current working directory\n";
EXIT(EXIT_FAILURE);
}
} while (wd == NULL && errno == ERANGE);
std::string cwd(wd);
free(wd);
return cwd;
}

void FileUtil::symlinkAbs(const std::string &target, const std::string &link) {
if(FileUtil::fileExists(link.c_str())){
FileUtil::remove(link.c_str());
Expand Down
2 changes: 2 additions & 0 deletions src/commons/FileUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ class FileUtil {

static size_t getFreeSpace(const char *dir);

static std::string getCurrentWorkingDirectory();

static void symlinkAlias(const std::string &file, const std::string &alias);
static void symlinkAbs(const std::string &target, const std::string &link);

Expand Down

0 comments on commit 2a829ae

Please sign in to comment.