From 85e12f7e7b76953c075783871c7041e11b404798 Mon Sep 17 00:00:00 2001 From: Matheus Date: Sun, 28 Jun 2026 11:45:17 -0300 Subject: [PATCH] stat: fit AT_EMPTY_PATH --- kernel-src/sys/syscalls/stat.c | 55 +++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/kernel-src/sys/syscalls/stat.c b/kernel-src/sys/syscalls/stat.c index 50ac358d..81ab9cfd 100644 --- a/kernel-src/sys/syscalls/stat.c +++ b/kernel-src/sys/syscalls/stat.c @@ -65,32 +65,46 @@ syscallret_t syscall_fstatat(context_t *ctx, int dirfd, char *upath, stat_t *ust if (ret.errno) return ret; - char *path = alloc(pathlen + 1); - if (path == NULL) { - ret.errno = ENOMEM; - return ret; - } - - ret.errno = usercopy_fromuser(path, upath, pathlen); - if (ret.errno) { - free(path); - return ret; - } - vnode_t *node = NULL; vnode_t *dirnode = NULL; file_t *file = NULL; - ret.errno = dirfd_enter(path, dirfd, &file, &dirnode); - if (ret.errno) - goto cleanup; + char *path = NULL; + if (pathlen == 0 && (flags & AT_EMPTY_PATH)) { + file = fd_get(dirfd); + if (file == NULL) { + ret.errno = EBADF; + goto cleanup; + } - ret.errno = vfs_lookup(&node, dirnode, path, NULL, flags & AT_SYMLINK_NOFOLLOW ? VFS_LOOKUP_NOLINK : 0); - if (ret.errno) - goto cleanup; + node = file->vnode; + VOP_HOLD(node); + fd_release(file); + VOP_LOCK(node); + file = NULL; + } else { + path = alloc(pathlen + 1); + if (path == NULL) { + ret.errno = ENOMEM; + return ret; + } + + ret.errno = usercopy_fromuser(path, upath, pathlen); + if (ret.errno) { + free(path); + return ret; + } + + ret.errno = dirfd_enter(path, dirfd, &file, &dirnode); + if (ret.errno) + goto cleanup; + + ret.errno = vfs_lookup(&node, dirnode, path, NULL, flags & AT_SYMLINK_NOFOLLOW ? VFS_LOOKUP_NOLINK : 0); + if (ret.errno) + goto cleanup; + } stat_t buf; ret.errno = dostat(node, &buf); - // locked by vfs_lookup VOP_UNLOCK(node); if (ret.errno) goto cleanup; @@ -105,7 +119,8 @@ syscallret_t syscall_fstatat(context_t *ctx, int dirfd, char *upath, stat_t *ust if (dirnode) dirfd_leave(dirnode, file); - free(path); + if (path) + free(path); return ret; }