summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAsbjørn Sloth Tønnesen <ast@2e8.dk>2020-07-22 20:12:38 +0000
committerAsbjørn Sloth Tønnesen <ast@2e8.dk>2020-07-22 20:24:21 +0000
commita9c562c0b8aa9cd3a0cea4169628e96ae7839c43 (patch)
tree4648c6f9edf84f8cfa61af9cc81b084d5d788b06
parent3b7b0d1071af08f20ec567c9c5269fce5e167d8c (diff)
downloadlem-a9c562c0b8aa9cd3a0cea4169628e96ae7839c43.tar.gz
lem-a9c562c0b8aa9cd3a0cea4169628e96ae7839c43.tar.xz
lem-a9c562c0b8aa9cd3a0cea4169628e96ae7839c43.zip
make lem_debug() non-blocking stdout tolerant
Signed-off-by: Asbjørn Sloth Tønnesen <ast@2e8.dk>
-rw-r--r--bin/lem.c55
-rw-r--r--include/lem.h6
2 files changed, 58 insertions, 3 deletions
diff --git a/bin/lem.c b/bin/lem.c
index d1f9747..46143b4 100644
--- a/bin/lem.c
+++ b/bin/lem.c
@@ -37,7 +37,7 @@
#endif
#ifdef NDEBUG
-#define lem_log_error(fmt, ...) fprintf(stderr, fmt "\n", ##__VA_ARGS__)
+#define lem_log_error(fmt, ...) lem_dprintf(STDERR_FILENO, fmt "\n", ##__VA_ARGS__)
#else
#define lem_log_error lem_debug
#endif
@@ -93,6 +93,59 @@ lem_xmalloc(size_t size)
return p;
}
+/* non-blocking tolerant version of dprintf(3) */
+void
+lem_dprintf(int fd, const char *fmt, ...)
+{
+ int size = 0;
+ char *p = NULL;
+ va_list ap;
+ char *pos;
+ ssize_t ret;
+ size_t bytes_left;
+
+ /* Determine required size */
+ va_start(ap, fmt);
+ size = vsnprintf(p, size, fmt, ap);
+ va_end(ap);
+
+ if (size < 0)
+ return;
+
+ size++; /* for '\0' */
+ p = lem_xmalloc(size);
+ if (p == NULL)
+ return;
+
+ va_start(ap, fmt);
+ size = vsnprintf(p, size, fmt, ap);
+ va_end(ap);
+
+ if (size < 0) {
+ free(p);
+ return;
+ }
+
+ pos = p;
+ bytes_left = size;
+ while (bytes_left > 0) {
+ ret = write(fd, pos, bytes_left);
+ if (ret == -1) {
+ /* since this function is only used for debug messages
+ * we prefer sleeping, over missing debug messages */
+ if (errno == EAGAIN || errno == EINTR) {
+ usleep(100);
+ continue;
+ }
+ break;
+ } else {
+ pos += ret;
+ bytes_left -= ret;
+ }
+ }
+ free(p);
+}
+
static int
setsignal(int signal, void (*handler)(int), int flags)
{
diff --git a/include/lem.h b/include/lem.h
index 2b548b8..9277c3e 100644
--- a/include/lem.h
+++ b/include/lem.h
@@ -22,6 +22,7 @@
#include <ev.h>
#include <lua.h>
#include <lauxlib.h>
+#include <unistd.h>
/* Support gcc's __FUNCTION__ for people using other compilers */
#if !defined(__GNUC__) && !defined(__FUNCTION__)
@@ -38,9 +39,9 @@
#define lem_debug(...)
#else
#define lem_debug(fmt, ...) do { \
- printf("%s (%s:%u): " fmt "\n", \
+ lem_dprintf(STDOUT_FILENO, "%s (%s:%u): " fmt "\n", \
__FUNCTION__, __FILE__, __LINE__, ##__VA_ARGS__); \
- fflush(stdout); } while (0)
+ } while (0)
#endif
#if EV_MINPRI == EV_MAXPRI
@@ -72,6 +73,7 @@ void lem_queue(lua_State *T, int nargs);
void lem_exit(int status);
void lem_async_run(struct lem_async *a);
void lem_async_config(int delay, int min, int max);
+void lem_dprintf(int fd, const char *format, ...);
static inline void
lem_async_do(struct lem_async *a,