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/ldpart.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/ldpart.c')
-rw-r--r-- | lib/libc/locale/ldpart.c | 88 |
1 files changed, 31 insertions, 57 deletions
diff --git a/lib/libc/locale/ldpart.c b/lib/libc/locale/ldpart.c index 0e276cf..1933312 100644 --- a/lib/libc/locale/ldpart.c +++ b/lib/libc/locale/ldpart.c @@ -42,7 +42,6 @@ __FBSDID("$FreeBSD$"); #include "ldpart.h" static int split_lines(char *, const char *); -static void set_from_buf(const char *, int, const char **); int __part_load_locale(const char *name, @@ -53,35 +52,25 @@ __part_load_locale(const char *name, int locale_buf_size_min, const char **dst_localebuf) { - static char locale_buf_C[] = "C"; - static int num_lines; - int saverr; - int fd; - char *lbuf; - char *p; - const char *plim; - char filename[PATH_MAX]; + int saverr, fd, i, num_lines; + char *lbuf, *p; + const char *plim; + char filename[PATH_MAX]; struct stat st; - size_t namesize; - size_t bufsize; - int save_using_locale; - - save_using_locale = *using_locale; - *using_locale = 0; + size_t namesize, bufsize; /* 'name' must be already checked. */ - - if (!strcmp(name, "C") || !strcmp(name, "POSIX")) - return 0; + if (strcmp(name, "C") == 0 || strcmp(name, "POSIX") == 0) { + *using_locale = 0; + return (_LDP_CACHE); + } /* * If the locale name is the same as our cache, use the cache. */ - lbuf = locale_buf; - if (lbuf != NULL && strcmp(name, lbuf) == 0) { - set_from_buf(lbuf, num_lines, dst_localebuf); + if (locale_buf != NULL && strcmp(name, locale_buf) == 0) { *using_locale = 1; - return 0; + return (_LDP_CACHE); } /* @@ -90,16 +79,14 @@ __part_load_locale(const char *name, namesize = strlen(name) + 1; /* 'PathLocale' must be already set & checked. */ - /* Range checking not needed, 'name' size is limited */ strcpy(filename, _PathLocale); strcat(filename, "/"); strcat(filename, name); strcat(filename, "/"); strcat(filename, category_filename); - fd = _open(filename, O_RDONLY); - if (fd < 0) - goto no_locale; + if ((fd = _open(filename, O_RDONLY)) < 0) + return (_LDP_ERROR); if (_fstat(fd, &st) != 0) goto bad_locale; if (st.st_size <= 0) { @@ -107,18 +94,15 @@ __part_load_locale(const char *name, goto bad_locale; } bufsize = namesize + st.st_size; - locale_buf = NULL; - lbuf = (lbuf == NULL || lbuf == locale_buf_C) ? - malloc(bufsize) : reallocf(lbuf, bufsize); - if (lbuf == NULL) + if ((lbuf = malloc(bufsize)) == NULL) { + errno = ENOMEM; goto bad_locale; + } (void)strcpy(lbuf, name); p = lbuf + namesize; plim = p + st.st_size; if (_read(fd, p, (size_t) st.st_size) != st.st_size) goto bad_lbuf; - if (_close(fd) != 0) - goto bad_lbuf; /* * Parse the locale file into localebuf. */ @@ -133,37 +117,37 @@ __part_load_locale(const char *name, num_lines = locale_buf_size_min; else { errno = EFTYPE; - goto reset_locale; + goto bad_lbuf; } - set_from_buf(lbuf, num_lines, dst_localebuf); + (void)_close(fd); /* * Record the successful parse in the cache. */ + if (locale_buf != NULL) + free(locale_buf); locale_buf = lbuf; - + for (p = locale_buf, i = 0; i < num_lines; i++) + dst_localebuf[i] = (p += strlen(p) + 1); + for (i = num_lines; i < locale_buf_size_max; i++) + dst_localebuf[i] = NULL; *using_locale = 1; - return 0; + return (_LDP_LOADED); -reset_locale: - locale_buf = locale_buf_C; - save_using_locale = 0; bad_lbuf: - saverr = errno; - free(lbuf); + saverr = errno; + free(lbuf); errno = saverr; bad_locale: - saverr = errno; - (void)_close(fd); + saverr = errno; + (void)_close(fd); errno = saverr; -no_locale: - *using_locale = save_using_locale; - return -1; + return (_LDP_ERROR); } static int -split_lines(char *p, const char *plim) +split_lines(char *p, const char *plim) { int i; @@ -174,13 +158,3 @@ split_lines(char *p, const char *plim) return (i); } -static void -set_from_buf(const char *p, int num_lines, const char **dst_localebuf) { - - const char **ap; - int i; - - for (ap = dst_localebuf, i = 0; i < num_lines; ++ap, ++i) - *ap = p += strlen(p) + 1; -} - |