fileops.cc 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #include <errno.h>
  2. #include <poll.h>
  3. #include <sys/mman.h>
  4. #include <unistd.h>
  5. #include <types/path.hpp>
  6. #include <kernel/log.hpp>
  7. #include <kernel/mem/vm_area.hpp>
  8. #include <kernel/process.hpp>
  9. #include <kernel/syscall.hpp>
  10. #include <kernel/vfs.hpp>
  11. #define NOT_IMPLEMENTED not_implemented(__FILE__, __LINE__)
  12. static inline void not_implemented(const char* pos, int line) {
  13. kmsgf(
  14. "[kernel] the function at %s:%d is not implemented, killing the "
  15. "pid%d...",
  16. pos, line, current_process->pid);
  17. current_thread->send_signal(SIGSYS);
  18. }
  19. uintptr_t kernel::syscall::do_mmap_pgoff(uintptr_t addr, size_t len, int prot, int flags, int fd,
  20. off_t pgoffset) {
  21. if (addr & 0xfff)
  22. return -EINVAL;
  23. if (len == 0)
  24. return -EINVAL;
  25. len = (len + 0xfff) & ~0xfff;
  26. // TODO: shared mappings
  27. if (flags & MAP_SHARED)
  28. return -ENOMEM;
  29. if (flags & MAP_ANONYMOUS) {
  30. if (fd != -1)
  31. return -EINVAL;
  32. if (pgoffset != 0)
  33. return -EINVAL;
  34. // TODO: shared mappings
  35. if (!(flags & MAP_PRIVATE))
  36. return -EINVAL;
  37. auto& mms = current_process->mms;
  38. // do unmapping, equal to munmap, MAP_FIXED set
  39. if (prot == PROT_NONE) {
  40. if (int ret = mms.unmap(addr, len, true); ret != 0)
  41. return ret;
  42. } else {
  43. // TODO: add NULL check in mm_list
  44. if (!addr || !mms.is_avail(addr, len)) {
  45. if (flags & MAP_FIXED)
  46. return -ENOMEM;
  47. addr = mms.find_avail(addr, len);
  48. }
  49. // TODO: check current cs
  50. if (addr + len > 0x100000000ULL)
  51. return -ENOMEM;
  52. mem::mm_list::map_args args{};
  53. args.vaddr = addr;
  54. args.length = len;
  55. args.flags = mem::MM_ANONYMOUS;
  56. if (prot & PROT_WRITE)
  57. args.flags |= mem::MM_WRITE;
  58. if (prot & PROT_EXEC)
  59. args.flags |= mem::MM_EXECUTE;
  60. if (int ret = mms.mmap(args); ret != 0)
  61. return ret;
  62. }
  63. }
  64. return addr;
  65. }
  66. int kernel::syscall::do_munmap(uintptr_t addr, size_t len) {
  67. if (addr & 0xfff)
  68. return -EINVAL;
  69. return current_process->mms.unmap(addr, len, true);
  70. }
  71. int kernel::syscall::do_poll(pollfd __user* fds, nfds_t nfds, int timeout) {
  72. if (nfds == 0)
  73. return 0;
  74. if (nfds > 1) {
  75. NOT_IMPLEMENTED;
  76. return -EINVAL;
  77. }
  78. // TODO: handle timeout
  79. // if (timeout != -1) {
  80. // }
  81. (void)timeout;
  82. // for now, we will poll from console only
  83. int ret = tty::console->poll();
  84. if (ret < 0)
  85. return ret;
  86. fds[0].revents = POLLIN;
  87. return ret;
  88. // TODO: check address validity
  89. // TODO: poll multiple fds and other type of files
  90. // for (nfds_t i = 0; i < nfds; ++i) {
  91. // auto& pfd = fds[i];
  92. // auto* file = current_process->files[pfd.fd];
  93. // if (!file || !S_ISCHR(file->mode))
  94. // return -EINVAL;
  95. // // poll the fds
  96. // }
  97. //
  98. // return 0;
  99. }
  100. int kernel::syscall::do_socket(int domain, int type, int protocol) {
  101. return -EINVAL;
  102. }