blob: caf7153236c0caffe2c3ad7ceffc3c629c966548 [file] [log] [blame]
/*
* We assume there's only one error buffer for the whole system.
* If you use ffork, you need to provide a _syserrstr. Since most
* people will use libthread (which provides a _syserrstr), this is
* okay.
*/
#include <u.h>
#include <errno.h>
#include <string.h>
#include <libc.h>
enum
{
EPLAN9 = 0x19283745
};
char *(*_syserrstr)(void);
static char xsyserr[ERRMAX];
static char*
getsyserr(void)
{
char *s;
s = nil;
if(_syserrstr)
s = (*_syserrstr)();
if(s == nil)
s = xsyserr;
return s;
}
int
errstr(char *err, uint n)
{
char tmp[ERRMAX];
char *syserr;
strecpy(tmp, tmp+ERRMAX, err);
rerrstr(err, n);
syserr = getsyserr();
strecpy(syserr, syserr+ERRMAX, tmp);
errno = EPLAN9;
return 0;
}
void
rerrstr(char *err, uint n)
{
char *syserr;
syserr = getsyserr();
if(errno == EINTR)
strcpy(syserr, "interrupted");
else if(errno != EPLAN9)
strcpy(syserr, strerror(errno));
strecpy(err, err+n, syserr);
}
/* replaces __errfmt in libfmt */
int
__errfmt(Fmt *f)
{
if(errno == EPLAN9)
return fmtstrcpy(f, getsyserr());
return fmtstrcpy(f, strerror(errno));
}
void
werrstr(char *fmt, ...)
{
va_list arg;
char buf[ERRMAX];
va_start(arg, fmt);
vseprint(buf, buf+ERRMAX, fmt, arg);
va_end(arg);
errstr(buf, ERRMAX);
}