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 most4 * people will use libthread (which provides a _syserrstr), this is5 * okay.6 */8 #include <u.h>9 #include <errno.h>10 #include <string.h>11 #include <libc.h>13 enum14 {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 int34 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 void51 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 int64 __errfmt(Fmt *f)65 {66 if(errno == EPLAN9)67 return fmtstrcpy(f, getsyserr());68 return fmtstrcpy(f, strerror(errno));69 }71 void72 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 }