Convert omode to 9p for devmnt [4/7]
[akaros.git] / kern / src / ns / util.c
1 /* misc utilities for plan9 */
2
3 #include <ns.h>
4 #include <string.h>
5
6 /* Copies n bytes from mem + offset into buf, similar to a read() call. */
7 int readmem(unsigned long offset, char *buf, unsigned long n,
8                         void *mem, size_t mem_len)
9 {
10         if (offset >= mem_len)
11                 return 0;
12         if (offset + n > mem_len)
13                 n = mem_len - offset;
14         memmove(buf, mem + offset, n);
15         return n;
16 }
17
18 /* Read a num/string to user mode, accounting for offset.  Not a huge fan of the
19  * 'size' parameter (the old plan9 users just picked NUMSIZE (12), though they
20  * seem to want to limit it).  */
21 int readnum(unsigned long off, char *buf, unsigned long n, unsigned long val,
22                         size_t size)
23 {
24         char tmp[64];
25         size = MIN(sizeof(tmp), size);
26         /* we really need the %* format. */
27         size = snprintf(tmp, size, "%lu", val);
28         /* size is now strlen, so the rest of this is just like readstr. */
29         /* always include the \0 */
30         return readmem(off, buf, n, tmp, size + 1);
31 }
32
33 int readstr(unsigned long offset, char *buf, unsigned long n, char *str)
34 {
35         /* always include the \0 */
36         return readmem(offset, buf, n, str, strlen(str) + 1);
37 }
38
39 /* Converts open mode flags, e.g. O_RDWR, to a rwx------ value, e.g. S_IRUSR */
40 int omode_to_rwx(int open_flags)
41 {
42         static int rwx_opts[] = { [O_RDWR | O_EXEC] = 0700,
43                                   [O_RDWR] = 0600,
44                                   [O_READ | O_EXEC] = 0500,
45                                   [O_READ] = 0400,
46                                   [O_WRITE | O_EXEC] = 0300,
47                                   [O_WRITE] = 0200,
48                                   [O_EXEC] = 0100 };
49         return rwx_opts[open_flags & O_ACCMODE];
50 }
51
52 /* Converts open mode flags related to permissions, e.g. O_RDWR, to 9p.  It's a
53  * bit ugly, since 9p (according to http://man.cat-v.org/plan_9/5/open) seems to
54  * require that O_EXEC is mutually exclusive with the others.  If someone on
55  * Akaros wants EXEC, we'll just substitute READ. */
56 int omode_to_9p_accmode(int open_flags)
57 {
58         static int acc_opts[] = { [O_RDWR | O_EXEC] = 2,
59                                   [O_WRITE | O_EXEC] = 2,
60                                   [O_READ | O_EXEC] = 0,
61                                   [O_EXEC] = 0,
62                                   [O_RDWR] = 2,
63                                   [O_WRITE] = 1,
64                                   [O_READ] = 0,
65                                   [0] = 0 /* we can't express no permissions */
66                                   };
67         return acc_opts[open_flags & O_ACCMODE];
68 }