Commit c589f725 authored by Ramon Nou's avatar Ramon Nou
Browse files

Merge branch 'rnou/359-symlinkat-and-libc-mkdir' into 'master'

Resolve "symlinkat and libc mkdir"

Closes #359

Closes #359

See merge request !254
parents 103170ac 30d8e9bf
Loading
Loading
Loading
Loading
Loading
+38 −2
Original line number Diff line number Diff line
@@ -570,6 +570,9 @@ DLSYM_WRAPPER(int, renameat2,
              (olddirfd, oldpath, newdirfd, newpath, flags), "renameat2")
DLSYM_WRAPPER(int, symlink, (const char* path1, const char* path2),
              (path1, path2), "symlink")
DLSYM_WRAPPER(int, symlinkat,
              (const char* path1, int newdirfd, const char* path2),
              (path1, newdirfd, path2), "symlinkat")
DLSYM_WRAPPER(ssize_t, readlink, (const char* path, char* buf, size_t bufsize),
              (path, buf, bufsize), "readlink")
DLSYM_WRAPPER(ssize_t, readlinkat,
@@ -1348,9 +1351,15 @@ mkdir(const char* path, mode_t mode) {
    if(CTX->interception_enabled()) {
        std::string resolved;
        switch(resolve_gkfs_path(AT_FDCWD, path, resolved)) {
            case PathStatus::Internal:
            case PathStatus::Internal: {
                DEBUG_INFO("[GKFS] mkdir(path='{}')", resolved);
                return gkfs::syscall::gkfs_create(resolved, mode | S_IFDIR);
                auto ret = gkfs::syscall::gkfs_create(resolved, mode | S_IFDIR);
                DEBUG_INFO("[GKFS] mkdir(path='{}') {} --- {}", resolved, ret,
                           errno);
                if(ret < 0 and errno == EEXIST)
                    return 0;
                return ret;
            }
            case PathStatus::Error:
                return -1;
            default: // External
@@ -1848,6 +1857,33 @@ symlink(const char* path1, const char* path2) {
    GKFS_FALLBACK(symlink, path1, path2);
}

// symlinkat
int
symlinkat(const char* path1, int newdirfd, const char* path2) {
    gkfs_init_routine_placeholder();
    if(CTX->interception_enabled()) {
        std::string resolved;
        if(resolve_gkfs_path(AT_FDCWD, path1, resolved) ==
           PathStatus::Internal) {
            DEBUG_INFO("[GKFS] path 1 internal {}", resolved);
            std::string resolved2;
            if(resolve_gkfs_path(newdirfd, path2, resolved2) ==
               PathStatus::Internal) {
                DEBUG_INFO("[GKFS] path 2 internal {}", resolved2);
#ifdef HAS_SYMLINKS
                // In Gekko we invert the parameters.
                return gkfs::syscall::gkfs_mk_symlink(resolved2, resolved);
#else
                DEBUG_INFO("[GKFS] symlinks not supported/compiled");
                errno = ENOTSUP;
                return -1;
#endif
            }
        }
    }
    GKFS_FALLBACK(symlinkat, path1, newdirfd, path2);
}

#ifdef HAS_SYMLINKS
ssize_t
readlink(const char* path, char* buf, size_t bufsize) {