Advertisement
Guest User

syscall.c

a guest
May 26th, 2019
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.53 KB | None | 0 0
  1. #include "userprog/syscall.h"
  2. #include <console.h>
  3. #include <stdio.h>
  4. #include <syscall-nr.h>
  5. #include "devices/shutdown.h"
  6. #include "filesys/directory.h"
  7. #include "filesys/file.h"
  8. #include "filesys/filesys.h"
  9. #include "filesys/inode.h"
  10. #include "list.h"
  11. #include "process.h"
  12. #include "threads/interrupt.h"
  13. #include "threads/malloc.h"
  14. #include "threads/thread.h"
  15. #include "threads/vaddr.h"
  16. #include "userprog/pagedir.h"
  17. #include "userprog/process.h"
  18.  
  19. static struct lock filesys_lock;
  20. static void syscall_handler(struct intr_frame *);
  21.  
  22. void syscall_init(void) {
  23.   intr_register_int(0x30, 3, INTR_ON, syscall_handler, "syscall");
  24.   lock_init(&filesys_lock);
  25. }
  26.  
  27. static void syscall_halt(struct intr_frame *f UNUSED, uint32_t *args);
  28. static void syscall_exit(struct intr_frame *f UNUSED, uint32_t *args);
  29. static void syscall_exec(struct intr_frame *f UNUSED, uint32_t *args);
  30. static void syscall_wait(struct intr_frame *f UNUSED, uint32_t *args);
  31. static void syscall_create(struct intr_frame *f UNUSED, uint32_t *args);
  32. static void syscall_remove(struct intr_frame *f UNUSED, uint32_t *args);
  33. static void syscall_open(struct intr_frame *f UNUSED, uint32_t *args);
  34. static void syscall_filesize(struct intr_frame *f UNUSED, uint32_t *args);
  35. static void syscall_read(struct intr_frame *f UNUSED, uint32_t *args);
  36. static void syscall_write(struct intr_frame *f UNUSED, uint32_t *args);
  37. static void syscall_seek(struct intr_frame *f UNUSED, uint32_t *args);
  38. static void syscall_tell(struct intr_frame *f UNUSED, uint32_t *args);
  39. static void syscall_close(struct intr_frame *f UNUSED, uint32_t *args);
  40. static void syscall_practice(struct intr_frame *f UNUSED, uint32_t *args);
  41.  
  42. typedef void (*syscall_func_t)(struct intr_frame *f UNUSED, uint32_t *args);
  43.  
  44. syscall_func_t syscall_func_arr[14] = {
  45.     syscall_halt,   syscall_exit,    syscall_exec, syscall_wait,
  46.     syscall_create, syscall_remove,  syscall_open, syscall_filesize,
  47.     syscall_read,   syscall_write,   syscall_seek, syscall_tell,
  48.     syscall_close,  syscall_practice};
  49.  
  50. static void syscall_handler(struct intr_frame *f UNUSED) {
  51.   uint32_t *args = ((uint32_t *)f->esp);
  52.   syscall_func_arr[args[0]](f, args);
  53. }
  54.  
  55. static bool valid_ptr(void *ptr, int size) {
  56.   if (ptr == NULL) return false;
  57.  
  58.   ptr += size - 1;
  59.   if (!is_user_vaddr(ptr)) return false;
  60.   if (pagedir_get_page(thread_current()->pagedir, ptr) == NULL) return false;
  61.  
  62.   return true;
  63. }
  64.  
  65. static void syscall_halt(struct intr_frame *f UNUSED, uint32_t *args) {
  66.   _halt();
  67. }
  68.  
  69. static void syscall_exit(struct intr_frame *f UNUSED, uint32_t *args) {
  70.   _exit(*(int *)(&args[1]));
  71. }
  72.  
  73. static void syscall_exec(struct intr_frame *f UNUSED, uint32_t *args) {
  74.   if (!valid_ptr(args[1], sizeof(char))) {
  75.     _exit(-1);
  76.     NOT_REACHED();
  77.   }
  78.   f->eax = _exec((char *)args[1]);
  79. }
  80.  
  81. static void syscall_wait(struct intr_frame *f UNUSED, uint32_t *args) {
  82.   f->eax = _wait(args[1]);
  83. }
  84.  
  85. static void syscall_create(struct intr_frame *f UNUSED, uint32_t *args) {
  86.   // retrieving file name
  87.   char *cur_arg = args;
  88.   cur_arg += sizeof(void *);
  89.   char *file_name = *((char **)cur_arg);
  90.   // retrieving size
  91.   cur_arg += sizeof(char *);
  92.   off_t sz = *(off_t *)cur_arg;
  93.   // check pointer
  94.   if (!valid_ptr(file_name, sizeof(char))) {
  95.     _exit(-1);
  96.     NOT_REACHED();
  97.   }
  98.  
  99.   f->eax = _create(file_name, sz);
  100. }
  101.  
  102. static void syscall_remove(struct intr_frame *f UNUSED, uint32_t *args) {
  103.   // retrieving file name
  104.   char *cur_arg = args;
  105.   cur_arg += sizeof(void *);
  106.   char *file_name = *((char **)cur_arg);
  107.   // check pointer
  108.   if (!valid_ptr(file_name, sizeof(char))) {
  109.     _exit(-1);
  110.     NOT_REACHED();
  111.   }
  112.  
  113.   f->eax = _remove(file_name);
  114. }
  115.  
  116. static void syscall_open(struct intr_frame *f UNUSED, uint32_t *args) {
  117.   if (!valid_ptr(args[1], sizeof(char))) {
  118.     _exit(-1);
  119.     NOT_REACHED();
  120.   }
  121.   char *file_name = (char *)args[1];
  122.   f->eax = _open(file_name);
  123. }
  124.  
  125. static void syscall_filesize(struct intr_frame *f UNUSED, uint32_t *args) {
  126.   f->eax = _filesize(args[1]);
  127. }
  128.  
  129. static void syscall_read(struct intr_frame *f UNUSED, uint32_t *args) {
  130.   // retrieving fd
  131.   char *cur_arg = args;
  132.   cur_arg += sizeof(void *);
  133.   int fd = *((int *)cur_arg);
  134.   // retrieving buff pointer
  135.   cur_arg += sizeof(int);
  136.   void *buff = *(void **)cur_arg;
  137.  
  138.   // retrieving size
  139.   cur_arg += sizeof(void *);
  140.   off_t sz = *(off_t *)cur_arg;
  141.  
  142.   // check pointer
  143.   if (!valid_ptr(buff, sz)) {
  144.     _exit(-1);
  145.     NOT_REACHED();
  146.   }
  147.  
  148.   f->eax = _read(fd, buff, sz);
  149. }
  150.  
  151. static void syscall_write(struct intr_frame *f UNUSED, uint32_t *args) {
  152.   //  printf("\n write start\n");
  153.   // retrieving fd
  154.   char *cur_arg = args;
  155.   cur_arg += sizeof(void *);
  156.   int fd = *((int *)cur_arg);
  157.   // retrieving buff pointer
  158.   cur_arg += sizeof(int);
  159.   void *buff = *(void **)cur_arg;
  160.  
  161.   // retrieving size
  162.   cur_arg += sizeof(void *);
  163.   off_t sz = *(off_t *)cur_arg;
  164.  
  165.   //   printf ("ppp: %p %d\n", buff, sz);
  166.  
  167.   // check pointer
  168.   if (!valid_ptr(buff, sz)) {
  169.     _exit(-1);
  170.     NOT_REACHED();
  171.   }
  172.  
  173.   f->eax = _write(fd, buff, sz);
  174. }
  175.  
  176. static void syscall_seek(struct intr_frame *f UNUSED, uint32_t *args) {
  177.   // retrieving fd
  178.   char *cur_arg = args;
  179.   cur_arg += sizeof(void *);
  180.   int fd = *((int *)cur_arg);
  181.   // retrieving size
  182.   cur_arg += sizeof(int);
  183.   off_t pos = *(off_t *)cur_arg;
  184.   _seek(fd, pos);
  185. }
  186.  
  187. static void syscall_tell(struct intr_frame *f UNUSED, uint32_t *args) {
  188.   // retrieving fd
  189.   char *cur_arg = args;
  190.   cur_arg += sizeof(void *);
  191.   int fd = *((int *)cur_arg);
  192.   f->eax = _tell(fd);
  193. }
  194.  
  195. static void syscall_close(struct intr_frame *f UNUSED, uint32_t *args) {
  196.   // retrieving fd
  197.   char *cur_arg = args;
  198.   cur_arg += sizeof(void *);
  199.   int fd = *((int *)cur_arg);
  200.   _close(fd);
  201. }
  202.  
  203. static void syscall_practice(struct intr_frame *f UNUSED, uint32_t *args) {
  204.   f->eax = _practice(args[1]);
  205. }
  206.  
  207. int _practice(int i) { return i + 1; }
  208.  
  209. void _halt(void) { shutdown_power_off(); }
  210.  
  211. void _exit(int status) {
  212.   printf("%s: exit(%d)\n", &thread_current()->name, status);
  213.   struct child_info_t *child = get_child_info_t(thread_current());
  214.   if (child != NULL) {
  215.     child->status = status;
  216.   }
  217.   thread_exit();
  218. }
  219.  
  220. pid_t _exec(const char *cmd_line) {
  221.   lock_acquire(&filesys_lock);
  222.   tid_t process_pid = process_execute(cmd_line);
  223.   if (process_pid != TID_ERROR) {
  224.     lock_release(&filesys_lock);
  225.  
  226.     _exit(-1);
  227.   }
  228.   pid_t res = process_pid;
  229.   lock_release(&filesys_lock);
  230.   return res;
  231. }
  232.  
  233. int _wait(pid_t pid) {
  234.   tid_t tid = pid;
  235.   return process_wait(tid);
  236. }
  237.  
  238. bool _create(const char *file, unsigned initial_size) {
  239.   lock_acquire(&filesys_lock);
  240.   bool res = filesys_create(file, initial_size);
  241.   lock_release(&filesys_lock);
  242.   return res;
  243. }
  244.  
  245. bool _remove(const char *file) {
  246.   lock_acquire(&filesys_lock);
  247.   bool res = filesys_remove(file);
  248.   lock_release(&filesys_lock);
  249.   return res;
  250. }
  251.  
  252. int _open(const char *file) {
  253.   struct list *process_files = &(thread_current()->files);
  254.   int new_fd = 0;
  255.  
  256.   if (list_empty(process_files)) {
  257.     new_fd = 2;  // non-standard dscriptors start from 2
  258.   } else {
  259.     struct list_elem *e = list_back(process_files);
  260.     struct file_info_t *front_file_info =
  261.         list_entry(e, struct file_info_t, elem);
  262.     new_fd = front_file_info->fd + 1;
  263.   }
  264.   lock_acquire(&filesys_lock);
  265.   // Get file struct of given path
  266.   struct file *cur_file_data = filesys_open(file);
  267.  
  268.   // Fill our struct members
  269.   struct file_info_t *cur_file_info =
  270.       (struct file_info_t *)malloc(sizeof(struct file_info_t));
  271.   cur_file_info->fd = new_fd;
  272.   cur_file_info->file_data = cur_file_data;
  273.  
  274.   // Add new opened file to list of opened files for this thread
  275.   list_push_front(&(thread_current()->files), &(cur_file_info->elem));
  276.   int res = new_fd;
  277.  
  278.   lock_release(&filesys_lock);
  279.   return res;
  280. }
  281.  
  282. int _filesize(int fd) {
  283.   struct file_info_t *file = get_file_info_t(fd);
  284.   if (file == NULL) {
  285.     return -1;
  286.   }
  287.   lock_acquire(&filesys_lock);
  288.   int res = file_length(file->file_data);
  289.   lock_release(&filesys_lock);
  290.   return res;
  291. }
  292.  
  293. int _read(int fd, void *buffer, unsigned size) {
  294.   if (fd == 0) {
  295.     // TODO: კლავიატურიდან წაკითხვა
  296.     return size;
  297.   }
  298.  
  299.   struct file_info_t *file = get_file_info_t(fd);
  300.  
  301.   if (file == NULL) {
  302.     return -1;
  303.   }
  304.  
  305.   lock_acquire(&filesys_lock);
  306.   int res = file_read(file->file_data, buffer, size);
  307.   lock_release(&filesys_lock);
  308.   return res;
  309. }
  310.  
  311. int _write(int fd, const void *buffer, unsigned size) {
  312.   if (fd == 1) {
  313.     putbuf(buffer, size);
  314.     //  printf("\n write :   %s\n", buff);
  315.     return size;
  316.   }
  317.  
  318.   struct file_info_t *file = get_file_info_t(fd);
  319.  
  320.   if (file == NULL) {
  321.     return -1;
  322.   }
  323.  
  324.   lock_acquire(&filesys_lock);
  325.   int res = file_write(file->file_data, buffer, size);
  326.   lock_release(&filesys_lock);
  327.   return res;
  328. }
  329.  
  330. void _seek(int fd, unsigned position) {
  331.   struct file_info_t *file = get_file_info_t(fd);
  332.   if (file == NULL) {
  333.     return;
  334.   }
  335.  
  336.   lock_acquire(&filesys_lock);
  337.   file_seek(file->file_data, position);
  338.   lock_release(&filesys_lock);
  339. }
  340.  
  341. unsigned _tell(int fd) {
  342.   struct file_info_t *file = get_file_info_t(fd);
  343.   if (file == NULL) {
  344.     return -1;
  345.   }
  346.   lock_acquire(&filesys_lock);
  347.   unsigned res = file_tell(file->file_data);
  348.   lock_release(&filesys_lock);
  349.   return res;
  350. }
  351.  
  352. void _close(int fd) {
  353.   struct file_info_t *file = get_file_info_t(fd);
  354.   if (file == NULL) {
  355.     return;
  356.     NOT_REACHED();
  357.   }
  358.   lock_acquire(&filesys_lock);
  359.   file_close(file->file_data);
  360.   lock_release(&filesys_lock);
  361. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement