From ba5b97343c8a2b6a38a24e9e762d5a3f2a30b576 Mon Sep 17 00:00:00 2001 From: Jon Olav Hauglid Date: Wed, 16 Feb 2011 16:26:19 +0100 Subject: Bug #11752069 (former bug 43152) Assertion `bitmap_is_set_all(&table->s->all_set)' failed in handler::ha_reset This assertion could be triggered if two connections simultaneously executed two bitmap test functions on the same bitmap. For example, the assertion could be triggered if one connection executed UPDATE while a second connection executed SELECT on the same table. Even if bitmap test functions have read-only semantics and have const bitmaps as parameter, several of them modified the internal state of the bitmap. With interleaved execution of two such functions it was possible for one function to modify the state of the same bitmap that the other function had just modified. This lead to an inconsistent state and could trigger the assert. Internally the bitmap uses 32 bit words for storage. Since bitmaps can contain any number of bits, the last word in the bitmap may not be fully used. A 32 bit mask is maintained where a bit is set if the corresponding bit in the last bitmap word is unused. The problem was that several test functions applied this mask to the last word. Sometimes the mask was negated and used to zero out the remainder of the last word and sometimes the mask was used as-is to fill the remainder of the last word with 1's. This meant that if a function first used the negated mask and another function then used the mask as-is (or vice-versa), the first function would then get the wrong result. This patch fixes the problem by changing the implementation of 9 bitmap functions that modified the bitmap state even if the bitmap was declared const. These functions now preserve the internal state of the bitmap. This makes it possible for two connections to concurrently execute two of these functions on the same bitmap without issues. The patch also removes dead testing code from my_bitmap.c. These tests have already been moved to unittest/mysys/bitmap-t.c. Existing test coverage of my_bitmap has been extended. No MTR test case added as this would require adding several sync points to the bitmap functions. The patch has been tested with a non-deterministic test case posted on the bug report. --- include/my_bit.h | 24 +++++++++++++++++++++--- include/my_bitmap.h | 9 +++++---- 2 files changed, 26 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/my_bit.h b/include/my_bit.h index 2e464e89049..2ab47b04184 100644 --- a/include/my_bit.h +++ b/include/my_bit.h @@ -1,3 +1,18 @@ +/* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + /* Some useful bit functions */ @@ -42,9 +57,12 @@ STATIC_INLINE uint my_count_bits(ulonglong v) #endif } -STATIC_INLINE uint my_count_bits_ushort(ushort v) +STATIC_INLINE uint my_count_bits_uint32(uint32 v) { - return _my_bits_nbits[v]; + return (uint) (uchar) (_my_bits_nbits[(uchar) v] + + _my_bits_nbits[(uchar) (v >> 8)] + + _my_bits_nbits[(uchar) (v >> 16)] + + _my_bits_nbits[(uchar) (v >> 24)]); } @@ -104,6 +122,6 @@ extern uint32 my_round_up_to_next_power(uint32 v); uint32 my_clear_highest_bit(uint32 v); uint32 my_reverse_bits(uint32 key); extern uint my_count_bits(ulonglong v); -extern uint my_count_bits_ushort(ushort v); +extern uint my_count_bits_uint32(uint32 v); #endif /* HAVE_INLINE */ C_MODE_END diff --git a/include/my_bitmap.h b/include/my_bitmap.h index ab69b2d671d..42f985c8918 100644 --- a/include/my_bitmap.h +++ b/include/my_bitmap.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -149,9 +149,10 @@ bitmap_is_set(const MY_BITMAP *map,uint bit) static inline my_bool bitmap_cmp(const MY_BITMAP *map1, const MY_BITMAP *map2) { - *(map1)->last_word_ptr|= (map1)->last_word_mask; - *(map2)->last_word_ptr|= (map2)->last_word_mask; - return memcmp((map1)->bitmap, (map2)->bitmap, 4*no_words_in_map((map1)))==0; + if (memcmp(map1->bitmap, map2->bitmap, 4*(no_words_in_map(map1)-1)) != 0) + return FALSE; + return ((*map1->last_word_ptr | map1->last_word_mask) == + (*map2->last_word_ptr | map2->last_word_mask)); } #define bitmap_clear_all(MAP) \ -- cgit v1.2.1 From 4c4cb80b0af1b9e4a5e38130ee3566615bd8a8b4 Mon Sep 17 00:00:00 2001 From: Magne Mahre Date: Mon, 28 Mar 2011 10:47:30 +0200 Subject: Bug#11900714 REMOVE LGPL LICENSED FILES IN MYSQL 5.1 The LGPL license is used in some legacy code, and to adhere to current licensing polity, we remove those files that are no longer used, and reorganize the remaining LGPL code so it will be GPL licensed from now on. Note: This patch only removed LGPL licensed files in MySQL 5.1, and is the second of a set of patches to remove LGPL from all trees. (See Bug# 11840513 for details) --- include/Makefile.am | 2 +- include/heap.h | 2 +- include/my_compare.h | 89 +++++++++++++++++++++++++++++++++++ include/my_global.h | 2 +- include/my_handler.h | 128 --------------------------------------------------- include/myisam.h | 24 +++++++++- 6 files changed, 115 insertions(+), 132 deletions(-) create mode 100644 include/my_compare.h delete mode 100644 include/my_handler.h (limited to 'include') diff --git a/include/Makefile.am b/include/Makefile.am index a3dbc386857..2e29806e0df 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -37,7 +37,7 @@ noinst_HEADERS = config-win.h config-netware.h my_bit.h \ my_nosys.h my_alarm.h queues.h rijndael.h sha1.h \ my_aes.h my_tree.h my_trie.h hash.h thr_alarm.h \ thr_lock.h t_ctype.h violite.h my_md5.h base64.h \ - my_handler.h my_time.h my_vle.h my_user.h \ + my_compare.h my_time.h my_vle.h my_user.h \ my_libwrap.h my_stacktrace.h EXTRA_DIST = mysql.h.pp mysql/plugin.h.pp diff --git a/include/heap.h b/include/heap.h index 4a1c7d419ed..126ce4fa12d 100644 --- a/include/heap.h +++ b/include/heap.h @@ -30,7 +30,7 @@ extern "C" { #include #endif -#include "my_handler.h" +#include "my_compare.h" #include "my_tree.h" /* defines used by heap-funktions */ diff --git a/include/my_compare.h b/include/my_compare.h new file mode 100644 index 00000000000..dedae5c8052 --- /dev/null +++ b/include/my_compare.h @@ -0,0 +1,89 @@ +/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef _my_compare_h +#define _my_compare_h + +#include "my_base.h" +#include "m_ctype.h" +#include "myisampack.h" + +typedef struct st_HA_KEYSEG /* Key-portion */ +{ + CHARSET_INFO *charset; + uint32 start; /* Start of key in record */ + uint32 null_pos; /* position to NULL indicator */ + uint16 bit_pos; /* Position to bit part */ + uint16 flag; + uint16 length; /* Keylength */ + uint8 type; /* Type of key (for sort) */ + uint8 language; + uint8 null_bit; /* bitmask to test for NULL */ + uint8 bit_start,bit_end; /* if bit field */ + uint8 bit_length; /* Length of bit part */ +} HA_KEYSEG; + +#define get_key_length(length,key) \ +{ if ((uchar) *(key) != 255) \ + length= (uint) (uchar) *((key)++); \ + else \ + { length=mi_uint2korr((key)+1); (key)+=3; } \ +} + +#define get_key_length_rdonly(length,key) \ +{ if ((uchar) *(key) != 255) \ + length= ((uint) (uchar) *((key))); \ + else \ + { length=mi_uint2korr((key)+1); } \ +} + +#define get_key_pack_length(length,length_pack,key) \ +{ if ((uchar) *(key) != 255) \ + { length= (uint) (uchar) *((key)++); length_pack=1; }\ + else \ + { length=mi_uint2korr((key)+1); (key)+=3; length_pack=3; } \ +} + +#define store_key_length_inc(key,length) \ +{ if ((length) < 255) \ + { *(key)++=(length); } \ + else \ + { *(key)=255; mi_int2store((key)+1,(length)); (key)+=3; } \ +} + +#define get_rec_bits(bit_ptr, bit_ofs, bit_len) \ + (((((uint16) (bit_ptr)[1] << 8) | (uint16) (bit_ptr)[0]) >> (bit_ofs)) & \ + ((1 << (bit_len)) - 1)) + +#define set_rec_bits(bits, bit_ptr, bit_ofs, bit_len) \ +{ \ + (bit_ptr)[0]= ((bit_ptr)[0] & ~(((1 << (bit_len)) - 1) << (bit_ofs))) | \ + ((bits) << (bit_ofs)); \ + if ((bit_ofs) + (bit_len) > 8) \ + (bit_ptr)[1]= ((bit_ptr)[1] & ~((1 << ((bit_len) - 8 + (bit_ofs))) - 1)) | \ + ((bits) >> (8 - (bit_ofs))); \ +} + +#define clr_rec_bits(bit_ptr, bit_ofs, bit_len) \ + set_rec_bits(0, bit_ptr, bit_ofs, bit_len) + +extern int ha_compare_text(CHARSET_INFO *, uchar *, uint, uchar *, uint , + my_bool, my_bool); +extern int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, + register uchar *b, uint key_length, uint nextflag, + uint *diff_pos); + + +#endif /* _my_compare_h */ diff --git a/include/my_global.h b/include/my_global.h index ac5d72249f2..005180dae3b 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -359,7 +359,7 @@ C_MODE_END #define ulonglong2double(A) my_ulonglong2double(A) #define my_off_t2double(A) my_ulonglong2double(A) C_MODE_START -double my_ulonglong2double(unsigned long long A); +inline double my_ulonglong2double(unsigned long long A) { return (double) A; } C_MODE_END #endif /* _AIX */ diff --git a/include/my_handler.h b/include/my_handler.h deleted file mode 100644 index 7dfdb345a89..00000000000 --- a/include/my_handler.h +++ /dev/null @@ -1,128 +0,0 @@ -/* Copyright (C) 2002-2006 MySQL AB - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; version 2 - of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA */ - -#ifndef _my_handler_h -#define _my_handler_h - -#include "myisampack.h" -#ifdef __cplusplus -extern "C" { -#endif - -/* - There is a hard limit for the maximum number of keys as there are only - 8 bits in the index file header for the number of keys in a table. - This means that 0..255 keys can exist for a table. The idea of - HA_MAX_POSSIBLE_KEY is to ensure that one can use myisamchk & tools on - a MyISAM table for which one has more keys than MyISAM is normally - compiled for. If you don't have this, you will get a core dump when - running myisamchk compiled for 128 keys on a table with 255 keys. -*/ - -#define HA_MAX_POSSIBLE_KEY 255 /* For myisamchk */ -/* - The following defines can be increased if necessary. - But beware the dependency of MI_MAX_POSSIBLE_KEY_BUFF and HA_MAX_KEY_LENGTH. -*/ - -#define HA_MAX_KEY_LENGTH 1000 /* Max length in bytes */ -#define HA_MAX_KEY_SEG 16 /* Max segments for key */ - -#define HA_MAX_POSSIBLE_KEY_BUFF (HA_MAX_KEY_LENGTH + 24+ 6+6) -#define HA_MAX_KEY_BUFF (HA_MAX_KEY_LENGTH+HA_MAX_KEY_SEG*6+8+8) - -typedef struct st_HA_KEYSEG /* Key-portion */ -{ - CHARSET_INFO *charset; - uint32 start; /* Start of key in record */ - uint32 null_pos; /* position to NULL indicator */ - uint16 bit_pos; /* Position to bit part */ - uint16 flag; - uint16 length; /* Keylength */ - uint8 type; /* Type of key (for sort) */ - uint8 language; - uint8 null_bit; /* bitmask to test for NULL */ - uint8 bit_start,bit_end; /* if bit field */ - uint8 bit_length; /* Length of bit part */ -} HA_KEYSEG; - -#define get_key_length(length,key) \ -{ if (*(uchar*) (key) != 255) \ - length= (uint) *(uchar*) ((key)++); \ - else \ - { length= mi_uint2korr((key)+1); (key)+=3; } \ -} - -#define get_key_length_rdonly(length,key) \ -{ if (*(uchar*) (key) != 255) \ - length= ((uint) *(uchar*) ((key))); \ - else \ - { length= mi_uint2korr((key)+1); } \ -} - -#define get_key_pack_length(length,length_pack,key) \ -{ if (*(uchar*) (key) != 255) \ - { length= (uint) *(uchar*) ((key)++); length_pack= 1; }\ - else \ - { length=mi_uint2korr((key)+1); (key)+= 3; length_pack= 3; } \ -} - -#define store_key_length_inc(key,length) \ -{ if ((length) < 255) \ - { *(key)++= (length); } \ - else \ - { *(key)=255; mi_int2store((key)+1,(length)); (key)+=3; } \ -} - -#define size_to_store_key_length(length) ((length) < 255 ? 1 : 3) - -#define get_rec_bits(bit_ptr, bit_ofs, bit_len) \ - (((((uint16) (bit_ptr)[1] << 8) | (uint16) (bit_ptr)[0]) >> (bit_ofs)) & \ - ((1 << (bit_len)) - 1)) - -#define set_rec_bits(bits, bit_ptr, bit_ofs, bit_len) \ -{ \ - (bit_ptr)[0]= ((bit_ptr)[0] & ~(((1 << (bit_len)) - 1) << (bit_ofs))) | \ - ((bits) << (bit_ofs)); \ - if ((bit_ofs) + (bit_len) > 8) \ - (bit_ptr)[1]= ((bit_ptr)[1] & ~((1 << ((bit_len) - 8 + (bit_ofs))) - 1)) | \ - ((bits) >> (8 - (bit_ofs))); \ -} - -#define clr_rec_bits(bit_ptr, bit_ofs, bit_len) \ - set_rec_bits(0, bit_ptr, bit_ofs, bit_len) - -extern int ha_compare_text(CHARSET_INFO *, uchar *, uint, uchar *, uint , - my_bool, my_bool); -extern int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, - register uchar *b, uint key_length, uint nextflag, - uint *diff_pos); - -extern HA_KEYSEG *ha_find_null(HA_KEYSEG *keyseg, uchar *a); -extern void my_handler_error_register(void); -extern void my_handler_error_unregister(void); -/* - Inside an in-memory data record, memory pointers to pieces of the - record (like BLOBs) are stored in their native byte order and in - this amount of bytes. -*/ -#define portable_sizeof_char_ptr 8 -#ifdef __cplusplus -} -#endif - -#endif /* _my_handler_h */ diff --git a/include/myisam.h b/include/myisam.h index e502daa2f17..09f54ef0019 100644 --- a/include/myisam.h +++ b/include/myisam.h @@ -30,8 +30,30 @@ extern "C" { #ifndef _keycache_h #include "keycache.h" #endif -#include "my_handler.h" #include +#include "my_compare.h" + +/* + There is a hard limit for the maximum number of keys as there are only + 8 bits in the index file header for the number of keys in a table. + This means that 0..255 keys can exist for a table. The idea of + HA_MAX_POSSIBLE_KEY is to ensure that one can use myisamchk & tools on + a MyISAM table for which one has more keys than MyISAM is normally + compiled for. If you don't have this, you will get a core dump when + running myisamchk compiled for 128 keys on a table with 255 keys. +*/ + +#define HA_MAX_POSSIBLE_KEY 255 /* For myisamchk */ +/* + The following defines can be increased if necessary. + But beware the dependency of MI_MAX_POSSIBLE_KEY_BUFF and HA_MAX_KEY_LENGTH. +*/ + +#define HA_MAX_KEY_LENGTH 1000 /* Max length in bytes */ +#define HA_MAX_KEY_SEG 16 /* Max segments for key */ + +#define HA_MAX_POSSIBLE_KEY_BUFF (HA_MAX_KEY_LENGTH + 24+ 6+6) +#define HA_MAX_KEY_BUFF (HA_MAX_KEY_LENGTH+HA_MAX_KEY_SEG*6+8+8) /* Limit max keys according to HA_MAX_POSSIBLE_KEY -- cgit v1.2.1 From 25221cccd2dde986c91c1ad3bdca3ee2869ed2ac Mon Sep 17 00:00:00 2001 From: Guilhem Bichot Date: Mon, 16 May 2011 22:04:01 +0200 Subject: Fix for BUG#11755168 '46895: test "outfile_loaddata" fails (reproducible)'. In sql_class.cc, 'row_count', of type 'ha_rows', was used as last argument for ER_TRUNCATED_WRONG_VALUE_FOR_FIELD which is "Incorrect %-.32s value: '%-.128s' for column '%.192s' at row %ld". So 'ha_rows' was used as 'long'. On SPARC32 Solaris builds, 'long' is 4 bytes and 'ha_rows' is 'longlong' i.e. 8 bytes. So the printf-like code was reading only the first 4 bytes. Because the CPU is big-endian, 1LL is 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x01 so the first four bytes yield 0. So the warning message had "row 0" instead of "row 1" in test outfile_loaddata.test: -Warning 1366 Incorrect string value: '\xE1\xE2\xF7' for column 'b' at row 1 +Warning 1366 Incorrect string value: '\xE1\xE2\xF7' for column 'b' at row 0 All error-messaging functions which internally invoke some printf-life function are potential candidate for such mistakes. One apparently easy way to catch such mistakes is to use ATTRIBUTE_FORMAT (from my_attribute.h). But this works only when call site has both: a) the format as a string literal b) the types of arguments. So: func(ER(ER_BLAH), 10); will silently not be checked, because ER(ER_BLAH) is not known at compile time (it is known at run-time, and depends on the chosen language). And func("%s", a va_list argument); has the same problem, as the *real* type of arguments is not known at this site at compile time (it's known in some caller). Moreover, func(ER(ER_BLAH)); though possibly correct (if ER(ER_BLAH) has no '%' markers), will not compile (gcc says "error: format not a string literal and no format arguments"). Consequences: 1) ATTRIBUTE_FORMAT is here added only to functions which in practice take "string literal" formats: "my_error_reporter" and "print_admin_msg". 2) it cannot be added to the other functions: my_error(), push_warning_printf(), Table_check_intact::report_error(), general_log_print(). To do a one-time check of functions listed in (2), the following "static code analysis" has been done: 1) replace my_error(ER_xxx, arguments for substitution in format) with the equivalent my_printf_error(ER_xxx,ER(ER_xxx), arguments for substitution in format), so that we have ER(ER_xxx) and the arguments *in the same call site* 2) add ATTRIBUTE_FORMAT to push_warning_printf(), Table_check_intact::report_error(), general_log_print() 3) replace ER(xxx) with the hard-coded English text found in errmsg.txt (like: ER(ER_UNKNOWN_ERROR) is replaced with "Unknown error"), so that a call site has the format as string literal 4) this way, ATTRIBUTE_FORMAT can effectively do its job 5) compile, fix errors detected by ATTRIBUTE_FORMAT 6) revert steps 1-2-3. The present patch has no compiler error when submitted again to the static code analysis above. It cannot catch all problems though: see Field::set_warning(), in which a call to push_warning_printf() has a variable error (thus, not replacable by a string literal); I checked set_warning() calls by hand though. See also WL 5883 for one proposal to avoid such bugs from appearing again in the future. The issues fixed in the patch are: a) mismatch in types (like 'int' passed to '%ld') b) more arguments passed than specified in the format. This patch resolves mismatches by changing the type/number of arguments, not by changing error messages of sql/share/errmsg.txt. The latter would be wrong, per the following old rule: errmsg.txt must be as stable as possible; no insertions or deletions of messages, no changes of type or number of printf-like format specifiers, are allowed, as long as the change impacts a message already released in a GA version. If this rule is not followed: - Connectors, which use error message numbers, will be confused (by insertions/deletions of messages) - using errmsg.sys of MySQL 5.1.n with mysqld of MySQL 5.1.(n+1) could produce wrong messages or crash; such usage can easily happen if installing 5.1.(n+1) while /etc/my.cnf still has --language=/path/to/5.1.n/xxx; or if copying mysqld from 5.1.(n+1) into a 5.1.n installation. When fixing b), I have verified that the superfluous arguments were not used in the format in the first 5.1 GA (5.1.30 'bteam@astra04-20081114162938-z8mctjp6st27uobm'). Had they been used, then passing them today, even if the message doesn't use them anymore, would have been necessary, as explained above. --- include/my_getopt.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/my_getopt.h b/include/my_getopt.h index d7c996302fd..a379e8c4716 100644 --- a/include/my_getopt.h +++ b/include/my_getopt.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2004 MySQL AB +/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _my_getopt_h #define _my_getopt_h @@ -59,7 +59,9 @@ struct my_option }; typedef my_bool (*my_get_one_option)(int, const struct my_option *, char *); -typedef void (*my_error_reporter)(enum loglevel level, const char *format, ...); +typedef void (*my_error_reporter)(enum loglevel level, const char *format, ...) + ATTRIBUTE_FORMAT_FPTR(printf, 2, 3); + /** Used to retrieve a reference to the object (variable) that holds the value for the given option. For example, if var_type is GET_UINT, the function -- cgit v1.2.1 From 79de9c71887aafe46efd005be65e8cc596eff5cb Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 27 May 2011 08:09:25 -0300 Subject: BUG 11763056 - 55721: AIX 5.1.50 build failing, cannot locate bzero The problem is that although AIX implements bzero, its prototype is not declared by default. Since AC_CHECK_FUNC(bzero) succeeds even though a prototype is not declared, this breaks compilation in C++ files where a prototype is required. The solution is to only use bzero if a prototype is also declared. --- include/m_string.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/m_string.h b/include/m_string.h index 0d248ea0ad3..53572a4ac9e 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -58,7 +58,7 @@ # define bfill(A,B,C) memset((A),(C),(B)) #endif -#if !defined(bzero) && !defined(HAVE_BZERO) +#if !defined(bzero) && (!defined(HAVE_BZERO) || !defined(HAVE_DECL_BZERO)) # define bzero(A,B) memset((A),0,(B)) #endif -- cgit v1.2.1