Serenity Operating System
at master 60 lines 2.0 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <Kernel/Debug.h> 8#include <Kernel/FileSystem/OpenFileDescription.h> 9#include <Kernel/Process.h> 10 11namespace Kernel { 12 13ErrorOr<FlatPtr> Process::sys$fcntl(int fd, int cmd, uintptr_t arg) 14{ 15 VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this); 16 TRY(require_promise(Pledge::stdio)); 17 dbgln_if(IO_DEBUG, "sys$fcntl: fd={}, cmd={}, arg={}", fd, cmd, arg); 18 auto description = TRY(open_file_description(fd)); 19 // NOTE: The FD flags are not shared between OpenFileDescription objects. 20 // This means that dup() doesn't copy the FD_CLOEXEC flag! 21 switch (cmd) { 22 case F_DUPFD_CLOEXEC: 23 case F_DUPFD: { 24 int arg_fd = (int)arg; 25 if (arg_fd < 0) 26 return EINVAL; 27 return m_fds.with_exclusive([&](auto& fds) -> ErrorOr<FlatPtr> { 28 auto fd_allocation = TRY(fds.allocate(arg_fd)); 29 fds[fd_allocation.fd].set(*description, (cmd == F_DUPFD_CLOEXEC) ? FD_CLOEXEC : 0); 30 return fd_allocation.fd; 31 }); 32 } 33 case F_GETFD: 34 return m_fds.with_exclusive([fd](auto& fds) { return fds[fd].flags(); }); 35 case F_SETFD: 36 m_fds.with_exclusive([fd, arg](auto& fds) { fds[fd].set_flags(arg); }); 37 break; 38 case F_GETFL: 39 return description->file_flags(); 40 case F_SETFL: 41 description->set_file_flags(arg); 42 break; 43 case F_ISTTY: 44 return description->is_tty(); 45 case F_GETLK: 46 TRY(description->get_flock(Userspace<flock*>(arg))); 47 return 0; 48 case F_SETLK: 49 TRY(description->apply_flock(Process::current(), Userspace<flock const*>(arg), ShouldBlock::No)); 50 return 0; 51 case F_SETLKW: 52 TRY(description->apply_flock(Process::current(), Userspace<flock const*>(arg), ShouldBlock::Yes)); 53 return 0; 54 default: 55 return EINVAL; 56 } 57 return 0; 58} 59 60}