Implements werrstr in glibc (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Thu, 1 Jan 2015 23:40:42 +0000 (18:40 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 1 Jan 2015 23:40:42 +0000 (18:40 -0500)
Userspace needs a helper to write errstr.  The kernel's version is
set_errstr().  I left the user's as werrstr, which is the Plan 9 name for the
function.

I put it in glibc, since that manages the errstr code and also uses it (e.g.
openat()).  Finding a place for it was a pain.  Don't try to #include stdio.h
from within errno.c.

Incidentally, the #warning to do this was around a while, but it was a bit of
motivation to get it done (esp as part of the new toolchain).

kern/include/ns.h
kern/src/net/kernel.h
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/Versions
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/bits/errno.h
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/init-first.c
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/openat.c
user/ndblib/include/ndb.h
user/ndblib/read9pmsg.c

index 07c1413..6467ee5 100644 (file)
@@ -875,7 +875,6 @@ uint32_t userpc(void);
 void validname(char *, int);
 void validwstatname(char *);
 int walk(struct chan **, char **unused_char_pp_t, int unused_int, int, int *);
-void werrstr(char *unused_char_p_t, ...);
 void *xalloc(uint32_t);
 void *xallocz(uint32_t, int);
 void xfree(void *);
index 9f927f0..253ad0f 100644 (file)
@@ -7,4 +7,3 @@ extern int kopen(char *, int);
 extern long kread(int, void *, long);
 extern long kseek(int, vlong, int);
 extern long kwrite(int, void *, long);
-extern void kwerrstr(char *, ...);
index e05dcae..7de9fe7 100644 (file)
@@ -6,6 +6,7 @@ libc {
     ros_errstr_loc;
     __errno_location;
     errstr;
+    werrstr;
     ros_syscall_blockon;
     ros_syscall_sync;
     __ros_scp_syscall_blockon;
index 7b61c73..63ee0e8 100644 (file)
@@ -10,6 +10,8 @@ extern char *(*ros_errstr_loc)(void);
 int *__errno_location(void);
 #define errno (*__errno_location())
 char *errstr(void);    /* can't macro, errstr is used internally in libc */
+/* this is defined in init-first.c, but declared here for easy #includes */
+void werrstr(char *fmt, ...);
 
 # ifdef libc_hidden_proto
 libc_hidden_proto(__errno_location_tls)
index a315bb3..13d2dca 100644 (file)
@@ -18,6 +18,7 @@
    02111-1307 USA.  */
 
 #include <stdio.h>
+#include <stdarg.h>
 #include <stdlib.h>
 #include <fcntl.h>
 #include <unistd.h>
@@ -159,3 +160,17 @@ _dl_start (void)
 {
   abort ();
 }
+
+/* There are issues using stdio as part of rtld.  You'll get errors like: 
+ *             multiple definition of `__libc_multiple_libcs'
+ * Some info: https://sourceware.org/ml/libc-hacker/2000-01/msg00170.html
+ * For this reason, I couldn't put this in sysdeps/akaros/errno.c and still use
+ * snprintf.  init-first is a reasonable dumping ground, and is one of the
+ * sources of the multiple_libcs. */
+void werrstr(char *fmt, ...)
+{
+       va_list ap;
+       va_start(ap, fmt);
+       vsnprintf(errstr(), MAX_ERRSTR_LEN, fmt, ap);
+       va_end(ap);
+}
index a0c3646..d3771d1 100644 (file)
@@ -72,8 +72,7 @@ __openat (fd, file, oflag)
        /* TODO: actually implement openat as the primary kernel interface.  for
         * now, only allow absolute or relative-to-CWD paths. */
        if (fd != AT_FDCWD && file[0] != '/') {
-               char openat_err[] = "openat not implemented";
-               memcpy(errstr(), openat_err, MIN(sizeof(openat_err), MAX_ERRSTR_LEN));
+               werrstr("openat not implemented");
                __set_errno (ENOSYS);
                return -1;
        }
index 636d3c8..1e847ad 100755 (executable)
@@ -170,7 +170,6 @@ struct ndbtuple*_ndbparseline(char *cp);
 //void         ndbsetmalloctag(struct ndbtuple*, uintptr_t);
 static inline void             ndbsetmalloctag(struct ndbtuple*t, uintptr_t v){}
 
-static inline void werrstr(char *v, ...){}
 static inline uintptr_t getcallerpc(void *v){return 0;}
 static inline void setmalloctag(void *v){}
 
index a9b1052..7b39e68 100644 (file)
@@ -56,8 +56,7 @@ read9pmsg(int fd, void *abuf, unsigned int n)
 
        len = GBIT32(buf);
        if(len <= BIT32SZ || len > n){
-#warning "implement werrstr in user mode"
-               /*werrstr(*/fprintf(stderr,"bad length in 9P2000 message header");
+               werrstr("bad length in 9P2000 message header");
                return -1;
        }
        len -= BIT32SZ;