serenity/Kernel/Syscalls/utimensat.cpp
Andreas Kling 97ac4601f5 Kernel: Use custody_for_dirfd() in more syscalls
This simplifies a lot of syscalls, some of which were doing very
unnecessarily verbose things instead of calling this.
2023-04-04 10:33:42 +02:00

46 lines
1.4 KiB
C++

/*
* Copyright (c) 2022, Ariel Don <ariel@arieldon.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Assertions.h>
#include <AK/StringView.h>
#include <Kernel/FileSystem/VirtualFileSystem.h>
#include <Kernel/KLexicalPath.h>
#include <Kernel/Process.h>
namespace Kernel {
ErrorOr<FlatPtr> Process::sys$utimensat(Userspace<Syscall::SC_utimensat_params const*> user_params)
{
VERIFY_NO_PROCESS_BIG_LOCK(this);
TRY(require_promise(Pledge::fattr));
auto params = TRY(copy_typed_from_user(user_params));
auto now = kgettimeofday().to_timespec();
int follow_symlink = params.flag & AT_SYMLINK_NOFOLLOW ? O_NOFOLLOW_NOERROR : 0;
timespec times[2];
if (params.times) {
TRY(copy_from_user(times, params.times, sizeof(times)));
if (times[0].tv_nsec == UTIME_NOW)
times[0] = now;
if (times[1].tv_nsec == UTIME_NOW)
times[1] = now;
} else {
// According to POSIX, both access and modification times are set to
// the current time given a nullptr.
times[0] = now;
times[1] = now;
}
auto path = TRY(get_syscall_path_argument(params.path));
auto base = TRY(custody_for_dirfd(params.dirfd));
auto& atime = times[0];
auto& mtime = times[1];
TRY(VirtualFileSystem::the().utimensat(credentials(), path->view(), *base, atime, mtime, follow_symlink));
return 0;
}
}