fix O_RDWR bug.
[mit-jos.git] / lib / ipc.c
blobba7e00339c73b2a38a7ca536f5fd76a41f3c08af
1 // User-level IPC library routines
3 #include <inc/lib.h>
4 // Receive a value via IPC and return it.
5 // If 'pg' is nonnull, then any page sent by the sender will be mapped at
6 // that address.
7 // If 'fromenv' is nonnull, then store the IPC sender's envid in *fromenv.
8 // If 'perm' is nonnull, then store the IPC sender's page permission in *perm
9 // (this is nonzero iff a page was successfully transferred to 'pg').
10 // If the system call fails, then store 0 in *fromenv and *perm (if
11 // they're nonnull) and return the error.
13 // Hint:
14 // Use 'env' to discover the value and who sent it.
15 // If 'pg' is null, pass sys_ipc_recv a value that it will understand
16 // as meaning "no page". (Zero is not the right value.)
17 int32_t
18 ipc_recv(envid_t *from_env_store, void *pg, int *perm_store)
20 // LAB 4: Your code here.
21 int r;
23 if (!pg)
24 pg = (void *)USTACKTOP;
26 if ((r = sys_ipc_recv(pg)) < 0) {
27 if (from_env_store)
28 *from_env_store = 0;
29 if (perm_store)
30 *perm_store = 0;
31 return r;
32 } else {
33 if (from_env_store)
34 *from_env_store = env->env_ipc_from;
35 if (perm_store)
36 *perm_store = env->env_ipc_perm;
37 return env->env_ipc_value;
41 // Send 'val' (and 'pg' with 'perm', assuming 'pg' is nonnull) to 'toenv'.
42 // This function keeps trying until it succeeds.
43 // It should panic() on any error other than -E_IPC_NOT_RECV.
45 // Hint:
46 // Use sys_yield() to be CPU-friendly.
47 // If 'pg' is null, pass sys_ipc_recv a value that it will understand
48 // as meaning "no page". (Zero is not the right value.)
49 void
50 ipc_send(envid_t to_env, uint32_t val, void *pg, int perm)
52 // LAB 4: Your code here.
53 int r;
55 while (1) {
56 r = sys_ipc_try_send(to_env, val, pg, perm);
57 if (r >= 0)
58 return;
59 if (r != -E_IPC_NOT_RECV)
60 panic("sys_ipc_try_send error: %e", r);
62 sys_yield();