1 /* misc utilities for plan9 */
8 /* Copies n bytes from mem + offset into buf, similar to a read() call. */
9 int readmem(unsigned long offset, char *buf, unsigned long n,
10 void *mem, size_t mem_len)
12 if (offset >= mem_len)
14 if (offset + n > mem_len)
16 memmove(buf, mem + offset, n);
20 /* Read a num/string to user mode, accounting for offset. Not a huge fan of the
21 * 'size' parameter (the old plan9 users just picked NUMSIZE (12), though they
22 * seem to want to limit it). */
23 static int __readnum(unsigned long off, char *buf, unsigned long n,
24 unsigned long val, size_t size, const char *fmt)
27 size = MIN(sizeof(tmp), size);
28 /* we really need the %* format. */
29 size = snprintf(tmp, size, fmt, val);
30 /* size is now strlen, so the rest of this is just like readstr. */
31 /* always include the \0 */
32 return readmem(off, buf, n, tmp, size + 1);
35 int readnum(unsigned long off, char *buf, unsigned long n, unsigned long val,
38 return __readnum(off, buf, n, val, size, "%lu");
41 int readnum_hex(unsigned long off, char *buf, unsigned long n,
42 unsigned long val, size_t size)
44 return __readnum(off, buf, n, val, size, "0x%lx");
47 int readstr(unsigned long offset, char *buf, unsigned long n, char *str)
49 /* always include the \0 */
50 return readmem(offset, buf, n, str, strlen(str) + 1);
53 /* Helper: extracts a long from a user buffer (in text). */
54 unsigned long strtoul_from_ubuf(void *ubuf, size_t count, int base)
56 char num64[NUMSIZE64];
58 /* want to give strtoul a null-terminated buf (can't handle random
60 if (count > sizeof(num64)) {
62 error(EFAIL, "attempted to write %d chars, max %d", count,
65 memcpy(num64, ubuf, count);
66 num64[count] = 0; /* enforce trailing 0 */
67 return strtoul(num64, 0, base);
70 /* Converts open mode flags, e.g. O_RDWR, to a rwx------ value, e.g. S_IRUSR */
71 int omode_to_rwx(int open_flags)
73 static int rwx_opts[] = { [O_RDWR | O_EXEC] = 0700,
75 [O_READ | O_EXEC] = 0500,
77 [O_WRITE | O_EXEC] = 0300,
80 return rwx_opts[open_flags & O_ACCMODE];
83 /* Converts open mode flags related to permissions, e.g. O_RDWR, to 9p. It's a
84 * bit ugly, since 9p (according to http://man.cat-v.org/plan_9/5/open) seems to
85 * require that O_EXEC is mutually exclusive with the others. If someone on
86 * Akaros wants EXEC, we'll just substitute READ. */
87 int omode_to_9p_accmode(int open_flags)
89 static int acc_opts[] = { [O_RDWR | O_EXEC] = 2,
90 [O_WRITE | O_EXEC] = 2,
91 [O_READ | O_EXEC] = 0,
96 [0] = 0 /* we can't express no permissions */
98 return acc_opts[open_flags & O_ACCMODE];