Blob


1 /*
2 * We assume there's only one error buffer for the whole system.
3 * If you use ffork, you need to provide a _syserrstr. Since most
4 * people will use libthread (which provides a _syserrstr), this is
5 * okay.
6 */
8 #include <errno.h>
9 #include <string.h>
10 #include <lib9.h>
12 enum
13 {
14 EPLAN9 = 0x19283745,
15 };
17 char *(*_syserrstr)(void);
18 static char xsyserr[ERRMAX];
19 static char*
20 getsyserr(void)
21 {
22 char *s;
24 s = nil;
25 if(_syserrstr)
26 s = (*_syserrstr)();
27 if(s == nil)
28 s = xsyserr;
29 return s;
30 }
32 int
33 errstr(char *err, uint n)
34 {
35 char tmp[ERRMAX];
36 char *syserr;
38 syserr = getsyserr();
39 if(errno != EPLAN9)
40 strcpy(syserr, strerror(errno));
42 strecpy(tmp, tmp+ERRMAX, syserr);
43 strecpy(syserr, syserr+ERRMAX, err);
44 strecpy(err, err+n, tmp);
45 errno = EPLAN9;
46 return 0;
47 }
49 void
50 rerrstr(char *err, uint n)
51 {
52 char *syserr;
54 syserr = getsyserr();
55 if(errno != EPLAN9)
56 strcpy(syserr, strerror(errno));
57 strecpy(err, err+n, syserr);
58 }
60 /* replaces __errfmt in libfmt */
62 int
63 __errfmt(Fmt *f)
64 {
65 if(errno == EPLAN9)
66 return fmtstrcpy(f, getsyserr());
67 return fmtstrcpy(f, strerror(errno));
68 }
70 void
71 werrstr(char *fmt, ...)
72 {
73 va_list arg;
74 char buf[ERRMAX];
76 va_start(arg, fmt);
77 vseprint(buf, buf+ERRMAX, fmt, arg);
78 va_end(arg);
79 errstr(buf, ERRMAX);
80 }