summaryrefslogtreecommitdiff
path: root/mysys
diff options
context:
space:
mode:
Diffstat (limited to 'mysys')
-rw-r--r--mysys/charset.c45
-rw-r--r--mysys/mf_iocache.c4
-rw-r--r--mysys/my_access.c9
-rw-r--r--mysys/my_addr_resolve.c30
-rw-r--r--mysys/my_bitmap.c2
-rw-r--r--mysys/my_error.c2
-rw-r--r--mysys/my_fopen.c6
-rw-r--r--mysys/my_redel.c7
-rw-r--r--mysys/my_static.c1
-rw-r--r--mysys/stacktrace.c4
-rw-r--r--mysys/thr_lock.c12
11 files changed, 79 insertions, 43 deletions
diff --git a/mysys/charset.c b/mysys/charset.c
index 016d0fc3012..8939b6d7a4f 100644
--- a/mysys/charset.c
+++ b/mysys/charset.c
@@ -258,12 +258,38 @@ static my_bool simple_cs_is_full(CHARSET_INFO *cs)
#if defined(HAVE_UCA_COLLATIONS) && (defined(HAVE_CHARSET_ucs2) || defined(HAVE_CHARSET_utf8))
+/**
+ Initialize a loaded collation.
+ @param [OUT] to - The new charset_info_st structure to initialize.
+ @param [IN] from - A template collation, to fill the missing data from.
+ @param [IN] loaded - The collation data loaded from the LDML file.
+ some data may be missing in "loaded".
+*/
static void
-copy_uca_collation(struct charset_info_st *to, CHARSET_INFO *from)
+copy_uca_collation(struct charset_info_st *to, CHARSET_INFO *from,
+ CHARSET_INFO *loaded)
{
to->cset= from->cset;
to->coll= from->coll;
- to->strxfrm_multiply= from->strxfrm_multiply;
+ /*
+ Single-level UCA collation have strnxfrm_multiple=8.
+ In case of a multi-level UCA collation we use strnxfrm_multiply=4.
+ That means MY_COLLATION_HANDLER::strnfrmlen() will request the caller
+ to allocate a buffer smaller size for each level, for performance purpose,
+ and to fit longer VARCHARs to @@max_sort_length.
+ This makes filesort produce non-precise order for some rare Unicode
+ characters that produce more than 4 weights (long expansions).
+ UCA requires 2 bytes per weight multiplied by the number of levels.
+ In case of a 2-level collation, each character requires 4*2=8 bytes.
+ Therefore, the longest VARCHAR that fits into the default @@max_sort_length
+ is 1024/8=VARCHAR(128). With strnxfrm_multiply==8, only VARCHAR(64)
+ would fit.
+ Note, the built-in collation utf8_thai_520_w2 also uses strnxfrm_multiply=4,
+ for the same purpose.
+ TODO: we could add a new LDML syntax to choose strxfrm_multiply value.
+ */
+ to->strxfrm_multiply= loaded->levels_for_order > 1 ?
+ 4 : from->strxfrm_multiply;
to->min_sort_char= from->min_sort_char;
to->max_sort_char= from->max_sort_char;
to->mbminlen= from->mbminlen;
@@ -312,7 +338,8 @@ static int add_collation(struct charset_info_st *cs)
#if defined(HAVE_CHARSET_ucs2) && defined(HAVE_UCA_COLLATIONS)
copy_uca_collation(newcs, newcs->state & MY_CS_NOPAD ?
&my_charset_ucs2_unicode_nopad_ci :
- &my_charset_ucs2_unicode_ci);
+ &my_charset_ucs2_unicode_ci,
+ cs);
newcs->state|= MY_CS_AVAILABLE | MY_CS_LOADED | MY_CS_NONASCII;
#endif
}
@@ -321,7 +348,8 @@ static int add_collation(struct charset_info_st *cs)
#if defined (HAVE_CHARSET_utf8) && defined(HAVE_UCA_COLLATIONS)
copy_uca_collation(newcs, newcs->state & MY_CS_NOPAD ?
&my_charset_utf8_unicode_nopad_ci :
- &my_charset_utf8_unicode_ci);
+ &my_charset_utf8_unicode_ci,
+ cs);
newcs->ctype= my_charset_utf8_unicode_ci.ctype;
if (init_state_maps(newcs))
return MY_XML_ERROR;
@@ -332,7 +360,8 @@ static int add_collation(struct charset_info_st *cs)
#if defined (HAVE_CHARSET_utf8mb4) && defined(HAVE_UCA_COLLATIONS)
copy_uca_collation(newcs, newcs->state & MY_CS_NOPAD ?
&my_charset_utf8mb4_unicode_nopad_ci :
- &my_charset_utf8mb4_unicode_ci);
+ &my_charset_utf8mb4_unicode_ci,
+ cs);
newcs->ctype= my_charset_utf8mb4_unicode_ci.ctype;
newcs->state|= MY_CS_AVAILABLE | MY_CS_LOADED;
#endif
@@ -342,7 +371,8 @@ static int add_collation(struct charset_info_st *cs)
#if defined (HAVE_CHARSET_utf16) && defined(HAVE_UCA_COLLATIONS)
copy_uca_collation(newcs, newcs->state & MY_CS_NOPAD ?
&my_charset_utf16_unicode_nopad_ci :
- &my_charset_utf16_unicode_ci);
+ &my_charset_utf16_unicode_ci,
+ cs);
newcs->state|= MY_CS_AVAILABLE | MY_CS_LOADED | MY_CS_NONASCII;
#endif
}
@@ -351,7 +381,8 @@ static int add_collation(struct charset_info_st *cs)
#if defined (HAVE_CHARSET_utf32) && defined(HAVE_UCA_COLLATIONS)
copy_uca_collation(newcs, newcs->state & MY_CS_NOPAD ?
&my_charset_utf32_unicode_nopad_ci :
- &my_charset_utf32_unicode_ci);
+ &my_charset_utf32_unicode_ci,
+ cs);
newcs->state|= MY_CS_AVAILABLE | MY_CS_LOADED | MY_CS_NONASCII;
#endif
}
diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c
index 77581a51d75..bfdda25cafa 100644
--- a/mysys/mf_iocache.c
+++ b/mysys/mf_iocache.c
@@ -1945,8 +1945,6 @@ int my_b_flush_io_cache(IO_CACHE *info, int need_append_buffer_lock)
if ((length=(size_t) (info->write_pos - info->write_buffer)))
{
- info->write_end= (info->write_buffer + info->buffer_length -
- ((info->pos_in_file + length) & (IO_SIZE - 1)));
if (append_cache)
{
@@ -1968,6 +1966,8 @@ int my_b_flush_io_cache(IO_CACHE *info, int need_append_buffer_lock)
set_if_bigger(info->end_of_file, info->pos_in_file);
}
+ info->write_end= (info->write_buffer + info->buffer_length -
+ ((info->pos_in_file + length) & (IO_SIZE - 1)));
info->write_pos= info->write_buffer;
++info->disk_writes;
UNLOCK_APPEND_BUFFER;
diff --git a/mysys/my_access.c b/mysys/my_access.c
index 68cd01d33e6..91a536d214e 100644
--- a/mysys/my_access.c
+++ b/mysys/my_access.c
@@ -173,6 +173,11 @@ static my_bool does_drive_exists(char drive_letter)
file names with a colon (:) are not allowed because such file names
store data in Alternate Data Streams which can be used to hide
the data.
+ Apart from colon, other characters that are not allowed in filenames
+ on Windows are greater/less sign, double quotes, forward slash, backslash,
+ pipe and star characters.
+
+ See MSDN documentation on filename restrictions.
@param name contains the file name with or without path
@param length contains the length of file name
@@ -181,6 +186,8 @@ static my_bool does_drive_exists(char drive_letter)
@return TRUE if the file name is allowed, FALSE otherwise.
*/
+#define ILLEGAL_FILENAME_CHARS "<>:\"/\\|?*"
+
my_bool is_filename_allowed(const char *name __attribute__((unused)),
size_t length __attribute__((unused)),
my_bool allow_current_dir __attribute__((unused)))
@@ -205,6 +212,8 @@ my_bool is_filename_allowed(const char *name __attribute__((unused)),
return (allow_current_dir && (ch - name == 1) &&
does_drive_exists(*name));
}
+ else if (strchr(ILLEGAL_FILENAME_CHARS, *ch))
+ return FALSE;
}
return TRUE;
} /* is_filename_allowed */
diff --git a/mysys/my_addr_resolve.c b/mysys/my_addr_resolve.c
index 72b04119855..83716bf11e1 100644
--- a/mysys/my_addr_resolve.c
+++ b/mysys/my_addr_resolve.c
@@ -34,6 +34,13 @@ static const char *strip_path(const char *s)
return prev;
}
+#if defined(HAVE_LINK_H) && defined(HAVE_DLOPEN)
+#include <link.h>
+static ptrdiff_t offset= 0;
+#else
+#define offset 0
+#endif
+
/*
The following is very much single-threaded code and it's only supposed
to be used on shutdown or for a crash report
@@ -60,7 +67,7 @@ static asymbol **symtable= 0;
*/
int my_addr_resolve(void *ptr, my_addr_loc *loc)
{
- bfd_vma addr= (intptr)ptr;
+ bfd_vma addr= (intptr)ptr - offset;
asection *sec;
for (sec= bfdh->sections; sec; sec= sec->next)
@@ -103,6 +110,12 @@ const char *my_addr_resolve_init()
uint unused;
char **matching;
+#if defined(HAVE_LINK_H) && defined(HAVE_DLOPEN)
+ struct link_map *lm = (struct link_map*) dlopen(0, RTLD_NOW);
+ if (lm)
+ offset= lm->l_addr;
+#endif
+
bfdh= bfd_openr(my_progname, NULL);
if (!bfdh)
goto err;
@@ -133,13 +146,6 @@ err:
#include <m_string.h>
#include <ctype.h>
-#if defined(HAVE_LINK_H) && defined(HAVE_DLOPEN)
-#include <link.h>
-static ptrdiff_t offset= 0;
-#else
-#define offset 0
-#endif
-
static int in[2], out[2];
static int initialized= 0;
static char output[1024];
@@ -174,7 +180,7 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc)
extra_bytes_read= read(out[0], output + total_bytes_read,
sizeof(output) - total_bytes_read);
if (extra_bytes_read < 0)
- return 1;
+ return 2;
/* Timeout or max bytes read. */
if (extra_bytes_read == 0)
break;
@@ -184,7 +190,7 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc)
/* Failed starting addr2line. */
if (total_bytes_read == 0)
- return 1;
+ return 3;
/* Go through the addr2line response and get the required data.
The response is structured in 2 lines. The first line contains the function
@@ -205,14 +211,14 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc)
}
/* Response is malformed. */
if (filename_start == -1 || line_number_start == -1)
- return 1;
+ return 4;
loc->func= output;
loc->file= output + filename_start;
/* Addr2line was unable to extract any meaningful information. */
if (strcmp(loc->file, "??") == 0)
- return 1;
+ return 5;
loc->file= strip_path(loc->file);
diff --git a/mysys/my_bitmap.c b/mysys/my_bitmap.c
index 0eaf1a88aa1..a0c1a23d63c 100644
--- a/mysys/my_bitmap.c
+++ b/mysys/my_bitmap.c
@@ -168,7 +168,7 @@ static inline uint get_first_set(my_bitmap_map value, uint word_pos)
my_bool my_bitmap_init(MY_BITMAP *map, my_bitmap_map *buf, uint n_bits,
- my_bool thread_safe __attribute__((unused)))
+ my_bool thread_safe)
{
DBUG_ENTER("my_bitmap_init");
if (!buf)
diff --git a/mysys/my_error.c b/mysys/my_error.c
index c0698b19a20..f9614e07c6a 100644
--- a/mysys/my_error.c
+++ b/mysys/my_error.c
@@ -131,7 +131,7 @@ void my_error(uint nr, myf MyFlags, ...)
Print an error message.
@note
- Goes through the (sole) function registered in error_handler_hook
+ Just like my_error, but for cases when the error message is not ER(error)
@param error error number
@param format format string
diff --git a/mysys/my_fopen.c b/mysys/my_fopen.c
index 1fa3f9b9b8f..2ac033c8264 100644
--- a/mysys/my_fopen.c
+++ b/mysys/my_fopen.c
@@ -101,6 +101,7 @@ static FILE *my_win_freopen(const char *path, const char *mode, FILE *stream)
HANDLE osfh;
DBUG_ASSERT(path && stream);
+ DBUG_ASSERT(strchr(mode, 'a')); /* We use FILE_APPEND_DATA below */
/* Services don't have stdout/stderr on Windows, so _fileno returns -1. */
if (fd < 0)
@@ -111,15 +112,14 @@ static FILE *my_win_freopen(const char *path, const char *mode, FILE *stream)
fd= _fileno(stream);
}
- if ((osfh= CreateFile(path, GENERIC_READ | GENERIC_WRITE,
+ if ((osfh= CreateFile(path, GENERIC_READ | FILE_APPEND_DATA,
FILE_SHARE_READ | FILE_SHARE_WRITE |
FILE_SHARE_DELETE, NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,
NULL)) == INVALID_HANDLE_VALUE)
return NULL;
- if ((handle_fd= _open_osfhandle((intptr_t)osfh,
- _O_APPEND | _O_TEXT)) == -1)
+ if ((handle_fd= _open_osfhandle((intptr_t)osfh, _O_TEXT)) == -1)
{
CloseHandle(osfh);
return NULL;
diff --git a/mysys/my_redel.c b/mysys/my_redel.c
index 61e61b40791..976fc5a18c3 100644
--- a/mysys/my_redel.c
+++ b/mysys/my_redel.c
@@ -1,5 +1,5 @@
-/*
- Copyright (c) 2000, 2010, Oracle and/or its affiliates
+/* Copyright (c) 2000, 2010, Oracle and/or its affiliates
+ Copyright (c) 2009, 2016, MariaDB
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
@@ -49,7 +49,8 @@ int my_redel(const char *org_name, const char *tmp_name,
DBUG_PRINT("my",("org_name: '%s' tmp_name: '%s' MyFlags: %lu",
org_name,tmp_name,MyFlags));
- if (my_copystat(org_name,tmp_name,MyFlags) < 0)
+ if (!my_disable_copystat_in_redel &&
+ my_copystat(org_name,tmp_name,MyFlags) < 0)
goto end;
if (MyFlags & MY_REDEL_MAKE_BACKUP)
{
diff --git a/mysys/my_static.c b/mysys/my_static.c
index ce9e8831be6..08edf2c4200 100644
--- a/mysys/my_static.c
+++ b/mysys/my_static.c
@@ -98,6 +98,7 @@ my_bool my_disable_sync=0;
my_bool my_disable_async_io=0;
my_bool my_disable_flush_key_blocks=0;
my_bool my_disable_symlinks=0;
+my_bool my_disable_copystat_in_redel=0;
/* Typelib by all clients */
const char *sql_protocol_names_lib[] =
diff --git a/mysys/stacktrace.c b/mysys/stacktrace.c
index 395659238b3..e22fb4162ec 100644
--- a/mysys/stacktrace.c
+++ b/mysys/stacktrace.c
@@ -38,13 +38,13 @@
static char *heap_start;
-#ifdef HAVE_BSS_START
+#if(defined HAVE_BSS_START) && !(defined __linux__)
extern char *__bss_start;
#endif
void my_init_stacktrace()
{
-#ifdef HAVE_BSS_START
+#if(defined HAVE_BSS_START) && !(defined __linux__)
heap_start = (char*) &__bss_start;
#endif
}
diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c
index e8c4ed9c614..a77db04acef 100644
--- a/mysys/thr_lock.c
+++ b/mysys/thr_lock.c
@@ -498,18 +498,6 @@ has_old_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner)
return 0;
}
-static inline my_bool have_specific_lock(THR_LOCK_DATA *data,
- enum thr_lock_type type)
-{
- for ( ; data ; data=data->next)
- {
- if (data->type == type)
- return 1;
- }
- return 0;
-}
-
-
static void wake_up_waiters(THR_LOCK *lock);