Loading...
cache-builder/FileUtils.cpp dyld-960 dyld-1066.8
--- dyld/dyld-960/cache-builder/FileUtils.cpp
+++ dyld/dyld-1066.8/cache-builder/FileUtils.cpp
@@ -48,6 +48,11 @@
 #include "StringUtils.h"
 #include "Diagnostics.h"
 #include "JSONReader.h"
+
+#if BUILDING_CACHE_BUILDER || BUILDING_CACHE_BUILDER_UNIT_TESTS
+#include "BuilderOptions.h"
+#include "NewSharedCacheBuilder.h"
+#endif
 
 
 void iterateDirectoryTree(const std::string& pathPrefix, const std::string& path, bool (^dirFilter)(const std::string& path), void (^fileCallback)(const std::string& path, const struct stat&), bool processFiles, bool recurse)
@@ -272,271 +277,3 @@
     return retval;
 }
 
-
-#if BUILDING_CACHE_BUILDER
-
-FileCache fileCache;
-
-FileCache::FileCache(void)
-{
-    cache_queue = dispatch_queue_create("com.apple.dyld.cache.cache", dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_USER_INITIATED, 0));
-}
-
-std::pair<uint8_t*, struct stat> FileCache::cacheLoad(Diagnostics& diags, const std::string path)
-{
-    __block bool found = false;
-    __block std::pair<uint8_t*, struct stat> retval;
-    std::string normalizedPath = normalize_absolute_file_path(path);
-    dispatch_sync(cache_queue, ^{
-        auto entry = entries.find(normalizedPath);
-        if (entry != entries.end()) {
-            retval = entry->second;
-            found = true;
-        }
-    });
-
-    if (!found) {
-        auto info = fill(diags, normalizedPath);
-        dispatch_sync(cache_queue, ^{
-            auto entry = entries.find(normalizedPath);
-            if (entry != entries.end()) {
-                retval = entry->second;
-            } else {
-                retval = entries[normalizedPath] = info;
-                retval = info;
-            }
-        });
-    }
-
-    return retval;
-}
-
-//FIXME error handling
-std::pair<uint8_t*, struct stat> FileCache::fill(Diagnostics& diags, const std::string& path)
-{
-    void* buffer_ptr = nullptr;
-    struct stat stat_buf;
-    struct statfs statfs_buf;
-    bool localcopy = true;
-
-    int fd = ::open(path.c_str(), O_RDONLY, 0);
-    if (fd == -1) {
-        diags.verbose("can't open file '%s', errno=%d\n", path.c_str(), errno);
-        return std::make_pair((uint8_t*)(-1), stat_buf);
-    }
-
-    if (fstat(fd, &stat_buf) == -1) {
-        diags.verbose("can't stat open file '%s', errno=%d\n", path.c_str(), errno);
-        ::close(fd);
-        return std::make_pair((uint8_t*)(-1), stat_buf);
-    }
-
-    if (stat_buf.st_size < 4096) {
-        diags.verbose("file too small '%s'\n", path.c_str());
-        ::close(fd);
-        return std::make_pair((uint8_t*)(-1), stat_buf);
-    }
-
-    if(fstatfs(fd, &statfs_buf) == 0) {
-        std::string fsName = statfs_buf.f_fstypename;
-        if (fsName == "hfs" || fsName == "apfs") {
-            localcopy = false;
-        }
-    }
-    
-    if (!localcopy) {
-        buffer_ptr = mmap(NULL, (size_t)stat_buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
-        if (buffer_ptr == MAP_FAILED) {
-            diags.verbose("mmap() for file at %s failed, errno=%d\n", path.c_str(), errno);
-            ::close(fd);
-            return std::make_pair((uint8_t*)(-1), stat_buf);
-        }
-    } else {
-        buffer_ptr = malloc((size_t)stat_buf.st_size);
-        ssize_t readBytes = pread(fd, buffer_ptr, (size_t)stat_buf.st_size, 0);
-        if (readBytes == -1) {
-            diags.verbose("Network read for file at %s failed, errno=%d\n", path.c_str(), errno);
-            ::close(fd);
-            return std::make_pair((uint8_t*)(-1), stat_buf);
-        } else if (readBytes != stat_buf.st_size) {
-            diags.verbose("Network read udnerrun for file at %s, expected %lld bytes, got  %zd bytes\n", path.c_str(), stat_buf.st_size, readBytes);
-            ::close(fd);
-            return std::make_pair((uint8_t*)(-1), stat_buf);
-        }
-    }
-
-    ::close(fd);
-
-    return std::make_pair((uint8_t*)buffer_ptr, stat_buf);
-}
-
-static void normalizePath(std::string& path) {
-    // Remove a bunch of stuff we don't need, like trailing slashes.
-    while ( !path.empty() && (path.back() == '/'))
-        path.pop_back();
-}
-
-void SymlinkResolver::addFile(Diagnostics& diags, std::string path) {
-    if (path.front() != '/') {
-        diags.error("Path must start with '/'");
-        return;
-    }
-    if (symlinks.find(path) != symlinks.end()) {
-        diags.error("Cannot add regular file as it is already a symlink");
-        return;
-    }
-    filePaths.insert(path);
-}
-
-void SymlinkResolver::addSymlink(Diagnostics& diags, std::string fromPath, std::string toPath) {
-    normalizePath(fromPath);
-    normalizePath(toPath);
-    if (fromPath.front() != '/') {
-        diags.error("Path must start with '/'");
-        return;
-    }
-    if (filePaths.find(fromPath) != filePaths.end()) {
-        diags.error("Cannot add symlink from '%s' as it is already a regular path", fromPath.c_str());
-        return;
-    }
-    auto itAndInserted = symlinks.insert({ fromPath, toPath });
-    if (!itAndInserted.second) {
-        // The path is already a symlink.  Make sure its a dupe.
-        if (toPath != itAndInserted.first->second) {
-            diags.error("Duplicate symlink for path '%s'", fromPath.c_str());
-            return;
-        }
-    }
-}
-
-std::string SymlinkResolver::realPath(Diagnostics& diags, const std::string& originalPath) const {
-    // First make sure the path doesn't have any magic in it.
-    std::string path = originalPath;
-    normalizePath(path);
-
-    std::set<std::string> seenSymlinks;
-
-    // Now see if any prefix is a symlink
-    if (path.front() != '/')
-        return path;
-
-    std::string::size_type prev_pos = 0;
-    while (prev_pos != std::string::npos) {
-        std::string::size_type pos = path.find("/", prev_pos + 1);
-
-        // First look to see if this path component is special, eg, ., .., etc.
-        std::string component = path.substr(prev_pos, pos - prev_pos);
-        if (component == "/..") {
-            // Fold with the previous path component.
-            if (prev_pos == 0) {
-                // This is the root path, and .. applied to / is just /
-                path = path.substr(3);
-                prev_pos = 0;
-            } else {
-                std::string::size_type lastSlashPos = path.rfind("/", prev_pos - 1);
-                path = path.substr(0, lastSlashPos) + path.substr(pos);
-                prev_pos = lastSlashPos;
-            }
-            continue;
-        } else if (component == "/.") {
-            if (prev_pos == 0) {
-                // Path starts with /./ so just remove the first one.
-                path = path.substr(2);
-            } else {
-                if (pos == std::string::npos) {
-                    // Trailing . on the path
-                    path = path.substr(0, prev_pos );
-                } else {
-                    path = path.substr(0, prev_pos) + path.substr(pos);
-                }
-            }
-            continue;
-        } else if (component == "/") {
-            // Path must contain // somewhere so strip out the duplicates.
-            if (prev_pos == 0) {
-                // Path starts with // so just remove the first one.
-                path = path.substr(1);
-            } else {
-                if (pos == std::string::npos) {
-                    // Trailing / on the path
-                    path = path.substr(0, prev_pos);
-                    prev_pos = pos;
-                } else {
-                    path = path.substr(0, pos) + path.substr(pos + 1);
-                }
-            }
-            continue;
-        }
-
-        // Path is not special, so see if it is a symlink to something.
-        std::string prefix = path.substr(0, pos);
-        //printf("%s\n", prefix.c_str());
-        auto it = symlinks.find(prefix);
-        if (it == symlinks.end()) {
-            // This is not a symlink so move to the next prefix.
-            prev_pos = pos;
-            continue;
-        }
-
-        // If we've already done this prefix then error out.
-        if (seenSymlinks.count(prefix)) {
-            diags.error("Loop in symlink processing for '%s'", originalPath.c_str());
-            return std::string();
-        }
-
-        seenSymlinks.insert(prefix);
-
-        // This is a symlink, so resolve the new path.
-        std::string toPath = it->second;
-        if (toPath.front() == '/') {
-            // Symlink points to an absolute address so substitute the whole prefix for the new path
-            // If we didn't substitute the last component of the path then there is also a path suffix.
-            std::string pathSuffix = "";
-            if (pos != std::string::npos) {
-                std::string::size_type nextSlashPos = path.find("/", pos + 1);
-                if (nextSlashPos != std::string::npos)
-                    pathSuffix = path.substr(nextSlashPos);
-            }
-            path = toPath + pathSuffix;
-            prev_pos = 0;
-            continue;
-        }
-
-        // Symlink points to a relative path so we need to do more processing to get the real path.
-
-        // First calculate which part of the previous prefix we'll keep.  Eg, in /a/b/c where "b -> blah", we want to keep /a here.
-        std::string prevPrefix = path.substr(0, prev_pos);
-        //printf("prevPrefix %s\n", prevPrefix.c_str());
-
-        // If we didn't substitute the last component of the path then there is also a path suffix.
-        std::string pathSuffix = "";
-        if (prefix.size() != path.size())
-            pathSuffix = path.substr(pos);
-
-        // The new path is the remaining prefix, plus the symlink target, plus any remaining suffix from the original path.
-        path = prevPrefix + "/" + toPath + pathSuffix;
-        prev_pos = 0;
-    }
-    return path;
-}
-
-std::vector<DyldSharedCache::FileAlias> SymlinkResolver::getResolvedSymlinks(Diagnostics& diags) {
-    diags.assertNoError();
-    std::vector<DyldSharedCache::FileAlias> aliases;
-    for (auto& fromPathAndToPath : symlinks) {
-        std::string newPath = realPath(diags, fromPathAndToPath.first);
-        if (diags.hasError()) {
-            aliases.clear();
-            return aliases;
-        }
-
-        if (filePaths.count(newPath)) {
-            aliases.push_back({ newPath, fromPathAndToPath.first });
-            // printf("symlink ('%s' -> '%s') resolved to '%s'\n", fromPathAndToPath.first.c_str(), fromPathAndToPath.second.c_str(), newPath.c_str());
-        }
-    }
-    return aliases;
-}
-
-#endif // BUILDING_CACHE_BUILDER
-