16
16
/* open a isam-database */
18
#include "myisamdef.h"
19
#include <mystrings/m_ctype.h>
18
#include "myisam_priv.h"
23
#include "drizzled/charset_info.h"
24
#include "drizzled/internal/m_string.h"
25
#include "drizzled/util/test.h"
26
#include "drizzled/global_charset_info.h"
27
#include "drizzled/charset.h"
28
#include "drizzled/memory/multi_malloc.h"
32
using namespace drizzled;
21
34
static void setup_key_functions(MI_KEYDEF *keyinfo);
22
#define get_next_element(to,pos,size) \
24
memcpy(to, pos, size); \
35
static unsigned char *mi_keydef_read(unsigned char *ptr, MI_KEYDEF *keydef);
36
static unsigned char *mi_keyseg_read(unsigned char *ptr, HA_KEYSEG *keyseg);
37
static unsigned char *mi_recinfo_read(unsigned char *ptr, MI_COLUMNDEF *recinfo);
38
static uint64_t mi_safe_mul(uint64_t a, uint64_t b);
39
static unsigned char *mi_state_info_read(unsigned char *ptr, MI_STATE_INFO *state);
40
static unsigned char *mi_uniquedef_read(unsigned char *ptr, MI_UNIQUEDEF *def);
41
static unsigned char *my_n_base_info_read(unsigned char *ptr, MI_BASE_INFO *base);
29
43
#define disk_pos_assert(pos, end_pos) \
30
44
if (pos > end_pos) \
32
my_errno=HA_ERR_CRASHED; \
46
errno=HA_ERR_CRASHED; \
62
76
have an open count of 0.
63
77
******************************************************************************/
65
MI_INFO *mi_open(const char *name, int mode, uint open_flags)
79
MI_INFO *mi_open(const char *name, int mode, uint32_t open_flags)
67
81
int lock_error,kfile,open_mode,save_errno,have_rtree=0;
68
uint i,j,len,errpos,head_length,base_pos,offset,info_length,keys,
82
uint32_t i,j,len,errpos,head_length,base_pos,offset,info_length,keys,
69
83
key_parts,unique_key_parts,fulltext_keys,uniques;
70
84
char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN],
72
uchar *disk_cache, *disk_pos, *end_pos;
85
data_name[FN_REFLEN], rp_buff[PATH_MAX];
86
unsigned char *disk_cache= NULL;
87
unsigned char *disk_pos, *end_pos;
73
88
MI_INFO info,*m_info,*old_info;
74
89
MYISAM_SHARE share_buff,*share;
75
90
ulong rec_per_key_part[HA_MAX_POSSIBLE_KEY*MI_MAX_KEY_SEG];
76
my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
91
internal::my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
77
92
uint64_t max_key_file_length, max_data_file_length;
82
97
head_length=sizeof(share_buff.state.header);
83
98
memset(&info, 0, sizeof(info));
85
my_realpath(name_buff, fn_format(org_name,name,"",MI_NAME_IEXT,
86
MY_UNPACK_FILENAME),MYF(0));
100
(void)internal::fn_format(org_name,name,"",MI_NAME_IEXT, MY_UNPACK_FILENAME);
101
if (!realpath(org_name,rp_buff))
102
internal::my_load_path(rp_buff,org_name, NULL);
103
rp_buff[FN_REFLEN-1]= '\0';
104
strcpy(name_buff,rp_buff);
87
105
pthread_mutex_lock(&THR_LOCK_myisam);
88
106
if (!(old_info=test_if_reopen(name_buff)))
92
110
share_buff.state.rec_per_key_part=rec_per_key_part;
93
111
share_buff.state.key_root=key_root;
94
112
share_buff.state.key_del=key_del;
95
share_buff.key_cache= multi_key_cache_search((uchar*) name_buff,
113
share_buff.key_cache= dflt_key_cache;
98
if ((kfile=my_open(name_buff,(open_mode=O_RDWR) | O_SHARE,MYF(0))) < 0)
115
if ((kfile=internal::my_open(name_buff,(open_mode=O_RDWR),MYF(0))) < 0)
100
117
if ((errno != EROFS && errno != EACCES) ||
101
118
mode != O_RDONLY ||
102
(kfile=my_open(name_buff,(open_mode=O_RDONLY) | O_SHARE,MYF(0))) < 0)
119
(kfile=internal::my_open(name_buff,(open_mode=O_RDONLY),MYF(0))) < 0)
105
122
share->mode=open_mode;
107
if (my_read(kfile, share->state.header.file_version, head_length,
124
if (internal::my_read(kfile, share->state.header.file_version, head_length,
110
my_errno= HA_ERR_NOT_A_TABLE;
127
errno= HA_ERR_NOT_A_TABLE;
113
130
if (memcmp(share->state.header.file_version, myisam_file_magic, 4))
115
my_errno=HA_ERR_NOT_A_TABLE;
132
errno=HA_ERR_NOT_A_TABLE;
118
135
share->options= mi_uint2korr(share->state.header.options);
119
136
if (share->options &
120
137
~(HA_OPTION_PACK_RECORD | HA_OPTION_PACK_KEYS |
121
138
HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA |
122
HA_OPTION_TEMP_COMPRESS_RECORD | HA_OPTION_CHECKSUM |
123
HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE |
124
HA_OPTION_RELIES_ON_SQL_LAYER))
126
my_errno=HA_ERR_OLD_FILE;
129
if ((share->options & HA_OPTION_RELIES_ON_SQL_LAYER) &&
130
! (open_flags & HA_OPEN_FROM_SQL_LAYER))
132
my_errno= HA_ERR_UNSUPPORTED;
139
HA_OPTION_TEMP_COMPRESS_RECORD |
143
errno=HA_ERR_OLD_FILE;
135
147
/* Don't call realpath() if the name can't be a link */
136
if (!strcmp(name_buff, org_name) ||
137
my_readlink(index_name, org_name, MYF(0)) == -1)
138
(void) stpcpy(index_name, org_name);
148
ssize_t sym_link_size= readlink(org_name,index_name,FN_REFLEN-1);
149
if (sym_link_size >= 0 )
150
index_name[sym_link_size]= '\0';
151
if (!strcmp(name_buff, org_name) || sym_link_size == -1)
152
(void) strcpy(index_name, org_name);
139
153
*strrchr(org_name, '.')= '\0';
140
(void) fn_format(data_name,org_name,"",MI_NAME_DEXT,
154
(void) internal::fn_format(data_name,org_name,"",MI_NAME_DEXT,
141
155
MY_APPEND_EXT|MY_UNPACK_FILENAME|MY_RESOLVE_SYMLINKS);
143
157
info_length=mi_uint2korr(share->state.header.header_length);
144
158
base_pos=mi_uint2korr(share->state.header.base_pos);
145
if (!(disk_cache= (uchar*) my_alloca(info_length+128)))
159
if (!(disk_cache= (unsigned char*) malloc(info_length+128)))
150
164
end_pos=disk_cache+info_length;
153
VOID(my_seek(kfile,0L,MY_SEEK_SET,MYF(0)));
167
lseek(kfile,0,SEEK_SET);
155
if (my_read(kfile,disk_cache,info_length,MYF(MY_NABP)))
169
if (internal::my_read(kfile,disk_cache,info_length,MYF(MY_NABP)))
157
my_errno=HA_ERR_CRASHED;
171
errno=HA_ERR_CRASHED;
160
174
len=mi_uint2korr(share->state.header.state_info_length);
204
215
mi_safe_mul(MI_MIN_KEY_BLOCK_LENGTH,
205
216
((uint64_t) 1 << (share->base.key_reflength*8))-1);
206
217
#if SIZEOF_OFF_T == 4
207
set_if_smaller(max_data_file_length, INT_MAX32);
208
set_if_smaller(max_key_file_length, INT_MAX32);
218
set_if_smaller(max_data_file_length, INT32_MAX);
219
set_if_smaller(max_key_file_length, INT32_MAX);
210
221
if (share->base.raid_type)
212
my_errno=HA_ERR_UNSUPPORTED;
223
errno=HA_ERR_UNSUPPORTED;
215
share->base.max_data_file_length=(my_off_t) max_data_file_length;
216
share->base.max_key_file_length=(my_off_t) max_key_file_length;
226
share->base.max_data_file_length=(internal::my_off_t) max_data_file_length;
227
share->base.max_key_file_length=(internal::my_off_t) max_key_file_length;
218
229
if (share->options & HA_OPTION_COMPRESS_RECORD)
219
230
share->base.max_key_length+=2; /* For safety */
221
232
/* Add space for node pointer */
222
233
share->base.max_key_length+= share->base.key_reflength;
224
if (!my_multi_malloc(MY_WME,
225
&share,sizeof(*share),
226
&share->state.rec_per_key_part,sizeof(long)*key_parts,
227
&share->keyinfo,keys*sizeof(MI_KEYDEF),
228
&share->uniqueinfo,uniques*sizeof(MI_UNIQUEDEF),
230
(key_parts+unique_key_parts+keys+uniques) *
233
(share->base.fields+1)*sizeof(MI_COLUMNDEF),
234
&share->blobs,sizeof(MI_BLOB)*share->base.blobs,
235
&share->unique_file_name,strlen(name_buff)+1,
236
&share->index_file_name,strlen(index_name)+1,
237
&share->data_file_name,strlen(data_name)+1,
238
&share->state.key_root,keys*sizeof(my_off_t),
239
&share->state.key_del,
240
(share->state.header.max_block_size_index*sizeof(my_off_t)),
241
&share->key_root_lock,sizeof(rw_lock_t)*keys,
242
&share->mmap_lock,sizeof(rw_lock_t),
235
if (!drizzled::memory::multi_malloc(false,
236
&share,sizeof(*share),
237
&share->state.rec_per_key_part,sizeof(long)*key_parts,
238
&share->keyinfo,keys*sizeof(MI_KEYDEF),
239
&share->uniqueinfo,uniques*sizeof(MI_UNIQUEDEF),
241
(key_parts+unique_key_parts+keys+uniques) * sizeof(HA_KEYSEG),
242
&share->rec, (share->base.fields+1)*sizeof(MI_COLUMNDEF),
243
&share->blobs,sizeof(MI_BLOB)*share->base.blobs,
244
&share->unique_file_name,strlen(name_buff)+1,
245
&share->index_file_name,strlen(index_name)+1,
246
&share->data_file_name,strlen(data_name)+1,
247
&share->state.key_root,keys*sizeof(uint64_t),
248
&share->state.key_del,
249
(share->state.header.max_block_size_index*sizeof(uint64_t)),
250
&share->key_root_lock,sizeof(pthread_rwlock_t)*keys,
251
&share->mmap_lock,sizeof(pthread_rwlock_t),
246
255
*share=share_buff;
247
256
memcpy(share->state.rec_per_key_part, rec_per_key_part,
248
257
sizeof(long)*key_parts);
249
258
memcpy(share->state.key_root, key_root,
250
sizeof(my_off_t)*keys);
259
sizeof(internal::my_off_t)*keys);
251
260
memcpy(share->state.key_del, key_del,
252
sizeof(my_off_t) * share->state.header.max_block_size_index);
253
stpcpy(share->unique_file_name, name_buff);
261
sizeof(internal::my_off_t) * share->state.header.max_block_size_index);
262
strcpy(share->unique_file_name, name_buff);
254
263
share->unique_name_length= strlen(name_buff);
255
stpcpy(share->index_file_name, index_name);
256
stpcpy(share->data_file_name, data_name);
264
strcpy(share->index_file_name, index_name);
265
strcpy(share->data_file_name, data_name);
258
share->blocksize=min(IO_SIZE,myisam_block_size);
267
share->blocksize=min((uint32_t)IO_SIZE,myisam_block_size);
260
269
HA_KEYSEG *pos=share->keyparts;
261
270
for (i=0 ; i < keys ; i++)
374
381
share->base.margin_key_file_length=(share->base.max_key_file_length -
375
382
(keys ? MI_INDEX_BLOCK_MARGIN *
376
383
share->blocksize * keys : 0));
377
share->blocksize=min(IO_SIZE,myisam_block_size);
384
share->blocksize=min((uint32_t)IO_SIZE,myisam_block_size);
378
385
share->data_file_type=STATIC_RECORD;
379
386
if (share->options & HA_OPTION_PACK_RECORD)
380
387
share->data_file_type = DYNAMIC_RECORD;
381
my_afree(disk_cache);
382
390
mi_setup_functions(share);
383
391
share->is_log_table= false;
384
392
thr_lock_init(&share->lock);
385
VOID(pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST));
393
pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST);
386
394
for (i=0; i<keys; i++)
387
VOID(my_rwlock_init(&share->key_root_lock[i], NULL));
388
VOID(my_rwlock_init(&share->mmap_lock, NULL));
395
pthread_rwlock_init(&share->key_root_lock[i], NULL);
396
pthread_rwlock_init(&share->mmap_lock, NULL);
389
397
if (!thr_lock_inited)
391
399
/* Probably a single threaded program; Don't use concurrent inserts */
433
433
/* alloc and set up private structure parts */
434
if (!my_multi_malloc(MY_WME,
435
&m_info,sizeof(MI_INFO),
436
&info.blobs,sizeof(MI_BLOB)*share->base.blobs,
437
&info.buff,(share->base.max_key_block_length*2+
438
share->base.max_key_length),
439
&info.lastkey,share->base.max_key_length*3+1,
440
&info.first_mbr_key, share->base.max_key_length,
441
&info.filename,strlen(name)+1,
442
&info.rtree_recursion_state,have_rtree ? 1024 : 0,
434
if (!drizzled::memory::multi_malloc(MY_WME,
435
&m_info,sizeof(MI_INFO),
436
&info.blobs,sizeof(MI_BLOB)*share->base.blobs,
437
&info.buff,(share->base.max_key_block_length*2+
438
share->base.max_key_length),
439
&info.lastkey,share->base.max_key_length*3+1,
440
&info.first_mbr_key, share->base.max_key_length,
441
&info.filename,strlen(name)+1,
442
&info.rtree_recursion_state,have_rtree ? 1024 : 0,
448
448
info.rtree_recursion_state= NULL;
450
stpcpy(info.filename,name);
450
strcpy(info.filename,name);
451
451
memcpy(info.blobs,share->blobs,sizeof(MI_BLOB)*share->base.blobs);
452
452
info.lastkey2=info.lastkey+share->base.max_key_length;
484
484
share->temporary=share->delay_key_write=1;
485
485
share->write_flag=MYF(MY_NABP);
486
share->w_locks++; /* We don't have to update status */
487
* The following two statements are commented out as a fix of
488
* bug https://bugs.launchpad.net/drizzle/+bug/387627
490
* UPDATE can be TRUNCATE on TEMPORARY TABLE (MyISAM).
491
* The root cause of why this makes a difference hasn't
492
* been found, but this fixes things for now.
494
// share->w_locks++; // We don't have to update status
495
// share->tot_locks++;
488
496
info.lock_type=F_WRLCK;
490
if (((open_flags & HA_OPEN_DELAY_KEY_WRITE) ||
491
(share->options & HA_OPTION_DELAY_KEY_WRITE)) &&
492
myisam_delay_key_write)
493
share->delay_key_write=1;
499
share->delay_key_write= 1;
494
500
info.state= &share->state.state; /* Change global values by default */
495
501
pthread_mutex_unlock(&share->intern_lock);
505
511
thr_lock_data_init(&share->lock,&m_info->lock,(void*) m_info);
506
m_info->open_list.data=(void*) m_info;
507
myisam_open_list=list_add(myisam_open_list,&m_info->open_list);
512
myisam_open_list.push_front(m_info);
509
514
pthread_mutex_unlock(&THR_LOCK_myisam);
513
save_errno=my_errno ? my_errno : HA_ERR_END_OF_FILE;
518
if (disk_cache != NULL)
520
save_errno=errno ? errno : HA_ERR_END_OF_FILE;
514
521
if ((save_errno == HA_ERR_CRASHED) ||
515
522
(save_errno == HA_ERR_CRASHED_ON_USAGE) ||
516
523
(save_errno == HA_ERR_CRASHED_ON_REPAIR))
517
524
mi_report_error(save_errno, name);
518
525
switch (errpos) {
520
my_free((uchar*) m_info,MYF(0));
527
free((unsigned char*) m_info);
521
528
/* fall through */
523
VOID(my_close(info.dfile,MYF(0)));
530
internal::my_close(info.dfile,MYF(0));
525
532
break; /* Don't remove open table */
526
533
/* fall through */
528
my_free((uchar*) share,MYF(0));
535
free((unsigned char*) share);
529
536
/* fall through */
531
538
/* fall through */
533
my_afree(disk_cache);
536
VOID(my_close(kfile,MYF(0)));
540
internal::my_close(kfile,MYF(0));
537
541
/* fall through */
542
546
pthread_mutex_unlock(&THR_LOCK_myisam);
548
uchar *mi_alloc_rec_buff(MI_INFO *info, ulong length, uchar **buf)
552
unsigned char *mi_alloc_rec_buff(MI_INFO *info, size_t length, unsigned char **buf)
551
555
uint32_t old_length= 0;
553
557
if (! *buf || length > (old_length=mi_get_rec_buff_len(info, *buf)))
555
uchar *newptr = *buf;
559
unsigned char *newptr = *buf;
557
561
/* to simplify initial init of info->rec_buf in mi_open and mi_extra */
558
562
if (length == (ulong) -1)
752
755
return(my_pwrite(file, buff, (size_t) (ptr-buff), 0L,
753
756
MYF(MY_NABP | MY_THREADSAFE)) != 0);
754
return(my_write(file, buff, (size_t) (ptr-buff),
757
return(internal::my_write(file, buff, (size_t) (ptr-buff),
755
758
MYF(MY_NABP)) != 0);
759
uchar *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state)
762
static unsigned char *mi_state_info_read(unsigned char *ptr, MI_STATE_INFO *state)
761
uint i,keys,key_parts,key_blocks;
764
uint32_t i,keys,key_parts,key_blocks;
762
765
memcpy(&state->header,ptr, sizeof(state->header));
763
766
ptr +=sizeof(state->header);
764
767
keys=(uint) state->header.keys;
812
uint mi_state_info_read_dsk(File file, MI_STATE_INFO *state, bool pRead)
815
uint32_t mi_state_info_read_dsk(int file, MI_STATE_INFO *state, bool pRead)
814
uchar buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
817
unsigned char buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
816
if (!myisam_single_user)
820
if (my_pread(file, buff, state->state_length,0L, MYF(MY_NABP)))
823
else if (my_read(file, buff, state->state_length,MYF(MY_NABP)))
821
if (my_pread(file, buff, state->state_length,0L, MYF(MY_NABP)))
825
mi_state_info_read(buff, state);
824
else if (internal::my_read(file, buff, state->state_length,MYF(MY_NABP)))
826
mi_state_info_read(buff, state);
859
860
mi_int2store(ptr,base->max_key_length); ptr +=2;
860
861
mi_int2store(ptr,base->extra_alloc_bytes); ptr +=2;
861
862
*ptr++= base->extra_alloc_procent;
862
*ptr++= base->raid_type;
863
mi_int2store(ptr,base->raid_chunks); ptr +=2;
864
mi_int4store(ptr,base->raid_chunksize); ptr +=4;
863
/* old raid info slots */
865
mi_int2store(ptr,UINT16_C(0)); ptr +=2;
866
mi_int4store(ptr,UINT32_C(0)); ptr +=4;
865
868
memset(ptr, 0, 6); ptr +=6; /* extra */
866
return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
869
return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
870
uchar *my_n_base_info_read(uchar *ptr, MI_BASE_INFO *base)
873
static unsigned char *my_n_base_info_read(unsigned char *ptr, MI_BASE_INFO *base)
872
875
base->keystart = mi_sizekorr(ptr); ptr +=8;
873
876
base->max_data_file_length = mi_sizekorr(ptr); ptr +=8;
912
909
---------------------------------------------------------------------------*/
914
uint mi_keydef_write(File file, MI_KEYDEF *keydef)
911
uint32_t mi_keydef_write(int file, MI_KEYDEF *keydef)
916
uchar buff[MI_KEYDEF_SIZE];
913
unsigned char buff[MI_KEYDEF_SIZE];
914
unsigned char *ptr=buff;
919
*ptr++ = (uchar) keydef->keysegs;
916
*ptr++ = (unsigned char) keydef->keysegs;
920
917
*ptr++ = keydef->key_alg; /* Rtree or Btree */
921
918
mi_int2store(ptr,keydef->flag); ptr +=2;
922
919
mi_int2store(ptr,keydef->block_length); ptr +=2;
923
920
mi_int2store(ptr,keydef->keylength); ptr +=2;
924
921
mi_int2store(ptr,keydef->minlength); ptr +=2;
925
922
mi_int2store(ptr,keydef->maxlength); ptr +=2;
926
return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
923
return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
929
uchar *mi_keydef_read(uchar *ptr, MI_KEYDEF *keydef)
926
static unsigned char *mi_keydef_read(unsigned char *ptr, MI_KEYDEF *keydef)
931
928
keydef->keysegs = (uint) *ptr++;
932
929
keydef->key_alg = *ptr++; /* Rtree or Btree */
997
994
---------------------------------------------------------------------------*/
999
uint mi_uniquedef_write(File file, MI_UNIQUEDEF *def)
996
uint32_t mi_uniquedef_write(int file, MI_UNIQUEDEF *def)
1001
uchar buff[MI_UNIQUEDEF_SIZE];
998
unsigned char buff[MI_UNIQUEDEF_SIZE];
999
unsigned char *ptr=buff;
1004
1001
mi_int2store(ptr,def->keysegs); ptr+=2;
1005
*ptr++= (uchar) def->key;
1006
*ptr++ = (uchar) def->null_are_equal;
1002
*ptr++= (unsigned char) def->key;
1003
*ptr++ = (unsigned char) def->null_are_equal;
1008
return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1005
return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1011
uchar *mi_uniquedef_read(uchar *ptr, MI_UNIQUEDEF *def)
1008
static unsigned char *mi_uniquedef_read(unsigned char *ptr, MI_UNIQUEDEF *def)
1013
1010
def->keysegs = mi_uint2korr(ptr);
1014
1011
def->key = ptr[2];
1020
1017
** MI_COLUMNDEF
1021
1018
***************************************************************************/
1023
uint mi_recinfo_write(File file, MI_COLUMNDEF *recinfo)
1020
uint32_t mi_recinfo_write(int file, MI_COLUMNDEF *recinfo)
1025
uchar buff[MI_COLUMNDEF_SIZE];
1022
unsigned char buff[MI_COLUMNDEF_SIZE];
1023
unsigned char *ptr=buff;
1028
1025
mi_int2store(ptr,recinfo->type); ptr +=2;
1029
1026
mi_int2store(ptr,recinfo->length); ptr +=2;
1030
1027
*ptr++ = recinfo->null_bit;
1031
1028
mi_int2store(ptr,recinfo->null_pos); ptr+= 2;
1032
return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1029
return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1035
uchar *mi_recinfo_read(uchar *ptr, MI_COLUMNDEF *recinfo)
1032
static unsigned char *mi_recinfo_read(unsigned char *ptr, MI_COLUMNDEF *recinfo)
1037
1034
recinfo->type= mi_sint2korr(ptr); ptr +=2;
1038
1035
recinfo->length=mi_uint2korr(ptr); ptr +=2;
1050
1047
exist a dup()-like call that would give us two different file descriptors.
1051
1048
*************************************************************************/
1053
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share,
1054
File file_to_dup __attribute__((unused)))
1050
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, int file_to_dup)
1056
info->dfile=my_open(share->data_file_name, share->mode | O_SHARE,
1053
info->dfile=internal::my_open(share->data_file_name, share->mode,
1058
1055
return info->dfile >= 0 ? 0 : 1;
1062
1059
int mi_open_keyfile(MYISAM_SHARE *share)
1064
if ((share->kfile=my_open(share->unique_file_name, share->mode | O_SHARE,
1061
if ((share->kfile=internal::my_open(share->unique_file_name, share->mode,
1065
1062
MYF(MY_WME))) < 0)