]> xenbits.xensource.com Git - unikraft/unikraft.git/commitdiff
lib/vfscore: Add support for renameat syscall
authorRadu Nichita <radunichita99@gmail.com>
Mon, 27 May 2024 22:51:47 +0000 (01:51 +0300)
committerUnikraft Bot <monkey@unikraft.io>
Fri, 31 May 2024 20:39:47 +0000 (20:39 +0000)
The implementation converts the relative paths to absolute
paths then returns the result of the `rename` syscall.

Signed-off-by: Radu Nichita <radunichita99@gmail.com>
Reviewed-by: Andrei Tatar <andrei@unikraft.io>
Reviewed-by: Stefan Jumarea <stefanjumarea02@gmail.com>
Approved-by: Razvan Deaconescu <razvand@unikraft.io>
GitHub-Closes: #1430

lib/vfscore/Makefile.uk
lib/vfscore/exportsyms.uk
lib/vfscore/main.c

index e4e9ee05ea7974b1cae5723f601be931bdad126c..51483f680da5ab75d8cc2dd6e48aa4e3ea5ec606 100644 (file)
@@ -40,6 +40,7 @@ UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += utimes-2
 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += mknod-3
 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += rmdir-1
 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += rename-2
+UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += renameat-4
 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += fsync-1
 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += fdatasync-1
 UK_PROVIDED_SYSCALLS-$(CONFIG_LIBVFSCORE) += umask-1
index 38edab60a8acfcce9a9489ab9a9a292a875dd940..83a77367c273953a24dba78f93b52934c3e67078 100644 (file)
@@ -210,6 +210,9 @@ euidaccess
 rename
 uk_syscall_e_rename
 uk_syscall_r_rename
+renameat
+uk_syscall_e_renameat
+uk_syscall_r_renameat
 __xmknod
 __xstat
 __xstat64
index 7175187c0b4e09b68f670368665de573d4297ad3..51ae65d4a5c1e2a93e1a81f9b404c691b7b69967 100644 (file)
@@ -1318,6 +1318,66 @@ UK_SYSCALL_R_DEFINE(int, rename, const char*, oldpath, const char*, newpath)
        return -error;
 }
 
+UK_TRACEPOINT(trace_vfs_renameat, "\"%s\" \"%s\"", const char*, const char*);
+UK_TRACEPOINT(trace_vfs_renameat_ret, "");
+UK_TRACEPOINT(trace_vfs_renameat_err, "%d", int);
+
+UK_SYSCALL_R_DEFINE(int, renameat,
+       int, olddirfd, const char*, oldpath, int, newdirfd, const char*, newpath)
+{
+       char src[PATH_MAX];
+       char dest[PATH_MAX];
+
+       if (!(oldpath[0] == '/' || olddirfd == AT_FDCWD)) {
+               struct vfscore_file *fp;
+               struct vnode *vp;
+               int error = fget(olddirfd, &fp);
+
+               if (error)
+                       return -error;
+
+               vp = fp->f_dentry->d_vnode;
+
+               vn_lock(vp);
+
+               /* build absolute path */
+               strlcpy(src, fp->f_dentry->d_mount->m_path, PATH_MAX);
+               strlcat(src, fp->f_dentry->d_path, PATH_MAX);
+               strlcat(src, "/", PATH_MAX);
+               strlcat(src, oldpath, PATH_MAX);
+
+               vn_unlock(vp);
+               fdrop(fp);
+       } else {
+               strlcpy(src, oldpath, PATH_MAX);
+       }
+
+       if (!(newpath[0] == '/' || newdirfd == AT_FDCWD)) {
+               struct vfscore_file *fp;
+               struct vnode *vp;
+               int error = fget(newdirfd, &fp);
+
+               if (error)
+                       return -error;
+
+               vp = fp->f_dentry->d_vnode;
+               vn_lock(vp);
+
+               /* build absolute path */
+               strlcpy(dest, fp->f_dentry->d_mount->m_path, PATH_MAX);
+               strlcat(dest, fp->f_dentry->d_path, PATH_MAX);
+               strlcat(dest, "/", PATH_MAX);
+               strlcat(dest, newpath, PATH_MAX);
+
+               vn_unlock(vp);
+               fdrop(fp);
+       } else {
+               strlcpy(src, newpath, PATH_MAX);
+       }
+
+       return sys_rename(src, dest);
+}
+
 UK_TRACEPOINT(trace_vfs_chdir, "\"%s\"", const char*);
 UK_TRACEPOINT(trace_vfs_chdir_ret, "");
 UK_TRACEPOINT(trace_vfs_chdir_err, "%d", int);