Add the helper strtoul_from_ubuf()
authorBarret Rhoden <brho@cs.berkeley.edu>
Wed, 13 Apr 2016 15:46:49 +0000 (11:46 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 15 Apr 2016 14:29:13 +0000 (10:29 -0400)
This comes up a lot: we want to read a number from a user buffer.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/drivers/dev/alarm.c
kern/include/ns.h
kern/src/ns/util.c

index a917937..55d571a 100644 (file)
@@ -367,7 +367,6 @@ static long alarmread(struct chan *c, void *ubuf, long n, int64_t offset)
  * proc_alarm. */
 static long alarmwrite(struct chan *c, void *ubuf, long n, int64_t unused)
 {
-       char num64[NUMSIZE64];
        struct proc_alarm *p_alarm;
        uint64_t hexval;
 
@@ -377,16 +376,7 @@ static long alarmwrite(struct chan *c, void *ubuf, long n, int64_t unused)
                case Qctl:
                        error(EPERM, ERROR_FIXME);
                case Qtimer:
-                       /* want to give strtoul a null-terminated buf (can't handle random
-                        * user strings) */
-                       if (n > sizeof(num64)) {
-                               set_errno(EINVAL);
-                               error(EFAIL, "attempted to write %d chars, max %d", n,
-                                         sizeof(num64));
-                       }
-                       memcpy(num64, ubuf, n);
-                       num64[n] = 0;   /* enforce trailing 0 */
-                       hexval = strtoul(num64, 0, 16);
+                       hexval = strtoul_from_ubuf(ubuf, n, 16);
                        p_alarm = QID2A(c->qid);
                        if (hexval) {
                                /* if you don't know if it was running or not, resetting will
index 44855aa..4f072a5 100644 (file)
@@ -852,6 +852,7 @@ int readnum(unsigned long off, char *buf, unsigned long n, unsigned long val,
                        size_t size);
 int readstr(unsigned long offset, char *buf, unsigned long n, char *str);
 int readnum_int64_t(uint32_t, char *unused_char_p_t, uint32_t, int64_t, int);
+unsigned long strtoul_from_ubuf(void *ubuf, size_t count, int base);
 void ready(struct proc *);
 void renameproguser(char *unused_char_p_t, char *);
 void renameuser(char *unused_char_p_t, char *);
index 8f5c373..633d752 100644 (file)
@@ -2,6 +2,8 @@
 
 #include <ns.h>
 #include <string.h>
+#include <err.h>
+#include <syscall.h>
 
 /* Copies n bytes from mem + offset into buf, similar to a read() call. */
 int readmem(unsigned long offset, char *buf, unsigned long n,
@@ -36,6 +38,22 @@ int readstr(unsigned long offset, char *buf, unsigned long n, char *str)
        return readmem(offset, buf, n, str, strlen(str) + 1);
 }
 
+/* Helper: extracts a long from a user buffer (in text). */
+unsigned long strtoul_from_ubuf(void *ubuf, size_t count, int base)
+{
+       char num64[NUMSIZE64];
+
+       /* want to give strtoul a null-terminated buf (can't handle random
+        * user strings) */
+       if (count > sizeof(num64)) {
+               set_errno(EINVAL);
+               error(EFAIL, "attempted to write %d chars, max %d", count,
+                         sizeof(num64)); }
+       memcpy(num64, ubuf, count);
+       num64[count] = 0;       /* enforce trailing 0 */
+       return strtoul(num64, 0, base);
+}
+
 /* Converts open mode flags, e.g. O_RDWR, to a rwx------ value, e.g. S_IRUSR */
 int omode_to_rwx(int open_flags)
 {