+/* Taken from Drepper: How to write shared libraries, Appendix B. */
+#include <stddef.h>
+#define MSGSTRFIELD(line) MSGSTRFIELD1(line)
+#define MSGSTRFIELD1(line) str##line
+static const union msgstr_t {
+ struct {
+#define _S(n, s) char MSGSTRFIELD(__LINE__)[sizeof(s)];
+#include "errtab.h"
+#undef _S
+ };
+ char str[0];
+} msgstr = { {
+#define _S(n, s) s,
+#include "errtab.h"
+#undef _S
+} };
+static const unsigned int errmsgidx[] = {
+#define _S(n, s) [n] = offsetof(union msgstr_t, MSGSTRFIELD(__LINE__)),
+#include "errtab.h"
+#undef _S
+};
+
+__export const char *osl_strerror(int num)
+{
+ if (IS_SYSTEM_ERROR(num))
+ return strerror((num) & ((1 << SYSTEM_ERROR_BIT) - 1));
+ return msgstr.str + errmsgidx[num];
+}
+
+static int loglevel;
+
+static void __attribute ((constructor)) init_loglevel(void)
+{
+ char *p = getenv("OSL_LOGLEVEL");
+
+ /* don't log anything if unset */
+ loglevel = p? atoi(p) : EMERG + 1;
+}
+