From: Mark Andrews Date: Thu, 22 Nov 2001 04:09:52 +0000 (+0000) Subject: pullup: X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2032a3c5c83fba9cd718c42555fe43b003a13fb5;p=thirdparty%2Fbind9.git pullup: 1134. [bug] Multithreaded servers could deadlock in ferror() when reloading zone files. [RT #1951, #1998] --- diff --git a/CHANGES b/CHANGES index 7353d576122..b525ba5ecd1 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +1134. [bug] Multithreaded servers could deadlock in ferror() + when reloading zone files. [RT #1951, #1998] + 1118. [bug] On multithreaded servers, a race condition could cause an assertion failure in resolver.c during resolver shutdown. [RT #2029] diff --git a/lib/isc/lex.c b/lib/isc/lex.c index 37afc0c0b8a..d156a5025f5 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.57.4.3 2001/01/22 20:04:10 bwelling Exp $ */ +/* $Id: lex.c,v 1.57.4.4 2001/11/22 04:09:52 marka Exp $ */ #include @@ -236,10 +236,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); @@ -256,9 +252,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); @@ -297,9 +290,6 @@ isc_lex_close(isc_lex_t *lex) { 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)); } @@ -423,6 +413,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) { @@ -436,7 +432,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; } @@ -454,8 +451,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; + } } } @@ -505,10 +504,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') { @@ -543,8 +546,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 = @@ -587,7 +592,8 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { ulong = strtoul(lex->data, &e, base); if (ulong == ULONG_MAX && errno == ERANGE) { - return (ISC_R_RANGE); + result = ISC_R_RANGE; + goto done; } else if (*e == 0) { tokenp->type = isc_tokentype_number; @@ -619,7 +625,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; @@ -631,8 +637,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 = @@ -647,7 +655,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; @@ -670,14 +678,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. @@ -693,8 +705,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; @@ -702,8 +716,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; @@ -730,7 +746,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; @@ -750,7 +766,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