fcntl.cpp 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  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/FileDescription.h>
  8. #include <Kernel/Process.h>
  9. namespace Kernel {
  10. KResultOr<FlatPtr> Process::sys$fcntl(int fd, int cmd, u32 arg)
  11. {
  12. VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
  13. REQUIRE_PROMISE(stdio);
  14. dbgln_if(IO_DEBUG, "sys$fcntl: fd={}, cmd={}, arg={}", fd, cmd, arg);
  15. auto description = fds().file_description(fd);
  16. if (!description)
  17. return EBADF;
  18. // NOTE: The FD flags are not shared between FileDescription objects.
  19. // This means that dup() doesn't copy the FD_CLOEXEC flag!
  20. switch (cmd) {
  21. case F_DUPFD: {
  22. int arg_fd = (int)arg;
  23. if (arg_fd < 0)
  24. return EINVAL;
  25. auto new_fd_or_error = fds().allocate(arg_fd);
  26. if (new_fd_or_error.is_error())
  27. return new_fd_or_error.error();
  28. auto new_fd = new_fd_or_error.release_value();
  29. m_fds[new_fd.fd].set(*description);
  30. return new_fd.fd;
  31. }
  32. case F_GETFD:
  33. return m_fds[fd].flags();
  34. case F_SETFD:
  35. m_fds[fd].set_flags(arg);
  36. break;
  37. case F_GETFL:
  38. return description->file_flags();
  39. case F_SETFL:
  40. description->set_file_flags(arg);
  41. break;
  42. case F_ISTTY:
  43. return description->is_tty();
  44. case F_GETLK:
  45. return description->get_flock(Userspace<flock*>(arg));
  46. case F_SETLK:
  47. return description->apply_flock(Process::current(), Userspace<const flock*>(arg));
  48. default:
  49. return EINVAL;
  50. }
  51. return 0;
  52. }
  53. }