diff --git a/src/client/gkfs_libc.cpp b/src/client/gkfs_libc.cpp index a25294234390fe86b7d86f46db379150e74e76a2..9403efd4a26e4e93606445229a9fcbc7b04200fe 100644 --- a/src/client/gkfs_libc.cpp +++ b/src/client/gkfs_libc.cpp @@ -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) {