errstr.c - 9base - revived minimalist port of Plan 9 userland to Unix | |
git clone git://git.suckless.org/9base | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
errstr.c (1261B) | |
--- | |
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 */ | |
7 | |
8 #include <u.h> | |
9 #include <errno.h> | |
10 #include <string.h> | |
11 #include <libc.h> | |
12 | |
13 enum | |
14 { | |
15 EPLAN9 = 0x19283745 | |
16 }; | |
17 | |
18 char *(*_syserrstr)(void); | |
19 static char xsyserr[ERRMAX]; | |
20 static char* | |
21 getsyserr(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 | |
33 int | |
34 errstr(char *err, uint n) | |
35 { | |
36 char tmp[ERRMAX]; | |
37 char *syserr; | |
38 | |
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 } | |
46 | |
47 void | |
48 rerrstr(char *err, uint n) | |
49 { | |
50 char *syserr; | |
51 | |
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 } | |
59 | |
60 /* replaces __errfmt in libfmt */ | |
61 | |
62 int | |
63 __errfmt(Fmt *f) | |
64 { | |
65 if(errno == EPLAN9) | |
66 return fmtstrcpy(f, getsyserr()); | |
67 return fmtstrcpy(f, strerror(errno)); | |
68 } | |
69 | |
70 void | |
71 werrstr(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 } | |
81 |