blob: caf7153236c0caffe2c3ad7ceffc3c629c966548 [file] [log] [blame]
rscb2cfc4e2003-09-30 17:47:41 +00001/*
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 */
7
rsc8ad51792004-03-25 23:03:57 +00008#include <u.h>
rscb2cfc4e2003-09-30 17:47:41 +00009#include <errno.h>
10#include <string.h>
rsc8ad51792004-03-25 23:03:57 +000011#include <libc.h>
rscb2cfc4e2003-09-30 17:47:41 +000012
13enum
14{
rsccbeb0b22006-04-01 19:24:03 +000015 EPLAN9 = 0x19283745
rscb2cfc4e2003-09-30 17:47:41 +000016};
17
18char *(*_syserrstr)(void);
19static char xsyserr[ERRMAX];
20static char*
21getsyserr(void)
22{
23 char *s;
24
25 s = nil;
26 if(_syserrstr)
27 s = (*_syserrstr)();
28 if(s == nil)
29 s = xsyserr;
30 return s;
31}
32
33int
34errstr(char *err, uint n)
35{
36 char tmp[ERRMAX];
37 char *syserr;
38
rsc66c10f02005-01-04 22:18:54 +000039 strecpy(tmp, tmp+ERRMAX, err);
40 rerrstr(err, n);
rscb2cfc4e2003-09-30 17:47:41 +000041 syserr = getsyserr();
rsc66c10f02005-01-04 22:18:54 +000042 strecpy(syserr, syserr+ERRMAX, tmp);
rscb2cfc4e2003-09-30 17:47:41 +000043 errno = EPLAN9;
44 return 0;
45}
46
47void
48rerrstr(char *err, uint n)
49{
50 char *syserr;
51
52 syserr = getsyserr();
rsc66c10f02005-01-04 22:18:54 +000053 if(errno == EINTR)
54 strcpy(syserr, "interrupted");
55 else if(errno != EPLAN9)
rscb2cfc4e2003-09-30 17:47:41 +000056 strcpy(syserr, strerror(errno));
57 strecpy(err, err+n, syserr);
58}
59
60/* replaces __errfmt in libfmt */
61
62int
63__errfmt(Fmt *f)
64{
65 if(errno == EPLAN9)
66 return fmtstrcpy(f, getsyserr());
67 return fmtstrcpy(f, strerror(errno));
68}
rsc169aba12003-10-14 02:10:47 +000069
70void
71werrstr(char *fmt, ...)
72{
73 va_list arg;
74 char buf[ERRMAX];
75
76 va_start(arg, fmt);
77 vseprint(buf, buf+ERRMAX, fmt, arg);
78 va_end(arg);
79 errstr(buf, ERRMAX);
80}
rscfd04aac2003-11-23 18:12:54 +000081