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