]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
pullup:
authorMark Andrews <marka@isc.org>
Thu, 22 Nov 2001 01:23:19 +0000 (01:23 +0000)
committerMark Andrews <marka@isc.org>
Thu, 22 Nov 2001 01:23:19 +0000 (01:23 +0000)
1134.   [bug]           Multithreaded servers could deadlock in ferror()
                        when reloading zone files. [RT #1951, #1998]

CHANGES
lib/isc/lex.c

diff --git a/CHANGES b/CHANGES
index 639a196c9cf818fbae33748d29c578cb716d19d1..5a498368183743757c17c0a90dec7406a502bde0 100644 (file)
--- 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]
 
index 5604b3cd271ef6b3c7b3b09dc6f64c9571169f23..3066a67b2db4478430c57b7f305e9de3ee7dceaa 100644 (file)
@@ -15,7 +15,7 @@
  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: lex.c,v 1.66.2.1 2001/11/16 19:00:37 gson Exp $ */
+/* $Id: lex.c,v 1.66.2.2 2001/11/22 01:23:19 marka Exp $ */
 
 #include <config.h>
 
@@ -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