mirror of
https://github.com/fergalmoran/ladybird.git
synced 2026-02-09 01:06:11 +00:00
To be able to do this, we add a new class called CustodyBase, which can be resolved on-demand internally in the VirtualFileSystem resolving path code. When being resolved, CustodyBase will return a known custody if it was constructed with such, if that's not the case it will provide the root custody if the original path is absolute. Lastly, if that's not the case as well, it will resolve the given dirfd to provide a Custody object.
82 lines
2.4 KiB
C++
82 lines
2.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/Library/KLexicalPath.h>
|
|
#include <Kernel/Tasks/Process.h>
|
|
|
|
namespace Kernel {
|
|
|
|
ErrorOr<FlatPtr> Process::sys$futimens(Userspace<Syscall::SC_futimens_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();
|
|
|
|
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 description = TRY(open_file_description(params.fd));
|
|
if (!description->inode())
|
|
return EBADF;
|
|
if (!description->custody())
|
|
return EBADF;
|
|
|
|
auto& atime = times[0];
|
|
auto& mtime = times[1];
|
|
TRY(VirtualFileSystem::the().do_utimens(credentials(), *description->custody(), atime, mtime));
|
|
return 0;
|
|
}
|
|
|
|
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& atime = times[0];
|
|
auto& mtime = times[1];
|
|
|
|
CustodyBase base(params.dirfd, path->view());
|
|
TRY(VirtualFileSystem::the().utimensat(credentials(), path->view(), base, atime, mtime, follow_symlink));
|
|
return 0;
|
|
}
|
|
|
|
}
|