aboutsummaryrefslogtreecommitdiff
path: root/src/lib9/errstr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib9/errstr.c')
-rw-r--r--src/lib9/errstr.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/src/lib9/errstr.c b/src/lib9/errstr.c
new file mode 100644
index 00000000..e576b12b
--- /dev/null
+++ b/src/lib9/errstr.c
@@ -0,0 +1,68 @@
+/*
+ * We assume there's only one error buffer for the whole system.
+ * If you use ffork, you need to provide a _syserrstr. Since most
+ * people will use libthread (which provides a _syserrstr), this is
+ * okay.
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <lib9.h>
+
+enum
+{
+ EPLAN9 = 0x19283745,
+};
+
+char *(*_syserrstr)(void);
+static char xsyserr[ERRMAX];
+static char*
+getsyserr(void)
+{
+ char *s;
+
+ s = nil;
+ if(_syserrstr)
+ s = (*_syserrstr)();
+ if(s == nil)
+ s = xsyserr;
+ return s;
+}
+
+int
+errstr(char *err, uint n)
+{
+ char tmp[ERRMAX];
+ char *syserr;
+
+ syserr = getsyserr();
+ if(errno != EPLAN9)
+ strcpy(syserr, strerror(errno));
+
+ strecpy(tmp, tmp+ERRMAX, syserr);
+ strecpy(syserr, syserr+ERRMAX, err);
+ strecpy(err, err+n, tmp);
+ errno = EPLAN9;
+ return 0;
+}
+
+void
+rerrstr(char *err, uint n)
+{
+ char *syserr;
+
+ syserr = getsyserr();
+ if(errno != EPLAN9)
+ strcpy(syserr, strerror(errno));
+ strecpy(err, err+n, syserr);
+}
+
+/* replaces __errfmt in libfmt */
+
+int
+__errfmt(Fmt *f)
+{
+ if(errno == EPLAN9)
+ return fmtstrcpy(f, getsyserr());
+ return fmtstrcpy(f, strerror(errno));
+}