aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2021-07-09 22:29:55 -0400
committerDavid Robillard <d@drobilla.net>2022-01-13 23:03:49 -0500
commitcc03e614b22b5695a1bbe0bedebd1bf0cf284bf7 (patch)
treee77be535c4dae3c9edade87492e0d0a297d62c9a
parentbf4f881c2241fa8ae6459bd9c8ee6cc83ee563a9 (diff)
downloadserd-cc03e614b22b5695a1bbe0bedebd1bf0cf284bf7.tar.gz
serd-cc03e614b22b5695a1bbe0bedebd1bf0cf284bf7.tar.bz2
serd-cc03e614b22b5695a1bbe0bedebd1bf0cf284bf7.zip
Use thread-safe strerror_r() if available
-rw-r--r--src/serd_config.h13
-rw-r--r--src/system.c14
-rw-r--r--src/system.h4
-rw-r--r--src/world.c12
4 files changed, 37 insertions, 6 deletions
diff --git a/src/serd_config.h b/src/serd_config.h
index 7f58696e..d5a6db33 100644
--- a/src/serd_config.h
+++ b/src/serd_config.h
@@ -67,6 +67,13 @@
# endif
# endif
+// POSIX.1-2001: strerror_r()
+# ifndef HAVE_STRERROR_R
+# if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L
+# define HAVE_STRERROR_R
+# endif
+# endif
+
#endif // !defined(SERD_NO_DEFAULT_CONFIG)
/*
@@ -95,4 +102,10 @@
# define USE_POSIX_MEMALIGN 0
#endif
+#ifdef HAVE_STRERROR_R
+# define USE_STRERROR_R 1
+#else
+# define USE_STRERROR_R 0
+#endif
+
#endif // SERD_CONFIG_H
diff --git a/src/system.c b/src/system.c
index 76a39ad2..4a70c204 100644
--- a/src/system.c
+++ b/src/system.c
@@ -27,6 +27,20 @@
#include <stdlib.h>
#include <string.h>
+int
+serd_system_strerror(const int errnum, char* const buf, const size_t buflen)
+{
+#if USE_STRERROR_R
+ return strerror_r(errnum, buf, buflen);
+
+#else // Not thread-safe, but... oh well?
+ const char* const message = strerror(errnum);
+
+ strncpy(buf, message, buflen);
+ return 0;
+#endif
+}
+
void*
serd_malloc_aligned(const size_t alignment, const size_t size)
{
diff --git a/src/system.h b/src/system.h
index ff8ec7c0..dbff890a 100644
--- a/src/system.h
+++ b/src/system.h
@@ -22,6 +22,10 @@
#include <stdint.h>
#include <stdio.h>
+/// Write the message for a system error code (like errno) to a buffer
+int
+serd_system_strerror(int errnum, char* buf, size_t buflen);
+
/// Allocate a buffer aligned to `alignment` bytes
SERD_I_MALLOC_FUNC
void*
diff --git a/src/world.c b/src/world.c
index 71fd32c8..e14a04c9 100644
--- a/src/world.c
+++ b/src/world.c
@@ -17,6 +17,7 @@
#include "world.h"
#include "serd_config.h"
+#include "system.h"
#if defined(USE_POSIX_FADVISE)
# include <fcntl.h>
@@ -26,18 +27,17 @@
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
FILE*
serd_world_fopen(SerdWorld* world, const char* path, const char* mode)
{
FILE* fd = fopen(path, mode);
if (!fd) {
- serd_world_errorf(world,
- SERD_ERR_INTERNAL,
- "failed to open file %s (%s)\n",
- path,
- strerror(errno));
+ char message[1024] = {0};
+ serd_system_strerror(errno, message, sizeof(message));
+
+ serd_world_errorf(
+ world, SERD_ERR_INTERNAL, "failed to open file %s (%s)\n", path, message);
return NULL;
}