* more re-work
[mascara-docs.git] / i386 / junos / MIT / course / src / src.lab / lib / file.c
blob4755e62a6da9454330c7a8363965a14b1e2c1fd4
1 #include <inc/fs.h>
2 #include <inc/string.h>
3 #include <inc/lib.h>
5 #define debug 0
7 union Fsipc fsipcbuf __attribute__((aligned(PGSIZE)));
9 // Send an inter-environment request to the file server, and wait for
10 // a reply. The request body should be in fsipcbuf, and parts of the
11 // response may be written back to fsipcbuf.
12 // type: request code, passed as the simple integer IPC value.
13 // dstva: virtual address at which to receive reply page, 0 if none.
14 // Returns result from the file server.
15 static int
16 fsipc(unsigned type, void *dstva)
18 static envid_t fsenv;
19 if (fsenv == 0)
20 fsenv = ipc_find_env(ENV_TYPE_FS);
22 static_assert(sizeof(fsipcbuf) == PGSIZE);
24 if (debug)
25 cprintf("[%08x] fsipc %d %08x\n", thisenv->env_id, type, *(uint32_t *)&fsipcbuf);
27 ipc_send(fsenv, type, &fsipcbuf, PTE_P | PTE_W | PTE_U);
28 return ipc_recv(NULL, dstva, NULL);
31 static int devfile_flush(struct Fd *fd);
32 static ssize_t devfile_read(struct Fd *fd, void *buf, size_t n);
33 static ssize_t devfile_write(struct Fd *fd, const void *buf, size_t n);
34 static int devfile_stat(struct Fd *fd, struct Stat *stat);
35 static int devfile_trunc(struct Fd *fd, off_t newsize);
37 struct Dev devfile =
39 .dev_id = 'f',
40 .dev_name = "file",
41 .dev_read = devfile_read,
42 .dev_write = devfile_write,
43 .dev_close = devfile_flush,
44 .dev_stat = devfile_stat,
45 .dev_trunc = devfile_trunc
48 // Open a file (or directory).
50 // Returns:
51 // The file descriptor index on success
52 // -E_BAD_PATH if the path is too long (>= MAXPATHLEN)
53 // < 0 for other errors.
54 int
55 open(const char *path, int mode)
57 // Find an unused file descriptor page using fd_alloc.
58 // Then send a file-open request to the file server.
59 // Include 'path' and 'omode' in request,
60 // and map the returned file descriptor page
61 // at the appropriate fd address.
62 // FSREQ_OPEN returns 0 on success, < 0 on failure.
64 // (fd_alloc does not allocate a page, it just returns an
65 // unused fd address. Do you need to allocate a page?)
67 // Return the file descriptor index.
68 // If any step after fd_alloc fails, use fd_close to free the
69 // file descriptor.
71 // LAB 5: Your code here.
72 panic("open not implemented");
75 // Flush the file descriptor. After this the fileid is invalid.
77 // This function is called by fd_close. fd_close will take care of
78 // unmapping the FD page from this environment. Since the server uses
79 // the reference counts on the FD pages to detect which files are
80 // open, unmapping it is enough to free up server-side resources.
81 // Other than that, we just have to make sure our changes are flushed
82 // to disk.
83 static int
84 devfile_flush(struct Fd *fd)
86 fsipcbuf.flush.req_fileid = fd->fd_file.id;
87 return fsipc(FSREQ_FLUSH, NULL);
90 // Read at most 'n' bytes from 'fd' at the current position into 'buf'.
92 // Returns:
93 // The number of bytes successfully read.
94 // < 0 on error.
95 static ssize_t
96 devfile_read(struct Fd *fd, void *buf, size_t n)
98 // Make an FSREQ_READ request to the file system server after
99 // filling fsipcbuf.read with the request arguments. The
100 // bytes read will be written back to fsipcbuf by the file
101 // system server.
102 // LAB 5: Your code here
103 panic("devfile_read not implemented");
106 // Write at most 'n' bytes from 'buf' to 'fd' at the current seek position.
108 // Returns:
109 // The number of bytes successfully written.
110 // < 0 on error.
111 static ssize_t
112 devfile_write(struct Fd *fd, const void *buf, size_t n)
114 // Make an FSREQ_WRITE request to the file system server. Be
115 // careful: fsipcbuf.write.req_buf is only so large, but
116 // remember that write is always allowed to write *fewer*
117 // bytes than requested.
118 // LAB 5: Your code here
119 panic("devfile_write not implemented");
122 static int
123 devfile_stat(struct Fd *fd, struct Stat *st)
125 int r;
127 fsipcbuf.stat.req_fileid = fd->fd_file.id;
128 if ((r = fsipc(FSREQ_STAT, NULL)) < 0)
129 return r;
130 strcpy(st->st_name, fsipcbuf.statRet.ret_name);
131 st->st_size = fsipcbuf.statRet.ret_size;
132 st->st_isdir = fsipcbuf.statRet.ret_isdir;
133 return 0;
136 // Truncate or extend an open file to 'size' bytes
137 static int
138 devfile_trunc(struct Fd *fd, off_t newsize)
140 fsipcbuf.set_size.req_fileid = fd->fd_file.id;
141 fsipcbuf.set_size.req_size = newsize;
142 return fsipc(FSREQ_SET_SIZE, NULL);
145 // Delete a file
147 remove(const char *path)
149 if (strlen(path) >= MAXPATHLEN)
150 return -E_BAD_PATH;
151 strcpy(fsipcbuf.remove.req_path, path);
152 return fsipc(FSREQ_REMOVE, NULL);
155 // Synchronize disk with buffer cache
157 sync(void)
159 // Ask the file server to update the disk
160 // by writing any dirty blocks in the buffer cache.
162 return fsipc(FSREQ_SYNC, NULL);