fcntl.cpp 1.7 KB

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