aboutsummaryrefslogtreecommitdiff
path: root/src/lib9/errstr.c
blob: e576b12bcfd98fde5c800ae68d3a43f4cdca2255 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/*
 * 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 <errno.h>
#include <string.h>
#include <lib9.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;

	syserr = getsyserr();
	if(errno != EPLAN9)
		strcpy(syserr, strerror(errno));

	strecpy(tmp, tmp+ERRMAX, syserr);
	strecpy(syserr, syserr+ERRMAX, err);
	strecpy(err, err+n, tmp);
	errno = EPLAN9;
	return 0;
}

void
rerrstr(char *err, uint n)
{
	char *syserr;

	syserr = getsyserr();
	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));
}