summaryrefslogtreecommitdiff
path: root/mysys
diff options
context:
space:
mode:
Diffstat (limited to 'mysys')
-rw-r--r--mysys/Makefile.am3
-rw-r--r--mysys/charset.c116
-rw-r--r--mysys/default.c92
-rw-r--r--mysys/default_modify.c68
-rw-r--r--mysys/hash.c3
-rw-r--r--mysys/my_access.c9
-rw-r--r--mysys/my_bitmap.c45
-rw-r--r--mysys/my_copy.c18
-rw-r--r--mysys/my_fopen.c84
-rw-r--r--mysys/tree.c3
10 files changed, 353 insertions, 88 deletions
diff --git a/mysys/Makefile.am b/mysys/Makefile.am
index f61c95f523a..41a8a3e647a 100644
--- a/mysys/Makefile.am
+++ b/mysys/Makefile.am
@@ -17,7 +17,8 @@
MYSQLDATAdir = $(localstatedir)
MYSQLSHAREdir = $(pkgdatadir)
MYSQLBASEdir= $(prefix)
-INCLUDES = @ZLIB_INCLUDES@ -I$(top_srcdir)/include -I$(srcdir)
+INCLUDES = @ZLIB_INCLUDES@ -I$(top_builddir)/include \
+ -I$(top_srcdir)/include -I$(srcdir)
pkglib_LIBRARIES = libmysys.a
LDADD = libmysys.a ../dbug/libdbug.a \
../strings/libmystrings.a
diff --git a/mysys/charset.c b/mysys/charset.c
index cbd9ba16b4c..4920e7806a2 100644
--- a/mysys/charset.c
+++ b/mysys/charset.c
@@ -561,11 +561,30 @@ CHARSET_INFO *get_charset_by_csname(const char *cs_name,
DBUG_RETURN(cs);
}
+
/*
+ Escape string with backslashes (\)
+
+ SYNOPSIS
+ escape_string_for_mysql()
+ charset_info Charset of the strings
+ to Buffer for escaped string
+ to_length Length of destination buffer, or 0
+ from The string to escape
+ length The length of the string to escape
+
+ DESCRIPTION
+ This escapes the contents of a string by adding backslashes before special
+ characters, and turning others into specific escape sequences, such as
+ turning newlines into \n and null bytes into \0.
+
NOTE
- to keep old C API, to_length may be 0 to mean "big enough"
- RETURN
- the length of the escaped string or ~0 if it did not fit.
+ To maintain compatibility with the old C API, to_length may be 0 to mean
+ "big enough"
+
+ RETURN VALUES
+ ~0 The escaped string did not fit in the to buffer
+ >=0 The length of the escaped string
*/
ulong escape_string_for_mysql(CHARSET_INFO *charset_info,
char *to, ulong to_length,
@@ -573,20 +592,20 @@ ulong escape_string_for_mysql(CHARSET_INFO *charset_info,
{
const char *to_start= to;
const char *end, *to_end=to_start + (to_length ? to_length-1 : 2*length);
- my_bool overflow=0;
+ my_bool overflow= FALSE;
#ifdef USE_MB
my_bool use_mb_flag= use_mb(charset_info);
#endif
for (end= from + length; from < end; from++)
{
- char escape=0;
+ char escape= 0;
#ifdef USE_MB
int tmp_length;
if (use_mb_flag && (tmp_length= my_ismbchar(charset_info, from, end)))
{
if (to + tmp_length > to_end)
{
- overflow=1;
+ overflow= TRUE;
break;
}
while (tmp_length--)
@@ -636,7 +655,7 @@ ulong escape_string_for_mysql(CHARSET_INFO *charset_info,
{
if (to + 2 > to_end)
{
- overflow=1;
+ overflow= TRUE;
break;
}
*to++= '\\';
@@ -646,7 +665,7 @@ ulong escape_string_for_mysql(CHARSET_INFO *charset_info,
{
if (to + 1 > to_end)
{
- overflow=1;
+ overflow= TRUE;
break;
}
*to++= *from;
@@ -656,3 +675,84 @@ ulong escape_string_for_mysql(CHARSET_INFO *charset_info,
return overflow ? (ulong)~0 : (ulong) (to - to_start);
}
+
+/*
+ Escape apostrophes by doubling them up
+
+ SYNOPSIS
+ escape_quotes_for_mysql()
+ charset_info Charset of the strings
+ to Buffer for escaped string
+ to_length Length of destination buffer, or 0
+ from The string to escape
+ length The length of the string to escape
+
+ DESCRIPTION
+ This escapes the contents of a string by doubling up any apostrophes that
+ it contains. This is used when the NO_BACKSLASH_ESCAPES SQL_MODE is in
+ effect on the server.
+
+ NOTE
+ To be consistent with escape_string_for_mysql(), to_length may be 0 to
+ mean "big enough"
+
+ RETURN VALUES
+ ~0 The escaped string did not fit in the to buffer
+ >=0 The length of the escaped string
+*/
+ulong escape_quotes_for_mysql(CHARSET_INFO *charset_info,
+ char *to, ulong to_length,
+ const char *from, ulong length)
+{
+ const char *to_start= to;
+ const char *end, *to_end=to_start + (to_length ? to_length-1 : 2*length);
+ my_bool overflow= FALSE;
+#ifdef USE_MB
+ my_bool use_mb_flag= use_mb(charset_info);
+#endif
+ for (end= from + length; from < end; from++)
+ {
+ char escape= 0;
+#ifdef USE_MB
+ int tmp_length;
+ if (use_mb_flag && (tmp_length= my_ismbchar(charset_info, from, end)))
+ {
+ if (to + tmp_length > to_end)
+ {
+ overflow= TRUE;
+ break;
+ }
+ while (tmp_length--)
+ *to++= *from++;
+ from--;
+ continue;
+ }
+ /*
+ We don't have the same issue here with a non-multi-byte character being
+ turned into a multi-byte character by the addition of an escaping
+ character, because we are only escaping the ' character with itself.
+ */
+#endif
+ if (*from == '\'')
+ {
+ if (to + 2 > to_end)
+ {
+ overflow= TRUE;
+ break;
+ }
+ *to++= '\'';
+ *to++= '\'';
+ }
+ else
+ {
+ if (to + 1 > to_end)
+ {
+ overflow= TRUE;
+ break;
+ }
+ *to++= *from;
+ }
+ }
+ *to= 0;
+ return overflow ? (ulong)~0 : (ulong) (to - to_start);
+}
diff --git a/mysys/default.c b/mysys/default.c
index 1fa8deaa65c..15c92e816a6 100644
--- a/mysys/default.c
+++ b/mysys/default.c
@@ -48,13 +48,14 @@ char *defaults_extra_file=0;
/* Which directories are searched for options (and in which order) */
-#define MAX_DEFAULT_DIRS 5
+#define MAX_DEFAULT_DIRS 6
const char *default_directories[MAX_DEFAULT_DIRS + 1];
#ifdef __WIN__
static const char *f_extensions[]= { ".ini", ".cnf", 0 };
#define NEWLINE "\r\n"
-static char system_dir[FN_REFLEN], shared_system_dir[FN_REFLEN];
+static char system_dir[FN_REFLEN], shared_system_dir[FN_REFLEN],
+ config_dir[FN_REFLEN];
#else
static const char *f_extensions[]= { ".cnf", 0 };
#define NEWLINE "\n"
@@ -286,8 +287,8 @@ int load_defaults(const char *conf_file, const char **groups,
{
DYNAMIC_ARRAY args;
TYPELIB group;
- my_bool found_print_defaults=0;
- uint args_used=0;
+ my_bool found_print_defaults= 0;
+ uint args_used= 0;
int error= 0;
MEM_ROOT alloc;
char *ptr,**res;
@@ -328,8 +329,8 @@ int load_defaults(const char *conf_file, const char **groups,
ctx.args= &args;
ctx.group= &group;
- if (*argc >= 2 + args_used &&
- is_prefix(argv[0][1+args_used], instance_option))
+ if (*argc >= 2 &&
+ is_prefix(argv[0][1], instance_option))
{
args_used++;
defaults_instance= argv[0][args_used]+sizeof(instance_option)-1;
@@ -870,6 +871,45 @@ void print_defaults(const char *conf_file, const char **groups)
#include <help_end.h>
+#ifdef __WIN__
+/*
+ This wrapper for GetSystemWindowsDirectory() will dynamically bind to the
+ function if it is available, emulate it on NT4 Terminal Server by stripping
+ the \SYSTEM32 from the end of the results of GetSystemDirectory(), or just
+ return GetSystemDirectory().
+ */
+
+typedef UINT (WINAPI *GET_SYSTEM_WINDOWS_DIRECTORY)(LPSTR, UINT);
+
+static uint my_get_system_windows_directory(char *buffer, uint size)
+{
+ GET_SYSTEM_WINDOWS_DIRECTORY
+ func_ptr= (GET_SYSTEM_WINDOWS_DIRECTORY)
+ GetProcAddress(GetModuleHandle("kernel32.dll"),
+ "GetSystemWindowsDirectoryA");
+
+ if (func_ptr)
+ return func_ptr(buffer, size);
+ else
+ {
+ /*
+ Windows NT 4.0 Terminal Server Edition:
+ To retrieve the shared Windows directory, call GetSystemDirectory and
+ trim the "System32" element from the end of the returned path.
+ */
+ UINT count= GetSystemDirectory(buffer, size);
+
+ if (count > 8 && stricmp(buffer+(count-8), "\\System32") == 0)
+ {
+ count-= 8;
+ buffer[count] = '\0';
+ }
+ return count;
+ }
+}
+#endif
+
+
/*
Create the list of default directories.
@@ -878,7 +918,8 @@ void print_defaults(const char *conf_file, const char **groups)
2. GetWindowsDirectory()
3. GetSystemWindowsDirectory()
4. getenv(DEFAULT_HOME_ENV)
- 5. ""
+ 5. Direcotry above where the executable is located
+ 6. ""
On Novell NetWare, this is:
1. sys:/etc/
@@ -909,13 +950,10 @@ static void init_default_directories()
if (GetWindowsDirectory(system_dir,sizeof(system_dir)))
*ptr++= (char*)&system_dir;
-#if defined(_MSC_VER) && (_MSC_VER >= 1300)
- /* Only VC7 and up */
- /* Only add shared system directory if different from default. */
- if (GetSystemWindowsDirectory(shared_system_dir,sizeof(shared_system_dir)) &&
+ if (my_get_system_windows_directory(shared_system_dir,
+ sizeof(shared_system_dir)) &&
strcmp(system_dir, shared_system_dir))
*ptr++= (char *)&shared_system_dir;
-#endif
#elif defined(__NETWARE__)
*ptr++= "sys:/etc/";
@@ -931,6 +969,36 @@ static void init_default_directories()
*ptr++= ""; /* Place for defaults_extra_file */
#if !defined(__WIN__) && !defined(__NETWARE__)
*ptr++= "~/";;
+#elif defined(__WIN__)
+ if (GetModuleFileName(NULL, config_dir, sizeof(config_dir)))
+ {
+ char *last= NULL, *end= strend(config_dir);
+ /*
+ Look for the second-to-last \ in the filename, but hang on
+ to a pointer after the last \ in case we're in the root of
+ a drive.
+ */
+ for ( ; end > config_dir; end--)
+ {
+ if (*end == FN_LIBCHAR)
+ {
+ if (last)
+ break;
+ last= end;
+ }
+ }
+
+ if (last)
+ {
+ if (end != config_dir && end[-1] == FN_DEVCHAR) /* Ended up with D:\ */
+ end[1]= 0; /* Keep one \ */
+ else if (end != config_dir)
+ end[0]= 0;
+ else
+ last[1]= 0;
+ }
+ *ptr++= (char *)&config_dir;
+ }
#endif
*ptr= 0; /* end marker */
}
diff --git a/mysys/default_modify.c b/mysys/default_modify.c
index 00caa7beed6..ea384f9f27a 100644
--- a/mysys/default_modify.c
+++ b/mysys/default_modify.c
@@ -20,6 +20,8 @@
#include <my_dir.h>
#define BUFF_SIZE 1024
+/* should be big enough to handle at least one line */
+#define RESERVE 1024
#ifdef __WIN__
#define NEWLINE "\r\n"
@@ -66,8 +68,11 @@ int modify_defaults_file(const char *file_location, const char *option,
FILE *cnf_file;
MY_STAT file_stat;
char linebuff[BUFF_SIZE], *src_ptr, *dst_ptr, *file_buffer;
- uint opt_len, optval_len, sect_len, nr_newlines= 0;
+ uint opt_len, optval_len, sect_len, nr_newlines= 0, buffer_size;
my_bool in_section= FALSE, opt_applied= 0;
+ uint reserve_extended= 1, old_opt_len= 0;
+ uint new_opt_len;
+ int reserve_occupied= 0;
DBUG_ENTER("modify_defaults_file");
if (!(cnf_file= my_fopen(file_location, O_RDWR | O_BINARY, MYF(0))))
@@ -75,28 +80,33 @@ int modify_defaults_file(const char *file_location, const char *option,
/* my_fstat doesn't use the flag parameter */
if (my_fstat(fileno(cnf_file), &file_stat, MYF(0)))
- goto err;
+ goto malloc_err;
opt_len= (uint) strlen(option);
optval_len= (uint) strlen(option_value);
+ new_opt_len= opt_len + 1 + optval_len + NEWLINE_LEN;
+
+ /* calculate the size of the buffer we need */
+ buffer_size= sizeof(char) * (file_stat.st_size +
+ /* option name len */
+ opt_len +
+ /* reserve for '=' char */
+ 1 +
+ /* option value len */
+ optval_len +
+ /* reserve space for newline */
+ NEWLINE_LEN +
+ /* The ending zero */
+ 1 +
+ /* reserve some additional space */
+ RESERVE);
+
/*
Reserve space to read the contents of the file and some more
for the option we want to add.
*/
- if (!(file_buffer= (char*) my_malloc(sizeof(char) *
- (file_stat.st_size +
- /* option name len */
- opt_len +
- /* reserve space for newline */
- NEWLINE_LEN +
- /* reserve for '=' char */
- 1 +
- /* option value len */
- optval_len +
- /* The ending zero */
- 1), MYF(MY_WME))))
-
+ if (!(file_buffer= (char*) my_malloc(buffer_size, MYF(MY_WME))))
goto malloc_err;
sect_len= (uint) strlen(section_name);
@@ -115,13 +125,37 @@ int modify_defaults_file(const char *file_location, const char *option,
}
/* correct the option */
- if (!opt_applied && in_section && !strncmp(src_ptr, option, opt_len) &&
+ if (in_section && !strncmp(src_ptr, option, opt_len) &&
(*(src_ptr + opt_len) == '=' ||
my_isspace(&my_charset_latin1, *(src_ptr + opt_len)) ||
*(src_ptr + opt_len) == '\0'))
{
+ /*
+ we should change all options. If opt_applied is set, we are running
+ into reserved memory area. Hence we should check for overruns.
+ */
+ if (opt_applied)
+ {
+ src_ptr+= opt_len; /* If we correct an option, we know it's name */
+ old_opt_len= opt_len;
+
+ while (*src_ptr++) /* Find the end of the line */
+ old_opt_len++;
+
+ /* could be negative */
+ reserve_occupied+= (int) new_opt_len - (int) old_opt_len;
+ if ((int) reserve_occupied > (int) (RESERVE*reserve_extended))
+ {
+ if (!(file_buffer= (char*) my_realloc(file_buffer, buffer_size +
+ RESERVE*reserve_extended,
+ MYF(MY_WME|MY_FREE_ON_ERROR))))
+ goto malloc_err;
+ reserve_extended++;
+ }
+ }
+ else
+ opt_applied= 1;
dst_ptr= add_option(dst_ptr, option_value, option, remove_option);
- opt_applied= 1;
}
else
{
diff --git a/mysys/hash.c b/mysys/hash.c
index 28f8797288c..45cf7d5ff1d 100644
--- a/mysys/hash.c
+++ b/mysys/hash.c
@@ -277,9 +277,8 @@ static void movelink(HASH_LINK *array,uint find,uint next_link,uint newlink)
record being compared against.
RETURN
- < 0 key of record < key
= 0 key of record == key
- > 0 key of record > key
+ != 0 key of record != key
*/
static int hashcmp(HASH *hash,HASH_LINK *pos,const byte *key,uint length)
diff --git a/mysys/my_access.c b/mysys/my_access.c
index c01031827c0..256749ed447 100644
--- a/mysys/my_access.c
+++ b/mysys/my_access.c
@@ -98,17 +98,16 @@ int check_if_legal_filename(const char *path)
for (reserved_name= reserved_names; *reserved_name; reserved_name++)
{
+ const char *reserved= *reserved_name; /* never empty */
const char *name= path;
- const char *current_reserved_name= *reserved_name;
- while (name != end && *current_reserved_name)
+ do
{
- if (*current_reserved_name != my_toupper(&my_charset_latin1, *name))
+ if (*reserved != my_toupper(&my_charset_latin1, *name))
break;
- current_reserved_name++;
if (++name == end)
DBUG_RETURN(1); /* Found wrong path */
- }
+ } while (*++reserved);
}
DBUG_RETURN(0);
}
diff --git a/mysys/my_bitmap.c b/mysys/my_bitmap.c
index 0260bc2ee41..6cfabad1d3b 100644
--- a/mysys/my_bitmap.c
+++ b/mysys/my_bitmap.c
@@ -159,6 +159,51 @@ void bitmap_free(MY_BITMAP *map)
}
+/*
+ test if bit already set and set it if it was not (thread unsafe method)
+
+ SYNOPSIS
+ bitmap_fast_test_and_set()
+ MAP bit map struct
+ BIT bit number
+
+ RETURN
+ 0 bit was not set
+ !=0 bit was set
+*/
+
+my_bool bitmap_fast_test_and_set(MY_BITMAP *map, uint bitmap_bit)
+{
+ uchar *byte= map->bitmap + (bitmap_bit / 8);
+ uchar bit= 1 << ((bitmap_bit) & 7);
+ uchar res= (*byte) & bit;
+ *byte|= bit;
+ return res;
+}
+
+
+/*
+ test if bit already set and set it if it was not (thread safe method)
+
+ SYNOPSIS
+ bitmap_fast_test_and_set()
+ map bit map struct
+ bitmap_bit bit number
+
+ RETURN
+ 0 bit was not set
+ !=0 bit was set
+*/
+
+my_bool bitmap_test_and_set(MY_BITMAP *map, uint bitmap_bit)
+{
+ my_bool res;
+ DBUG_ASSERT(map->bitmap && bitmap_bit < map->bitmap_size*8);
+ bitmap_lock(map);
+ res= bitmap_fast_test_and_set(map, bitmap_bit);
+ bitmap_unlock(map);
+}
+
uint bitmap_set_next(MY_BITMAP *map)
{
uint bit_found;
diff --git a/mysys/my_copy.c b/mysys/my_copy.c
index 03f3feb54d3..072492172e3 100644
--- a/mysys/my_copy.c
+++ b/mysys/my_copy.c
@@ -16,7 +16,7 @@
#define USES_TYPES /* sys/types is included */
#include "mysys_priv.h"
-#include <sys/stat.h>
+#include <my_dir.h> /* for stat */
#include <m_string.h>
#if defined(HAVE_UTIME_H)
#include <utime.h>
@@ -53,26 +53,28 @@ struct utimbuf {
int my_copy(const char *from, const char *to, myf MyFlags)
{
uint Count;
- int new_file_stat, create_flag;
+ my_bool new_file_stat; /* 1 if we could stat "to" */
+ int create_flag;
File from_file,to_file;
char buff[IO_SIZE];
- struct stat stat_buff,new_stat_buff;
+ MY_STAT stat_buff,new_stat_buff;
DBUG_ENTER("my_copy");
DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags));
from_file=to_file= -1;
- new_file_stat=0;
+ LINT_INIT(new_file_stat);
+ DBUG_ASSERT(!(MyFlags & (MY_FNABP | MY_NABP))); /* for my_read/my_write */
if (MyFlags & MY_HOLD_ORIGINAL_MODES) /* Copy stat if possible */
- new_file_stat=stat((char*) to, &new_stat_buff);
+ new_file_stat= test(my_stat((char*) to, &new_stat_buff, MYF(0)));
if ((from_file=my_open(from,O_RDONLY | O_SHARE,MyFlags)) >= 0)
{
- if (stat(from,&stat_buff))
+ if (!my_stat(from, &stat_buff, MyFlags))
{
my_errno=errno;
goto err;
}
- if (MyFlags & MY_HOLD_ORIGINAL_MODES && !new_file_stat)
+ if (MyFlags & MY_HOLD_ORIGINAL_MODES && new_file_stat)
stat_buff=new_stat_buff;
create_flag= (MyFlags & MY_DONT_OVERWRITE_FILE) ? O_EXCL : O_TRUNC;
@@ -91,7 +93,7 @@ int my_copy(const char *from, const char *to, myf MyFlags)
/* Copy modes if possible */
- if (MyFlags & MY_HOLD_ORIGINAL_MODES && new_file_stat)
+ if (MyFlags & MY_HOLD_ORIGINAL_MODES && !new_file_stat)
DBUG_RETURN(0); /* File copyed but not stat */
VOID(chmod(to, stat_buff.st_mode & 07777)); /* Copy modes */
#if !defined(MSDOS) && !defined(__WIN__) && !defined(__EMX__) && !defined(OS2) && !defined(__NETWARE__)
diff --git a/mysys/my_fopen.c b/mysys/my_fopen.c
index 002e5ca0f06..f07beec9f39 100644
--- a/mysys/my_fopen.c
+++ b/mysys/my_fopen.c
@@ -19,27 +19,36 @@
#include <errno.h>
#include "mysys_err.h"
-static void make_ftype(my_string to,int flag);
+static void make_ftype(my_string to,int flag);
- /* Open a file as stream */
+/*
+ Open a file as stream
-FILE *my_fopen(const char *FileName, int Flags, myf MyFlags)
- /* Path-name of file */
- /* Read | write .. */
- /* Special flags */
+ SYNOPSIS
+ my_fopen()
+ FileName Path-name of file
+ Flags Read | write | append | trunc (like for open())
+ MyFlags Flags for handling errors
+
+ RETURN
+ 0 Error
+ # File handler
+*/
+
+FILE *my_fopen(const char *filename, int flags, myf MyFlags)
{
FILE *fd;
char type[5];
DBUG_ENTER("my_fopen");
- DBUG_PRINT("my",("Name: '%s' Flags: %d MyFlags: %d",
- FileName, Flags, MyFlags));
+ DBUG_PRINT("my",("Name: '%s' flags: %d MyFlags: %d",
+ filename, flags, MyFlags));
/*
if we are not creating, then we need to use my_access to make sure
the file exists since Windows doesn't handle files like "com1.sym"
very well
*/
#ifdef __WIN__
- if (check_if_legal_filename(FileName))
+ if (check_if_legal_filename(filename))
{
errno= EACCES;
fd= 0;
@@ -47,8 +56,8 @@ FILE *my_fopen(const char *FileName, int Flags, myf MyFlags)
else
#endif
{
- make_ftype(type,Flags);
- fd = fopen(FileName, type);
+ make_ftype(type,flags);
+ fd = fopen(filename, type);
}
if (fd != 0)
@@ -65,7 +74,7 @@ FILE *my_fopen(const char *FileName, int Flags, myf MyFlags)
}
pthread_mutex_lock(&THR_LOCK_open);
if ((my_file_info[fileno(fd)].name = (char*)
- my_strdup(FileName,MyFlags)))
+ my_strdup(filename,MyFlags)))
{
my_stream_opened++;
my_file_info[fileno(fd)].type = STREAM_BY_FOPEN;
@@ -81,9 +90,9 @@ FILE *my_fopen(const char *FileName, int Flags, myf MyFlags)
my_errno=errno;
DBUG_PRINT("error",("Got error %d on open",my_errno));
if (MyFlags & (MY_FFNF | MY_FAE | MY_WME))
- my_error((Flags & O_RDONLY) || (Flags == O_RDONLY ) ? EE_FILENOTFOUND :
+ my_error((flags & O_RDONLY) || (flags == O_RDONLY ) ? EE_FILENOTFOUND :
EE_CANTCREATEFILE,
- MYF(ME_BELL+ME_WAITTANG), FileName,my_errno);
+ MYF(ME_BELL+ME_WAITTANG), filename, my_errno);
DBUG_RETURN((FILE*) 0);
} /* my_fopen */
@@ -158,33 +167,39 @@ FILE *my_fdopen(File Filedes, const char *name, int Flags, myf MyFlags)
DBUG_RETURN(fd);
} /* my_fdopen */
+
/*
- make_ftype
- Make a filehandler-open-typestring from ordinary inputflags
+ Make a fopen() typestring from a open() type bitmap
+
+ SYNOPSIS
+ make_ftype()
+ to String for fopen() is stored here
+ flag Flag used by open()
- Note: This routine attempts to find the best possible match
- between a numeric option and a string option that could be
- fed to fopen. There is not a 1 to 1 mapping between the two.
+ IMPLEMENTATION
+ This routine attempts to find the best possible match
+ between a numeric option and a string option that could be
+ fed to fopen. There is not a 1 to 1 mapping between the two.
- r == O_RDONLY
- w == O_WRONLY|O_TRUNC|O_CREAT
- a == O_WRONLY|O_APPEND|O_CREAT
- r+ == O_RDWR
- w+ == O_RDWR|O_TRUNC|O_CREAT
- a+ == O_RDWR|O_APPEND|O_CREAT
+ NOTE
+ On Unix, O_RDONLY is usually 0
+
+ MAPPING
+ r == O_RDONLY
+ w == O_WRONLY|O_TRUNC|O_CREAT
+ a == O_WRONLY|O_APPEND|O_CREAT
+ r+ == O_RDWR
+ w+ == O_RDWR|O_TRUNC|O_CREAT
+ a+ == O_RDWR|O_APPEND|O_CREAT
*/
+
static void make_ftype(register my_string to, register int flag)
{
-#if FILE_BINARY
- /* If we have binary-files */
- reg3 int org_flag=flag;
-#endif
- flag&= ~FILE_BINARY; /* remove binary bit */
-
/* check some possible invalid combinations */
- DBUG_ASSERT(flag & (O_TRUNC|O_APPEND) != O_TRUNC|O_APPEND);
+ DBUG_ASSERT((flag & (O_TRUNC | O_APPEND)) != (O_TRUNC | O_APPEND));
+ DBUG_ASSERT((flag & (O_WRONLY | O_RDWR)) != (O_WRONLY | O_RDWR));
- if (flag & (O_RDONLY|O_WRONLY) == O_WRONLY)
+ if ((flag & (O_RDONLY|O_WRONLY)) == O_WRONLY)
*to++= (flag & O_APPEND) ? 'a' : 'w';
else if (flag & O_RDWR)
{
@@ -201,9 +216,8 @@ static void make_ftype(register my_string to, register int flag)
*to++= 'r';
#if FILE_BINARY /* If we have binary-files */
- if (org_flag & FILE_BINARY)
+ if (flag & FILE_BINARY)
*to++='b';
#endif
*to='\0';
} /* make_ftype */
-
diff --git a/mysys/tree.c b/mysys/tree.c
index bec1ec680f1..1780913961e 100644
--- a/mysys/tree.c
+++ b/mysys/tree.c
@@ -263,6 +263,9 @@ TREE_ELEMENT *tree_insert(TREE *tree, void *key, uint key_size,
if (tree->flag & TREE_NO_DUPS)
return(NULL);
element->count++;
+ /* Avoid a wrap over of the count. */
+ if (! element->count)
+ element->count--;
}
DBUG_EXECUTE("check_tree", test_rb_tree(tree->root););
return element;