parlib: Expand our printf hacks
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 26 May 2017 19:23:46 +0000 (15:23 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 26 May 2017 19:56:14 +0000 (15:56 -0400)
The hacked versions of printf() now return values and have a vfprintf()
variant.  Dropbear needed these.

Unfortunately, anyone who tries to printf from signal handlers, which are
currently executed in vcore context for IPC, will need to manually #include
<parlib/stdio.h>.  We might be able to get the regular stdio.h to include
it, but my feeble attempts couldn't get the toolchain to build.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
user/parlib/include/parlib/stdio.h

index 8ed87b5..ac5e517 100644 (file)
@@ -13,6 +13,7 @@
 #include <parlib/assert.h>
 #include <sys/types.h>
 #include <unistd.h>
+#include <stdarg.h>
 
 __BEGIN_DECLS
 
@@ -27,24 +28,37 @@ int akaros_printf(const char *format, ...);
 #define printd(args...) {}
 #endif
 
+static inline int __vc_ctx_vfprintf(FILE *f_stream, const char *format,
+                                    va_list ap)
+{
+       char buf[128];
+       int ret, fd;
+
+       if (f_stream == stdout)
+               fd = 1;
+       else if (f_stream == stderr)
+               fd = 2;
+       else
+               panic("__vc_ctx tried to fprintf to non-std stream!");
+       ret = vsnprintf(buf, sizeof(buf), format, ap);
+       /* Just print whatever we can */
+       ret = MAX(ret, 0);
+       ret = MIN(ret, sizeof(buf));
+       write(fd, buf, ret);
+       return ret;
+}
+
 /* Technically, this is also used by uthreads with notifs disabled. */
-#define __vc_ctx_fprintf(f_stream, ...)                                        \
-do {                                                                           \
-       char buf[128];                                                             \
-       int ret, fd;                                                               \
-                                                                                  \
-       if (f_stream == stdout)                                                    \
-               fd = 1;                                                                \
-       else if (f_stream == stderr)                                               \
-               fd = 2;                                                                \
-       else                                                                       \
-               panic("__vc_ctx tried to fprintf to non-std stream!");                 \
-       ret = snprintf(buf, sizeof(buf), __VA_ARGS__);                             \
-       /* Just print whatever we can */                                           \
-       ret = MAX(ret, 0);                                                         \
-       ret = MIN(ret, sizeof(buf));                                               \
-       write(fd, buf, ret);                                                       \
-} while (0)
+static inline int __vc_ctx_fprintf(FILE *f_stream, const char *format, ...)
+{
+       va_list args;
+       int ret;
+
+       va_start(args, format);
+       __vc_ctx_vfprintf(f_stream, format, args);
+       va_end(args);
+       return ret;
+}
 
 static inline bool __safe_to_printf(void)
 {
@@ -59,26 +73,44 @@ static inline bool __safe_to_printf(void)
        return TRUE;
 }
 
-#define fprintf(f, ...)                                                        \
-do {                                                                           \
+#define vfprintf(f_stream, fmt, ...)                                           \
+({                                                                             \
+       int ret;                                                                   \
+                                                                                  \
        if (__safe_to_printf())                                                    \
-               fprintf(f, __VA_ARGS__);                                               \
+               ret = vfprintf(f_stream, fmt, __VA_ARGS__);                            \
        else                                                                       \
-               __vc_ctx_fprintf(f, __VA_ARGS__);                                      \
-} while (0)
+               ret = __vc_ctx_vfprintf(f_stream, fmt, __VA_ARGS__);                   \
+       ret;                                                                       \
+})
 
+#define fprintf(f_stream, ...)                                                 \
+({                                                                             \
+       int ret;                                                                   \
+                                                                                  \
+       if (__safe_to_printf())                                                    \
+               ret = fprintf(f_stream, __VA_ARGS__);                                  \
+       else                                                                       \
+               ret = __vc_ctx_fprintf(f_stream, __VA_ARGS__);                         \
+       ret;                                                                       \
+})
 
 #define printf(...)                                                            \
-do {                                                                           \
+({                                                                             \
+       int ret;                                                                   \
+                                                                                  \
        if (__safe_to_printf())                                                    \
-               printf(__VA_ARGS__);                                                   \
+               ret = printf(__VA_ARGS__);                                             \
        else                                                                       \
-               __vc_ctx_fprintf(stdout, __VA_ARGS__);                                 \
-} while (0)
+               ret = __vc_ctx_fprintf(stdout, __VA_ARGS__);                           \
+       ret;                                                                       \
+})
 
 #define I_AM_HERE __vc_ctx_fprintf(stderr,                                     \
                                    "PID %d, vcore %d is in %s() at %s:%d\n",   \
                                    getpid(), vcore_id(), __FUNCTION__,         \
                                    __FILE__, __LINE__)
+#define debug_fprintf(f, ...) __vc_ctx_fprintf(f, __VA_ARGS__)
+#define debug_printf(...) __vc_ctx_fprintf(stdout, __VA_ARGS__)
 
 __END_DECLS