|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? 200?, Version 4.0.5
+- Updated ext/mysql/libmysql to version 3.23.32; bug fixes (tim@mysql.com)
- Fixed possible crash in all (non-pcre) regex functions. (Thies)
- Improved str_replace() to accept an array for any parameter - similar
to preg_replace(). (Andrei)
AC_DEFUN(MYSQL_CHECK_GETHOSTNAME_R,[
# Check definition of gethostbyname_r (glibc2.0.100 is different from Solaris)
+ac_save_CXXFLAGS="$CXXFLAGS"
AC_CACHE_CHECK([style of gethostname_r routines], mysql_cv_gethostname_style,
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+if test "$ac_cv_prog_gxx" = "yes"
+then
+ CXXFLAGS="$CXXFLAGS -Werror"
+fi
AC_TRY_COMPILE(
-[#ifndef SCO
+[#if !defined(SCO) && !defined(__osf__)
#define _REENTRANT
#endif
#include <pthread.h>
#include <netdb.h>],
[int skr;
- int res = gethostbyname_r((const char *) 0,
+ skr = gethostbyname_r((const char *) 0,
(struct hostent*) 0, (char*) 0, 0, (struct hostent **) 0, &skr);],
mysql_cv_gethostname_style=glibc2, mysql_cv_gethostname_style=other))
+AC_LANG_RESTORE
+CXXFLAGS="$ac_save_CXXFLAGS"
if test "$mysql_cv_gethostname_style" = "glibc2"
then
- AC_DEFINE(HAVE_GLIBC2_STYLE_GETHOSTBYNAME_R,,[ ])
+ AC_DEFINE(HAVE_GETHOSTBYNAME_R_GLIBC2_STYLE, , [ ])
+fi
+
+# Check 3rd argument of getthostbyname_r
+ac_save_CXXFLAGS="$CXXFLAGS"
+AC_CACHE_CHECK([3 argument to gethostname_r routines], mysql_cv_gethostname_arg,
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+if test "$ac_cv_prog_gxx" = "yes"
+then
+ CXXFLAGS="$CXXFLAGS -Werror"
+fi
+AC_TRY_COMPILE(
+[#if !defined(SCO) && !defined(__osf__)
+#define _REENTRANT
+#endif
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>],
+[int skr;
+
+ skr = gethostbyname_r((const char *) 0, (struct hostent*) 0, (hostent_data*) 0);],
+mysql_cv_gethostname_arg=hostent_data, mysql_cv_gethostname_arg=char))
+AC_LANG_RESTORE
+CXXFLAGS="$ac_save_CXXFLAGS"
+if test "$mysql_cv_gethostname_arg" = "hostent_data"
+then
+ AC_DEFINE(HAVE_GETHOSTBYNAME_R_RETURN_INT, , [ ])
fi
])
#else
void bmove(dst, src, len)
-register byte *dst;
+register char *dst;
register const char *src;
register uint len;
{
#include <m_string.h>
#include <my_dir.h>
+typedef struct cs_id_st {
+ char *name;
+ uint number;
+} CS_ID;
+
const char *charsets_dir = NULL;
static DYNAMIC_ARRAY cs_info_table;
-static TYPELIB available_charsets;
+static CS_ID **available_charsets;
static int charset_initialized=0;
#define MAX_LINE 1024
const char *compiled_charset_name(uint charset_number);
+static uint num_from_csname(CS_ID **cs, const char *name)
+{
+ CS_ID **c;
+ for (c = cs; *c; ++c)
+ if (!strcmp((*c)->name, name))
+ return (*c)->number;
+ return 0; /* this mimics find_type() */
+}
+
+static char *name_from_csnum(CS_ID **cs, uint number)
+{
+ CS_ID **c;
+ if(cs)
+ for (c = cs; *c; ++c)
+ if ((*c)->number == number)
+ return (*c)->name;
+ return (char*) "?"; /* this mimics find_type() */
+}
+
static my_bool get_word(struct simpleconfig_buf_st *fb, char *buf)
{
char *endptr=fb->p;
}
-static char *get_charsets_dir(char *buf)
+char *get_charsets_dir(char *buf)
{
const char *sharedir = SHAREDIR;
DBUG_ENTER("get_charsets_dir");
if (charsets_dir != NULL)
- strnmov(buf, charsets_dir, FN_REFLEN);
+ strmake(buf, charsets_dir, FN_REFLEN-1);
else
{
if (test_if_hard_path(sharedir) ||
}
-static my_bool read_charset_index(TYPELIB *charsets, myf myflags)
+static my_bool read_charset_index(CS_ID ***charsets, myf myflags)
{
struct simpleconfig_buf_st fb;
- char buf[MAX_LINE];
+ char buf[MAX_LINE], num_buf[MAX_LINE];
DYNAMIC_ARRAY cs;
- my_string s;
+ CS_ID *csid;
strmov(get_charsets_dir(buf), "Index");
fb.buf[0] = '\0';
fb.p = fb.buf;
- if (init_dynamic_array(&cs, sizeof(my_string), 32, 32))
+ if (init_dynamic_array(&cs, sizeof(CS_ID *), 32, 32))
return TRUE;
- while (!get_word(&fb, buf))
+ while (!get_word(&fb, buf) && !get_word(&fb, num_buf))
{
+ uint csnum;
uint length;
- if (!(s= (char*) my_once_alloc(length= (uint) strlen(buf)+1, myflags)))
+
+ if (!(csnum = atoi(num_buf)))
+ {
+ /* corrupt Index file */
+ my_fclose(fb.f,myflags);
+ return TRUE;
+ }
+
+ if (!(csid = (CS_ID*) my_once_alloc(sizeof(CS_ID), myflags)) ||
+ !(csid->name=
+ (char*) my_once_alloc(length= (uint) strlen(buf)+1, myflags)))
{
my_fclose(fb.f,myflags);
return TRUE;
}
- memcpy(s,buf,length);
- insert_dynamic(&cs, (gptr) &s);
+ memcpy(csid->name,buf,length);
+ csid->number = csnum;
+
+ insert_dynamic(&cs, (gptr) &csid);
}
my_fclose(fb.f,myflags);
- /* I seriously doubt this is the best way to initialize this
- * TYPELIB from the Index file. But it's the best way I could
- * come up with right now. */
- charsets->count = cs.elements;
- charsets->name = "";
- if (!(charsets->type_names =
- (const char **) my_once_alloc((cs.elements + 1) * sizeof(const char *),
- myflags)))
+ if (!(*charsets =
+ (CS_ID **) my_once_alloc((cs.elements + 1) * sizeof(CS_ID *), myflags)))
return TRUE;
/* unwarranted chumminess with dynamic_array implementation? */
- memcpy((char*) charsets->type_names, cs.buffer,
- cs.elements * sizeof(my_string *));
- charsets->type_names[cs.elements] = NullS;
+ memcpy((byte *) *charsets, cs.buffer, cs.elements * sizeof(CS_ID *));
+ (*charsets)[cs.elements] = NULL;
delete_dynamic(&cs);
return FALSE;
charset_initialized=1;
pthread_mutex_unlock(&THR_LOCK_charset);
}
- return error || available_charsets.count == 0;
+ if(!available_charsets || !available_charsets[0])
+ error = TRUE;
+ return error;
}
static void get_charset_conf_name(uint cs_number, char *buf)
{
strxmov(get_charsets_dir(buf),
- get_type(&available_charsets, cs_number - 1), ".conf", NullS);
+ name_from_csnum(available_charsets, cs_number), ".conf", NullS);
}
if (error)
return compiled_charset_number(charset_name);
else
- return find_type((char*)charset_name, &available_charsets, 1);
+ return num_from_csname(available_charsets, charset_name);
}
const char *get_charset_name(uint charset_number)
if (error)
return compiled_charset_name(charset_number);
else
- return get_type(&available_charsets, charset_number - 1);
+ return name_from_csnum(available_charsets, charset_number);
}
(void) init_available_charsets(MYF(0)); /* If it isn't initialized */
cs=get_internal_charset(cs_number);
- if (!cs && flags & MY_WME)
+ if (!cs && (flags & MY_WME))
{
char index_file[FN_REFLEN], cs_string[23];
strmov(get_charsets_dir(index_file), "Index");
DYNAMIC_STRING s;
char *p;
+ (void)init_available_charsets(MYF(0));
init_dynamic_string(&s, NullS, 256, 1024);
if (want_flags & MY_COMPILED_SETS)
if (want_flags & MY_CONFIG_SETS)
{
- uint i;
- const char *cs_name;
+ CS_ID **c;
char buf[FN_REFLEN];
- MY_STAT stat;
-
- for (i = 0; i < available_charsets.count; i++)
- {
- cs_name = get_type(&available_charsets, i);
- if (charset_in_string(cs_name, &s))
- continue;
- get_charset_conf_name(i + 1, buf);
- if (!my_stat(buf, &stat, MYF(0)))
- continue; /* conf file doesn't exist */
- dynstr_append(&s, cs_name);
- dynstr_append(&s, " ");
- }
+ MY_STAT status;
+
+ if((c=available_charsets))
+ for (; *c; ++c)
+ {
+ if (charset_in_string((*c)->name, &s))
+ continue;
+ get_charset_conf_name((*c)->number, buf);
+ if (!my_stat(buf, &status, MYF(0)))
+ continue; /* conf file doesn't exist */
+ dynstr_append(&s, (*c)->name);
+ dynstr_append(&s, " ");
+ }
}
if (want_flags & MY_INDEX_SETS)
{
- uint i;
- for (i = 0; i < available_charsets.count; i++)
- charset_append(&s, get_type(&available_charsets, i));
+ CS_ID **c;
+ for (c = available_charsets; *c; ++c)
+ charset_append(&s, (*c)->name);
}
if (want_flags & MY_LOADED_SETS)
#define SYSTEM_TYPE "Win95/Win98"
#endif
-#ifdef _WIN32
-#define MACHINE_TYPE "i32" /* Define to machine type name */
+#ifdef _WIN64
+#define MACHINE_TYPE "ia64" /* Define to machine type name */
#else
-#define MACHINE_TYPE "i64" /* Define to machine type name */
+#define MACHINE_TYPE "i32" /* Define to machine type name */
+#ifndef _WIN32
+#define _WIN32 /* Compatible with old source */
#endif
+#ifndef __WIN32__
+#define __WIN32__
+#endif
+#endif /* _WIN64 */
#ifndef __WIN__
#define __WIN__ /* To make it easier in VC++ */
#endif
#define SIGQUIT SIGTERM /* No SIGQUIT */
#undef _REENTRANT /* Crashes something for win32 */
+#undef SAFE_MUTEX /* Can't be used on windows */
#define LONGLONG_MIN ((__int64) 0x8000000000000000)
#define LONGLONG_MAX ((__int64) 0x7FFFFFFFFFFFFFFF)
#define HAVE_RINT /* defined in this file */
#define NO_FCNTL_NONBLOCK /* No FCNTL */
#define HAVE_ALLOCA
-/* #define HAVE_COMPRESS */
+#define HAVE_STRPBRK
+#define HAVE_STRSTR
+#define HAVE_COMPRESS
#ifdef NOT_USED
#define HAVE_SNPRINTF /* Gave link error */
#define FN_NETWORK_DRIVES /* Uses \\ to indicate network drives */
#define FN_NO_CASE_SENCE /* Files are not case-sensitive */
#define FN_LOWER_CASE TRUE /* Files are represented in lower case */
-#define MY_NFILE 127 /* This is only used to save filenames */
-
+#define MY_NFILE 1024
+#define DO_NOT_REMOVE_THREAD_WRAPPERS
#define thread_safe_increment(V,L) InterlockedIncrement((long*) &(V))
/* The following is only used for statistics, so it should be good enough */
#ifdef __NT__ /* This should also work on Win98 but .. */
#define DEBUGGER_ON _no_db_=0
#define DBUG_LOCK_FILE { _db_lock_file(); }
#define DBUG_UNLOCK_FILE { _db_unlock_file(); }
+#define DBUG_ASSERT(A) A
#else /* No debugger */
#define DBUG_ENTER(a1)
#define DEBUGGER_ON
#define DBUG_LOCK_FILE
#define DBUG_UNLOCK_FILE
+#define DBUG_ASSERT(A) {}
#endif
#ifdef __cplusplus
}
** The following arguments are handled automaticly; If used, they must be
** first argument on the command line!
** --no-defaults ; no options are read.
-** --print-defaults ; Print the modified command line and exit
** --defaults-file=full-path-to-default-file ; Only this file will be read.
+** --defaults-extra-file=full-path-to-default-file ; Read this file before ~/
+** --print-defaults ; Print the modified command line and exit
****************************************************************************/
#undef SAFEMALLOC /* safe_malloc is not yet initailized */
#include "m_string.h"
#include "m_ctype.h"
+char *defaults_extra_file=0;
+
/* Which directories are searched for options (and in which order) */
const char *default_directories[]= {
#ifdef DATADIR
DATADIR,
#endif
+"", /* Place for defaults_extra_dir */
#ifndef __WIN__
"~/",
#endif
int *argc, char ***argv)
{
DYNAMIC_ARRAY args;
- const char **dirs, *extra_default_file;
+ const char **dirs, *forced_default_file;
TYPELIB group;
my_bool found_print_defaults=0;
+ uint args_used=0;
MEM_ROOT alloc;
char *ptr,**res;
DBUG_ENTER("load_defaults");
- init_alloc_root(&alloc,128);
+ init_alloc_root(&alloc,128,0);
if (*argc >= 2 && !strcmp(argv[0][1],"--no-defaults"))
{
/* remove the --no-defaults argument and return only the other arguments */
}
/* Check if we want to force the use a specific default file */
- extra_default_file=0;
- if (*argc >= 2 && is_prefix(argv[0][1],"--defaults-file="))
- extra_default_file=strchr(argv[0][1],'=')+1;
+ forced_default_file=0;
+ if (*argc >= 2)
+ {
+ if (is_prefix(argv[0][1],"--defaults-file="))
+ {
+ forced_default_file=strchr(argv[0][1],'=')+1;
+ args_used++;
+ }
+ else if (is_prefix(argv[0][1],"--defaults-extra-file="))
+ {
+ defaults_extra_file=strchr(argv[0][1],'=')+1;
+ args_used++;
+ }
+ }
group.count=0;
group.name= "defaults";
if (init_dynamic_array(&args, sizeof(char*),*argc, 32))
goto err;
- if (extra_default_file)
+ if (forced_default_file)
{
- if (search_default_file(&args, &alloc, "", extra_default_file, "",
+ if (search_default_file(&args, &alloc, "", forced_default_file, "",
&group))
goto err;
}
if (search_default_file(&args, &alloc, system_dir, conf_file, windows_ext,
&group))
goto err;
+#endif
+#ifdef __EMX__
+ if (getenv("ETC") &&
+ search_default_file(&args, &alloc, getenv("ETC"), conf_file,
+ default_ext, &group))
+ goto err;
#endif
for (dirs=default_directories ; *dirs; dirs++)
{
- if (search_default_file(&args, &alloc, *dirs, conf_file, default_ext,
- &group))
+ int error=0;
+ if (**dirs)
+ error=search_default_file(&args, &alloc, *dirs, conf_file,
+ default_ext, &group);
+ else if (defaults_extra_file)
+ error=search_default_file(&args, &alloc, NullS, defaults_extra_file,
+ default_ext, &group);
+ if (error)
goto err;
}
}
/* copy name + found arguments + command line arguments to new array */
res[0]=argv[0][0];
memcpy((gptr) (res+1), args.buffer, args.elements*sizeof(char*));
- if (extra_default_file)
- {
- --*argc; /* Skipp --defaults-file */
- ++*argv;
- }
+ /* Skipp --defaults-file and --defaults-extra-file */
+ (*argc)-= args_used;
+ (*argv)+= args_used;
/* Check if we wan't to see the new argument list */
if (*argc >= 2 && !strcmp(argv[0][1],"--print-defaults"))
{
MEM_ROOT ptr;
memcpy_fixed((char*) &ptr,(char *) argv - sizeof(ptr), sizeof(ptr));
- free_root(&ptr);
+ free_root(&ptr,MYF(0));
}
#ifdef __WIN__
GetWindowsDirectory(name,sizeof(name));
printf("%s\\%s%s ",name,conf_file,have_ext ? "" : windows_ext);
+#endif
+#ifdef __EMX__
+ if (getenv("ETC"))
+ printf("%s\\%s%s ", getenv("ETC"), conf_file, default_ext);
#endif
for (dirs=default_directories ; *dirs; dirs++)
{
- strmov(name,*dirs);
+ if (**dirs)
+ strmov(name,*dirs);
+ else if (defaults_extra_file)
+ strmov(name,defaults_extra_file);
+ else
+ continue;
convert_dirname(name);
if (name[0] == FN_HOMELIB) /* Add . to filenames in home */
strcat(name,".");
puts("\nThe following options may be given as the first argument:\n\
--print-defaults Print the program argument list and exit\n\
--no-defaults Don't read default options from any options file\n\
---defaults-file=# Only read default options from the given file #");
+--defaults-file=# Only read default options from the given file #\n\
+--defaults-extra-file=# Read this file after the global files are read");
}
"%d files and %d streams is left open\n",
"Disk is full writing '%s'. Waiting for someone to free space...",
"Can't create directory '%s' (Errcode: %d)",
- "Character set '%s' is not a compiled character set and is not specified in the '%s' file"
+ "Character set '%s' is not a compiled character set and is not specified in the '%s' file",
+ "Out of resources when opening file '%s' (Errcode: %d)",
};
void init_glob_errs(void)
EE(EE_DISK_FULL) = "Disk is full writing '%s'. Waiting for someone to free space...";
EE(EE_CANT_MKDIR) ="Can't create directory '%s' (Errcode: %d)";
EE(EE_UNKNOWN_CHARSET)= "Character set is not a compiled character set and is not specified in the %s file";
+ EE(EE_OUT_OF_FILERESOURCES)="Out of resources when opening file '%s' (Errcode: %d)",
}
#endif
for i in $@; do
sed \
+ -e '/Copyright Abandoned.*MySQL.*/,/NO WARRANTY of any kind/c\
+/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB \
+This file is public domain and comes with NO WARRANTY of any kind */' \
-e '/Copyright.*MySQL.*/,/MA 02111/c\
/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB \
- This file is public domain and comes with NO WARRANTY of any kind */' \
+This file is public domain and comes with NO WARRANTY of any kind */' \
-e '/Copyright (C) .*MySQL.*TCX/,/For a more info/c\
/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB \
- This file is public domain and comes with NO WARRANTY of any kind */' \
+This file is public domain and comes with NO WARRANTY of any kind */' \
-e '/Copyright (C) .*TCX.*Monty/,/For a more info/c\
/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB \
- This file is public domain and comes with NO WARRANTY of any kind */' \
+This file is public domain and comes with NO WARRANTY of any kind */' \
-e '/Copyright (C) .... Monty.*/,/be preserved on all copies/c\
/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB \
- This file is public domain and comes with NO WARRANTY of any kind */' \
+This file is public domain and comes with NO WARRANTY of any kind */' \
< $i > tmp
cp tmp $i
done
#ifndef _global_h
#define _global_h
-#if defined(_WIN32) || defined(_WIN64)
+#if defined( __EMX__) && !defined( MYSQL_SERVER)
+/* moved here to use below VOID macro redefinition */
+#define INCL_BASE
+#define INCL_NOPMAPI
+#include <os2.h>
+#endif /* __EMX__ */
+
+#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
#include <config-win.h>
#else
#include <my_config.h>
#endif
#endif /* _cplusplus */
+/* Fix problem with S_ISLNK() on Linux */
+#if defined(HAVE_LINUXTHREADS)
+#undef _GNU_SOURCE
+#define _GNU_SOURCE 1
+#endif
+
/* The client defines this to avoid all thread code */
#if defined(UNDEF_THREADS_HACK)
#undef THREAD
#ifndef __STDC_EXT__
#define __STDC_EXT__ 1 /* To get large file support on hpux */
#endif
-#if defined(THREAD) && defined(HAVE_LINUXTHREADS) && defined(HAVE_PTHREAD_RWLOCK_RDLOCK)
-#define _GNU_SOURCE 1
-#endif
#if defined(THREAD) && !defined(__WIN__)
+#ifndef _POSIX_PTHREAD_SEMANTICS
#define _POSIX_PTHREAD_SEMANTICS /* We want posix threads */
+#endif
/* was #if defined(HAVE_LINUXTHREADS) || defined(HAVE_DEC_THREADS) || defined(HPUX) */
#if !defined(SCO)
#define _REENTRANT 1 /* Some thread libraries require this */
#endif
/* In Linux-alpha we have atomic.h if we are using gcc */
-#if defined(HAVE_LINUXTHREADS) && defined(__GNUC__) && defined(__alpha__) && (__GNUC__ > 2 || ( __GNUC__ == 2 && __GNUC_MINOR__ >= 95))
+#if defined(HAVE_LINUXTHREADS) && defined(__GNUC__) && defined(__alpha__) && (__GNUC__ > 2 || ( __GNUC__ == 2 && __GNUC_MINOR__ >= 95)) && !defined(HAVE_ATOMIC_ADD)
#define HAVE_ATOMIC_ADD
#define HAVE_ATOMIC_SUB
#endif
/* In Linux-ia64 including atomic.h will give us an error */
-#if defined(HAVE_LINUXTHREADS) && defined(__GNUC__) && defined(__ia64__)
+#if (defined(HAVE_LINUXTHREADS) && defined(__GNUC__) && defined(__ia64__)) || !defined(THREAD)
#undef HAVE_ATOMIC_ADD
#undef HAVE_ATOMIC_SUB
#endif
typedef SOCKET_SIZE_TYPE size_socket;
#endif
+#ifndef SOCKOPT_OPTLEN_TYPE
+#define SOCKOPT_OPTLEN_TYPE size_socket
+#endif
+
/* file create flags */
#ifndef O_SHARE
#define FN_DEVCHAR ':'
#ifndef FN_LIBCHAR
+#ifdef __EMX__
+#define FN_LIBCHAR '\\'
+#define FN_ROOTDIR "\\"
+#else
#define FN_LIBCHAR '/'
#define FN_ROOTDIR "/"
-#define MY_NFILE 127 /* This is only used to save filenames */
+#endif
+#define MY_NFILE 1024 /* This is only used to save filenames */
#endif
/* #define EXT_IN_LIBNAME */
#undef HAVE_MLOCK
#undef HAVE_TEMPNAM /* Use ours */
#undef HAVE_PTHREAD_SETPRIO
+#undef HAVE_FTRUNCATE
+#undef HAVE_READLINK
#endif
/* This is from the old m-machine.h file */
*((T)+4)=(uchar) (((A) >> 32)); }
#define int8store(T,A) *((ulonglong *) (T))= (ulonglong) (A)
-#define doubleget(V,M) { *((long *) &V) = *((long*) M); \
- *(((long *) &V)+1) = *(((long*) M)+1); }
-#define doublestore(T,V) { *((long *) T) = *((long*) &V); \
- *(((long *) T)+1) = *(((long*) &V)+1); }
+typedef union {
+ double v;
+ long m[2];
+} doubleget_union;
+#define doubleget(V,M) { ((doubleget_union *)&V)->m[0] = *((long*) M); \
+ ((doubleget_union *)&V)->m[1] = *(((long*) M)+1); }
+#define doublestore(T,V) { *((long *) T) = ((doubleget_union *)&V)->m[0]; \
+ *(((long *) T)+1) = ((doubleget_union *)&V)->m[1]; }
#define float4get(V,M) { *((long *) &(V)) = *((long*) (M)); }
#define float8get(V,M) doubleget((V),(M))
#define float4store(V,M) memcpy((byte*) V,(byte*) (&M),sizeof(float))
#endif
#endif
+#ifndef THREAD
+#define thread_safe_increment(V,L) (V)++
+#define thread_safe_add(V,C,L) (V)+=(C)
+#define thread_safe_sub(V,C,L) (V)-=(C)
+#define statistic_increment(V,L) (V)++
+#define statistic_add(V,C,L) (V)+=(C)
+#endif
#endif /* _global_h */
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_LOCAL_FILES | CLIENT_TRANSACTIONS)
+#ifdef __WIN__
+#define CONNECT_TIMEOUT 20
+#else
+#define CONNECT_TIMEOUT 0
+#endif
+
#if defined(MSDOS) || defined(__WIN__)
#define ERRNO WSAGetLastError()
#define perror(A)
* Base version coded by Steve Bernacki, Jr. <steve@navinet.net>
*****************************************************************************/
-static int connect2(File s, const struct sockaddr *name, uint namelen, uint to)
+static int connect2(my_socket s, const struct sockaddr *name, uint namelen,
+ uint timeout)
{
#if defined(__WIN__)
return connect(s, (struct sockaddr*) name, namelen);
#else
int flags, res, s_err;
- size_socket s_err_size = sizeof(uint);
+ SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint);
fd_set sfds;
struct timeval tv;
time_t start_time, now_time;
* exactly like the normal connect() call does.
*/
- if (to == 0)
+ if (timeout == 0)
return connect(s, (struct sockaddr*) name, namelen);
flags = fcntl(s, F_GETFL, 0); /* Set socket to not block */
start_time = time(NULL);
for (;;)
{
- tv.tv_sec = (long) to;
+ tv.tv_sec = (long) timeout;
tv.tv_usec = 0;
if ((res = select(s+1, NULL, &sfds, NULL, &tv)) >= 0)
break;
now_time=time(NULL);
- to-= (uint) (now_time - start_time);
- if (errno != EINTR || (int) to <= 0)
+ timeout-= (uint) (now_time - start_time);
+ if (errno != EINTR || (int) timeout <= 0)
return -1;
}
return(-1);
if (s_err)
- { /* getsockopt() could suceed */
+ { /* getsockopt could succeed */
errno = s_err;
return(-1); /* but return an error... */
}
{
if (cur)
{
- free_root(&cur->alloc);
+ free_root(&cur->alloc,MYF(0));
my_free((gptr) cur,MYF(0));
}
}
{
DBUG_ENTER("free_old_query");
if (mysql->fields)
- free_root(&mysql->field_alloc);
- init_alloc_root(&mysql->field_alloc,8192); /* Assume rowlength < 8192 */
+ free_root(&mysql->field_alloc,MYF(0));
+ init_alloc_root(&mysql->field_alloc,8192,0); /* Assume rowlength < 8192 */
mysql->fields=0;
mysql->field_count=0; /* For API */
DBUG_VOID_RETURN;
static void read_user_name(char *name)
{
- char *str=getenv("USER");
- strmov(name,str ? str : "ODBC"); /* ODBC will send user variable */
+ char *str=getenv("USER"); /* ODBC will send user variable */
+ strmake(name,str ? str : "ODBC", USERNAME_LENGTH);
}
#endif
**************************************************************************/
void STDCALL
-mysql_debug(const char *debug)
+mysql_debug(const char *debug __attribute__((unused)))
{
#ifndef DBUG_OFF
char *env;
}
free_rows(result->data);
if (result->fields)
- free_root(&result->field_alloc);
+ free_root(&result->field_alloc,MYF(0));
if (result->row)
my_free((gptr) result->row,MYF(0));
my_free((gptr) result,MYF(0));
static const char *default_options[]=
{"port","socket","compress","password","pipe", "timeout", "user",
"init-command", "host", "database", "debug", "return-found-rows",
- "ssl_key" ,"ssl_cert" ,"ssl_ca" ,"ssl_capath",
- "character-set-dir", "default-character-set",
+ "ssl-key" ,"ssl-cert" ,"ssl-ca" ,"ssl-capath",
+ "character-set-dir", "default-character-set", "interactive-timeout",
+ "connect_timeout",
NullS
};
case 5: /* pipe */
options->named_pipe=1; /* Force named pipe */
break;
+ case 20: /* connect_timeout */
case 6: /* timeout */
if (opt_arg)
options->connect_timeout=atoi(opt_arg);
my_free(options->charset_name,MYF(MY_ALLOW_ZERO_PTR));
options->charset_name = my_strdup(opt_arg, MYF(MY_WME));
break;
+ case 19: /* Interactive-timeout */
+ options->client_flag|=CLIENT_INTERACTIVE;
+ break;
default:
DBUG_PRINT("warning",("unknown option: %s",option[0]));
}
field->flags= (uint) (uchar) row->data[4][0];
field->decimals=(uint) (uchar) row->data[4][1];
}
+ if (INTERNAL_NUM_FIELD(field))
+ field->flags|= NUM_FLAG;
if (default_value && row->data[5])
field->def=strdup_root(alloc,(char*) row->data[5]);
else
strmov(net->last_error,ER(net->last_errno));
DBUG_RETURN(0);
}
- init_alloc_root(&result->alloc,8192); /* Assume rowlength < 8192 */
+ init_alloc_root(&result->alloc,8192,0); /* Assume rowlength < 8192 */
result->alloc.min_malloc=sizeof(MYSQL_ROWS);
prev_ptr= &result->data;
result->rows=0;
}
else
bzero((char*) (mysql),sizeof(*(mysql)));
-#ifdef __WIN__
- mysql->options.connect_timeout=20;
-#endif
+ mysql->options.connect_timeout=CONNECT_TIMEOUT;
#if defined(SIGPIPE) && defined(THREAD)
if (!((mysql)->client_flag & CLIENT_IGNORE_SIGPIPE))
(void) signal(SIGPIPE,pipe_sig_handler);
const char *passwd, const char *db,
uint port, const char *unix_socket,uint client_flag)
{
- char buff[100],charset_name_buff[16],*end,*host_info, *charset_name;
- int sock;
+ char buff[NAME_LEN+USERNAME_LENGTH+100],charset_name_buff[16];
+ char *end,*host_info,*charset_name;
+ my_socket sock;
uint32 ip_addr;
struct sockaddr_in sock_addr;
uint pkt_length;
host=LOCAL_HOST;
sprintf(host_info=buff,ER(CR_TCP_CONNECTION),host);
DBUG_PRINT("info",("Server name: '%s'. TCP sock: %d", host,port));
- if ((sock = socket(AF_INET,SOCK_STREAM,0)) == SOCKET_ERROR)
+ /* _WIN64 ; Assume that the (int) range is enough for socket() */
+ if ((sock = (my_socket) socket(AF_INET,SOCK_STREAM,0)) == SOCKET_ERROR)
{
net->last_errno=CR_IPSOCK_ERROR;
sprintf(net->last_error,ER(net->last_errno),ERRNO);
if (!net->vio || my_net_init(net, net->vio))
{
vio_delete(net->vio);
+ net->vio = 0;
net->last_errno=CR_OUT_OF_MEMORY;
strmov(net->last_error,ER(net->last_errno));
goto error;
/* Get version info */
mysql->protocol_version= PROTOCOL_VERSION; /* Assume this */
+ if (mysql->options.connect_timeout &&
+ vio_poll_read(net->vio, mysql->options.connect_timeout))
+ {
+ net->last_errno= CR_SERVER_LOST;
+ strmov(net->last_error,ER(net->last_errno));
+ goto error;
+ }
if ((pkt_length=net_safe_read(mysql)) == packet_error)
goto error;
{
charset_name=charset_name_buff;
sprintf(charset_name,"%d",mysql->server_language); /* In case of errors */
- mysql->charset=get_charset((uint8) mysql->server_language, MYF(MY_WME));
+ if (!(mysql->charset =
+ get_charset((uint8) mysql->server_language, MYF(MY_WME))))
+ mysql->charset = default_charset_info; /* shouldn't be fatal */
+
}
else
mysql->charset=default_charset_info;
if (!mysql->charset)
{
net->last_errno=CR_CANT_READ_CHARSET;
- sprintf(net->last_error,ER(net->last_errno),
- charset_name ? charset_name : "unknown",
- mysql->options.charset_dir ? mysql->options.charset_dir :
- "default");
+ if (mysql->options.charset_dir)
+ sprintf(net->last_error,ER(net->last_errno),
+ charset_name ? charset_name : "unknown",
+ mysql->options.charset_dir);
+ else
+ {
+ char cs_dir_name[FN_REFLEN];
+ get_charsets_dir(cs_dir_name);
+ sprintf(net->last_error,ER(net->last_errno),
+ charset_name ? charset_name : "unknown",
+ cs_dir_name);
+ }
goto error;
}
mysql->unix_socket=0;
strmov(mysql->server_version,(char*) net->read_pos+1);
mysql->port=port;
- mysql->client_flag=client_flag | mysql->options.client_flag;
- DBUG_PRINT("info",("Server version = '%s' capabilites: %ld status: %d",
- mysql->server_version,mysql->server_capabilities,
- mysql->server_status));
+ client_flag|=mysql->options.client_flag;
/* Send client information for access check */
client_flag|=CLIENT_CAPABILITIES;
if (db)
client_flag|=CLIENT_CONNECT_WITH_DB;
#ifdef HAVE_COMPRESS
- if (mysql->server_capabilities & CLIENT_COMPRESS &&
- (mysql->options.compress || client_flag & CLIENT_COMPRESS))
+ if ((mysql->server_capabilities & CLIENT_COMPRESS) &&
+ (mysql->options.compress || (client_flag & CLIENT_COMPRESS)))
client_flag|=CLIENT_COMPRESS; /* We will use compression */
else
#endif
}
#endif /* HAVE_OPENSSL */
+ DBUG_PRINT("info",("Server version = '%s' capabilites: %ld status: %d client_flag: %d",
+ mysql->server_version,mysql->server_capabilities,
+ mysql->server_status, client_flag));
+
int3store(buff+2,max_allowed_packet);
if (user && user[0])
- strmake(buff+5,user,32);
+ strmake(buff+5,user,32); /* Max user name */
else
read_user_name((char*) buff+5);
#ifdef _CUSTOMCONFIG_
(my_bool) (mysql->protocol_version == 9));
if (db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB))
{
- end=strmov(end+1,db);
+ end=strmake(end+1,db,NAME_LEN);
mysql->db=my_strdup(db,MYF(MY_WME));
db=0;
}
return mysql_real_query(mysql,query, (uint) strlen(query));
}
+int STDCALL
+mysql_send_query(MYSQL* mysql, const char* query)
+{
+ return mysql_real_send_query(mysql, query, strlen(query));
+}
+
+/* send the query and return so we can do something else */
+/* needs to be followed by mysql_reap_query() when we want to
+ finish processing it
+*/
+int STDCALL
+mysql_real_send_query(MYSQL* mysql, const char* query, uint len)
+{
+ return simple_command(mysql, COM_QUERY, query, len, 1);
+}
+
+int STDCALL
+mysql_reap_query(MYSQL* mysql)
+{
+ uchar *pos;
+ ulong field_count;
+ MYSQL_DATA *fields;
+ uint len;
+ DBUG_ENTER("mysql_reap_query");
+ DBUG_PRINT("enter",("handle: %lx",mysql));
+ if((len = net_safe_read(mysql)) == packet_error)
+ DBUG_RETURN(-1);
+ free_old_query(mysql); /* Free old result */
+ get_info:
+ pos=(uchar*) mysql->net.read_pos;
+ if ((field_count= net_field_length(&pos)) == 0)
+ {
+ mysql->affected_rows= net_field_length_ll(&pos);
+ mysql->insert_id= net_field_length_ll(&pos);
+ if (mysql->server_capabilities & CLIENT_TRANSACTIONS)
+ {
+ mysql->server_status=uint2korr(pos); pos+=2;
+ }
+ if (pos < mysql->net.read_pos+len && net_field_length(&pos))
+ mysql->info=(char*) pos;
+ DBUG_RETURN(0);
+ }
+ if (field_count == NULL_LENGTH) /* LOAD DATA LOCAL INFILE */
+ {
+ int error=send_file_to_server(mysql,(char*) pos);
+ if ((len=net_safe_read(mysql)) == packet_error || error)
+ DBUG_RETURN(-1);
+ goto get_info; /* Get info packet */
+ }
+ if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT))
+ mysql->server_status|= SERVER_STATUS_IN_TRANS;
+
+ mysql->extra_info= net_field_length_ll(&pos); /* Maybe number of rec */
+ if (!(fields=read_rows(mysql,(MYSQL_FIELD*) 0,5)))
+ DBUG_RETURN(-1);
+ if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc,
+ (uint) field_count,0,
+ (my_bool) test(mysql->server_capabilities &
+ CLIENT_LONG_FLAG))))
+ DBUG_RETURN(-1);
+ mysql->status=MYSQL_STATUS_GET_RESULT;
+ mysql->field_count=field_count;
+ DBUG_RETURN(0);
+
+}
int STDCALL
mysql_real_query(MYSQL *mysql, const char *query, uint length)
#if !defined(HAVE_MEMCPY) && !defined(HAVE_MEMMOVE)
# define memcpy(d, s, n) bcopy ((s), (d), (n))
# define memset(A,C,B) bfill((A),(B),(C))
-# define memmove(d, s, n) bmove ((s), (d), (n))
+# define memmove(d, s, n) bmove ((d), (s), (n))
#elif defined(HAVE_MEMMOVE)
# define bmove(d, s, n) memmove((d), (s), (n))
#else
#endif
#if !defined(HAVE_BMOVE) && !defined(bmove)
-extern void bmove(gptr dst,const char *src,uint len);
+extern void bmove(char *dst, const char *src,uint len);
#endif
extern void bmove_upp(char *dst,const char *src,uint len);
#define FN_DEVCHAR '\0' /* For easier code */
#endif
-void convert_dirname(my_string to)
+char *convert_dirname(my_string to)
{
+ reg1 char *pos;
#ifdef FN_UPPER_CASE
caseup_str(to);
#endif
#endif
#if FN_LIBCHAR != '/'
{
- reg1 my_string pos;
pos=to-1; /* Change from '/' */
while ((pos=strchr(pos+1,'/')) != 0)
*pos=FN_LIBCHAR;
#endif
#ifdef FN_C_BEFORE_DIR_2
{
- reg1 my_string pos;
for (pos=to ; *pos ; pos++)
{
if (*pos == FN_C_BEFORE_DIR_2)
}
#else
{ /* Append FN_LIBCHAR if not there */
- char *end=strend(to);
- if (end != to && (end[-1] != FN_LIBCHAR && end[-1] != FN_DEVCHAR))
+ pos=strend(to);
+ if (pos != to && (pos[-1] != FN_LIBCHAR && pos[-1] != FN_DEVCHAR))
{
- end[0]=FN_LIBCHAR;
- end[1]=0;
+ *pos++=FN_LIBCHAR;
+ *pos=0;
}
}
#endif
+ return pos; /* Pointer to end of dir */
} /* convert_dirname */
/* 8 Pack filename as short as possibly */
/* 16 Resolve symbolic links for filename */
/* 32 Resolve filename to full path */
+ /* 64 Return NULL if too long path */
+#ifdef SCO
+#define BUFF_LEN 4097
+#else
#ifdef MAXPATHLEN
#define BUFF_LEN MAXPATHLEN
#else
#define BUFF_LEN FN_LEN
#endif
+#endif
my_string fn_format(my_string to, const char *name, const char *dsk,
const char *form, int flag)
name+=(length=dirname_part(dev,(startpos=(my_string) name)));
if (length == 0 || flag & 1)
{
- (void) strmov(dev,dsk); /* Use given directory */
+ (void) strmake(dev,dsk, sizeof(dev) - 2);
+ /* Use given directory */
convert_dirname(dev); /* Fix to this OS */
}
if (flag & 8)
if (strlen(dev)+length+strlen(ext) >= FN_REFLEN || length >= FN_LEN )
{ /* To long path, return original */
- uint tmp_length=strlength(startpos);
+ uint tmp_length;
+ if (flag & 64)
+ return 0;
+ tmp_length=strlength(startpos);
DBUG_PRINT("error",("dev: '%s' ext: '%s' length: %d",dev,ext,length));
(void) strmake(to,startpos,min(tmp_length,FN_REFLEN-1));
}
bmove(buff,(char*) name,length); /* Save name for last copy */
name=buff;
}
- (void) strmov(strnmov(strmov(to,dev),name,length),ext);
+ pos=strmake(strmov(to,dev),name,length);
#ifdef FN_UPPER_CASE
caseup_str(to);
#endif
#ifdef FN_LOWER_CASE
casedn_str(to);
#endif
+ (void) strmov(pos,ext); /* Don't convert extension */
}
/* Purify gives a lot of UMR errors when using realpath */
#if defined(HAVE_REALPATH) && !defined(HAVE_purify)
if (flag & 32 || (!lstat(to,&stat_buff) && S_ISLNK(stat_buff.st_mode)))
{
if (realpath(to,buff))
- strmov(to,buff);
+ strmake(to,buff,FN_REFLEN-1);
}
}
#endif
/* Pack a dirname ; Changes HOME to ~/ and current dev to ./ */
/* from is a dirname (from dirname() ?) ending with FN_LIBCHAR */
+ /* to may be == from */
void pack_dirname(my_string to, const char *from)
-
- /* to may be == from */
{
int cwd_err;
uint d_length,length,buff_length;
/* test if file without filename is found in path */
/* Returns to if found and to has dirpart if found, else NullS */
-#if defined(MSDOS) || defined(__WIN__)
+#if defined(MSDOS) || defined(__WIN__) || defined(__EMX__)
#define F_OK 0
#define PATH_SEP ';'
#define PROGRAM_EXTENSION ".exe"
#include <my_sys.h>
#include <m_string.h>
-void init_alloc_root(MEM_ROOT *mem_root,uint block_size)
+void init_alloc_root(MEM_ROOT *mem_root, uint block_size, uint pre_alloc_size)
{
mem_root->free=mem_root->used=0;
mem_root->min_malloc=16;
mem_root->block_size=block_size-MALLOC_OVERHEAD-sizeof(USED_MEM)-8;
mem_root->error_handler=0;
+#if !(defined(HAVE_purify) && defined(EXTRA_DEBUG))
+ if (pre_alloc_size)
+ {
+ if ((mem_root->free = mem_root->pre_alloc=
+ (USED_MEM*) my_malloc(pre_alloc_size+ ALIGN_SIZE(sizeof(USED_MEM)),
+ MYF(0))))
+ {
+ mem_root->free->size=pre_alloc_size+ALIGN_SIZE(sizeof(USED_MEM));
+ mem_root->free->left=pre_alloc_size;
+ mem_root->free->next=0;
+ }
+ }
+#endif
}
gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size)
/* deallocate everything used by alloc_root */
-void free_root(MEM_ROOT *root)
+void free_root(MEM_ROOT *root, myf MyFlags)
{
reg1 USED_MEM *next,*old;
DBUG_ENTER("free_root");
if (!root)
DBUG_VOID_RETURN; /* purecov: inspected */
- for (next= root->used ; next ; )
+ if (!(MyFlags & MY_KEEP_PREALLOC))
+ root->pre_alloc=0;
+
+ for ( next=root->used; next ;)
{
old=next; next= next->next ;
- my_free((gptr) old,MYF(0));
+ if (old != root->pre_alloc)
+ my_free((gptr) old,MYF(0));
}
for (next= root->free ; next ; )
{
old=next; next= next->next ;
- my_free((gptr) old,MYF(0));
+ if (old != root->pre_alloc)
+ my_free((gptr) old,MYF(0));
}
root->used=root->free=0;
+ if (root->pre_alloc)
+ {
+ root->free=root->pre_alloc;
+ root->free->left=root->pre_alloc->size-ALIGN_SIZE(sizeof(USED_MEM));
+ root->free->next=0;
+ }
DBUG_VOID_RETURN;
}
+
char *strdup_root(MEM_ROOT *root,const char *str)
{
uint len= (uint) strlen(str)+1;
#include <my_dir.h>
#include "mysys_err.h"
#include <errno.h>
-#if defined(MSDOS) || defined(__WIN__)
+#if defined(MSDOS) || defined(__WIN__) || defined(__EMX__)
#include <share.h>
#endif
DBUG_PRINT("my",("Name: '%s' CreateFlags: %d AccessFlags: %d MyFlags: %d",
FileName, CreateFlags, access_flags, MyFlags));
-#if !defined(NO_OPEN_3)
+#if !defined(NO_OPEN_3) && !defined(__EMX__)
fd = open((my_string) FileName, access_flags | O_CREAT,
CreateFlags ? CreateFlags : my_umask);
#elif defined(VMS)
fd = open((my_string) FileName, access_flags | O_CREAT, 0,
"ctx=stm","ctx=bin");
-#elif defined(MSDOS) || defined(__WIN__)
+#elif defined(MSDOS) || defined(__WIN__) || defined(__EMX__)
if (access_flags & O_SHARE)
fd = sopen((my_string) FileName, access_flags | O_CREAT | O_BINARY,
SH_DENYNO, MY_S_IREAD | MY_S_IWRITE);
fd = open(FileName, access_flags);
#endif
- if (fd >= 0)
- {
- if ((int) fd >= MY_NFILE)
- {
- DBUG_PRINT("exit",("fd: %d",fd));
- DBUG_RETURN(fd); /* safeguard */
- }
- if ((my_file_info[fd].name = (char*) my_strdup(FileName,MyFlags)))
- {
- my_file_opened++;
- my_file_info[fd].type = FILE_BY_CREATE;
- DBUG_PRINT("exit",("fd: %d",fd));
- DBUG_RETURN(fd);
- }
- VOID(my_close(fd,MyFlags));
- my_errno=ENOMEM;
- }
- else
- my_errno=errno;
- if (MyFlags & (MY_FFNF | MY_FAE | MY_WME))
- my_error(EE_CANTCREATEFILE, MYF(ME_BELL+ME_WAITTANG), FileName,my_errno);
- DBUG_RETURN(-1);
+ DBUG_RETURN(my_register_filename(fd, FileName, FILE_BY_CREATE,
+ EE_CANTCREATEFILE, MyFlags));
} /* my_create */
so we can ignore if this doesn't work.
*/
if ((uint) fileno(fd) >= MY_NFILE)
+ {
+ thread_safe_increment(my_stream_opened,&THR_LOCK_open);
DBUG_RETURN(fd); /* safeguard */
+ }
pthread_mutex_lock(&THR_LOCK_open);
if ((my_file_info[fileno(fd)].name = (char*)
my_strdup(FileName,MyFlags)))
my_error(EE_BADCLOSE, MYF(ME_BELL+ME_WAITTANG),
my_filename(file),errno);
}
+ else
+ my_stream_opened--;
if ((uint) file < MY_NFILE && my_file_info[file].type != UNOPEN)
{
my_file_info[file].type = UNOPEN;
- my_free(my_file_info[file].name, MYF(0));
- my_stream_opened--;
+ my_free(my_file_info[file].name, MYF(MY_ALLOW_ZERO_PTR));
}
pthread_mutex_unlock(&THR_LOCK_open);
DBUG_RETURN(err);
/* Make a stream out of a file handle */
+ /* Name may be 0 */
-FILE *my_fdopen(File Filedes, int Flags, myf MyFlags)
-
- /* Read | write .. */
- /* Special flags */
+FILE *my_fdopen(File Filedes, const char *name, int Flags, myf MyFlags)
{
FILE *fd;
char type[5];
else
{
pthread_mutex_lock(&THR_LOCK_open);
- if (my_file_info[Filedes].type != UNOPEN)
+ my_stream_opened++;
+ if (Filedes < MY_NFILE)
{
+ if (my_file_info[Filedes].type != UNOPEN)
+ {
+ my_file_opened--; /* File is opened with my_open ! */
+ }
+ else
+ {
+ my_file_info[Filedes].name= my_strdup(name,MyFlags);
+ }
my_file_info[Filedes].type = STREAM_BY_FDOPEN;
- my_file_opened--; /* File is opened with my_open ! */
- my_stream_opened++;
}
pthread_mutex_unlock(&THR_LOCK_open);
}
#endif
static my_bool my_init_done=0;
+
+static ulong atoi_octal(const char *str)
+{
+ long int tmp;
+ while (*str && isspace(*str))
+ str++;
+ str2int(str,
+ (*str == '0' ? 8 : 10), /* Octalt or decimalt */
+ 0, INT_MAX, &tmp);
+ return (ulong) tmp;
+}
+
+
/* Init my_sys functions and my_sys variabels */
void my_init(void)
if ((home_dir=getenv("HOME")) != 0)
home_dir=intern_filename(home_dir_buff,home_dir);
#ifndef VMS
+ /* Default creation of new files */
if ((str=getenv("UMASK")) != 0)
- my_umask=atoi(str) | 0600; /* Default creation of new files */
+ my_umask=(int) (atoi_octal(str) | 0600);
+ /* Default creation of new dir's */
if ((str=getenv("UMASK_DIR")) != 0)
- my_umask_dir=atoi(str) | 0700; /* Default creation of new dir's */
+ my_umask_dir=(int) (atoi_octal(str) | 0700);
#endif
#ifdef VMS
init_ctype(); /* Stupid linker don't link _ctype.c */
if (have_tcpip);
WSACleanup( );
#endif /* __WIN__ */
+ my_init_done=0;
} /* my_end */
#ifdef __WIN__
#define USES_TYPES
#include "mysys_priv.h"
#include "mysys_err.h"
+#include <my_dir.h>
#include <errno.h>
-#if defined(MSDOS) || defined(__WIN__)
+#if defined(MSDOS) || defined(__WIN__) || defined(__EMX__)
#include <share.h>
#endif
DBUG_ENTER("my_open");
DBUG_PRINT("my",("Name: '%s' Flags: %d MyFlags: %d",
FileName, Flags, MyFlags));
-#if defined(MSDOS) || defined(__WIN__)
+#if defined(MSDOS) || defined(__WIN__) || defined(__EMX__)
if (Flags & O_SHARE)
- fd = sopen((my_string) FileName, (Flags & ~O_SHARE) | O_BINARY, SH_DENYNO);
+ fd = sopen((my_string) FileName, (Flags & ~O_SHARE) | O_BINARY, SH_DENYNO,
+ MY_S_IREAD | MY_S_IWRITE);
else
- fd = open((my_string) FileName, Flags | O_BINARY);
+ fd = open((my_string) FileName, Flags | O_BINARY,
+ MY_S_IREAD | MY_S_IWRITE);
#elif !defined(NO_OPEN_3)
- fd = open(FileName, Flags, 0); /* Normal unix */
+ fd = open(FileName, Flags, my_umask); /* Normal unix */
#else
fd = open((my_string) FileName, Flags);
#endif
-
- if ((int) fd >= 0)
- {
- if ((int) fd >= MY_NFILE)
- DBUG_RETURN(fd); /* safeguard */
- pthread_mutex_lock(&THR_LOCK_open);
- if ((my_file_info[fd].name = (char*) my_strdup(FileName,MyFlags)))
- {
- my_file_opened++;
- my_file_info[fd].type = FILE_BY_OPEN;
- pthread_mutex_unlock(&THR_LOCK_open);
- DBUG_PRINT("exit",("fd: %d",fd));
- DBUG_RETURN(fd);
- }
- pthread_mutex_unlock(&THR_LOCK_open);
- (void) my_close(fd,MyFlags);
- my_errno=ENOMEM;
- }
- else
- my_errno=errno;
- DBUG_PRINT("error",("Got error %d on open",my_errno));
- if (MyFlags & (MY_FFNF | MY_FAE | MY_WME))
- my_error(EE_FILENOTFOUND, MYF(ME_BELL+ME_WAITTANG), FileName,my_errno);
- DBUG_RETURN(fd);
+ DBUG_RETURN(my_register_filename(fd, FileName, FILE_BY_OPEN,
+ EE_FILENOTFOUND, MyFlags));
} /* my_open */
DBUG_PRINT("my",("fd: %d MyFlags: %d",fd, MyFlags));
pthread_mutex_lock(&THR_LOCK_open);
- if ((err = close(fd)) != 0)
+ if ((err = close(fd)))
{
+ DBUG_PRINT("error",("Got error %d on close",err));
my_errno=errno;
if (MyFlags & (MY_FAE | MY_WME))
my_error(EE_BADCLOSE, MYF(ME_BELL+ME_WAITTANG),my_filename(fd),errno);
}
if ((uint) fd < MY_NFILE && my_file_info[fd].type != UNOPEN)
{
- my_file_opened--;
my_free(my_file_info[fd].name, MYF(0));
+#if defined(THREAD) && !defined(HAVE_PREAD)
+ pthread_mutex_destroy(&my_file_info[fd].mutex);
+#endif
my_file_info[fd].type = UNOPEN;
+ my_file_opened--;
}
pthread_mutex_unlock(&THR_LOCK_open);
DBUG_RETURN(err);
} /* my_close */
+
+
+File my_register_filename(File fd, const char *FileName, enum file_type
+ type_of_file, uint error_message_number, myf MyFlags)
+{
+ if ((int) fd >= 0)
+ {
+ if ((int) fd >= MY_NFILE)
+ {
+#if defined(THREAD) && !defined(HAVE_PREAD)
+ (void) my_close(fd,MyFlags);
+ my_errno=EMFILE;
+ if (MyFlags & (MY_FFNF | MY_FAE | MY_WME))
+ my_error(EE_OUT_OF_FILERESOURCES, MYF(ME_BELL+ME_WAITTANG),
+ FileName, my_errno);
+ return(-1);
+#else
+ thread_safe_increment(my_file_opened,&THR_LOCK_open);
+#endif
+ return(fd); /* safeguard */
+ }
+ pthread_mutex_lock(&THR_LOCK_open);
+ if ((my_file_info[fd].name = (char*) my_strdup(FileName,MyFlags)))
+ {
+ my_file_opened++;
+ my_file_info[fd].type = type_of_file;
+#if defined(THREAD) && !defined(HAVE_PREAD)
+ pthread_mutex_init(&my_file_info[fd].mutex,NULL);
+#endif
+ pthread_mutex_unlock(&THR_LOCK_open);
+ DBUG_PRINT("exit",("fd: %d",fd));
+ return(fd);
+ }
+ pthread_mutex_unlock(&THR_LOCK_open);
+ (void) my_close(fd, MyFlags);
+ my_errno=ENOMEM;
+ }
+ else
+ my_errno=errno;
+ DBUG_PRINT("error",("Got error %d on open",my_errno));
+ if (MyFlags & (MY_FFNF | MY_FAE | MY_WME))
+ my_error(error_message_number, MYF(ME_BELL+ME_WAITTANG),
+ FileName, my_errno);
+ return(fd);
+}
int my_sigwait(const sigset_t *set,int *sig)
{
- int signal=sigwait(set);
+ int signal=sigwait((sigset_t*) set);
if (signal < 0)
return errno;
*sig=signal;
#if !defined(my_gethostbyname_r) && defined(HAVE_GETHOSTBYNAME_R)
-#if defined(HAVE_GLIBC2_STYLE_GETHOSTBYNAME_R)
+#if defined(HAVE_GETHOSTBYNAME_R_GLIBC2_STYLE)
struct hostent *my_gethostbyname_r(const char *name,
struct hostent *result, char *buffer,
int buflen, int *h_errnop)
{
struct hostent *hp;
- assert((size_t) buflen >= sizeof(*result));
+ dbug_assert((size_t) buflen >= sizeof(*result));
if (gethostbyname_r(name,result, buffer, (size_t) buflen, &hp, h_errnop))
return 0;
return hp;
}
-#elif defined(_HPUX_SOURCE) || (defined(_AIX) && !defined(_AIX32_THREADS))
+#elif defined(HAVE_GETHOSTBYNAME_R_RETURN_INT)
struct hostent *my_gethostbyname_r(const char *name,
struct hostent *result, char *buffer,
int buflen, int *h_errnop)
{
- assert(buflen >= sizeof(struct hostent_data));
+ dbug_assert(buflen >= sizeof(struct hostent_data));
if (gethostbyname_r(name,result,(struct hostent_data *) buffer) == -1)
{
*h_errnop= errno;
int buflen, int *h_errnop)
{
struct hostent *hp;
- assert(buflen >= sizeof(struct hostent_data));
+ dbug_assert(buflen >= sizeof(struct hostent_data));
hp= gethostbyname_r(name,result,(struct hostent_data *) buffer);
*h_errnop= errno;
return hp;
long tv_nsec;
};
+typedef int pthread_mutexattr_t;
#define win_pthread_self my_thread_var->pthread_self
-#define pthread_handler_decl(A,B) unsigned __cdecl A(void *B)
-typedef unsigned (__cdecl *pthread_handler)(void *);
+#define pthread_handler_decl(A,B) void * __cdecl A(void *B)
+typedef void * (__cdecl *pthread_handler)(void *);
+void win_pthread_init(void);
int win_pthread_setspecific(void *A,void *B,uint length);
int pthread_create(pthread_t *,pthread_attr_t *,pthread_handler,void *);
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);
int pthread_attr_destroy(pthread_attr_t *connect_att);
struct tm *localtime_r(const time_t *timep,struct tm *tmp);
-void pthread_exit(unsigned A); /* was #define pthread_exit(A) ExitThread(A)*/
+void pthread_exit(void *a); /* was #define pthread_exit(A) ExitThread(A)*/
#define ETIMEDOUT 145 /* Win32 doesn't have this */
#define getpid() GetCurrentThreadId()
#define HAVE_PTHREAD_ATTR_SETSTACKSIZE
#ifdef USE_TLS /* For LIBMYSQL.DLL */
+#undef SAFE_MUTEX /* This will cause conflicts */
#define pthread_key(T,V) DWORD V
#define pthread_key_create(A,B) ((*A=TlsAlloc())==0xFFFFFFFF)
#define pthread_getspecific(A) (TlsGetValue(A))
#define my_pthread_getspecific(T,A) ((T) TlsGetValue(A))
-#define my_pthread_getspecific_ptr(T,V) ((T) TlsGetValue(A))
-#define my_pthread_setspecific_ptr(T,V) TlsSetValue(T,V)
-#define pthread_setspecific(A,B) TlsSetValue(A,B)
+#define my_pthread_getspecific_ptr(T,V) ((T) TlsGetValue(V))
+#define my_pthread_setspecific_ptr(T,V) (!TlsSetValue((T),(V)))
+#define pthread_setspecific(A,B) (!TlsSetValue((A),(B)))
#else
#define pthread_key(T,V) __declspec(thread) T V
#define pthread_key_create(A,B) pthread_dummy(0)
#define pthread_condattr_init(A)
#define pthread_condattr_destroy(A)
-/*Irena: compiler does not like this:*/
-/*#define my_pthread_getprio(pthread_t thread_id) pthread_dummy(0)*/
+/*Irena: compiler does not like this: */
+/*#define my_pthread_getprio(pthread_t thread_id) pthread_dummy(0) */
#define my_pthread_getprio(thread_id) pthread_dummy(0)
#elif defined(HAVE_UNIXWARE7_THREADS)
#define pthread_handler_decl(A,B) void *A(void *B)
typedef void *(* pthread_handler)(void *);
-/* safe mutex for debugging */
-
-typedef struct st_safe_mutex_t
-{
- pthread_mutex_t global,mutex;
- char *file;
- uint line,count;
- pthread_t thread;
-} safe_mutex_t;
-
-int safe_mutex_init(safe_mutex_t *mp, const pthread_mutexattr_t *attr);
-int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line);
-int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line);
-int safe_mutex_destroy(safe_mutex_t *mp,const char *file, uint line);
-int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp,const char *file,
- uint line);
-int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
- struct timespec *abstime, const char *file, uint line);
-
-#ifdef SAFE_MUTEX
-#undef pthread_mutex_init
-#undef pthread_mutex_lock
-#undef pthread_mutex_unlock
-#undef pthread_mutex_destroy
-#undef pthread_mutex_wait
-#undef pthread_mutex_timedwait
-#undef pthread_mutex_t
-#define pthread_mutex_init(A,B) safe_mutex_init((A),(B))
-#define pthread_mutex_lock(A) safe_mutex_lock((A),__FILE__,__LINE__)
-#define pthread_mutex_unlock(A) safe_mutex_unlock((A),__FILE__,__LINE__)
-#define pthread_mutex_destroy(A) safe_mutex_destroy((A),__FILE__,__LINE__)
-#define pthread_cond_wait(A,B) safe_cond_wait((A),(B),__FILE__,__LINE__)
-#define pthread_cond_timedwait(A,B,C) safe_cond_timedwait((A),(B),(C),__FILE__,__LINE__)
-#define pthread_mutex_t safe_mutex_t
-#endif
-
/* Test first for RTS or FSU threads */
#if defined(PTHREAD_SCOPE_GLOBAL) && !defined(PTHREAD_SCOPE_SYSTEM)
#define HAVE_LOCALTIME_R
#undef HAVE_PTHREAD_ATTR_SETSCOPE
#define HAVE_PTHREAD_ATTR_SETSCOPE
-#undef HAVE_GLIBC2_STYLE_GETHOSTBYNAME_R /* If we are running linux */
+#undef HAVE_GETHOSTBYNAME_R_GLIBC2_STYLE /* If we are running linux */
#undef HAVE_RWLOCK_T
#undef HAVE_RWLOCK_INIT
#undef HAVE_PTHREAD_RWLOCK_RDLOCK
#endif /* defined(PTHREAD_SCOPE_GLOBAL) && !defined(PTHREAD_SCOPE_SYSTEM) */
#if defined(_BSDI_VERSION) && _BSDI_VERSION < 199910
-int sigwait(const sigset_t *set, int *sig);
+int sigwait(sigset_t *set, int *sig);
#endif
#if defined(HAVE_UNIXWARE7_POSIX)
#ifndef HAVE_NONPOSIX_SIGWAIT
#define my_sigwait(A,B) sigwait((A),(B))
#else
-int my_sigwait(sigset_t *set,int *sig);
+int my_sigwait(const sigset_t *set,int *sig);
#endif
#ifdef HAVE_NONPOSIX_PTHREAD_MUTEX_INIT
#endif
#if !defined(HAVE_SIGWAIT) && !defined(HAVE_mit_thread) && !defined(HAVE_rts_threads) && !defined(sigwait) && !defined(alpha_linux_port) && !defined(HAVE_NONPOSIX_SIGWAIT) && !defined(HAVE_DEC_3_2_THREADS) && !defined(_AIX)
-int sigwait(const sigset_t *setp, int *sigp); /* Use our implemention */
+int sigwait(sigset_t *setp, int *sigp); /* Use our implemention */
#endif
#if !defined(HAVE_SIGSET) && !defined(HAVE_mit_thread) && !defined(sigset)
#define sigset(A,B) do { struct sigaction s; sigset_t set; \
#define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(&tmp); }
#endif
+#ifdef HAVE_DARWIN_THREADS
+#define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C))
+#define pthread_kill(A,B) pthread_dummy(0)
+#define pthread_condattr_init(A) pthread_dummy(0)
+#define pthread_condattr_destroy(A) pthread_dummy(0)
+#define pthread_signal(A,B) pthread_dummy(0)
+#undef pthread_detach_this_thread
+#define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(tmp); }
+#undef sigset
+#define sigset(A,B) pthread_signal((A),(void (*)(int)) (B))
+#endif
+
#if ((defined(HAVE_PTHREAD_ATTR_CREATE) && !defined(HAVE_SIGWAIT)) || defined(HAVE_DEC_3_2_THREADS)) && !defined(HAVE_CTHREADS_WRAPPER)
/* This is set on AIX_3_2 and Siemens unix (and DEC OSF/1 3.2 too) */
#define pthread_key_create(A,B) \
#define HAVE_PTHREAD_KILL
#endif
-#if defined(HAVE_PTHREAD_ATTR_CREATE) || defined(_AIX) || defined(HAVE_GLIBC2_STYLE_GETHOSTBYNAME_R)
+#if defined(HAVE_PTHREAD_ATTR_CREATE) || defined(_AIX) || defined(HAVE_GETHOSTBYNAME_R_GLIBC2_STYLE)
#if !defined(HPUX)
struct hostent;
#endif /* HPUX */
struct hostent *my_gethostbyname_r(const char *name,
struct hostent *result, char *buffer,
int buflen, int *h_errnop);
-#if defined(HAVE_GLIBC2_STYLE_GETHOSTBYNAME_R)
+#if defined(HAVE_GETHOSTBYNAME_R_GLIBC2_STYLE)
#define GETHOSTBYNAME_BUFF_SIZE 2048
#else
#define GETHOSTBYNAME_BUFF_SIZE sizeof(struct hostent_data)
-#endif /* defined(HAVE_GLIBC2_STYLE_GETHOSTBYNAME_R) */
+#endif /* defined(HAVE_GETHOSTBYNAME_R_GLIBC2_STYLE) */
#else
-#ifdef HAVE_GETHOSTBYNAME_R_WITH_HOSTENT_DATA
-#define GETHOSTBYNAME_BUFF_SIZE sizeof(hostent_data)
-#define my_gethostbyname_r(A,B,C,D,E) gethostbyname_r((A),(B),(hostent_data*) (C))
+#ifdef HAVE_GETHOSTBYNAME_R_RETURN_INT
+#define GETHOSTBYNAME_BUFF_SIZE sizeof(struct hostent_data)
+struct hostent *my_gethostbyname_r(const char *name,
+ struct hostent *result, char *buffer,
+ int buflen, int *h_errnop);
#else
#define GETHOSTBYNAME_BUFF_SIZE 2048
#define my_gethostbyname_r(A,B,C,D,E) gethostbyname_r((A),(B),(C),(D),(E))
-#endif /* HAVE_GETHOSTBYNAME_R_WITH_HOSTENT_DATA */
-#endif /* defined(HAVE_PTHREAD_ATTR_CREATE) || defined(_AIX) || defined(HAVE_GLIBC2_STYLE_GETHOSTBYNAME_R) */
+#endif /* HAVE_GETHOSTBYNAME_R_RETURN_INT */
+#endif /* defined(HAVE_PTHREAD_ATTR_CREATE) || defined(_AIX) || defined(HAVE_GETHOSTBYNAME_R_GLIBC2_STYLE) */
#endif /* defined(__WIN__) */
-/* READ-WRITE thread locking */
+ /* safe_mutex adds checking to mutex for easier debugging */
+
+typedef struct st_safe_mutex_t
+{
+ pthread_mutex_t global,mutex;
+ char *file;
+ uint line,count;
+ pthread_t thread;
+} safe_mutex_t;
+
+int safe_mutex_init(safe_mutex_t *mp, const pthread_mutexattr_t *attr);
+int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line);
+int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line);
+int safe_mutex_destroy(safe_mutex_t *mp,const char *file, uint line);
+int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp,const char *file,
+ uint line);
+int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
+ struct timespec *abstime, const char *file, uint line);
+
+ /* Wrappers if safe mutex is actually used */
+#ifdef SAFE_MUTEX
+#undef pthread_mutex_init
+#undef pthread_mutex_lock
+#undef pthread_mutex_unlock
+#undef pthread_mutex_destroy
+#undef pthread_mutex_wait
+#undef pthread_mutex_timedwait
+#undef pthread_mutex_t
+#undef pthread_cond_wait
+#undef pthread_cond_timedwait
+#define pthread_mutex_init(A,B) safe_mutex_init((A),(B))
+#define pthread_mutex_lock(A) safe_mutex_lock((A),__FILE__,__LINE__)
+#define pthread_mutex_unlock(A) safe_mutex_unlock((A),__FILE__,__LINE__)
+#define pthread_mutex_destroy(A) safe_mutex_destroy((A),__FILE__,__LINE__)
+#define pthread_cond_wait(A,B) safe_cond_wait((A),(B),__FILE__,__LINE__)
+#define pthread_cond_timedwait(A,B,C) safe_cond_timedwait((A),(B),(C),__FILE__,__LINE__)
+#define pthread_mutex_t safe_mutex_t
+#endif /* SAFE_MUTEX */
+
+ /* READ-WRITE thread locking */
#if defined(USE_MUTEX_INSTEAD_OF_RW_LOCKS)
/* use these defs for simple mutex locking */
/* All thread specific variables are in the following struct */
#define THREAD_NAME_SIZE 10
+#if defined(__ia64__)
+#define DEFAULT_THREAD_STACK (128*1024)
+#else
+#define DEFAULT_THREAD_STACK (64*1024)
+#endif
struct st_my_thread_var
{
int thr_errno;
- int cmp_length;
- volatile int abort;
- long id;
pthread_cond_t suspend, *current_cond;
pthread_mutex_t mutex, *current_mutex;
pthread_t pthread_self;
+ long id;
+ int cmp_length;
+ volatile int abort;
#ifndef DBUG_OFF
- char name[THREAD_NAME_SIZE+1];
gptr dbug;
+ char name[THREAD_NAME_SIZE+1];
#endif
};
my_string home_dir=0,my_progname=0;
char NEAR curr_dir[FN_REFLEN]= {0},
NEAR home_dir_buff[FN_REFLEN]= {0};
-uint my_stream_opened=0,my_file_opened=0;
+ulong my_stream_opened=0,my_file_opened=0, my_tmp_file_created=0;
int NEAR my_umask=0664, NEAR my_umask_dir=0777;
#ifndef THREAD
int NEAR my_errno=0;
sig_handler (*func)(int number);
};
-typedef struct sec_link {
- struct sec_link *next_hash,**prev_hash;/* Blocks linked acc. to hash-value */
- struct sec_link *next_used,*prev_used;
- struct sec_link *next_changed,**prev_changed;
- File file;
- my_off_t diskpos;
- byte *buffer;
- my_bool changed;
-} SEC_LINK;
-
struct irem {
struct remember *_pNext; /* Linked list of structures */
struct remember *_pPrev; /* Other link */
extern volatile int _my_signals;
extern struct st_remember _my_sig_remember[MAX_SIGNALS];
-extern my_bool key_cache_inited;
-
extern const char *soundex_map;
extern USED_MEM* my_once_root_block;
#include <stdarg.h>
+#ifdef __EMX__
+/* record loging flags (F_GETLK, F_SETLK, F_SETLKW) */
+#define F_RDLCK 1 /* FreeBSD: shared or read lock */
+#define F_UNLCK 2 /* FreeBSD: unlock */
+#define F_WRLCK 3 /* FreeBSD: exclusive or write lock */
+#endif
+
#define MYSYS_PROGRAM_USES_CURSES() { error_handler_hook = my_message_curses; mysys_uses_curses=1; }
#define MYSYS_PROGRAM_DONT_USE_CURSES() { error_handler_hook = my_message_no_curses; mysys_uses_curses=0;}
#define MY_INIT(name); { my_progname= name; my_init(); }
#define MY_WME 16 /* Write message on error */
#define MY_WAIT_IF_FULL 32 /* Wait and try again if disk full error */
#define MY_RAID 64 /* Support for RAID (not the "Johnson&Johnson"-s one ;) */
+#define MY_DONT_CHECK_FILESIZE 128 /* Option to init_io_cache() */
#define MY_LINK_WARNING 32 /* my_redel() gives warning if links */
#define MY_COPYTIME 64 /* my_redel() copys time */
#define MY_HOLD_ORIGINAL_MODES 128 /* my_copy() holds to file modes */
+#define MY_REDEL_MAKE_BACKUP 256
#define MY_SEEK_NOT_DONE 32 /* my_lock may have to do a seek */
#define MY_DONT_WAIT 64 /* my_lock() don't wait if can't lock */
#define MY_ZEROFILL 32 /* my_malloc(), fill array with zero */
#define MIN_COMPRESS_LENGTH 50 /* Don't compress small bl. */
#define KEYCACHE_BLOCK_SIZE 1024
+ /* root_alloc flags */
+#define MY_KEEP_PREALLOC 1
+
/* defines when allocating data */
#ifdef SAFEMALLOC
#define QUICK_SAFEMALLOC sf_malloc_quick=1
#define NORMAL_SAFEMALLOC sf_malloc_quick=0
extern uint sf_malloc_prehunc,sf_malloc_endhunc,sf_malloc_quick;
+extern ulonglong safemalloc_mem_limit;
#else
#define my_checkmalloc() (0)
#define TERMINATE(A) {}
extern my_bool set_default_charset_by_name(const char *cs_name, myf flags);
extern void free_charsets(void);
extern char *list_charsets(myf want_flags); /* my_free() this string... */
+extern char *get_charsets_dir(char *buf);
-/* statisticts */
+/* statistics */
extern ulong _my_cache_w_requests,_my_cache_write,_my_cache_r_requests,
_my_cache_read;
extern ulong _my_blocks_used,_my_blocks_changed;
-extern uint my_file_opened,my_stream_opened;
+extern ulong my_file_opened,my_stream_opened, my_tmp_file_created;
+extern my_bool key_cache_inited;
/* Point to current my_message() */
extern void (*my_sigtstp_cleanup)(void),
NEAR my_disable_flush_key_blocks;
extern char wild_many,wild_one,wild_prefix;
extern const char *charsets_dir;
+extern char *defaults_extra_file;
typedef struct wild_file_pack /* Struct to hold info when selecting files */
{
const char **type_names;
} TYPELIB;
-enum cache_type {READ_CACHE,WRITE_CACHE,READ_NET,WRITE_NET};
+enum cache_type {READ_CACHE,WRITE_CACHE,READ_FIFO,READ_NET,WRITE_NET};
enum flush_type { FLUSH_KEEP, FLUSH_RELEASE, FLUSH_IGNORE_CHANGED,
FLUSH_FORCE_WRITE};
} RECORD_CACHE;
enum file_type { UNOPEN = 0, FILE_BY_OPEN, FILE_BY_CREATE,
- STREAM_BY_FOPEN, STREAM_BY_FDOPEN };
+ STREAM_BY_FOPEN, STREAM_BY_FDOPEN, FILE_BY_MKSTEMP };
extern struct my_file_info
{
my_string name;
enum file_type type;
+#if defined(THREAD) && !defined(HAVE_PREAD)
+ pthread_mutex_t mutex;
+#endif
} my_file_info[MY_NFILE];
typedef struct st_io_cache /* Used when cacheing files */
{
+ my_off_t pos_in_file,end_of_file;
byte *rc_pos,*rc_end,*buffer,*rc_request_pos;
+ int (*read_function)(struct st_io_cache *,byte *,uint);
+ char *file_name; /* if used with 'open_cached_file' */
+ char *dir,*prefix;
File file;
int seek_not_done,error;
uint buffer_length,read_length;
- my_off_t pos_in_file,end_of_file;
myf myflags; /* Flags used to my_read/my_write */
+ enum cache_type type;
#ifdef HAVE_AIOWAIT
uint inited;
my_off_t aio_read_pos;
my_aio_result aio_result;
#endif
- enum cache_type type;
- int (*read_function)(struct st_io_cache *,byte *,uint);
- char *file_name; /* if used with 'open_cached_file' */
} IO_CACHE;
typedef int (*qsort2_cmp)(const void *, const void *, const void *);
#define my_b_tell(info) ((info)->pos_in_file + \
((info)->rc_pos - (info)->rc_request_pos))
+#define my_b_bytes_in_cache(info) ((uint) ((info)->rc_end - (info)->rc_pos))
+
typedef struct st_changeable_var {
- const char *name;
- long *varptr;
- long def_value,min_value,max_value,sub_size,block_size;
+ const char *name; /* Name of variable */
+ long *varptr; /* Pointer to variable */
+ long def_value, /* Default value */
+ min_value, /* Min allowed value */
+ max_value, /* Max allowed value */
+ sub_size, /* Subtract this from given value */
+ block_size; /* Value should be a mult. of this */
} CHANGEABLE_VAR;
#define ST_USED_MEM_DEFINED
typedef struct st_used_mem { /* struct for once_alloc */
struct st_used_mem *next; /* Next block in use */
- unsigned int left; /* memory left in block */
- unsigned int size; /* size of block */
+ unsigned int left; /* memory left in block */
+ unsigned int size; /* Size of block */
} USED_MEM;
typedef struct st_mem_root {
USED_MEM *free;
USED_MEM *used;
+ USED_MEM *pre_alloc;
unsigned int min_malloc;
unsigned int block_size;
+
void (*error_handler)(void);
} MEM_ROOT;
#endif
extern void my_once_free(void);
extern my_string my_tempnam(const char *dir,const char *pfx,myf MyFlags);
extern File my_open(const char *FileName,int Flags,myf MyFlags);
+extern File my_register_filename(File fd, const char *FileName,
+ enum file_type type_of_file,
+ uint error_message_number, myf MyFlags);
extern File my_create(const char *FileName,int CreateFlags,
int AccsesFlags, myf MyFlags);
extern int my_close(File Filedes,myf MyFlags);
#endif
extern void init_glob_errs(void);
extern FILE *my_fopen(const char *FileName,int Flags,myf MyFlags);
-extern FILE *my_fdopen(File Filedes,int Flags,myf MyFlags);
+extern FILE *my_fdopen(File Filedes,const char *name, int Flags,myf MyFlags);
extern int my_fclose(FILE *fd,myf MyFlags);
extern int my_chsize(File fd,my_off_t newlength,myf MyFlags);
extern int my_error _VARARGS((int nr,myf MyFlags, ...));
extern uint dirname_length(const char *name);
#define base_name(A) (A+dirname_length(A))
extern int test_if_hard_path(const char *dir_name);
-extern void convert_dirname(my_string name);
+extern char *convert_dirname(my_string name);
extern void to_unix_path(my_string name);
extern my_string fn_ext(const char *name);
extern my_string fn_same(my_string toname,const char *name,int flag);
uint Count, my_off_t pos);
extern int flush_io_cache(IO_CACHE *info);
extern int end_io_cache(IO_CACHE *info);
+extern uint my_b_fill(IO_CACHE *info);
+extern void my_b_seek(IO_CACHE *info,my_off_t pos);
+extern uint my_b_gets(IO_CACHE *info, char *to, uint max_length);
+extern uint my_b_printf(IO_CACHE *info, const char* fmt, ...);
+extern uint my_b_vprintf(IO_CACHE *info, const char* fmt, va_list ap);
extern my_bool open_cached_file(IO_CACHE *cache,const char *dir,
const char *prefix, uint cache_size,
myf cache_myflags);
extern my_bool real_open_cached_file(IO_CACHE *cache);
extern void close_cached_file(IO_CACHE *cache);
+File create_temp_file(char *to, const char *dir, const char *pfx,
+ int mode, myf MyFlags);
extern my_bool init_dynamic_array(DYNAMIC_ARRAY *array,uint element_size,
uint init_alloc,uint alloc_increment);
extern my_bool insert_dynamic(DYNAMIC_ARRAY *array,gptr element);
extern my_bool init_dynamic_string(DYNAMIC_STRING *str, const char *init_str,
uint init_alloc,uint alloc_increment);
extern my_bool dynstr_append(DYNAMIC_STRING *str, const char *append);
+my_bool dynstr_append_mem(DYNAMIC_STRING *str, const char *append,
+ uint length);
extern my_bool dynstr_set(DYNAMIC_STRING *str, const char *init_str);
extern my_bool dynstr_realloc(DYNAMIC_STRING *str, ulong additional_size);
extern void dynstr_free(DYNAMIC_STRING *str);
#define my_malloc_lock(A,B) my_malloc((A),(B))
#define my_free_lock(A,B) my_free((A),(B))
#endif
-void init_alloc_root(MEM_ROOT *mem_root,uint block_size);
+#define alloc_root_inited(A) ((A)->min_malloc != 0)
+void init_alloc_root(MEM_ROOT *mem_root, uint block_size, uint pre_alloc_size);
gptr alloc_root(MEM_ROOT *mem_root,unsigned int Size);
-void free_root(MEM_ROOT *root);
+void free_root(MEM_ROOT *root, myf MyFLAGS);
char *strdup_root(MEM_ROOT *root,const char *str);
char *memdup_root(MEM_ROOT *root,const char *str,uint len);
void load_defaults(const char *conf_file, const char **groups,
#ifdef __cplusplus
}
#endif
-#ifdef USE_RAID
#include "raid.h"
-#endif
#endif /* _my_sys_h */
#ifndef HAVE_LOCALTIME_R
pthread_mutex_t LOCK_localtime_r;
#endif
-#ifdef __WIN__
-pthread_mutex_t THR_LOCK_thread;
-#endif
/* FIXME Note. TlsAlloc does not set an auto destructor, so
the function my_thread_global_free must be called from
pthread_mutex_init(&THR_LOCK_net,NULL);
pthread_mutex_init(&THR_LOCK_charset,NULL);
#ifdef __WIN__
- pthread_mutex_init(&THR_LOCK_thread,NULL);
+ win_pthread_init();
#endif
#ifndef HAVE_LOCALTIME_R
pthread_mutex_init(&LOCK_localtime_r,NULL);
static long thread_id=0;
+/*
+ We can't use mutex_locks here if we are using windows as
+ we may have compiled the program with SAFE_MUTEX, in which
+ case the checking of mutex_locks will not work until
+ the pthread_self thread specific variable is initialized.
+*/
+
my_bool my_thread_init(void)
{
struct st_my_thread_var *tmp;
+#if !defined(__WIN__) || defined(USE_TLS) || ! defined(SAFE_MUTEX)
pthread_mutex_lock(&THR_LOCK_lock);
+#endif
#if !defined(__WIN__) || defined(USE_TLS)
if (my_pthread_getspecific(struct st_my_thread_var *,THR_KEY_mysys))
{
pthread_setspecific(THR_KEY_mysys,tmp);
#else
- if (THR_KEY_mysys.id) /* Allready initialized */
+ if (THR_KEY_mysys.id) /* Already initialized */
{
+#if !defined(__WIN__) || defined(USE_TLS) || ! defined(SAFE_MUTEX)
pthread_mutex_unlock(&THR_LOCK_lock);
+#endif
return 0;
}
tmp= &THR_KEY_mysys;
tmp->id= ++thread_id;
pthread_mutex_init(&tmp->mutex,NULL);
pthread_cond_init(&tmp->suspend, NULL);
+#if !defined(__WIN__) || defined(USE_TLS) || ! defined(SAFE_MUTEX)
pthread_mutex_unlock(&THR_LOCK_lock);
+#endif
return 0;
}
/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB
This file is public domain and comes with NO WARRANTY of any kind */
-
/*****************************************************************************
** The following is a simple implementation of posix conditions
*****************************************************************************/
+#undef SAFE_MUTEX /* Avoid safe_mutex redefinitions */
#include "mysys_priv.h"
-#if defined(THREAD) && defined(__WIN32__)
+#if defined(THREAD) && defined(__WIN__)
#include <m_string.h>
#undef getpid
#include <process.h>
}
return tmp;
}
-#endif /* __WIN32__ */
+#endif /* __WIN__ */
Count-=writenbytes;
}
my_errno=errno;
- DBUG_PRINT("error",("Write only %d bytes",writenbytes));
+ DBUG_PRINT("error",("Write only %d bytes, error: %d",
+ writenbytes,my_errno));
#ifndef NO_BACKGROUND
#ifdef THREAD
if (my_thread_var->abort)
MyFlags&= ~ MY_WAIT_IF_FULL; /* End if aborted by user */
#endif
- if (my_errno == ENOSPC && (MyFlags & MY_WAIT_IF_FULL))
+ if (my_errno == ENOSPC && (MyFlags & MY_WAIT_IF_FULL) &&
+ (uint) writenbytes != (uint) -1)
{
if (!(errors++ % MY_WAIT_GIVE_USER_A_MESSAGE))
my_error(EE_DISK_FULL,MYF(ME_BELL | ME_NOREFRESH),
VOID(sleep(MY_WAIT_FOR_USER_TO_FIX_PANIC));
continue;
}
- if ((writenbytes == 0 && my_errno == EINTR) ||
- (writenbytes > 0 && (uint) writenbytes != (uint) -1))
+ if (!writenbytes)
+ {
+ /* We may come here on an interrupt or if the file quote is exeeded */
+ if (my_errno == EINTR)
+ continue;
+ if (!errors++) /* Retry once */
+ {
+ errno=EFBIG; /* Assume this is the error */
+ continue;
+ }
+ }
+ else if ((uint) writenbytes != (uint) -1)
continue; /* Retry */
#endif
if (MyFlags & (MY_NABP | MY_FNABP))
typedef struct st_mem_root {
USED_MEM *free;
USED_MEM *used;
+ USED_MEM *pre_alloc;
unsigned int min_malloc;
unsigned int block_size;
+
void (*error_handler)(void);
} MEM_ROOT;
#endif
#define IS_NOT_NULL(n) ((n) & NOT_NULL_FLAG)
#define IS_BLOB(n) ((n) & BLOB_FLAG)
#define IS_NUM(t) ((t) <= FIELD_TYPE_INT24 || (t) == FIELD_TYPE_YEAR)
+#define IS_NUM_FIELD(f) ((f)->flags & NUM_FLAG)
+#define INTERNAL_NUM_FIELD(f) (((f)->type <= FIELD_TYPE_INT24 && ((f)->type != FIELD_TYPE_TIMESTAMP || (f)->length == 14 || (f)->length == 8)) || (f)->type == FIELD_TYPE_YEAR)
typedef struct st_mysql_field {
char *name; /* Name of column */
void STDCALL mysql_close(MYSQL *sock);
int STDCALL mysql_select_db(MYSQL *mysql, const char *db);
int STDCALL mysql_query(MYSQL *mysql, const char *q);
+int STDCALL mysql_send_query(MYSQL *mysql, const char *q);
+int STDCALL mysql_reap_query(MYSQL *mysql);
int STDCALL mysql_real_query(MYSQL *mysql, const char *q,
unsigned int length);
+int STDCALL mysql_real_send_query(MYSQL *mysql, const char *q,
+ unsigned int len);
int STDCALL mysql_create_db(MYSQL *mysql, const char *DB);
int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB);
int STDCALL mysql_shutdown(MYSQL *mysql);
#define NAME_LEN 64 /* Field/table name length */
#define HOSTNAME_LENGTH 60
#define USERNAME_LENGTH 16
+#define SERVER_VERSION_LENGTH 60
#define LOCAL_HOST "localhost"
#define LOCAL_HOST_NAMEDPIPE "."
-#if defined(__EMX__) || defined(__OS2__)
-#undef MYSQL_UNIX_ADDR
-#define MYSQL_OS2_ADDR "\\socket\\MySQL"
-#define MYSQL_UNIX_ADDR MYSQL_OS2_ADDR
-#endif
#if defined(__WIN__) && !defined( _CUSTOMCONFIG_)
#define MYSQL_NAMEDPIPE "MySQL"
#define MYSQL_SERVICENAME "MySql"
COM_PROCESS_INFO,COM_CONNECT,COM_PROCESS_KILL,
COM_DEBUG,COM_PING,COM_TIME,COM_DELAYED_INSERT,
COM_CHANGE_USER, COM_BINLOG_DUMP,
- COM_TABLE_DUMP};
+ COM_TABLE_DUMP, COM_CONNECT_OUT};
#define NOT_NULL_FLAG 1 /* Field can't be NULL */
#define PRI_KEY_FLAG 2 /* Field is part of a primary key */
#define AUTO_INCREMENT_FLAG 512 /* field is a autoincrement field */
#define TIMESTAMP_FLAG 1024 /* Field is a timestamp */
#define SET_FLAG 2048 /* field is a set */
+#define NUM_FLAG 32768 /* Field is num (for clients) */
#define PART_KEY_FLAG 16384 /* Intern; Part of some key */
#define GROUP_FLAG 32768 /* Intern: Group field */
#define UNIQUE_FLAG 65536 /* Intern: Used by sql_yacc */
-/* Copyright Abandoned 1996,1999 TCX DataKonsult AB & Monty Program KB & Detron HB
- This file is public domain and comes with NO WARRANTY of any kind */
+/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB
+This file is public domain and comes with NO WARRANTY of any kind */
/* Version numbers for protocol & mysqld */
#ifdef _CUSTOMCONFIG_
- #include <custom_conf.h>
+#include <custom_conf.h>
#else
#define PROTOCOL_VERSION 10
-#define MYSQL_SERVER_VERSION "3.23.22-beta"
+#define MYSQL_SERVER_VERSION "3.23.32"
+#define MYSQL_SERVER_SUFFIX ""
#define FRM_VER 6
-#define MYSQL_VERSION_ID 32322
+#define MYSQL_VERSION_ID 32332
#define MYSQL_PORT 3306
+#define MYSQL_UNIX_ADDR "/tmp/mysql.sock"
/* mysqld compile time options */
#ifndef MYSQL_CHARSET
#define ER_MASTER_NET_WRITE 1190
#define ER_FT_MATCHING_KEY_NOT_FOUND 1191
#define ER_LOCK_OR_ACTIVE_TRANSACTION 1192
-#define ER_ERROR_MESSAGES 193
+#define ER_UNKNOWN_SYSTEM_VARIABLE 1193
+#define ER_CRASHED_ON_USAGE 1194
+#define ER_CRASHED_ON_REPAIR 1195
+#define ER_WARNING_NOT_COMPLETE_ROLLBACK 1196
+#define ER_TRANS_CACHE_FULL 1197
+#define ER_ERROR_MESSAGES 198
#endif
#define GLOB 0 /* Error maps */
-#define GLOBERRS 23 /* Max number of error messages in map's */
+#define GLOBERRS 24 /* Max number of error messages in map's */
#define EE(X) globerrs[ X ] /* Defines to add error to right map */
extern const char * NEAR globerrs[]; /* my_error_messages is here */
#define EE_DISK_FULL 20
#define EE_CANT_MKDIR 21
#define EE_UNKNOWN_CHARSET 22
+#define EE_OUT_OF_FILERESOURCES 23
#ifdef __cplusplus
}
#if !defined(__WIN__) && !defined(MSDOS)
#include <sys/socket.h>
#else
-#undef MYSQL_SERVER // Win32 can't handle interrupts
+#undef MYSQL_SERVER /* Win32 can't handle interrupts */
#endif
#if !defined(MSDOS) && !defined(__WIN__) && !defined(HAVE_BROKEN_NETINET_INCLUDES) && !defined(__BEOS__)
#include <netinet/in_systm.h>
typedef my_bool thr_alarm_t;
typedef my_bool ALARM;
#define thr_alarm_init(A) (*A)=0
-#define thr_alarm_in_use(A) (A)
+#define thr_alarm_in_use(A) (*(A))
#define thr_end_alarm(A)
#define thr_alarm(A,B,C) local_thr_alarm((A),(B),(C))
static inline int local_thr_alarm(my_bool *A,int B __attribute__((unused)),ALARM *C __attribute__((unused)))
if (!(test_flags & TEST_BLOCKING))
vio_blocking(vio, FALSE);
#endif
- vio_fastsend(vio,TRUE);
+ vio_fastsend(vio);
}
return 0;
}
int length;
char *pos,*end;
thr_alarm_t alarmed;
-#if (!defined(__WIN__) && !defined(__EMX__))
+#if !defined(__WIN__) && !defined(__EMX__)
ALARM alarm_buff;
#endif
uint retry_count=0;
pos=(char*) packet; end=pos+len;
while (pos != end)
{
- if ((int) (length=vio_write(net->vio,pos,(size_t) (end-pos))) <= 0)
+ if ((int) (length=vio_write(net->vio,pos,(int) (end-pos))) <= 0)
{
my_bool interrupted = vio_should_retry(net->vio);
#if (!defined(__WIN__) && !defined(__EMX__))
- if ((interrupted || length==0) && !thr_alarm_in_use(alarmed))
+ if ((interrupted || length==0) && !thr_alarm_in_use(&alarmed))
{
if (!thr_alarm(&alarmed,(uint) net_write_timeout,&alarm_buff))
{ /* Always true for client */
}
else
#endif /* (!defined(__WIN__) && !defined(__EMX__)) */
- if (thr_alarm_in_use(alarmed) && !thr_got_alarm(alarmed) &&
+ if (thr_alarm_in_use(&alarmed) && !thr_got_alarm(&alarmed) &&
interrupted)
{
if (retry_count++ < RETRY_COUNT)
if (net->compress)
my_free((char*) packet,MYF(0));
#endif
- if (thr_alarm_in_use(alarmed))
+ if (thr_alarm_in_use(&alarmed))
{
thr_end_alarm(&alarmed);
vio_blocking(net->vio, net_blocking);
static void my_net_skip_rest(NET *net, ulong remain, thr_alarm_t *alarmed)
{
- char buff[1024];
ALARM alarm_buff;
uint retry_count=0;
- if (!thr_alarm_in_use(alarmed))
+ if (!thr_alarm_in_use(&alarmed))
{
if (!thr_alarm(alarmed,net->timeout,&alarm_buff) ||
(!vio_is_blocking(net->vio) && vio_blocking(net->vio,TRUE) < 0))
- return; // Can't setup, abort
+ return; /* Can't setup, abort */
}
while (remain > 0)
{
if ((int) (length=vio_read(net->vio,(char*) net->buff,remain)) <= 0L)
{
my_bool interrupted = vio_should_retry(net->vio);
- if (!thr_got_alarm(alarmed) && interrupted)
+ if (!thr_got_alarm(&alarmed) && interrupted)
{ /* Probably in MIT threads */
if (retry_count++ < RETRY_COUNT)
continue;
an alarm to not 'read forever', change the socket to non blocking
mode and try again
*/
- if ((interrupted || length == 0) && !thr_alarm_in_use(alarmed))
+ if ((interrupted || length == 0) && !thr_alarm_in_use(&alarmed))
{
if (!thr_alarm(&alarmed,net->timeout,&alarm_buff)) /* Don't wait too long */
{
}
}
#endif /* (!defined(__WIN__) && !defined(__EMX__)) || defined(MYSQL_SERVER) */
- if (thr_alarm_in_use(alarmed) && !thr_got_alarm(alarmed) &&
+ if (thr_alarm_in_use(&alarmed) && !thr_got_alarm(&alarmed) &&
interrupted)
{ /* Probably in MIT threads */
if (retry_count++ < RETRY_COUNT)
}
end:
- if (thr_alarm_in_use(alarmed))
+ if (thr_alarm_in_use(&alarmed))
{
thr_end_alarm(&alarmed);
vio_blocking(net->vio, net_blocking);
--- /dev/null
+/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB
+This file is public domain and comes with NO WARRANTY of any kind */
+
+/* Parser needs these defines always, even if USE_RAID is not defined */
+#define RAID_TYPE_0 1 /* Striping */
+#define RAID_TYPE_x 2 /* Some new modes */
+#define RAID_TYPE_y 3
+
+#define RAID_DEFAULT_CHUNKS 4
+#define RAID_DEFAULT_CHUNKSIZE 256*1024 /* 256kB */
+
+extern const char *raid_type_string[];
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+const char *my_raid_type(int raid_type);
+#ifdef __cplusplus
+}
+#endif
+
+#ifdef USE_RAID
+
+#ifdef __GNUC__
+#pragma interface /* gcc class implementation */
+#endif
+#include "my_dir.h"
+
+/* Trap all occurences of my_...() in source and use our wrapper around this function */
+
+#ifdef MAP_TO_USE_RAID
+#define my_read(A,B,C,D) my_raid_read(A,B,C,D)
+#define my_write(A,B,C,D) my_raid_write(A,B,C,D)
+#define my_pwrite(A,B,C,D,E) my_raid_pwrite(A,B,C,D,E)
+#define my_pread(A,B,C,D,E) my_raid_pread(A,B,C,D,E)
+#define my_chsize(A,B,C) my_raid_chsize(A,B,C)
+#define my_close(A,B) my_raid_close(A,B)
+#define my_tell(A,B) my_raid_tell(A,B)
+#define my_seek(A,B,C,D) my_raid_seek(A,B,C,D)
+#define my_lock(A,B,C,D,E) my_raid_lock(A,B,C,D,E)
+#define my_fstat(A,B,C) my_raid_fstat(A,B,C)
+#endif /* MAP_TO_USE_RAID */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ void init_raid(void);
+ void end_raid(void);
+
+ bool is_raid(File fd);
+ File my_raid_create(const char *FileName, int CreateFlags, int access_flags,
+ uint raid_type, uint raid_chunks, ulong raid_chunksize,
+ myf MyFlags);
+ File my_raid_open(const char *FileName, int Flags,
+ uint raid_type, uint raid_chunks, ulong raid_chunksize,
+ myf MyFlags);
+ int my_raid_rename(const char *from, const char *to, uint raid_chunks,
+ myf MyFlags);
+ int my_raid_delete(const char *from, uint raid_chunks, myf MyFlags);
+ int my_raid_redel(const char *old_name, const char *new_name,
+ uint raid_chunks, myf MyFlags);
+
+ my_off_t my_raid_seek(File fd, my_off_t pos, int whence, myf MyFlags);
+ my_off_t my_raid_tell(File fd, myf MyFlags);
+
+ uint my_raid_write(File,const byte *Buffer, uint Count, myf MyFlags);
+ uint my_raid_read(File Filedes, byte *Buffer, uint Count, myf MyFlags);
+
+ uint my_raid_pread(File Filedes, byte *Buffer, uint Count, my_off_t offset,
+ myf MyFlags);
+ uint my_raid_pwrite(int Filedes, const byte *Buffer, uint Count,
+ my_off_t offset, myf MyFlags);
+
+ int my_raid_lock(File,int locktype, my_off_t start, my_off_t length,
+ myf MyFlags);
+ int my_raid_chsize(File fd, my_off_t newlength, myf MyFlags);
+ int my_raid_close(File, myf MyFlags);
+ int my_raid_fstat(int Filedes, struct stat *buf, myf MyFlags);
+
+#ifdef __cplusplus
+}
+
+class RaidName {
+ public:
+ RaidName(const char *FileName);
+ ~RaidName();
+ bool IsRaid();
+ int Rename(const char * from, const char * to, myf MyFlags);
+ private:
+ uint _raid_type; /* RAID_TYPE_0 or RAID_TYPE_1 or RAID_TYPE_5 */
+ uint _raid_chunks; /* 1..n */
+ ulong _raid_chunksize; /* 1..n in bytes */
+};
+
+class RaidFd {
+ public:
+ RaidFd(uint raid_type, uint raid_chunks , ulong raid_chunksize);
+ ~RaidFd();
+ File Create(const char *FileName, int CreateFlags, int access_flags,
+ myf MyFlags);
+ File Open(const char *FileName, int Flags, myf MyFlags);
+ my_off_t Seek(my_off_t pos,int whence,myf MyFlags);
+ my_off_t Tell(myf MyFlags);
+ int Write(const byte *Buffer, uint Count, myf MyFlags);
+ int Read(const byte *Buffer, uint Count, myf MyFlags);
+ int Lock(int locktype, my_off_t start, my_off_t length, myf MyFlags);
+ int Chsize(File fd, my_off_t newlength, myf MyFlags);
+ int Fstat(int fd, MY_STAT *stat_area, myf MyFlags );
+ int Close(myf MyFlags);
+ static bool IsRaid(File fd);
+ static DYNAMIC_ARRAY _raid_map; /* Map of RaidFD* */
+ private:
+
+ uint _raid_type; /* RAID_TYPE_0 or RAID_TYPE_1 or RAID_TYPE_5 */
+ uint _raid_chunks; /* 1..n */
+ ulong _raid_chunksize; /* 1..n in bytes */
+
+ ulong _total_block; /* We are operating with block no x (can be 0..many). */
+ uint _this_block; /* can be 0.._raid_chunks */
+ uint _remaining_bytes; /* Maximum bytes that can be written in this block */
+
+ my_off_t _position;
+ my_off_t _size; /* Cached file size for faster seek(SEEK_END) */
+ File _fd;
+ File *_fd_vector; /* Array of File */
+ off_t *_seek_vector; /* Array of cached seek positions */
+
+ inline void Calculate()
+ {
+ DBUG_ENTER("RaidFd::_Calculate");
+ DBUG_PRINT("info",("_position: %lu _raid_chunksize: %d, _size: %lu",
+ (ulong) _position, _raid_chunksize, (ulong) _size));
+
+ _total_block = (ulong) (_position / _raid_chunksize);
+ _this_block = _total_block % _raid_chunks; /* can be 0.._raid_chunks */
+ _remaining_bytes = (uint) (_raid_chunksize -
+ (_position - _total_block * _raid_chunksize));
+ DBUG_PRINT("info",
+ ("_total_block: %d this_block: %d _remaining_bytes:%d",
+ _total_block, _this_block, _remaining_bytes));
+ DBUG_VOID_RETURN;
+ }
+};
+
+#endif /* __cplusplus */
+#endif /* USE_RAID */
#include "my_static.h"
#include "mysys_err.h"
+ulonglong safemalloc_mem_limit = ~(ulonglong)0;
+
#define pNext tInt._pNext
#define pPrev tInt._pPrev
#define sFileName tInt._sFileName
DBUG_ENTER("_mymalloc");
DBUG_PRINT("enter",("Size: %u",uSize));
+
if (!sf_malloc_quick)
(void) _sanity (sFile, uLine);
- /* Allocate the physical memory */
- pTmp = (struct remember *) malloc (
+ if(uSize + lCurMemory > safemalloc_mem_limit)
+ pTmp = 0;
+ else
+ /* Allocate the physical memory */
+ pTmp = (struct remember *) malloc (
sizeof (struct irem) /* remember data */
+ sf_malloc_prehunc
+ uSize /* size requested */
DBUG_RETURN(FALSE);
}
+
my_bool dynstr_set(DYNAMIC_STRING *str, const char *init_str)
{
uint length;
DBUG_RETURN(FALSE);
}
+
my_bool dynstr_realloc(DYNAMIC_STRING *str, ulong additional_size)
{
DBUG_ENTER("dynstr_realloc");
my_bool dynstr_append(DYNAMIC_STRING *str, const char *append)
+{
+ return dynstr_append_mem(str,append,strlen(append));
+}
+
+
+my_bool dynstr_append_mem(DYNAMIC_STRING *str, const char *append,
+ uint length)
{
char *new_ptr;
- uint length=(uint) strlen(append)+1;
- if (str->length+length > str->max_length)
+ if (str->length+length >= str->max_length)
{
- uint new_length=(str->length+length+str->alloc_increment-1)/
+ uint new_length=(str->length+length+str->alloc_increment)/
str->alloc_increment;
new_length*=str->alloc_increment;
if (!(new_ptr=(char*) my_realloc(str->str,new_length,MYF(MY_WME))))
str->max_length=new_length;
}
memcpy(str->str + str->length,append,length);
- str->length+=length-1;
+ str->length+=length;
+ str->str[str->length]=0; /* Safety for C programs */
return FALSE;
}
+
void dynstr_free(DYNAMIC_STRING *str)
{
if (str->str)
extern "C" {
#endif
-typedef struct st_alarm {
- ulong expire_time;
- int alarmed; /* 1 when alarm is due */
- pthread_t thread;
- my_bool malloced;
-} ALARM;
-
#ifndef USE_ALARM_THREAD
#define USE_ONE_SIGNAL_HAND /* One must call process_alarm */
#endif
#define THR_SERVER_ALARM SIGALRM
#endif
-#ifdef DONT_USE_THR_ALARM
+#if defined(DONT_USE_THR_ALARM)
#define USE_ALARM_THREAD
#undef USE_ONE_SIGNAL_HAND
-typedef struct st_win_timer
+typedef struct st_thr_alarm_entry
{
uint crono;
-} thr_alarm_t;
+} thr_alarm_entry;
#define thr_alarm_init(A) (A)->crono=0
-#define thr_alarm_in_use(A) (A).crono
+#define thr_alarm_in_use(A) (A)->crono
#define init_thr_alarm(A)
#define thr_alarm_kill(A)
#define end_thr_alarm()
#define thr_alarm(A,B) (((A)->crono=1)-1)
-#define thr_got_alarm(A) (A).crono
+#define thr_got_alarm(A) (A)->crono
#define thr_end_alarm(A)
#else
-
-#ifdef __WIN__
-typedef struct st_win_timer
+#if defined(__WIN__)
+typedef struct st_thr_alarm_entry
{
rf_SetTimer crono;
-} thr_alarm_t;
+} thr_alarm_entry;
-bool thr_got_alarm(thr_alarm_t *alrm);
-#define thr_alarm_init(A) (A)->crono=0
-#define thr_alarm_in_use(A) (A)->crono
-#define init_thr_alarm(A)
-#define thr_alarm_kill(A)
-#else
+#elif defined(__EMX__)
+
+typedef struct st_thr_alarm_entry
+{
+ uint crono;
+ uint event;
+} thr_alarm_entry;
+
+#else /* System with posix threads */
+
+typedef int thr_alarm_entry;
+
+#define thr_got_alarm(thr_alarm) (**(thr_alarm))
-typedef int* thr_alarm_t;
-#define thr_got_alarm(thr_alarm) (*thr_alarm)
-#define thr_alarm_init(A) (*A)=0
-#define thr_alarm_in_use(A) ((A) != 0)
-void init_thr_alarm(uint max_alarm);
-void thr_alarm_kill(pthread_t thread_id);
-sig_handler process_alarm(int);
#endif /* __WIN__ */
-bool thr_alarm(thr_alarm_t *alarmed,uint sec, ALARM *buff);
+typedef thr_alarm_entry* thr_alarm_t;
+
+typedef struct st_alarm {
+ ulong expire_time;
+ thr_alarm_entry alarmed; /* set when alarm is due */
+ pthread_t thread;
+ my_bool malloced;
+} ALARM;
+
+#define thr_alarm_init(A) (*(A))=0
+#define thr_alarm_in_use(A) (*(A)!= 0)
+void init_thr_alarm(uint max_alarm);
+bool thr_alarm(thr_alarm_t *alarmed, uint sec, ALARM *buff);
+void thr_alarm_kill(pthread_t thread_id);
void thr_end_alarm(thr_alarm_t *alarmed);
void end_thr_alarm(void);
+sig_handler process_alarm(int);
+#ifndef thr_got_alarm
+bool thr_got_alarm(thr_alarm_t *alrm);
+#endif
+
+
#endif /* DONT_USE_THR_ALARM */
#ifdef __cplusplus
}
-#endif
-#endif
+#endif /* __cplusplus */
+#endif /* _thr_alarm_h */
+
{
fprintf(stderr,"safe_mutex: Trying to lock mutex at %s, line %d, when the mutex was already locked at %s, line %d\n",
file,line,mp->file,mp->line);
+ fflush(stderr);
abort();
}
pthread_mutex_unlock(&mp->global);
{
fprintf(stderr,"Got error %d when trying to lock mutex at %s, line %d\n",
error, file, line);
+ fflush(stderr);
abort();
}
if (mp->count++)
{
fprintf(stderr,"safe_mutex: Error in thread libray: Got mutex at %s, line %d more than 1 time\n", file,line);
+ fflush(stderr);
abort();
}
mp->thread=pthread_self();
{
fprintf(stderr,"safe_mutex: Trying to unlock mutex that wasn't locked at %s, line %d\n Last used at %s, line: %d\n",
file,line,mp->file ? mp->file : "",mp->line);
+ fflush(stderr);
abort();
}
if (!pthread_equal(pthread_self(),mp->thread))
{
fprintf(stderr,"safe_mutex: Trying to unlock mutex at %s, line %d that was locked by another thread at: %s, line: %d\n",
file,line,mp->file,mp->line);
+ fflush(stderr);
abort();
}
mp->count--;
+#ifdef __WIN__
+ pthread_mutex_unlock(&mp->mutex);
+ error=0;
+#else
error=pthread_mutex_unlock(&mp->mutex);
if (error)
{
fprintf(stderr,"safe_mutex: Got error: %d when trying to unlock mutex at %s, line %d\n", error, file, line);
+ fflush(stderr);
abort();
}
+#endif /* __WIN__ */
pthread_mutex_unlock(&mp->global);
return error;
}
if (mp->count == 0)
{
fprintf(stderr,"safe_mutex: Trying to cond_wait on a unlocked mutex at %s, line %d\n",file,line);
+ fflush(stderr);
abort();
}
if (!pthread_equal(pthread_self(),mp->thread))
{
fprintf(stderr,"safe_mutex: Trying to cond_wait on a mutex at %s, line %d that was locked by another thread at: %s, line: %d\n",
file,line,mp->file,mp->line);
+ fflush(stderr);
abort();
}
{
fprintf(stderr,"safe_mutex: Count was %d on locked mutex at %s, line %d\n",
mp->count+1, file, line);
+ fflush(stderr);
abort();
}
pthread_mutex_unlock(&mp->global);
if (error)
{
fprintf(stderr,"safe_mutex: Got error: %d when doing a safe_mutex_wait at %s, line %d\n", error, file, line);
+ fflush(stderr);
abort();
}
if (mp->count++)
fprintf(stderr,
"safe_mutex: Count was %d in thread %lx when locking mutex at %s, line %d\n",
mp->count-1, my_thread_id(), file, line);
+ fflush(stderr);
abort();
}
mp->thread=pthread_self();
if (mp->count != 1 || !pthread_equal(pthread_self(),mp->thread))
{
fprintf(stderr,"safe_mutex: Trying to cond_wait at %s, line %d on a not hold mutex\n",file,line);
+ fflush(stderr);
abort();
}
mp->count--; /* Mutex will be released */
fprintf(stderr,
"safe_mutex: Count was %d in thread %lx when locking mutex at %s, line %d (error: %d)\n",
mp->count-1, my_thread_id(), file, line, error);
+ fflush(stderr);
abort();
}
mp->thread=pthread_self();
int safe_mutex_destroy(safe_mutex_t *mp, const char *file, uint line)
{
+ int error=0;
if (mp->count != 0)
{
fprintf(stderr,"safe_mutex: Trying to destroy a mutex that was locked at %s, line %d at %s, line %d\n",
mp->file,mp->line, file, line);
+ fflush(stderr);
abort();
}
+#ifdef __WIN__
pthread_mutex_destroy(&mp->global);
- return pthread_mutex_destroy(&mp->mutex);
+ pthread_mutex_destroy(&mp->mutex);
+#else
+ if (pthread_mutex_destroy(&mp->global))
+ error=1;
+ if (pthread_mutex_destroy(&mp->mutex))
+ error=1;
+#endif
+ return error;
}
#endif /* THREAD && SAFE_MUTEX */
** If part, uniq field is found and full_name == 0 then x is expanded
** to full field.
** full_name has the following bit values:
-** If & 1 accept only hole names
+** If & 1 accept only whole names
** If & 2 don't expand if half field
** If & 4 allow #number# as type
****************************************************************************/
--- /dev/null
+#! /usr/bin/perl -w
+
+# Maybe I should have used PHP instead? ;)
+
+use strict;
+$| = 1;
+
+-f "libmysql.c" or die "$0 must be run from the libmysql directory\n";
+
+my $command = shift || usage();
+$command =~ /^--(?:update|huh|restore)$/ or usage();
+
+my $from = shift || '/users/tim/my/work';
+my @source_dirs = qw/dbug strings mysys libmysql include/;
+my $source_re = qr/\.(?:cc?|h)$/;
+my %skip = (
+ 'ctype_autoconf.c' => 1,
+ 'ctype_extra_sources.c' => 1,
+ 'my_config.h' => 1,
+);
+
+opendir D, "."
+ or die "can't opendir .: $!\n";
+my @files = grep { /$source_re/ and !$skip{$_} } readdir D;
+closedir D;
+
+if ($command eq '--restore')
+{
+ foreach (@files)
+ {
+ -f "$_.orig" and
+ system("mv -f $_.orig $_") and die "can't restore $_: $!\n";
+ }
+ exit 0;
+}
+
+if ($command eq '--huh')
+{
+ diff_files();
+ exit 0;
+}
+
+my %sources;
+foreach my $d (@source_dirs)
+{
+ opendir D, "$from/$d" or die "opendir $from/$d: $!\n";
+ foreach (grep { /$source_re/ } readdir D)
+ {
+ $sources{$_} ||= "$d/$_";
+ }
+ closedir D;
+}
+
+foreach my $f (@files)
+{
+ my $s = $sources{$f} or die "can't find source file for $f\n";
+ unlink "$f.orig";
+ system("mv $f $f.orig") and die "can't move $f: $!\n";
+ #print ">> ", scalar(`ls -l $from/$s`), "\n";
+ print ">> $s\n";
+ system("cp $from/$s $f") and die "can't copy $from/$s: $!\n";
+ #print "]] ", scalar(`ls -l $f`), "\n";
+}
+
+system("chmod u+w @files") and die "can't set perms on files: $!\n";
+system("./fix_copyright @files") and die "can't fix copyright: $!\n";
+diff_files();
+
+exit 0;
+
+
+sub usage
+{
+ die <<"EOF";
+usage: $0 --update [mysql-source-dir]
+ $0 --huh
+ $0 --restore
+EOF
+}
+
+sub diff_files {
+ foreach my $f (@files)
+ {
+ if (!-f "$f.orig" or !system("diff -u $f.orig $f"))
+ {
+ print STDERR "SAME: $f\n";
+ unlink "$f.orig";
+ }
+ else
+ {
+ print STDERR "DIFF: $f\n";
+ }
+ }
+}
#include <my_sys.h>
#include <my_net.h>
#include <m_string.h>
+#ifdef HAVE_POLL
+#include <sys/poll.h>
+#endif
#if defined(__EMX__)
#include <sys/ioctl.h>
-#define ioctlsocket(A,B,C) ioctl((A),(B),(void *)(C),sizeof(*(C)))
-#undef HAVE_FCNTL
+#define ioctlsocket ioctl
#endif /* defined(__EMX__) */
#if defined(MSDOS) || defined(__WIN__)
if ((vio = (Vio*) my_malloc(sizeof(*vio),MYF(MY_WME))))
{
vio_reset(vio, type, sd, 0, localhost);
- sprintf(vio->desc, "socket (%d)", vio->sd);
+ sprintf(vio->desc,
+ (vio->type == VIO_TYPE_SOCKET ? "socket (%d)" : "TCP/IP (%d)"),
+ vio->sd);
#if !defined(___WIN__) && !defined(__EMX__)
#if !defined(NO_FCNTL_NONBLOCK)
vio->fcntl_mode = fcntl(sd, F_GETFL);
#else /* !defined(__WIN__) && !defined(__EMX__) */
{
/* set to blocking mode by default */
- ulong arg=0;
+ ulong arg=0, r;
r = ioctlsocket(vio->sd,FIONBIO,(void*) &arg, sizeof(arg));
}
#endif
}
-int vio_fastsend(Vio * vio, my_bool onoff)
+int vio_fastsend(Vio * vio __attribute__((unused)))
{
int r=0;
DBUG_ENTER("vio_fastsend");
- DBUG_PRINT("enter", ("onoff:%d", (int) onoff));
#ifdef IPTOS_THROUGHPUT
{
if (vio->type == VIO_TYPE_NAMEDPIPE)
{
#if defined(__NT__) && defined(MYSQL_SERVER)
- CancelIO(vio->hPipe);
+ CancelIo(vio->hPipe);
DisconnectNamedPipe(vio->hPipe);
#endif
r=CloseHandle(vio->hPipe);
DBUG_VOID_RETURN;
}
+
+/* Return 0 if there is data to be read */
+
+my_bool vio_poll_read(Vio *vio,uint timeout)
+{
+#ifndef HAVE_POLL
+ return 0;
+#else
+ struct pollfd fds;
+ int res;
+ DBUG_ENTER("vio_poll");
+ fds.fd=vio->sd;
+ fds.events=POLLIN;
+ fds.revents=0;
+ if ((res=poll(&fds,1,(int) timeout*1000)) <= 0)
+ {
+ DBUG_RETURN(res < 0 ? 0 : 1); /* Don't return 1 on errors */
+ }
+ DBUG_RETURN(fds.revents & POLLIN ? 0 : 1);
+#endif
+}
+
#endif /* HAVE_VIO */
/*
* setsockopt TCP_NODELAY at IPPROTO_TCP level, when possible.
*/
-int vio_fastsend( Vio* vio,
- my_bool onoff);
+ int vio_fastsend( Vio* vio);
/*
* setsockopt SO_KEEPALIVE at SOL_SOCKET level, when possible.
*/
void vio_in_addr(Vio *vio, struct in_addr *in);
+ /* Return 1 if there is data to be read */
+my_bool vio_poll_read(Vio *vio,uint timeout);
+
#ifdef __cplusplus
}
#endif