From: Waldemar Kozaczuk <[email protected]>
Committer: Nadav Har'El <[email protected]>
Branch: master
Add missing readlinkat function and corresponding syscall
Fixes #956
Signed-off-by: Waldemar Kozaczuk <[email protected]>
---
diff --git a/fs/vfs/main.cc b/fs/vfs/main.cc
--- a/fs/vfs/main.cc
+++ b/fs/vfs/main.cc
@@ -1760,6 +1760,39 @@ ssize_t readlink(const char *pathname, char *buf,
size_t bufsize)
return -1;
}
+ssize_t readlinkat(int dirfd, const char *pathname, char *buf, size_t
bufsize)
+{
+ if (pathname[0] == '/' || dirfd == AT_FDCWD) {
+ return readlink(pathname, buf, bufsize);
+ }
+
+ struct file *fp;
+ int error = fget(dirfd, &fp);
+ if (error) {
+ errno = error;
+ return -1;
+ }
+
+ struct vnode *vp = fp->f_dentry->d_vnode;
+ vn_lock(vp);
+
+ std::unique_ptr<char []> up (new char[PATH_MAX]);
+ char *p = up.get();
+
+ /* build absolute path */
+ strlcpy(p, fp->f_dentry->d_mount->m_path, PATH_MAX);
+ strlcat(p, fp->f_dentry->d_path, PATH_MAX);
+ strlcat(p, "/", PATH_MAX);
+ strlcat(p, pathname, PATH_MAX);
+
+ error = readlink(p, buf, bufsize);
+
+ vn_unlock(vp);
+ fdrop(fp);
+
+ return error;
+}
+
TRACEPOINT(trace_vfs_fallocate, "%d %d 0x%x 0x%x", int, int, loff_t,
loff_t);
TRACEPOINT(trace_vfs_fallocate_ret, "");
TRACEPOINT(trace_vfs_fallocate_err, "%d", int);
diff --git a/linux.cc b/linux.cc
--- a/linux.cc
+++ b/linux.cc
@@ -429,6 +429,7 @@ long syscall(long number, ...)
SYSCALL2(nanosleep, const struct timespec*, struct timespec *);
SYSCALL4(fstatat, int, const char *, struct stat *, int);
SYSCALL1(sys_exit_group, int);
+ SYSCALL4(readlinkat, int, const char *, char *, size_t);
}
debug_always("syscall(): unimplemented system call %d\n", number);
--
You received this message because you are subscribed to the Google Groups "OSv
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.