lab3 finished
[mit-jos.git] / kern / syscall.c
blob572710653a252a78b3fcc2154993c94940cdf45c
1 /* See COPYRIGHT for copyright information. */
3 #include <inc/x86.h>
4 #include <inc/error.h>
5 #include <inc/string.h>
6 #include <inc/assert.h>
8 #include <kern/env.h>
9 #include <kern/pmap.h>
10 #include <kern/trap.h>
11 #include <kern/syscall.h>
12 #include <kern/console.h>
14 // Print a string to the system console.
15 // The string is exactly 'len' characters long.
16 // Destroys the environment on memory errors.
17 static void
18 sys_cputs(const char *s, size_t len)
20 // Check that the user has permission to read memory [s, s+len).
21 // Destroy the environment if not.
22 // LAB 3: Your code here.
23 user_mem_assert(curenv, (void *)s, len, 0);
25 // Print the string supplied by the user.
26 cprintf("%.*s", len, s);
29 // Read a character from the system console.
30 // Returns the character.
31 static int
32 sys_cgetc(void)
34 int c;
36 // The cons_getc() primitive doesn't wait for a character,
37 // but the sys_cgetc() system call does.
38 while ((c = cons_getc()) == 0)
39 /* do nothing */;
41 return c;
44 // Returns the current environment's envid.
45 static envid_t
46 sys_getenvid(void)
48 return curenv->env_id;
51 // Destroy a given environment (possibly the currently running environment).
53 // Returns 0 on success, < 0 on error. Errors are:
54 // -E_BAD_ENV if environment envid doesn't currently exist,
55 // or the caller doesn't have permission to change envid.
56 static int
57 sys_env_destroy(envid_t envid)
59 int r;
60 struct Env *e;
62 if ((r = envid2env(envid, &e, 1)) < 0)
63 return r;
64 if (e == curenv)
65 cprintf("[%08x] exiting gracefully\n", curenv->env_id);
66 else
67 cprintf("[%08x] destroying %08x\n", curenv->env_id, e->env_id);
68 env_destroy(e);
69 return 0;
72 // Dispatches to the correct kernel function, passing the arguments.
73 int32_t
74 syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
76 // Call the function corresponding to the 'syscallno' parameter.
77 // Return any appropriate return value.
78 // LAB 3: Your code here.
79 int ret = 0;
81 switch (syscallno) {
82 case SYS_cputs:
83 sys_cputs((const char *)a1, (size_t)a2);
84 break;
85 case SYS_cgetc:
86 ret = sys_cgetc();
87 break;
88 case SYS_getenvid:
89 ret = sys_getenvid();
90 break;
91 case SYS_env_destroy:
92 ret = sys_env_destroy((envid_t)a1);
93 break;
94 default:
95 // NSYSCALLS
96 ret = -E_INVAL;
97 break;
100 return ret;