Newer
Older
}
open_dir->pos(pos);
return written;
}
/**
* gkfs wrapper for make symlink() system calls
* errno may be set
*
* * NOTE: Currently unused
*
* @param path
* @param target_path
* @return 0 on success or -1 on error
*/
int gkfs_mk_symlink(const std::string& path, const std::string& target_path) {
gkfs::preload::init_ld_env_if_needed();
/* The following check is not POSIX compliant.
* In POSIX the target is not checked at all.
* Here if the target is a directory we raise a NOTSUP error.
* So that application know we don't support link to directory.
*/
auto target_md = gkfs::util::get_metadata(target_path, false);
if (target_md != nullptr) {
auto trg_mode = target_md->mode();
if (!(S_ISREG(trg_mode) || S_ISLNK(trg_mode))) {
assert(S_ISDIR(trg_mode));
LOG(DEBUG, "Target path is a directory. Not supported");
errno = ENOTSUP;
return -1;
}
}
auto link_md = gkfs::util::get_metadata(path, false);
errno = EEXIST;
return -1;
}
auto err = gkfs::rpc::forward_mk_symlink(path, target_path);
if (err) {
errno = err;
return -1;
}
return 0;
/**
* gkfs wrapper for reading symlinks
* errno may be set
*
* NOTE: Currently unused
*
* @param path
* @param buf
* @param bufsize
* @return 0 on success or -1 on error
*/
int gkfs_readlink(const std::string& path, char* buf, int bufsize) {
gkfs::preload::init_ld_env_if_needed();
auto md = gkfs::util::get_metadata(path, false);
LOG(DEBUG, "Named link doesn't exist");
return -1;
}
if (!(md->is_link())) {
LOG(DEBUG, "The named file is not a symbolic link");
errno = EINVAL;
return -1;
}
int path_size = md->target_path().size() + CTX->mountdir().size();
if (path_size >= bufsize) {
LOG(WARNING, "Destination buffer size is too short: {} < {}, {} ", bufsize, path_size, md->target_path());
errno = ENAMETOOLONG;
return -1;
}
CTX->mountdir().copy(buf, CTX->mountdir().size());
std::strcpy(buf + CTX->mountdir().size(), md->target_path().c_str());
return path_size;
}
} // namespace syscall
} // namespace gkfs