/* Copyright (C) 1996 Robert de Bath <robert@debath.thenet.co.uk>\r
* This file is part of the Linux-8086 C library and is distributed\r
* under the GNU Library General Public License.\r
+ *\r
+ * Rewritten by Alan Cox to use a binary file format and save a lot of space\r
*/ \r
#include <unistd.h>\r
#include <string.h>\r
#include <stdlib.h>\r
#include <paths.h>\r
#include <errno.h>\r
+#include <fcntl.h>\r
\r
-char **__sys_errlist = 0;
-int __sys_nerr = 0;
+static uint8_t *__sys_errlist;
+static uint16_t *__sys_errptr;
+static int __sys_nerr;
+static char retbuf[80];
\r
+static void _load_errlist(void)\r
+{\r
+ struct stat st;\r
+ int fd = open(_PATH_LIBERR, O_RDONLY);\r
+ if (fd < 0)\r
+ return;\r
+ if (fstat(fd, &st) < 0 || !S_ISREG(st.st_mode))\r
+ goto bad;\r
+ __sys_errlist = sbrk((st.st_size + 3)&~3);\r
+ if (__sys_errlist == (void *) -1)\r
+ goto bad;\r
+ if (read(fd,__sys_errlist, st.st_size) == st.st_size) {\r
+ __sys_nerr = *__sys_errlist;\r
+ __sys_errptr = (uint16_t *)__sys_errlist + 2;\r
+ close(fd);\r
+ return;\r
+ }\r
+bad:\r
+ close(fd);\r
+ __sys_errlist = NULL;\r
+ return;\r
+}\r
+ \r
char *strerror(int err) \r
-{
- static char retbuf[80];
- char *p, inbuf[128];
- int cc, fd;
- uint i, bufoff = 0;
- if (__sys_nerr) { /* sys_errlist preloaded */
- if (err < 0 || err >= __sys_nerr)
- goto UErr;
- return __sys_errlist[err];
- }
- if (err <= 0)
- goto UErr; /* NB the <= allows comments in the file */
- if ((fd = open(_PATH_LIBERR, 0)) < 0)
- goto UErr;
- while ((cc = read(fd, inbuf, sizeof(inbuf))) > 0) {
- i = 0;
- while (i < cc) {
- if (inbuf[i] == '\n') {
- retbuf[bufoff] = '\0';
- if (err == atoi(retbuf)) {
- if ((p = strchr(retbuf,' ')) == NULL) {
- close(fd);
- goto UErr;
- }
- while (*p == ' ')
- p++;
- close(fd);
- return p;
- }
- bufoff = 0;
- }
- else if (bufoff < sizeof(retbuf) - 1)
- retbuf[bufoff++] = inbuf[i];
- ++i;
- }
- }
-UErr: strcpy(retbuf, "Unknown error ");\r
- strncat(retbuf, _itoa(err), 10);
+{\r
+\r
+ if (!__sys_errlist)\r
+ _load_errlist();\r
+ if (__sys_errlist && err >= 0 && err < __sys_nerr)\r
+ return __sys_errlist[__sys_errptr[err]];\r
+ strcpy(retbuf, "Unknown error ");\r
+ strcpy(retbuf + 14, _itoa(err));
return retbuf;
}