diff --git a/CHANGES b/CHANGES index 27bb5c0077..d365f02dda 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +1134. [bug] Multithreaded servers could deadlock in ferror() + when reloading zone files. [RT #1951, #1998] + 1133. [bug] IN6_IS_ADDR_LOOPBACK was not portably defined on platforms without IN6_IS_ADDR_LOOPBACK. [RT #2106] diff --git a/lib/isc/lex.c b/lib/isc/lex.c index f4ec0c6954..e514e46770 100644 --- a/lib/isc/lex.c +++ b/lib/isc/lex.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: lex.c,v 1.67 2001/11/16 10:50:00 marka Exp $ */ +/* $Id: lex.c,v 1.68 2001/11/21 22:26:46 gson Exp $ */ #include @@ -235,10 +235,6 @@ isc_lex_openfile(isc_lex_t *lex, const char *filename) { if (result != ISC_R_SUCCESS) return (result); -#ifdef HAVE_FLOCKFILE - flockfile(stream); -#endif - result = new_source(lex, ISC_TRUE, ISC_TRUE, stream, filename); if (result != ISC_R_SUCCESS) fclose(stream); @@ -255,9 +251,6 @@ isc_lex_openstream(isc_lex_t *lex, FILE *stream) { REQUIRE(VALID_LEX(lex)); -#ifdef HAVE_FLOCKFILE - flockfile(stream); -#endif /* This is safe. */ sprintf(name, "stream-%p", stream); @@ -296,9 +289,6 @@ isc_lex_close(isc_lex_t *lex) { ISC_LIST_UNLINK(lex->sources, source, link); if (source->is_file) { -#ifdef HAVE_FLOCKFILE - funlockfile((FILE *)(source->input)); -#endif if (source->need_close) fclose((FILE *)(source->input)); } @@ -422,6 +412,12 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { prev = NULL; remaining = lex->max_token; + +#ifdef HAVE_FLOCKFILE + if (source->is_file) + flockfile(source->input); +#endif + do { if (isc_buffer_remaininglength(source->pushback) == 0) { if (source->is_file) { @@ -435,7 +431,8 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { if (c == EOF) { if (ferror(stream)) { source->result = ISC_R_IOERROR; - return (source->result); + result = source->result; + goto done; } source->at_eof = ISC_TRUE; } @@ -453,8 +450,10 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { } if (c != EOF) { source->result = pushandgrow(lex, source, c); - if (source->result != ISC_R_SUCCESS) - return (source->result); + if (source->result != ISC_R_SUCCESS) { + result = source->result; + goto done; + } } } @@ -504,10 +503,14 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { if (c == EOF) { lex->last_was_eol = ISC_FALSE; if ((options & ISC_LEXOPT_DNSMULTILINE) != 0 && - lex->paren_count != 0) - return (ISC_R_UNBALANCED); - if ((options & ISC_LEXOPT_EOF) == 0) - return (ISC_R_EOF); + lex->paren_count != 0) { + result = ISC_R_UNBALANCED; + goto done; + } + if ((options & ISC_LEXOPT_EOF) == 0) { + result = ISC_R_EOF; + goto done; + } tokenp->type = isc_tokentype_eof; done = ISC_TRUE; } else if (c == ' ' || c == '\t') { @@ -542,8 +545,10 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { options &= ~IWSEOL; lex->paren_count++; } else { - if (lex->paren_count == 0) - return (ISC_R_UNBALANCED); + if (lex->paren_count == 0) { + result = ISC_R_UNBALANCED; + goto done; + } lex->paren_count--; if (lex->paren_count == 0) options = @@ -586,7 +591,8 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { as_ulong = strtoul(lex->data, &e, base); if (as_ulong == ULONG_MAX && errno == ERANGE) { - return (ISC_R_RANGE); + result = ISC_R_RANGE; + goto done; } else if (*e == 0) { tokenp->type = isc_tokentype_number; @@ -618,7 +624,7 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { result = grow_data(lex, &remaining, &curr, &prev); if (result != ISC_R_SUCCESS) - return (result); + goto done; } INSIST(remaining > 0); *curr++ = c; @@ -630,8 +636,10 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { (c == ' ' || c == '\t' || lex->specials[c])) || c == '\r' || c == '\n' || c == EOF) { pushback(source, c); - if (source->result != ISC_R_SUCCESS) - return (source->result); + if (source->result != ISC_R_SUCCESS) { + result = source->result; + goto done; + } tokenp->type = isc_tokentype_string; tokenp->value.as_textregion.base = lex->data; tokenp->value.as_textregion.length = @@ -646,7 +654,7 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { result = grow_data(lex, &remaining, &curr, &prev); if (result != ISC_R_SUCCESS) - return (result); + goto done; } INSIST(remaining > 0); *curr++ = c; @@ -669,14 +677,18 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { state = saved_state; goto no_read; case lexstate_ccomment: - if (c == EOF) - return (ISC_R_UNEXPECTEDEND); + if (c == EOF) { + result = ISC_R_UNEXPECTEDEND; + goto done; + } if (c == '*') state = lexstate_ccommentend; break; case lexstate_ccommentend: - if (c == EOF) - return (ISC_R_UNEXPECTEDEND); + if (c == EOF) { + result = ISC_R_UNEXPECTEDEND; + goto done; + } if (c == '/') { /* * C-style comments become a single space. @@ -692,8 +704,10 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { state = lexstate_ccomment; break; case lexstate_eatline: - if (c == EOF) - return (ISC_R_UNEXPECTEDEND); + if (c == EOF) { + result = ISC_R_UNEXPECTEDEND; + goto done; + } if (c == '\n') { no_comments = ISC_FALSE; state = saved_state; @@ -701,8 +715,10 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { } break; case lexstate_qstring: - if (c == EOF) - return (ISC_R_UNEXPECTEDEND); + if (c == EOF) { + result = ISC_R_UNEXPECTEDEND; + goto done; + } if (c == '"') { if (escaped) { escaped = ISC_FALSE; @@ -724,7 +740,8 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { if (c == '\n' && !escaped && (options & ISC_LEXOPT_QSTRINGMULTILINE) == 0) { pushback(source, c); - return (ISC_R_UNBALANCEDQUOTES); + result = ISC_R_UNBALANCEDQUOTES; + goto done; } if (c == '\\' && !escaped) escaped = ISC_TRUE; @@ -734,7 +751,7 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { result = grow_data(lex, &remaining, &curr, &prev); if (result != ISC_R_SUCCESS) - return (result); + goto done; } INSIST(remaining > 0); prev = curr; @@ -754,7 +771,13 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { } while (!done); - return (ISC_R_SUCCESS); + result = ISC_R_SUCCESS; + done: +#ifdef HAVE_FLOCKFILE + if (source->is_file) + funlockfile(source->input); +#endif + return (result); } isc_result_t