diff options
author | ache <ache@FreeBSD.org> | 2002-08-08 05:51:54 +0000 |
---|---|---|
committer | ache <ache@FreeBSD.org> | 2002-08-08 05:51:54 +0000 |
commit | 3b0ddae36e14f345ddbfb571d2838b236c78d073 (patch) | |
tree | 92e69228cb60dc54efe523b4a60905762797b926 /lib/libc/locale/rune.c | |
parent | a72d8585b7d6c0e0b3cd0824b229a07724c33288 (diff) | |
download | FreeBSD-src-3b0ddae36e14f345ddbfb571d2838b236c78d073.zip FreeBSD-src-3b0ddae36e14f345ddbfb571d2838b236c78d073.tar.gz |
Rewrite locale loading procedures, so any load failure will not affect
currently cached data. It allows a number of nice things, like: removing
fallback code from single locale loading, remove memory leak when LC_CTYPE
data loaded again and again, efficient cache use, not only for
setlocale(locale1); setlocale(locale1), but for setlocale(locale1);
setlocale("C"); setlocale(locale1) too (i.e. data file loaded only once).
Diffstat (limited to 'lib/libc/locale/rune.c')
-rw-r--r-- | lib/libc/locale/rune.c | 48 |
1 files changed, 34 insertions, 14 deletions
diff --git a/lib/libc/locale/rune.c b/lib/libc/locale/rune.c index c67773c..63a50de 100644 --- a/lib/libc/locale/rune.c +++ b/lib/libc/locale/rune.c @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$"); #include "namespace.h" #include <arpa/inet.h> +#include <errno.h> #include <rune.h> #include <stdio.h> #include <string.h> @@ -59,22 +60,35 @@ _Read_RuneMagi(fp) _RuneLocale *rl; _RuneEntry *rr; struct stat sb; - int x; + int x, saverr; if (_fstat(fileno(fp), &sb) < 0) - return(0); + return (NULL); - if (sb.st_size < sizeof(_RuneLocale)) - return(0); + if (sb.st_size < sizeof(_RuneLocale)) { + errno = EFTYPE; + return (NULL); + } - if ((data = malloc(sb.st_size)) == NULL) - return(0); + if ((data = malloc(sb.st_size)) == NULL) { + errno = ENOMEM; + return (NULL); + } + errno = 0; rewind(fp); /* Someone might have read the magic number once already */ + if (errno) { + saverr = errno; + free(data); + errno = saverr; + return (NULL); + } if (fread(data, sb.st_size, 1, fp) != 1) { + saverr = errno; free(data); - return(0); + errno = saverr; + return (NULL); } rl = (_RuneLocale *)data; @@ -84,7 +98,8 @@ _Read_RuneMagi(fp) if (memcmp(rl->magic, _RUNE_MAGIC_1, sizeof(rl->magic))) { free(data); - return(0); + errno = EFTYPE; + return (NULL); } rl->invalid_rune = ntohl(rl->invalid_rune); @@ -103,21 +118,24 @@ _Read_RuneMagi(fp) rl->variable = rl->runetype_ext.ranges + rl->runetype_ext.nranges; if (rl->variable > lastp) { free(data); - return(0); + errno = EFTYPE; + return (NULL); } rl->maplower_ext.ranges = (_RuneEntry *)rl->variable; rl->variable = rl->maplower_ext.ranges + rl->maplower_ext.nranges; if (rl->variable > lastp) { free(data); - return(0); + errno = EFTYPE; + return (NULL); } rl->mapupper_ext.ranges = (_RuneEntry *)rl->variable; rl->variable = rl->mapupper_ext.ranges + rl->mapupper_ext.nranges; if (rl->variable > lastp) { free(data); - return(0); + errno = EFTYPE; + return (NULL); } for (x = 0; x < rl->runetype_ext.nranges; ++x) { @@ -131,7 +149,8 @@ _Read_RuneMagi(fp) rl->variable = rr[x].types + len; if (rl->variable > lastp) { free(data); - return(0); + errno = EFTYPE; + return (NULL); } while (len-- > 0) rr[x].types[len] = ntohl(rr[x].types[len]); @@ -156,7 +175,8 @@ _Read_RuneMagi(fp) } if (((char *)rl->variable) + rl->variable_len > (char *)lastp) { free(data); - return(0); + errno = EFTYPE; + return (NULL); } /* @@ -174,5 +194,5 @@ _Read_RuneMagi(fp) if (!rl->mapupper_ext.nranges) rl->mapupper_ext.ranges = 0; - return(rl); + return (rl); } |