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 <u.h>
9 #include <errno.h>
10 #include <string.h>
11 #include <libc.h>
13 enum
14 {
15 EPLAN9 = 0x19283745,
16 };
18 char *(*_syserrstr)(void);
19 static char xsyserr[ERRMAX];
20 static char*
21 getsyserr(void)
22 {
23 char *s;
25 s = nil;
26 if(_syserrstr)
27 s = (*_syserrstr)();
28 if(s == nil)
29 s = xsyserr;
30 return s;
31 }
33 int
34 errstr(char *err, uint n)
35 {
36 char tmp[ERRMAX];
37 char *syserr;
39 syserr = getsyserr();
40 if(errno != EPLAN9)
41 strcpy(syserr, strerror(errno));
43 strecpy(tmp, tmp+ERRMAX, syserr);
44 strecpy(syserr, syserr+ERRMAX, err);
45 strecpy(err, err+n, tmp);
46 errno = EPLAN9;
47 return 0;
48 }
50 void
51 rerrstr(char *err, uint n)
52 {
53 char *syserr;
55 syserr = getsyserr();
56 if(errno != EPLAN9)
57 strcpy(syserr, strerror(errno));
58 strecpy(err, err+n, syserr);
59 }
61 /* replaces __errfmt in libfmt */
63 int
64 __errfmt(Fmt *f)
65 {
66 if(errno == EPLAN9)
67 return fmtstrcpy(f, getsyserr());
68 return fmtstrcpy(f, strerror(errno));
69 }
71 void
72 werrstr(char *fmt, ...)
73 {
74 va_list arg;
75 char buf[ERRMAX];
77 va_start(arg, fmt);
78 vseprint(buf, buf+ERRMAX, fmt, arg);
79 va_end(arg);
80 errstr(buf, ERRMAX);
81 }
83 char*
84 gerrstr(void)
85 {
86 char *s;
88 s = getsyserr();
89 if(errno != EPLAN9)
90 strcpy(s, strerror(errno));
91 return s;
92 }