From d7ab8899eb04d537c4e72abb4210502ad0b60893 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 5 Dec 2003 21:45:19 +0400 Subject: Fix for #1890 and #1959 This bug happens under Windows & Embedded server Reason is that pthread_self() always returns NULL in this case. This confuses thr_lock function and it doesn't stop thread inserting in the write-locked table. Global problem is that there's no way under Windows to get unique thread handle for working thread. Monty made a workaround for server - we store the thread's handle we get when we create thread in the thread-specific variable. This doesn't work with the embedded library for we don't control thread creation there. I added code that sets CurrentThreadId as the pthread_self for the embedded library. It seems to solve problem because it's unique and we don't use pthread_self as a parameter for thread functions in embedded library. mysys/my_thr_init.c: setting of tmp->thread_self added --- mysys/my_thr_init.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'mysys') diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c index 9f64e9dcb60..3196256facc 100644 --- a/mysys/my_thr_init.c +++ b/mysys/my_thr_init.c @@ -157,6 +157,9 @@ my_bool my_thread_init(void) tmp= &THR_KEY_mysys; #endif tmp->id= ++thread_id; +#if defined(__WIN__) && defined(EMBEDDED_LIBRARY) + tmp->thread_self= (pthread_t)getpid(); +#endif pthread_mutex_init(&tmp->mutex,MY_MUTEX_INIT_FAST); pthread_cond_init(&tmp->suspend, NULL); tmp->init= 1; -- cgit v1.2.1 From 82b2a31343a1815c52ae5b966b6b747349f9e42f Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 10 Dec 2003 00:00:20 +0200 Subject: Added checking of return value from my_once_alloc() in charset Added checking of return value from malloc() in reg_init() client/mysqltest.c: Added comment dbug/dbug.c: Removed not needed test mysys/charset.c: Added checking of return value from my_once_alloc() regex/reginit.c: Abort if out of memory in reg_init() (unlikely) sql/item_strfunc.cc: Added comment --- mysys/charset.c | 54 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 15 deletions(-) (limited to 'mysys') diff --git a/mysys/charset.c b/mysys/charset.c index ba6733185e0..5e5be9e1b42 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -300,7 +300,25 @@ static CHARSET_INFO *find_charset_by_name(CHARSET_INFO **table, return NULL; } -static CHARSET_INFO *add_charset(uint cs_number, const char *cs_name, myf flags) +/* + Read charset from file. + + NOTES + One never has to deallocate character sets. They will all be deallocated + by my_once_free() when program ends. + + If my_once_alloc() fails then this function may 'leak' some memory + which my_once_free() will deallocate, but this is so unlikely to happen + that this can be ignored. + + RETURN + 0 Error + # Pointer to allocated charset structure +*/ + + +static CHARSET_INFO *add_charset(uint cs_number, const char *cs_name, + myf flags) { CHARSET_INFO tmp_cs,*cs; uchar tmp_ctype[CTYPE_TABLE_SIZE]; @@ -317,21 +335,27 @@ static CHARSET_INFO *add_charset(uint cs_number, const char *cs_name, myf flags) cs->sort_order=tmp_sort_order; cs->strxfrm_multiply=cs->mbmaxlen=1; if (read_charset_file(cs_number, cs, flags)) - return NULL; - - cs = (CHARSET_INFO*) my_once_alloc(sizeof(CHARSET_INFO), - MYF(MY_WME)); - *cs=tmp_cs; - cs->name = (char *) my_once_alloc((uint) strlen(cs_name)+1, MYF(MY_WME)); - cs->ctype = (uchar*) my_once_alloc(CTYPE_TABLE_SIZE, MYF(MY_WME)); - cs->to_lower = (uchar*) my_once_alloc(TO_LOWER_TABLE_SIZE, MYF(MY_WME)); - cs->to_upper = (uchar*) my_once_alloc(TO_UPPER_TABLE_SIZE, MYF(MY_WME)); + return 0; + + if (!(cs= (CHARSET_INFO*) my_once_alloc(sizeof(CHARSET_INFO), + MYF(MY_WME)))) + return 0; + + *cs= tmp_cs; + cs->name= (char *) my_once_alloc((uint) strlen(cs_name)+1, MYF(MY_WME)); + cs->ctype= (uchar*) my_once_alloc(CTYPE_TABLE_SIZE, MYF(MY_WME)); + cs->to_lower= (uchar*) my_once_alloc(TO_LOWER_TABLE_SIZE, MYF(MY_WME)); + cs->to_upper= (uchar*) my_once_alloc(TO_UPPER_TABLE_SIZE, MYF(MY_WME)); cs->sort_order=(uchar*) my_once_alloc(SORT_ORDER_TABLE_SIZE, MYF(MY_WME)); - cs->number = cs_number; - memcpy((char*) cs->name, (char*) cs_name, strlen(cs_name) + 1); - memcpy((char*) cs->ctype, (char*) tmp_ctype, sizeof(tmp_ctype)); - memcpy((char*) cs->to_lower, (char*) tmp_to_lower, sizeof(tmp_to_lower)); - memcpy((char*) cs->to_upper, (char*) tmp_to_upper, sizeof(tmp_to_upper)); + if (!cs->name || !cs->ctype || !cs->to_lower || !cs->to_upper || + !cs->sort_order) + return 0; + + cs->number= cs_number; + memcpy((char*) cs->name, (char*) cs_name, strlen(cs_name) + 1); + memcpy((char*) cs->ctype, (char*) tmp_ctype, sizeof(tmp_ctype)); + memcpy((char*) cs->to_lower, (char*) tmp_to_lower, sizeof(tmp_to_lower)); + memcpy((char*) cs->to_upper, (char*) tmp_to_upper, sizeof(tmp_to_upper)); memcpy((char*) cs->sort_order, (char*) tmp_sort_order, sizeof(tmp_sort_order)); insert_dynamic(&cs_info_table, (gptr) &cs); -- cgit v1.2.1 From bdeadbb6ff70859943bf00cb0fff8c6c3d9b7a65 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 11 Dec 2003 06:24:08 +0200 Subject: Fixed a possible memory leak on MacOSX when using the shared libmysql.so library (Bug #2061) mysql_server_init() now returns error code if something went wrong (Bug #2062) Don't use my_fopen() when reading symlink information as this may cause problems when a lot of files are opened. Free thread keys with pthread_key_delete() instead of relying on automatic free. (Bug #2062) Fixed bug in UNION statement with alias '*'. (Bug #1249) Fixed a bug in DELETE ... ORDER BY ... LIMIT where the rows where not deleted in the proper order. (Bug #1024). FOUND_ROWS() could return incorrect number of rows after a query with an impossible WHERE condition. HOW DATABASES doesn't anymore show .sym files (on windows) that doesn't point to a valid directory. (Bug #1385) include/config-win.h: Ensure that USE_SYMDIR is set for all windows versions (This is set in makefiles, so this is just an extra safety measure) include/my_pthread.h: Fixed a possible memory leak on MacOSX when using the shared libmysql.so library (Bug #2061) include/my_sys.h: my_init() now returns error code if something went wrong include/mysql.h: mysql_once_init() now returns error code if something went wrong include/mysql_com.h: my_init() now returns error code if something went wrong libmysql/libmysql.c: mysql_server_init() and mysql_once_init() now returns error code if something went wrong (Bug #2062) mysql-test/r/limit.result: Update results mysql-test/r/select_found.result: Update results mysql-test/r/union.result: Update results mysql-test/t/limit.test: Added test for DELETE ... ORDER BY ... LIMIT (bug #1024) mysql-test/t/select_found.test: Added test for problem with impossible WHERE (Bug #1468) mysql-test/t/union.test: Added test for problem with alias '*' (Bug #1249) mysys/mf_pack.c: Don't use my_fopen() when reading symlink information as this may cause problems when a lot of files are opened. mysys/my_init.c: my_init() now returns error code if something went wrong mysys/my_lib.c: More debug information mysys/my_thr_init.c: Free thread keys with pthread_key_delete() instead of relying on automatic free. (Bug #2062) sql/sql_base.cc: Fixed bug in UNION statement with alias '*'. (Bug #1249) sql/sql_delete.cc: Fixed a bug in DELETE ... ORDER BY ... LIMIT where the rows where not deleted in the proper order. (Bug #1024). sql/sql_select.cc: FOUND_ROWS() could return incorrect number of rows after a query with an impossible WHERE condition. sql/sql_show.cc: SHOW DATABASES doesn't anymore show .sym files (on windows) that doesn't point to a valid directory. (Bug #1385) sql/sql_yacc.yy: Allow syntax UNION DISTINCT --- mysys/mf_pack.c | 27 ++++++++++++++------------- mysys/my_init.c | 20 +++++++++++++++----- mysys/my_lib.c | 6 ++++-- mysys/my_thr_init.c | 26 ++++++++++++++++++++------ 4 files changed, 53 insertions(+), 26 deletions(-) (limited to 'mysys') diff --git a/mysys/mf_pack.c b/mysys/mf_pack.c index b3aa347006e..e2e811fe89a 100644 --- a/mysys/mf_pack.c +++ b/mysys/mf_pack.c @@ -210,13 +210,13 @@ uint cleanup_dirname(register my_string to, const char *from) } /* cleanup_dirname */ - /* - On system where you don't have symbolic links, the following - code will allow you to create a file: - directory-name.lnk that should contain the real path - to the directory. This will be used if the directory name - doesn't exists - */ +/* + On system where you don't have symbolic links, the following + code will allow you to create a file: + directory-name.sym that should contain the real path + to the directory. This will be used if the directory name + doesn't exists +*/ my_bool my_use_symdir=0; /* Set this if you want to use symdirs */ @@ -228,16 +228,17 @@ void symdirget(char *dir) char *pos=strend(dir); if (dir[0] && pos[-1] != FN_DEVCHAR && access(dir, F_OK)) { - FILE *fp; + File file; + uint length; char temp= *(--pos); /* May be "/" or "\" */ strmov(pos,".sym"); - fp = my_fopen(dir, O_RDONLY,MYF(0)); + file= my_open(dir, O_RDONLY, MYF(0)); *pos++=temp; *pos=0; /* Restore old filename */ - if (fp) + if (file >= 0) { - if (fgets(buff, sizeof(buff)-1, fp)) + if ((length= my_read(file, buff, sizeof(buff), MYF(0))) > 0) { - for (pos=strend(buff); + for (pos= buff + length ; pos > buff && (iscntrl(pos[-1]) || isspace(pos[-1])) ; pos --); @@ -247,7 +248,7 @@ void symdirget(char *dir) strmake(dir,buff, (uint) (pos-buff)); } - my_fclose(fp,MYF(0)); + my_close(file, MYF(0)); } } } diff --git a/mysys/my_init.c b/mysys/my_init.c index a8a184a2cb4..8d4ba2c97b6 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -62,13 +62,22 @@ static ulong atoi_octal(const char *str) } - /* Init my_sys functions and my_sys variabels */ +/* + Init my_sys functions and my_sys variabels + + SYNOPSIS + my_init() -void my_init(void) + RETURN + 0 ok + 1 Couldn't initialize environment +*/ + +my_bool my_init(void) { my_string str; if (my_init_done) - return; + return 0; my_init_done=1; #if defined(THREAD) && defined(SAFE_MUTEX) safe_mutex_global_init(); /* Must be called early */ @@ -78,7 +87,8 @@ void my_init(void) #if defined(HAVE_PTHREAD_INIT) pthread_init(); /* Must be called before DBUG_ENTER */ #endif - my_thread_global_init(); + if (my_thread_global_init()) + return 1; #if !defined( __WIN__) && !defined(OS2) && !defined(__NETWARE__) sigfillset(&my_signals); /* signals blocked by mf_brkhant */ #endif @@ -110,7 +120,7 @@ void my_init(void) #ifdef __WIN__ win32_init_tcp_ip(); #endif - DBUG_VOID_RETURN; + DBUG_RETURN(0); } } /* my_init */ diff --git a/mysys/my_lib.c b/mysys/my_lib.c index 035bafd07b9..426acedc646 100644 --- a/mysys/my_lib.c +++ b/mysys/my_lib.c @@ -602,9 +602,11 @@ MY_STAT *my_stat(const char *path, MY_STAT *stat_area, myf my_flags) if ((m_used= (stat_area == NULL))) if (!(stat_area = (MY_STAT *) my_malloc(sizeof(MY_STAT), my_flags))) goto error; - if ( ! stat((my_string) path, (struct stat *) stat_area) ) + if (! stat((my_string) path, (struct stat *) stat_area) ) DBUG_RETURN(stat_area); - my_errno=errno; + + DBUG_PRINT("error",("Got errno: %d from stat", errno)); + my_errno= errno; if (m_used) /* Free if new area */ my_free((gptr) stat_area,MYF(0)); diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c index 9f64e9dcb60..3827b24ac32 100644 --- a/mysys/my_thr_init.c +++ b/mysys/my_thr_init.c @@ -44,12 +44,23 @@ pthread_mutexattr_t my_fast_mutexattr; pthread_mutexattr_t my_errchk_mutexattr; #endif +/* + initialize thread environment + + SYNOPSIS + my_thread_global_init() + + RETURN + 0 ok + 1 error (Couldn't create THR_KEY_mysys) +*/ + my_bool my_thread_global_init(void) { - if (pthread_key_create(&THR_KEY_mysys,free)) + if (pthread_key_create(&THR_KEY_mysys,0)) { fprintf(stderr,"Can't initialize threads: error %d\n",errno); - exit(1); + return 1; } #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP pthread_mutexattr_init(&my_fast_mutexattr); @@ -79,15 +90,18 @@ my_bool my_thread_global_init(void) #ifndef HAVE_GETHOSTBYNAME_R pthread_mutex_init(&LOCK_gethostbyname_r,MY_MUTEX_INIT_SLOW); #endif - return my_thread_init(); + if (my_thread_init()) + { + my_thread_global_end(); /* Clean up */ + return 1; + } + return 0; } void my_thread_global_end(void) { -#if defined(USE_TLS) - (void) TlsFree(THR_KEY_mysys); -#endif + pthread_key_delete(THR_KEY_mysys); #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP pthread_mutexattr_destroy(&my_fast_mutexattr); #endif -- cgit v1.2.1 From f3327cc312d06663ff6f56207d11437ba59778ee Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 12 Dec 2003 03:39:29 +0300 Subject: Fix for Bug #1952 "SHOW TABLE STATUS very slow w/large number of tables" Replaced old algorithm which were used in my_dir() and stored all information about directory entries in one chunk of memory with new one which stores file names and MY_STAT structures in separate memroot, so now we don't need to copy this data during reallocation of dir_entry array. include/my_dir.h: Changed mystat member of FILEINFO structure to pointer since this prevents unneeded memory allocation and initialization. Added comment about new hidden members of MY_DIR structure. mysys/my_lib.c: Replaced old algorithm in my_dir() which stored all information about directory entries in one chunk of memory with new one which stores file names and MY_STAT structures in separate memroot. Now we don't copy this data during reallocation of array with FILEINFO structures. Also tuned sizes of memory chunks during first-other reallocations (we suppose that we either have < 100 files in the directory or > 1000 of them). sql/sql_show.cc: Updated only place in code where mystat member of FILEINFO structure is used. --- mysys/my_lib.c | 339 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 178 insertions(+), 161 deletions(-) (limited to 'mysys') diff --git a/mysys/my_lib.c b/mysys/my_lib.c index 426acedc646..055e00d2efc 100644 --- a/mysys/my_lib.c +++ b/mysys/my_lib.c @@ -62,8 +62,15 @@ #define READDIR(A,B,C) (!(C=readdir(A))) #endif +/* + We are assuming that directory we are reading is either has less than + 100 files and so can be read in one initial chunk or has more than 1000 + files and so big increment are suitable. +*/ +#define ENTRIES_START_SIZE (8192/sizeof(FILEINFO)) +#define ENTRIES_INCREMENT (65536/sizeof(FILEINFO)) +#define NAMES_START_SIZE 32768 -#define STARTSIZE ONCE_ALLOC_INIT*8 /* some mallocmargin */ static int comp_names(struct fileinfo *a,struct fileinfo *b); @@ -74,7 +81,13 @@ void my_dirend(MY_DIR *buffer) { DBUG_ENTER("my_dirend"); if (buffer) + { + delete_dynamic((DYNAMIC_ARRAY*)((char*)buffer + + ALIGN_SIZE(sizeof(MY_DIR)))); + free_root((MEM_ROOT*)((char*)buffer + ALIGN_SIZE(sizeof(MY_DIR)) + + ALIGN_SIZE(sizeof(DYNAMIC_ARRAY))), MYF(0)); my_free((gptr) buffer,MYF(0)); + } DBUG_VOID_RETURN; } /* my_dirend */ @@ -91,14 +104,14 @@ static int comp_names(struct fileinfo *a, struct fileinfo *b) MY_DIR *my_dir(const char *path, myf MyFlags) { + char *buffer; + MY_DIR *result= 0; + FILEINFO finfo; + DYNAMIC_ARRAY *dir_entries_storage; + MEM_ROOT *names_storage; DIR *dirp; struct dirent *dp; - struct fileinfo *fnames; - char *buffer, *obuffer, *tempptr; - uint fcnt,i,size,firstfcnt, maxfcnt,length; char tmp_path[FN_REFLEN+1],*tmp_file; - my_ptrdiff_t diff; - bool eof; #ifdef THREAD char dirent_tmp[sizeof(struct dirent)+_POSIX_PATH_MAX+1]; #endif @@ -110,74 +123,72 @@ MY_DIR *my_dir(const char *path, myf MyFlags) #endif dirp = opendir(directory_file_name(tmp_path,(my_string) path)); - size = STARTSIZE; #if defined(__amiga__) if ((dirp->dd_fd) < 0) /* Directory doesn't exists */ goto error; #endif - if (dirp == NULL || ! (buffer = (char *) my_malloc(size, MyFlags))) + if (dirp == NULL || + ! (buffer= my_malloc(ALIGN_SIZE(sizeof(MY_DIR)) + + ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)) + + sizeof(MEM_ROOT), MyFlags))) + goto error; + + dir_entries_storage= (DYNAMIC_ARRAY*)(buffer + ALIGN_SIZE(sizeof(MY_DIR))); + names_storage= (MEM_ROOT*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)) + + ALIGN_SIZE(sizeof(DYNAMIC_ARRAY))); + + if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO), + ENTRIES_START_SIZE, ENTRIES_INCREMENT)) + { + my_free((gptr) buffer,MYF(0)); goto error; + } + init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE); + + /* MY_DIR structure is allocated and completly initialized at this point */ + result= (MY_DIR*)buffer; - fcnt = 0; tmp_file=strend(tmp_path); - firstfcnt = maxfcnt = (size - sizeof(MY_DIR)) / - (sizeof(struct fileinfo) + FN_LEN); - fnames= (struct fileinfo *) (buffer + sizeof(MY_DIR)); - tempptr = (char *) (fnames + maxfcnt); #ifdef THREAD dp= (struct dirent*) dirent_tmp; #else dp=0; #endif - eof=0; - for (;;) + + while (!(READDIR(dirp,(struct dirent*) dirent_tmp,dp))) { - while (fcnt < maxfcnt && - !(eof= READDIR(dirp,(struct dirent*) dirent_tmp,dp))) + if (!(finfo.name= strdup_root(names_storage, dp->d_name))) + goto error; + + if (MyFlags & MY_WANT_STAT) { - bzero((gptr) (fnames+fcnt),sizeof(fnames[0])); /* for purify */ - fnames[fcnt].name = tempptr; - tempptr = strmov(tempptr,dp->d_name) + 1; - if (MyFlags & MY_WANT_STAT) - { - VOID(strmov(tmp_file,dp->d_name)); - VOID(my_stat(tmp_path, &fnames[fcnt].mystat, MyFlags)); - } - ++fcnt; + if (!(finfo.mystat= (MY_STAT*)alloc_root(names_storage, + sizeof(MY_STAT)))) + goto error; + + bzero(finfo.mystat, sizeof(MY_STAT)); + VOID(strmov(tmp_file,dp->d_name)); + VOID(my_stat(tmp_path, finfo.mystat, MyFlags)); } - if (eof) - break; - size += STARTSIZE; obuffer = buffer; - if (!(buffer = (char *) my_realloc((gptr) buffer, size, - MyFlags | MY_FREE_ON_ERROR))) - goto error; /* No memory */ - length= (uint) (sizeof(struct fileinfo ) * firstfcnt); - diff= PTR_BYTE_DIFF(buffer , obuffer) + (int) length; - fnames= (struct fileinfo *) (buffer + sizeof(MY_DIR)); - tempptr= ADD_TO_PTR(tempptr,diff,char*); - for (i = 0; i < maxfcnt; i++) - fnames[i].name = ADD_TO_PTR(fnames[i].name,diff,char*); - - /* move filenames upp a bit */ - maxfcnt += firstfcnt; - bmove_upp(tempptr,tempptr-length, - (uint) (tempptr- (char*) (fnames+maxfcnt))); + else + finfo.mystat= NULL; + + if (push_dynamic(dir_entries_storage, (gptr)&finfo)) + goto error; } (void) closedir(dirp); - { - MY_DIR * s = (MY_DIR *) buffer; - s->number_off_files = (uint) fcnt; - s->dir_entry = fnames; - } - if (!(MyFlags & MY_DONT_SORT)) - qsort((void *) fnames, (size_s) fcnt, sizeof(struct fileinfo), - (qsort_cmp) comp_names); #if defined(THREAD) && !defined(HAVE_READDIR_R) pthread_mutex_unlock(&THR_LOCK_open); #endif - DBUG_RETURN((MY_DIR *) buffer); + result->dir_entry= (FILEINFO *)dir_entries_storage->buffer; + result->number_off_files= dir_entries_storage->elements; + + if (!(MyFlags & MY_DONT_SORT)) + qsort((void *) result->dir_entry, result->number_off_files, + sizeof(FILEINFO), (qsort_cmp) comp_names); + DBUG_RETURN(result); error: #if defined(THREAD) && !defined(HAVE_READDIR_R) @@ -186,6 +197,7 @@ MY_DIR *my_dir(const char *path, myf MyFlags) my_errno=errno; if (dirp) (void) closedir(dirp); + my_dirend(result); if (MyFlags & (MY_FAE | MY_WME)) my_error(EE_DIR,MYF(ME_BELL+ME_WAITTANG),path,my_errno); DBUG_RETURN((MY_DIR *) NULL); @@ -349,10 +361,11 @@ my_string directory_file_name (my_string dst, const char *src) MY_DIR *my_dir(const char *path, myf MyFlags) { - struct fileinfo *fnames; - char *buffer, *obuffer, *tempptr; - int eof,i,fcnt,firstfcnt,length,maxfcnt; - uint size; + char *buffer; + MY_DIR *result= 0; + FILEINFO finfo; + DYNAMIC_ARRAY *dir_entries_storage; + MEM_ROOT *names_storage; #ifdef __BORLANDC__ struct ffblk find; #else @@ -360,7 +373,6 @@ MY_DIR *my_dir(const char *path, myf MyFlags) #endif ushort mode; char tmp_path[FN_REFLEN],*tmp_file,attrib; - my_ptrdiff_t diff; #ifdef _WIN64 __int64 handle; #else @@ -392,85 +404,88 @@ MY_DIR *my_dir(const char *path, myf MyFlags) goto error; #endif - size = STARTSIZE; - firstfcnt = maxfcnt = (size - sizeof(MY_DIR)) / - (sizeof(struct fileinfo) + FN_LEN); - if ((buffer = (char *) my_malloc(size, MyFlags)) == 0) + if (!(buffer= my_malloc(ALIGN_SIZE(sizeof(MY_DIR)) + + ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)) + + sizeof(MEM_ROOT), MyFlags))) goto error; - fnames= (struct fileinfo *) (buffer + sizeof(MY_DIR)); - tempptr = (char *) (fnames + maxfcnt); - fcnt = 0; - for (;;) + dir_entries_storage= (DYNAMIC_ARRAY*)(buffer + ALIGN_SIZE(sizeof(MY_DIR))); + names_storage= (MEM_ROOT*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)) + + ALIGN_SIZE(sizeof(DYNAMIC_ARRAY))); + + if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO), + ENTRIES_START_SIZE, ENTRIES_INCREMENT)) { - do + my_free((gptr) buffer,MYF(0)); + goto error; + } + init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE); + + /* MY_DIR structure is allocated and completly initialized at this point */ + result= (MY_DIR*)buffer; + + do + { +#ifdef __BORLANDC__ + if (!(finfo.name= strdup_root(names_storage, find.ff_name))) + goto error; +#else + if (!(finfo.name= strdup_root(names_storage, find.name))) + goto error; +#endif + if (MyFlags & MY_WANT_STAT) { - fnames[fcnt].name = tempptr; + if (!(finfo.mystat= (MY_STAT*)alloc_root(names_storage, + sizeof(MY_STAT)))) + goto error; + + bzero(finfo.mystat, sizeof(MY_STAT)); #ifdef __BORLANDC__ - tempptr = strmov(tempptr,find.ff_name) + 1; - fnames[fcnt].mystat.st_size=find.ff_fsize; - fnames[fcnt].mystat.st_uid=fnames[fcnt].mystat.st_gid=0; + finfo.mystat->st_size=find.ff_fsize; mode=MY_S_IREAD; attrib=find.ff_attrib; #else - tempptr = strmov(tempptr,find.name) + 1; - fnames[fcnt].mystat.st_size=find.size; - fnames[fcnt].mystat.st_uid=fnames[fcnt].mystat.st_gid=0; + finfo.mystat->st_size=find.size; mode=MY_S_IREAD; attrib=find.attrib; #endif if (!(attrib & _A_RDONLY)) mode|=MY_S_IWRITE; if (attrib & _A_SUBDIR) mode|=MY_S_IFDIR; - fnames[fcnt].mystat.st_mode=mode; + finfo.mystat->st_mode=mode; #ifdef __BORLANDC__ - fnames[fcnt].mystat.st_mtime=((uint32) find.ff_ftime); + finfo.mystat->st_mtime=((uint32) find.ff_ftime); #else - fnames[fcnt].mystat.st_mtime=((uint32) find.time_write); -#endif - ++fcnt; -#ifdef __BORLANDC__ - } while ((eof= findnext(&find)) == 0 && fcnt < maxfcnt); -#else - } while ((eof= _findnext(handle,&find)) == 0 && fcnt < maxfcnt); + finfo.mystat->st_mtime=((uint32) find.time_write); #endif + } + else + finfo.mystat= NULL; - DBUG_PRINT("test",("eof: %d errno: %d",eof,errno)); - if (eof) - break; - size += STARTSIZE; obuffer = buffer; - if (!(buffer = (char *) my_realloc((gptr) buffer, size, - MyFlags | MY_FREE_ON_ERROR))) + if (push_dynamic(dir_entries_storage, (gptr)&finfo)) goto error; - length= sizeof(struct fileinfo ) * firstfcnt; - diff= PTR_BYTE_DIFF(buffer , obuffer) +length; - fnames= (struct fileinfo *) (buffer + sizeof(MY_DIR)); - tempptr= ADD_TO_PTR(tempptr,diff,char*); - for (i = 0; i < maxfcnt; i++) - fnames[i].name = ADD_TO_PTR(fnames[i].name,diff,char*); - - /* move filenames upp a bit */ - maxfcnt += firstfcnt; - bmove_upp(tempptr,ADD_TO_PTR(tempptr,-length,char*), - (int) PTR_BYTE_DIFF(tempptr,fnames+maxfcnt)); - } - { - MY_DIR * s = (MY_DIR *) buffer; - s->number_off_files = (uint) fcnt; - s->dir_entry = fnames; - } - if (!(MyFlags & MY_DONT_SORT)) - qsort(fnames,fcnt,sizeof(struct fileinfo),(qsort_cmp) comp_names); -#ifndef __BORLANDC__ + +#ifdef __BORLANDC__ + } while (findnext(&find) == 0); +#else + } while (_findnext(handle,&find) == 0); + _findclose(handle); #endif - DBUG_RETURN((MY_DIR *) buffer); + result->dir_entry= (FILEINFO *)dir_entries_storage->buffer; + result->number_off_files= dir_entries_storage->elements; + + if (!(MyFlags & MY_DONT_SORT)) + qsort((void *) result->dir_entry, result->number_off_files, + sizeof(FILEINFO), (qsort_cmp) comp_names); + DBUG_RETURN(result); error: my_errno=errno; #ifndef __BORLANDC__ if (handle != -1) _findclose(handle); #endif + my_dirend(result); if (MyFlags & MY_FAE+MY_WME) my_error(EE_DIR,MYF(ME_BELL+ME_WAITTANG),path,errno); DBUG_RETURN((MY_DIR *) NULL); @@ -485,14 +500,14 @@ error: MY_DIR *my_dir(const char* path, myf MyFlags) { - struct fileinfo *fnames; - char *buffer, *obuffer, *tempptr; - int eof,i,fcnt,firstfcnt,length,maxfcnt; - uint size; + char *buffer; + MY_DIR *result= 0; + FILEINFO finfo; + DYNAMIC_ARRAY *dir_entries_storage; + MEM_ROOT *names_storage; struct find_t find; ushort mode; char tmp_path[FN_REFLEN],*tmp_file,attrib; - my_ptrdiff_t diff; DBUG_ENTER("my_dir"); DBUG_PRINT("my",("path: '%s' stat: %d MyFlags: %d",path,MyFlags)); @@ -514,63 +529,65 @@ MY_DIR *my_dir(const char* path, myf MyFlags) if (_dos_findfirst(tmp_path,_A_NORMAL | _A_SUBDIR, &find)) goto error; - size = STARTSIZE; - firstfcnt = maxfcnt = (size - sizeof(MY_DIR)) / - (sizeof(struct fileinfo) + FN_LEN); - if ((buffer = (char *) my_malloc(size, MyFlags)) == 0) + if (!(buffer= my_malloc(ALIGN_SIZE(sizeof(MY_DIR)) + + ALIGN_SIZE(sizeof(DYNAMIC_ARRAY)) + + sizeof(MEM_ROOT), MyFlags))) goto error; - fnames= (struct fileinfo *) (buffer + sizeof(MY_DIR)); - tempptr = (char *) (fnames + maxfcnt); - fcnt = 0; - for (;;) + dir_entries_storage= (DYNAMIC_ARRAY*)(buffer + ALIGN_SIZE(sizeof(MY_DIR))); + names_storage= (MEM_ROOT*)(buffer + ALIGN_SIZE(sizeof(MY_DIR)) + + ALIGN_SIZE(sizeof(DYNAMIC_ARRAY))); + + if (my_init_dynamic_array(dir_entries_storage, sizeof(FILEINFO), + ENTRIES_START_SIZE, ENTRIES_INCREMENT)) { - do + my_free((gptr) buffer,MYF(0)); + goto error; + } + init_alloc_root(names_storage, NAMES_START_SIZE, NAMES_START_SIZE); + + /* MY_DIR structure is allocated and completly initialized at this point */ + result= (MY_DIR*)buffer; + + do + { + if (!(finfo.name= strdup_root(names_storage, find.name))) + goto error; + + if (MyFlags & MY_WANT_STAT) { - fnames[fcnt].name = tempptr; - tempptr = strmov(tempptr,find.name) + 1; - fnames[fcnt].mystat.st_size=find.size; - fnames[fcnt].mystat.st_uid=fnames[fcnt].mystat.st_gid=0; - mode=MY_S_IREAD; attrib=find.attrib; + if (!(finfo.mystat= (MY_STAT*)alloc_root(names_storage, + sizeof(MY_STAT)))) + goto error; + + bzero(finfo.mystat, sizeof(MY_STAT)); + finfo.mystat->st_size= find.size; + mode= MY_S_IREAD; attrib= find.attrib; if (!(attrib & _A_RDONLY)) - mode|=MY_S_IWRITE; + mode|= MY_S_IWRITE; if (attrib & _A_SUBDIR) - mode|=MY_S_IFDIR; - fnames[fcnt].mystat.st_mode=mode; - fnames[fcnt].mystat.st_mtime=((uint32) find.wr_date << 16) + - find.wr_time; - ++fcnt; - } while ((eof= _dos_findnext(&find)) == 0 && fcnt < maxfcnt); - - DBUG_PRINT("test",("eof: %d errno: %d",eof,errno)); - if (eof) - break; - size += STARTSIZE; obuffer = buffer; - if (!(buffer = (char *) my_realloc((gptr) buffer, size, - MyFlags | MY_FREE_ON_ERROR))) + mode|= MY_S_IFDIR; + finfo.mystat->st_mode= mode; + finfo.mystat->st_mtime= ((uint32) find.wr_date << 16) + find.wr_time; + } + else + finfo.mystat= NULL; + + if (push_dynamic(dir_entries_storage, (gptr)&finfo)) goto error; - length= sizeof(struct fileinfo ) * firstfcnt; - diff= PTR_BYTE_DIFF(buffer , obuffer) +length; - fnames= (struct fileinfo *) (buffer + sizeof(MY_DIR)); - tempptr= ADD_TO_PTR(tempptr,diff,char*); - for (i = 0; i < maxfcnt; i++) - fnames[i].name = ADD_TO_PTR(fnames[i].name,diff,char*); - - /* move filenames upp a bit */ - maxfcnt += firstfcnt; - bmove_upp(tempptr,ADD_TO_PTR(tempptr,-length,char*), - (int) PTR_BYTE_DIFF(tempptr,fnames+maxfcnt)); - } - { - MY_DIR * s = (MY_DIR *) buffer; - s->number_off_files = (uint) fcnt; - s->dir_entry = fnames; - } + + } while (_dos_findnext(&find) == 0); + + result->dir_entry= (FILEINFO *)dir_entries_storage->buffer; + result->number_off_files= dir_entries_storage->elements; + if (!(MyFlags & MY_DONT_SORT)) - qsort(fnames,fcnt,sizeof(struct fileinfo),(qsort_cmp) comp_names); - DBUG_RETURN((MY_DIR *) buffer); + qsort((void *) result->dir_entry, result->number_off_files, + sizeof(FILEINFO), (qsort_cmp) comp_names); + DBUG_RETURN(result); error: + my_dirend(result); if (MyFlags & MY_FAE+MY_WME) my_error(EE_DIR,MYF(ME_BELL+ME_WAITTANG),path,errno); DBUG_RETURN((MY_DIR *) NULL); -- cgit v1.2.1 From 6c50fea9579d0f08754ac9e978550f58789c8638 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 12 Dec 2003 22:26:58 +0200 Subject: Fix autoincrement for signed columns (Bug #1366) Fixed problem with char > 128 in QUOTE() function. (Bug #1868) Disable creation of symlinks if my_disable_symlink is set Fixed searching of TEXT with end space. (Bug #1651) Fixed caching bug in multi-table-update where same table was used twice. (Bug #1711) Fixed problem with UNIX_TIMESTAMP() for timestamps close to 0. (Bug #1998) Fixed timestamp.test include/my_base.h: Add HA_END_SPACE_KEY to mark keys that has VARCHAR/TEXT fields. myisam/mi_check.c: Delete not used variable myisam/mi_key.c: Fix autoincrement for signed columns (Bug #1366). Patch by Holyfoot myisam/mi_open.c: Bug fix for future (doesn't affect current code) myisam/mi_search.c: Ignore end space for VARCHAR/TEXT columns mysql-test/r/auto_increment.result: Test auto_increment with signed numbers mysql-test/r/binary.result: Update results (old result was wrong) mysql-test/r/func_str.result: Added test of QUOTE() mysql-test/r/func_time.result: Add test of unix_timestamp() mysql-test/r/have_met_timezone.require: Fixed test mysql-test/r/innodb.result: Add test for InnoDB behaviour with TRUNCATE mysql-test/r/multi_update.result: Test of multi-update bug mysql-test/r/symlink.result: Test of ALTER TABLE and symlinks mysql-test/r/timezone.result: Test of from_unixtime() mysql-test/r/truncate.result: Test of truncate and auto_increment mysql-test/r/type_blob.result: Test of key search on TEXT/VARCHAR column with end space mysql-test/t/auto_increment.test: Test auto_increment with signed numbers mysql-test/t/func_str.test: Added test of QUOTE() mysql-test/t/func_time.test: Add test of unix_timestamp() mysql-test/t/innodb.test: Add test for InnoDB behaviour with TRUNCATE mysql-test/t/multi_update.test: Test of multi-update bug mysql-test/t/symlink.test: Test of ALTER TABLE and symlinks mysql-test/t/timezone.test: Test of from_unixtime() mysql-test/t/truncate.test: Test of truncate and auto_increment mysql-test/t/type_blob.test: Test of key search on TEXT/VARCHAR column with end space mysys/my_symlink2.c: Disable creation of symlinks if my_disable_symlink is set sql/field.h: Indentation cleanup sql/ha_innodb.cc: HA_PART_KEY -> HA_PART_KEY_SEG sql/item_strfunc.cc: Fixed problem with char > 128 in QUOTE() function. (Bug #1868) sql/mysql_priv.h: Make check_dup() external sql/opt_range.cc: Fixed searching of TEXT with end space. (Bug #1651) sql/records.cc: Fixed caching bug in multi-table-update where same table was used twice. (Bug #1711) sql/sql_acl.cc: Reset ip and ip_mask if hostname is NULL sql/sql_parse.cc: Make check_dup() global sql/sql_select.cc: Fixed searching of TEXT with end space. (Bug #1651) sql/sql_table.cc: Fixed searching of TEXT with end space. (Bug #1651) sql/sql_update.cc: Fixed caching bug in multi-table-update where same table was used twice. (Bug #1711) sql/table.cc: Fixed searching of TEXT with end space. (Bug #1651) sql/table.h: Fixed caching bug in multi-table-update where same table was used twice. (Bug #1711) sql/time.cc: Fixed problem with UNIX_TIMESTAMP() for timestamps close to 0. (Bug #1998) --- mysys/my_symlink2.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'mysys') diff --git a/mysys/my_symlink2.c b/mysys/my_symlink2.c index 68b034bec5c..913f632fbb4 100644 --- a/mysys/my_symlink2.c +++ b/mysys/my_symlink2.c @@ -31,9 +31,19 @@ File my_create_with_symlink(const char *linkname, const char *filename, File file; int tmp_errno; /* Test if we should create a link */ - int create_link=(linkname && strcmp(linkname,filename)); + int create_link; DBUG_ENTER("my_create_with_symlink"); + if (my_disable_symlinks) + { + /* Create only the file, not the link and file */ + create_link= 0; + if (linkname) + filename= linkname; + } + else + create_link= (linkname && strcmp(linkname,filename)); + if (!(MyFlags & MY_DELETE_OLD)) { if (!access(filename,F_OK)) -- cgit v1.2.1 From 7dacf46619e3d384bac7a3c49cbe5478457b3bd1 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 16 Dec 2003 13:20:17 +0200 Subject: Portability fixes (mostly test suite) Make ENGINE= an alias for TYPE= (Compabiltiy with 4.1) Fix when using symlinked data files and realpath() is not working client/mysqltest.c: Copied mysqltest from 4.1 and modified this to compile in 4.0 This was needed to get replace_columns to work. include/my_sys.h: Stop compiler warnings about alloca on freebsd myisam/mi_check.c: Fix when using symlinked data files and realpath() is not working mysql-test/r/handler.result: test engine= mysql-test/r/rpl_max_relay_size.result: Use replace_columns to replace some 'not constant' columns mysql-test/r/rpl_rotate_logs.result: Use replace_columns to replace some 'not constant' columns mysql-test/r/rpl_trunc_binlog.result: Use replace_columns to replace some 'not constant' columns mysql-test/t/handler.test: test engine= mysql-test/t/rpl_log_pos.test: Use replace_columns to replace some 'not constant' columns mysql-test/t/rpl_max_relay_size.test: Use replace_columns to replace some 'not constant' columns mysql-test/t/rpl_rotate_logs.test: Use replace_columns to replace some 'not constant' columns mysql-test/t/rpl_trunc_binlog.test: Use replace_columns to replace some 'not constant' columns mysys/my_symlink.c: More debugging sql/lex.h: Make ENGINE= an alias for TYPE= sql/mysqld.cc: Code cleanup strings/strto.c: Fix for True64 strings/strtoll.c: Fix for True64 strings/strtoull.c: Remove not needed include file --- mysys/my_symlink.c | 1 + 1 file changed, 1 insertion(+) (limited to 'mysys') diff --git a/mysys/my_symlink.c b/mysys/my_symlink.c index abef0096e28..b366678769e 100644 --- a/mysys/my_symlink.c +++ b/mysys/my_symlink.c @@ -72,6 +72,7 @@ int my_symlink(const char *content, const char *linkname, myf MyFlags) #else int result; DBUG_ENTER("my_symlink"); + DBUG_PRINT("enter",("content: %s linkname: %s", content, linkname)); result= 0; if (symlink(content, linkname)) -- cgit v1.2.1