Advertisement
Guest User

Untitled

a guest
Dec 16th, 2019
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.25 KB | None | 0 0
  1. #include "userprog/syscall.h"
  2. #include <stdio.h>
  3. #include <syscall-nr.h>
  4. #include "threads/interrupt.h"
  5. #include "threads/thread.h"
  6.  
  7. //my
  8. #include "threads/vaddr.h"
  9. #include "lib/kernel/list.h"
  10. #include "lib/string.h"
  11. #include "process.h"
  12. #include "threads/synch.h"
  13. #include "userprog/pagedir.h"
  14. #include "filesys/filesys.h"
  15. #include "filesys/file.h"
  16. #include "lib/string.h"
  17. #include "lib/kernel/stdio.h"
  18. #include "devices/input.h"
  19.  
  20. #define MAX_OPEN_FILES 128
  21. static struct file* open_files[MAX_OPEN_FILES];
  22. static int open_files_cnt;
  23.  
  24. static struct lock file_lock;
  25. //end my
  26.  
  27. static void syscall_handler (struct intr_frame*);
  28. bool bad_ptr(void* ptr);
  29. bool is_open(struct file* file);
  30. void sys_exit(int exit_code);
  31. struct file* find_file_by_fd(int fd);
  32.  
  33. void SHOW_OPEN_FILES()
  34. {
  35.   printf("Open files: ");
  36.   for (int i = 0; i < open_files_cnt; ++i) {
  37.     printf("%x ", open_files[i]);
  38.   }
  39.   printf("\n");
  40. }
  41.  
  42. void
  43. syscall_init (void)
  44. {
  45.   intr_register_int (0x30, 3, INTR_ON, syscall_handler, "syscall");
  46.  
  47.   //my
  48.   lock_init(&file_lock);
  49.   for (int i = 0; i < MAX_OPEN_FILES; ++i) {
  50.     open_files[i] = NULL;
  51.   }
  52.   open_files_cnt = 2;
  53.   //end my
  54. }
  55.  
  56. static void
  57. syscall_handler (struct intr_frame *f)
  58. {
  59.   //my
  60.   //printf("syscall_handler --> ");
  61.  
  62.   void* esp = f->esp;
  63.   int syscall_number = *(int*)esp;
  64.  
  65.   if (syscall_number == SYS_EXIT) {
  66.     int exit_status = *(int*)(esp + 4);
  67.     sys_exit(exit_status);
  68.   }
  69.  
  70.   else if (syscall_number == SYS_EXEC) {
  71.     //printf("SYS_EXEC\n");
  72.     char* cmd = *(char**)(esp + 4);
  73.  
  74.     if (bad_ptr(cmd)) {
  75.       f->eax = -1;
  76.       return;
  77.     }
  78.    
  79.     lock_acquire(&file_lock);
  80.     f->eax = process_execute(cmd);
  81.     lock_release(&file_lock);
  82.  
  83.     return;
  84.   }
  85.  
  86.   else if (syscall_number == SYS_WAIT) {
  87.     //printf("SYS_WAIT\n");
  88.  
  89.     tid_t tid = *(int*)(esp + 4);
  90.     f->eax = process_wait(tid);
  91.     return;
  92.   }
  93.  
  94.   else if (syscall_number == SYS_CREATE) {
  95.     char* file_name = *(char**)(esp + 4);
  96.     uint32_t size = *(uint32_t*)(esp + 8);
  97.  
  98.     //printf("sys_create, file_name=%s, size=%d\n", file_name, size);
  99.  
  100.     if (bad_ptr(file_name)) {
  101.       sys_exit(-1);
  102.     }
  103.  
  104.     f->eax = filesys_create (file_name, size);
  105.  
  106.     return;
  107.   }
  108.  
  109.   else if (syscall_number == SYS_OPEN) {
  110.     char* file_name = *(char**)(esp + 4);
  111.     struct file* new_file;
  112.  
  113.     if (bad_ptr(file_name)) {
  114.       sys_exit(-1);
  115.     }
  116.  
  117.     if (file_name[0] == '\0') {
  118.       f->eax = -1;
  119.       return;
  120.     }
  121.  
  122.     new_file = filesys_open(file_name);
  123.  
  124.     if (new_file == NULL) {
  125.       f->eax = -1;
  126.       return;
  127.     }
  128.  
  129.     if (!is_open(new_file)) {
  130.       open_files[open_files_cnt] = new_file;
  131.       open_files_cnt++;
  132.     }
  133.  
  134.     f->eax = open_files_cnt - 1;
  135.     return;
  136.   }
  137.  
  138.   else if (syscall_number == SYS_CLOSE) {
  139.     int fd = *(int*)(esp + 4);
  140.  
  141.     if (fd == 1) {
  142.       sys_exit(-1);
  143.     }
  144.  
  145.     struct file* file = find_file_by_fd(fd);
  146.    
  147.     if (file == NULL) {
  148.       sys_exit(-1);
  149.     }
  150.  
  151.     file_close(file);
  152.     open_files[fd] = NULL;
  153.  
  154.     return;
  155.   }
  156.  
  157.   else if (syscall_number == SYS_FILESIZE) {
  158.     int fd = *(int*)(esp + 4);
  159.  
  160.     //printf("SYS file size, fd=%d\n", fd);
  161.  
  162.     struct file* file = find_file_by_fd(fd);
  163.  
  164.     if (file == NULL) {
  165.       sys_exit(-1);
  166.     }
  167.  
  168.     f->eax = file_length(file);
  169.    
  170.     return;
  171.   }
  172.  
  173.   else if (syscall_number == SYS_READ) {
  174.     int fd = *(int*)(esp + 4);
  175.     void* buffer = *(void**)(esp + 8);
  176.     unsigned int size = *(unsigned int*)(esp + 12);
  177.  
  178.     //printf("SYS_read, fd=%d, buf=%x, size=%d\n", fd, buffer, size);
  179.  
  180.     if (bad_ptr(buffer) || fd == 1) {
  181.       sys_exit(-1);
  182.     }
  183.  
  184.     if (fd == 0) {
  185.       input_getc();
  186.       return;
  187.     }
  188.  
  189.     struct file* file_to_write;
  190.     file_to_write = find_file_by_fd(fd);
  191.  
  192.     if (file_to_write == NULL) {
  193.       sys_exit(-1);
  194.     }
  195.  
  196.     lock_acquire(&file_lock);
  197.     f->eax = file_read(file_to_write, buffer, size);
  198.     lock_release(&file_lock);
  199.    
  200.     return;
  201.   }
  202.  
  203.   else if (syscall_number == SYS_WRITE) {
  204.     int fd = *(int*)(esp + 4);
  205.     void* buffer = *(void**)(esp + 8);
  206.     unsigned int size = *(unsigned int*)(esp + 12);
  207.  
  208.     //printf("SYS_WRITE, fd=%d, buf=%x, size=%d\n", fd, buffer, size);
  209.  
  210.     if (bad_ptr(buffer) || fd == 0) {
  211.       sys_exit(-1);
  212.     }
  213.  
  214.     if (fd == 1) {
  215.       putbuf(buffer, size);
  216.       return;
  217.     }
  218.  
  219.     struct file* file_to_write;
  220.     file_to_write = find_file_by_fd(fd);
  221.  
  222.     if (file_to_write == NULL) {
  223.       sys_exit(-1);
  224.     }
  225.  
  226.     lock_acquire(&file_lock);
  227.     f->eax = file_write(file_to_write, buffer, size);
  228.     lock_release(&file_lock);
  229.    
  230.     return;
  231.   }
  232.   //end my
  233.  
  234.   printf ("system call %d!\n", syscall_number);
  235.   thread_exit ();
  236. }
  237.  
  238. bool bad_ptr (void* ptr)
  239. {
  240.   return (ptr == NULL) || (!is_user_vaddr (ptr)) || (pagedir_get_page(thread_current()->pagedir, ptr) == NULL);
  241. }
  242.  
  243. bool is_open(struct file* file)
  244. {
  245.   for (int i = 0; i < open_files_cnt; ++i) {
  246.     if (open_files[i] == file) {
  247.       return true;
  248.     }
  249.   }
  250.  
  251.   return false;
  252. }
  253.  
  254. void sys_exit(int exit_code)
  255. {
  256.   thread_current()->exit_status = exit_code;
  257.   thread_exit();
  258. }
  259.  
  260. struct file* find_file_by_fd(int fd)
  261. {
  262.   if (fd >= MAX_OPEN_FILES) {
  263.     return NULL;
  264.   }
  265.  
  266.   return open_files[fd];
  267. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement