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 strecpy(tmp, tmp+ERRMAX, err);
40 rerrstr(err, n);
41 syserr = getsyserr();
42 strecpy(syserr, syserr+ERRMAX, tmp);
43 errno = EPLAN9;
44 return 0;
45 }
47 void
48 rerrstr(char *err, uint n)
49 {
50 char *syserr;
52 syserr = getsyserr();
53 if(errno == EINTR)
54 strcpy(syserr, "interrupted");
55 else 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 }