home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 January / Chip_2001-01_cd1.bin / tema / mysql / mysql-3.23.28g-win-source.exe / myisam / mi_open.c < prev    next >
C/C++ Source or Header  |  2000-11-21  |  33KB  |  1,016 lines

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2.    
  3.    This program is free software; you can redistribute it and/or modify
  4.    it under the terms of the GNU General Public License as published by
  5.    the Free Software Foundation; either version 2 of the License, or
  6.    (at your option) any later version.
  7.    
  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.
  12.    
  13.    You should have received a copy of the GNU General Public License
  14.    along with this program; if not, write to the Free Software
  15.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  16.  
  17. /* open a isam-database */
  18.  
  19. #include "fulltext.h"
  20. #include <m_ctype.h>
  21.  
  22. #if defined(MSDOS) || defined(__WIN__)
  23. #ifdef __WIN__
  24. #include <fcntl.h>
  25. #else
  26. #include <process.h>            /* Prototype for getpid */
  27. #endif
  28. #endif
  29. #ifdef VMS
  30. #include "static.c"
  31. #endif
  32.  
  33. static void setup_functions(MYISAM_SHARE *info);
  34. static void setup_key_functions(MI_KEYDEF *keyinfo);
  35. #define get_next_element(to,pos,size) { memcpy((char*) to,pos,(size_t) size); \
  36.                     pos+=size;}
  37.  
  38.  
  39. /******************************************************************************
  40. ** Return the shared struct if the table is already open.
  41. ** In MySQL the server will handle version issues.
  42. ******************************************************************************/
  43.  
  44. static MI_INFO *test_if_reopen(char *filename)
  45. {
  46.   LIST *pos;
  47.  
  48.   for (pos=myisam_open_list ; pos ; pos=pos->next)
  49.   {
  50.     MI_INFO *info=(MI_INFO*) pos->data;
  51.     MYISAM_SHARE *share=info->s;
  52.     if (!strcmp(share->filename,filename) && share->last_version)
  53.       return info;
  54.   }
  55.   return 0;
  56. }
  57.  
  58.  
  59. /******************************************************************************
  60.   open a MyISAM database.
  61.   See my_base.h for the handle_locking argument
  62.   if handle_locking and HA_OPEN_ABORT_IF_CRASHED then abort if the table
  63.   is marked crashed or if we are not using locking and the table doesn't
  64.   have an open count of 0.
  65. ******************************************************************************/
  66.  
  67. MI_INFO *mi_open(const char *name, int mode, uint open_flags)
  68. {
  69.   int lock_error,kfile,open_mode,save_errno;
  70.   uint i,j,len,errpos,head_length,base_pos,offset,info_length,extra,keys,
  71.     key_parts,unique_key_parts,tmp_length,uniques;
  72.   char name_buff[FN_REFLEN],*disk_cache,*disk_pos;
  73.   MI_INFO info,*m_info,*old_info;
  74.   MYISAM_SHARE share_buff,*share;
  75.   ulong rec_per_key_part[MI_MAX_POSSIBLE_KEY*MI_MAX_KEY_SEG];
  76.   my_off_t key_root[MI_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
  77.   ulonglong max_key_file_length, max_data_file_length;
  78.   DBUG_ENTER("mi_open");
  79.  
  80.   LINT_INIT(m_info);
  81.   kfile= -1;
  82.   lock_error=1;
  83.   errpos=0;
  84.   head_length=sizeof(share_buff.state.header);
  85.   bzero((byte*) &info,sizeof(info));
  86.  
  87.   VOID(fn_format(name_buff,name,"",MI_NAME_IEXT,4+16+32));
  88.   pthread_mutex_lock(&THR_LOCK_myisam);
  89.   if (!(old_info=test_if_reopen(name_buff)))
  90.   {
  91.     share= &share_buff;
  92.     bzero((gptr) &share_buff,sizeof(share_buff));
  93.     share_buff.state.rec_per_key_part=rec_per_key_part;
  94.     share_buff.state.key_root=key_root;
  95.     share_buff.state.key_del=key_del;
  96.  
  97.     if ((kfile=my_open(name_buff,(open_mode=O_RDWR) | O_SHARE,MYF(0))) < 0)
  98.     {
  99.       if ((errno != EROFS && errno != EACCES) ||
  100.       mode != O_RDONLY ||
  101.       (kfile=my_open(name_buff,(open_mode=O_RDONLY) | O_SHARE,MYF(0))) < 0)
  102.     goto err;
  103.     }
  104.     share->mode=open_mode;
  105.     errpos=1;
  106.     if (my_read(kfile,(char*) share->state.header.file_version,head_length,
  107.         MYF(MY_NABP)))
  108.       goto err;
  109.  
  110.     if (memcmp((byte*) share->state.header.file_version,
  111.            (byte*) myisam_file_magic, 4))
  112.     {
  113.       DBUG_PRINT("error",("Wrong header in %s",name_buff));
  114.       DBUG_DUMP("error_dump",(char*) share->state.header.file_version,
  115.         head_length);
  116.       my_errno=HA_ERR_CRASHED;
  117.       goto err;
  118.     }
  119.     share->options= mi_uint2korr(share->state.header.options);
  120.     if (share->options &
  121.     ~(HA_OPTION_PACK_RECORD | HA_OPTION_PACK_KEYS |
  122.       HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA |
  123.       HA_OPTION_TEMP_COMPRESS_RECORD | HA_OPTION_CHECKSUM |
  124.       HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE))
  125.     {
  126.       DBUG_PRINT("error",("wrong options: 0x%lx",
  127.               share->options));
  128.       my_errno=HA_ERR_OLD_FILE;
  129.       goto err;
  130.     }
  131.     info_length=mi_uint2korr(share->state.header.header_length);
  132.     base_pos=mi_uint2korr(share->state.header.base_pos);
  133.     if (!(disk_cache=(char*) my_alloca(info_length)))
  134.     {
  135.       my_errno=ENOMEM;
  136.       goto err;
  137.     }
  138.     errpos=2;
  139.  
  140.     VOID(my_seek(kfile,0L,MY_SEEK_SET,MYF(0)));
  141.     if (!(open_flags & HA_OPEN_TMP_TABLE))
  142.     {
  143.       if ((lock_error=my_lock(kfile,F_RDLCK,0L,F_TO_EOF,
  144.                   MYF(open_flags & HA_OPEN_WAIT_IF_LOCKED ?
  145.                   0 : MY_DONT_WAIT))) &&
  146.       !(open_flags & HA_OPEN_IGNORE_IF_LOCKED))
  147.     goto err;
  148.     }
  149.     errpos=3;
  150.     if (my_read(kfile,disk_cache,info_length,MYF(MY_NABP)))
  151.       goto err;
  152.     len=mi_uint2korr(share->state.header.state_info_length);
  153.     keys=    (uint) share->state.header.keys;
  154.     uniques= (uint) share->state.header.uniques;
  155.     key_parts= mi_uint2korr(share->state.header.key_parts);
  156.     unique_key_parts= mi_uint2korr(share->state.header.unique_key_parts);
  157.     tmp_length=(MI_STATE_INFO_SIZE + keys * MI_STATE_KEY_SIZE +
  158.         key_parts*MI_STATE_KEYSEG_SIZE +
  159.         share->state.header.max_block_size*MI_STATE_KEYBLOCK_SIZE);
  160.     if (len != MI_STATE_INFO_SIZE)
  161.     {
  162.       DBUG_PRINT("warning",
  163.          ("saved_state_info_length: %d  state_info_length: %d",
  164.           len,MI_STATE_INFO_SIZE));
  165.     }
  166.     share->state_diff_length=len-MI_STATE_INFO_SIZE;
  167.  
  168.     mi_state_info_read(disk_cache, &share->state);
  169.     len= mi_uint2korr(share->state.header.base_info_length);
  170.     if (len != MI_BASE_INFO_SIZE)
  171.     {
  172.       DBUG_PRINT("warning",("saved_base_info_length: %d  base_info_length: %d",
  173.                 len,MI_BASE_INFO_SIZE))
  174.     }
  175.     disk_pos=my_n_base_info_read(disk_cache+base_pos, &share->base);
  176.     share->state.state_length=base_pos;
  177.  
  178.     if (!(open_flags & HA_OPEN_FOR_REPAIR) &&
  179.     ((share->state.changed & STATE_CRASHED) ||
  180.      ((open_flags & HA_OPEN_ABORT_IF_CRASHED) &&
  181.       (my_disable_locking && share->state.open_count))))
  182.     {
  183.       DBUG_PRINT("error",("Table is marked as crashed"));
  184.       my_errno=((share->state.changed & STATE_CRASHED_ON_REPAIR) ?
  185.         HA_ERR_CRASHED_ON_REPAIR : HA_ERR_CRASHED_ON_USAGE);
  186.       goto err;
  187.     }
  188.     /* Correct max_file_length based on length of sizeof_t */
  189.     max_data_file_length=
  190.       (share->options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ?
  191.       (((ulonglong) 1 << (share->base.rec_reflength*8))-1) :
  192.       (mi_safe_mul(share->base.reclength,
  193.            (ulonglong) 1 << (share->base.rec_reflength*8))-1);
  194.     max_key_file_length=
  195.       mi_safe_mul(MI_KEY_BLOCK_LENGTH,
  196.           ((ulonglong) 1 << (share->base.key_reflength*8))-1);
  197. #if SIZEOF_OFF_T == 4
  198.     set_if_smaller(max_data_file_length, INT_MAX32);
  199.     set_if_smaller(max_key_file_length, INT_MAX32);
  200. #endif
  201. #if USE_RAID && SYSTEM_SIZEOF_OFF_T == 4
  202.     set_if_smaller(max_key_file_length, INT_MAX32);
  203.     if (!share->base.raid_type)
  204.     {
  205.       set_if_smaller(max_data_file_length, INT_MAX32);
  206.     }
  207.     else
  208.     {
  209.       set_if_smaller(max_data_file_length,
  210.              (ulonglong) share->base.raid_chunks << 31);
  211.     }
  212. #elif !defined(USE_RAID)
  213.     if (share->base.raid_type)
  214.     {
  215.       DBUG_PRINT("error",("Table uses RAID but we don't have RAID support"));
  216.       my_errno=HA_ERR_UNSUPPORTED;
  217.       goto err;
  218.     }
  219. #endif
  220.     share->base.max_data_file_length=(my_off_t) max_data_file_length;
  221.     share->base.max_key_file_length=(my_off_t) max_key_file_length;
  222.  
  223.     if (share->base.max_key_length > MI_MAX_KEY_BUFF || keys > MI_MAX_KEY ||
  224.     key_parts >= MI_MAX_KEY * MI_MAX_KEY_SEG)
  225.     {
  226.       DBUG_PRINT("error",("Wrong key info:  Max_key_length: %d  keys: %d  key_parts: %d", share->base.max_key_length, keys, key_parts));
  227.       my_errno=HA_ERR_UNSUPPORTED;
  228.       goto err;
  229.     }
  230.     if (share->options & HA_OPTION_COMPRESS_RECORD)
  231.       share->base.max_key_length+=2;    /* For safety */
  232.  
  233.     if (!my_multi_malloc(MY_WME,
  234.              &share,sizeof(*share),
  235.              &share->state.rec_per_key_part,sizeof(long)*key_parts,
  236.              &share->keyinfo,keys*sizeof(MI_KEYDEF),
  237.              &share->uniqueinfo,uniques*sizeof(MI_UNIQUEDEF),
  238.              &share->keyparts,
  239.              (key_parts+unique_key_parts+keys+uniques) *
  240.              sizeof(MI_KEYSEG),
  241.              &share->rec,
  242.              (share->base.fields+1)*sizeof(MI_COLUMNDEF),
  243.              &share->blobs,sizeof(MI_BLOB)*share->base.blobs,
  244.              &share->filename,strlen(name_buff)+1,
  245.              &share->state.key_root,keys*sizeof(my_off_t),
  246.              &share->state.key_del,
  247.              (share->state.header.max_block_size*sizeof(my_off_t)),
  248. #ifdef THREAD
  249.              &share->key_root_lock,sizeof(rw_lock_t)*keys,
  250. #endif
  251.              NullS))
  252.       goto err;
  253.     errpos=4;
  254.     *share=share_buff;
  255.     memcpy((char*) share->state.rec_per_key_part,
  256.        (char*) rec_per_key_part, sizeof(long)*key_parts);
  257.     memcpy((char*) share->state.key_root,
  258.        (char*) key_root, sizeof(my_off_t)*keys);
  259.     memcpy((char*) share->state.key_del,
  260.        (char*) key_del, (sizeof(my_off_t) *
  261.                  share->state.header.max_block_size));
  262.     strmov(share->filename,name_buff);
  263.  
  264.     share->blocksize=min(IO_SIZE,myisam_block_size);
  265.     {
  266.       MI_KEYSEG *pos=share->keyparts;
  267.       for (i=0 ; i < keys ; i++)
  268.       {
  269.     disk_pos=mi_keydef_read(disk_pos, &share->keyinfo[i]);
  270.     set_if_smaller(share->blocksize,share->keyinfo[i].block_length);
  271.     share->keyinfo[i].seg=pos;
  272.     for (j=0 ; j < share->keyinfo[i].keysegs; j++,pos++)
  273.     {
  274.       disk_pos=mi_keyseg_read(disk_pos, pos);
  275.       if (pos->type == HA_KEYTYPE_TEXT || pos->type == HA_KEYTYPE_VARTEXT)
  276.       {
  277.         if (!pos->language)
  278.           pos->charset=default_charset_info;
  279.         else if (!(pos->charset= get_charset(pos->language, MYF(MY_WME))))
  280.         {
  281.           my_errno=HA_ERR_UNKNOWN_CHARSET;
  282.           goto err;
  283.         }
  284.       }
  285.     }
  286.     if (share->keyinfo[i].flag & HA_FULLTEXT)            /* SerG */
  287.     {
  288.       share->keyinfo[i].seg=pos-FT_SEGS;                /* SerG */
  289.       share->fulltext_index=1;
  290.     }
  291.     share->keyinfo[i].end=pos;
  292.     pos->type=HA_KEYTYPE_END;            /* End */
  293.     pos->length=share->base.rec_reflength;
  294.     pos->null_bit=0;
  295.     pos++;
  296.       }
  297.       for (i=0 ; i < uniques ; i++)
  298.       {
  299.     disk_pos=mi_uniquedef_read(disk_pos, &share->uniqueinfo[i]);
  300.     share->uniqueinfo[i].seg=pos;
  301.     for (j=0 ; j < share->uniqueinfo[i].keysegs; j++,pos++)
  302.     {
  303.       disk_pos=mi_keyseg_read(disk_pos, pos);
  304.       if (pos->type == HA_KEYTYPE_TEXT || pos->type == HA_KEYTYPE_VARTEXT)
  305.       {
  306.         if (!pos->language)
  307.           pos->charset=default_charset_info;
  308.         else if (!(pos->charset= get_charset(pos->language, MYF(MY_WME))))
  309.         {
  310.           my_errno=HA_ERR_UNKNOWN_CHARSET;
  311.           goto err;
  312.         }
  313.       }
  314.     }
  315.     share->uniqueinfo[i].end=pos;
  316.     pos->type=HA_KEYTYPE_END;            /* End */
  317.     pos->null_bit=0;
  318.     pos++;
  319.       }
  320.     }
  321.     for (i=0 ; i < keys ; i++)
  322.       setup_key_functions(share->keyinfo+i);
  323.  
  324.     for (i=j=offset=0 ; i < share->base.fields ; i++)
  325.     {
  326.       disk_pos=mi_recinfo_read(disk_pos,&share->rec[i]);
  327.       share->rec[i].pack_type=0;
  328.       share->rec[i].huff_tree=0;
  329.       share->rec[i].offset=offset;
  330.       if (share->rec[i].type == (int) FIELD_BLOB)
  331.       {
  332.     share->blobs[j].pack_length=
  333.       share->rec[i].length-mi_portable_sizeof_char_ptr;;
  334.     share->blobs[j].offset=offset;
  335.     j++;
  336.       }
  337.       offset+=share->rec[i].length;
  338.     }
  339.     share->rec[i].type=(int) FIELD_LAST;    /* End marker */
  340.  
  341.     if (! lock_error)
  342.     {
  343.       VOID(my_lock(kfile,F_UNLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE)));
  344.       lock_error=1;            /* Database unlocked */
  345.     }
  346.  
  347.     if (mi_open_datafile(&info, share))
  348.       goto err;
  349.     errpos=5;
  350.  
  351.     share->kfile=kfile;
  352.     share->this_process=(ulong) getpid();
  353.     share->rnd= (int)     share->this_process;    /* rnd-counter for splits */
  354. #ifndef DBUG_OFF
  355.     share->rnd=0;                /* To make things repeatable */
  356. #endif
  357.     share->last_process= share->state.process;
  358.     share->base.key_parts=key_parts;
  359.     share->base.all_key_parts=key_parts+unique_key_parts;
  360.     if (!(share->last_version=share->state.version))
  361.       share->last_version=1;            /* Safety */
  362.     share->rec_reflength=share->base.rec_reflength; /* May be changed */
  363.     share->base.margin_key_file_length=(share->base.max_key_file_length -
  364.                     (keys ? MI_INDEX_BLOCK_MARGIN *
  365.                      share->blocksize * keys : 0));
  366.     share->blocksize=min(IO_SIZE,myisam_block_size);
  367.  
  368.     share->data_file_type=STATIC_RECORD;
  369.     if (share->options & HA_OPTION_COMPRESS_RECORD)
  370.     {
  371.       share->data_file_type = COMPRESSED_RECORD;
  372.       share->options|= HA_OPTION_READ_ONLY_DATA;
  373.       info.s=share;
  374.       if (_mi_read_pack_info(&info,
  375.                  (pbool)
  376.                  test(!(share->options &
  377.                     (HA_OPTION_PACK_RECORD |
  378.                      HA_OPTION_TEMP_COMPRESS_RECORD)))))
  379.     goto err;
  380.     }
  381.     else if (share->options & HA_OPTION_PACK_RECORD)
  382.       share->data_file_type = DYNAMIC_RECORD;
  383.     my_afree((gptr) disk_cache);
  384.     setup_functions(share);
  385. #ifdef THREAD
  386.     thr_lock_init(&share->lock);
  387.     VOID(pthread_mutex_init(&share->intern_lock,NULL));
  388.     for (i=0; i<keys; i++)
  389.       VOID(my_rwlock_init(&share->key_root_lock[i], NULL));
  390.     if (!thr_lock_inited)
  391.     {
  392.       /* Probably a single threaded program; Don't use concurrent inserts */
  393.       myisam_concurrent_insert=0;
  394.     }
  395.     else if (myisam_concurrent_insert)
  396.     {
  397.       share->concurrent_insert=
  398.     ((share->options & (HA_OPTION_READ_ONLY_DATA | HA_OPTION_TMP_TABLE |
  399.                HA_OPTION_COMPRESS_RECORD |
  400.                HA_OPTION_TEMP_COMPRESS_RECORD)) ||
  401.      (open_flags & HA_OPEN_TMP_TABLE)) ? 0 : 1;
  402.       if (share->concurrent_insert)
  403.       {
  404.     share->lock.get_status=mi_get_status;
  405.     share->lock.copy_status=mi_copy_status;
  406.     share->lock.update_status=mi_update_status;
  407.     share->lock.check_status=mi_check_status;
  408.       }
  409.     }
  410. #endif
  411.   }
  412.   else
  413.   {
  414.     share= old_info->s;
  415.     if (mode == O_RDWR && share->mode == O_RDONLY)
  416.     {
  417.       my_errno=EACCES;                /* Can't open in write mode */
  418.       goto err;
  419.     }
  420.     if (mi_open_datafile(&info, share))
  421.       goto err;
  422.     errpos=5;
  423.   }
  424.  
  425.   /* alloc and set up private structure parts */
  426.   if (!my_multi_malloc(MY_WME,
  427.                &m_info,sizeof(MI_INFO),
  428.                &info.blobs,sizeof(MI_BLOB)*share->base.blobs,
  429.                &info.buff,(share->base.max_key_block_length*2+
  430.                    share->base.max_key_length),
  431.                &info.lastkey,share->base.max_key_length*3+1,
  432.                &info.filename,strlen(name)+1,
  433.                NullS))
  434.     goto err;
  435.   errpos=6;
  436.  
  437.   strmov(info.filename,name);
  438.   memcpy(info.blobs,share->blobs,sizeof(MI_BLOB)*share->base.blobs);
  439.   info.lastkey2=info.lastkey+share->base.max_key_length;
  440.  
  441.   info.s=share;
  442.   info.lastpos= HA_OFFSET_ERROR;
  443.   info.update= (short) (HA_STATE_NEXT_FOUND+HA_STATE_PREV_FOUND);
  444.   info.opt_flag=READ_CHECK_USED;
  445.   info.this_unique= (ulong) info.dfile; /* Uniq number in process */
  446.   if (share->data_file_type == COMPRESSED_RECORD)
  447.     info.this_unique= share->state.unique;
  448.   info.this_loop=0;                /* Update counter */
  449.   info.last_unique= share->state.unique;
  450.   info.last_loop=   share->state.update_count;
  451.   if (mode == O_RDONLY)
  452.     share->options|=HA_OPTION_READ_ONLY_DATA;
  453.   info.lock_type=F_UNLCK;
  454.   info.quick_mode=0;
  455.   info.errkey= -1;
  456.   info.page_changed=1;
  457.   pthread_mutex_lock(&share->intern_lock);
  458.   info.read_record=share->read_record;
  459.   share->reopen++;
  460.   share->write_flag=MYF(MY_NABP | MY_WAIT_IF_FULL);
  461.   if (share->options & HA_OPTION_READ_ONLY_DATA)
  462.   {
  463.     info.lock_type=F_RDLCK;
  464.     share->r_locks++;
  465.   }
  466.   if ((open_flags & HA_OPEN_TMP_TABLE) ||
  467.       (share->options & HA_OPTION_TMP_TABLE))
  468.   {
  469.     share->temporary=share->delay_key_write=1;
  470.     share->write_flag=MYF(MY_NABP);
  471.     share->w_locks++;            /* We don't have to update status */
  472.     info.lock_type=F_WRLCK;
  473.   }
  474.   if (((open_flags & HA_OPEN_DELAY_KEY_WRITE) ||
  475.       (share->options & HA_OPTION_DELAY_KEY_WRITE)) &&
  476.       myisam_delay_key_write)
  477.     share->delay_key_write=1;
  478.   info.state= &share->state.state;    /* Change global values by default */
  479.   pthread_mutex_unlock(&share->intern_lock);
  480.  
  481.   /* Allocate buffer for one record */
  482.  
  483.   extra=0;
  484.   if (share->options & HA_OPTION_PACK_RECORD)
  485.     extra=ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER)+MI_SPLIT_LENGTH+
  486.       MI_DYN_DELETE_BLOCK_HEADER;
  487.  
  488.   tmp_length=max(share->base.pack_reclength,share->base.max_key_length);
  489.   info.alloced_rec_buff_length=tmp_length;
  490.   if (!(info.rec_alloc=(byte*) my_malloc(tmp_length+extra+8,
  491.                      MYF(MY_WME | MY_ZEROFILL))))
  492.     goto err;
  493.   if (extra)
  494.     info.rec_buff=info.rec_alloc+ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER);
  495.   else
  496.     info.rec_buff=info.rec_alloc;
  497.  
  498.   *m_info=info;
  499. #ifdef THREAD
  500.   thr_lock_data_init(&share->lock,&m_info->lock,(void*) m_info);
  501. #endif
  502.   m_info->open_list.data=(void*) m_info;
  503.   myisam_open_list=list_add(myisam_open_list,&m_info->open_list);
  504.  
  505.   pthread_mutex_unlock(&THR_LOCK_myisam);
  506.   if (myisam_log_file >= 0)
  507.   {
  508.     intern_filename(name_buff,share->filename);
  509.     _myisam_log(MI_LOG_OPEN,m_info,name_buff,(uint) strlen(name_buff));
  510.   }
  511.   DBUG_RETURN(m_info);
  512.  
  513. err:
  514.   save_errno=my_errno ? my_errno : HA_ERR_END_OF_FILE;
  515.   switch (errpos) {
  516.   case 6:
  517.     my_free((gptr) m_info,MYF(0));
  518.     /* fall through */
  519.   case 5:
  520.     VOID(my_close(info.dfile,MYF(0)));
  521.     if (old_info)
  522.       break;                    /* Don't remove open table */
  523.     /* fall through */
  524.   case 4:
  525.     my_free((gptr) share,MYF(0));
  526.     /* fall through */
  527.   case 3:
  528.     if (! lock_error)
  529.       VOID(my_lock(kfile, F_UNLCK, 0L, F_TO_EOF, MYF(MY_SEEK_NOT_DONE)));
  530.     /* fall through */
  531.   case 2:
  532.     my_afree((gptr) disk_cache);
  533.     /* fall through */
  534.   case 1:
  535.     VOID(my_close(kfile,MYF(0)));
  536.     /* fall through */
  537.   case 0:
  538.   default:
  539.     break;
  540.   }
  541.   pthread_mutex_unlock(&THR_LOCK_myisam);
  542.   my_errno=save_errno;
  543.   DBUG_RETURN (NULL);
  544. } /* mi_open */
  545.  
  546.  
  547. ulonglong mi_safe_mul(ulonglong a, ulonglong b)
  548. {
  549.   ulonglong max_val= ~ (ulonglong) 0;        /* my_off_t is unsigned */
  550.  
  551.   if (!a || max_val / a < b)
  552.     return max_val;
  553.   return a*b;
  554. }
  555.  
  556.     /* Set up functions in structs */
  557.  
  558. static void setup_functions(register MYISAM_SHARE *share)
  559. {
  560.   if (share->options & HA_OPTION_COMPRESS_RECORD)
  561.   {
  562.     share->read_record=_mi_read_pack_record;
  563.     share->read_rnd=_mi_read_rnd_pack_record;
  564.     if (!(share->options & HA_OPTION_TEMP_COMPRESS_RECORD))
  565.       share->calc_checksum=0;                /* No checksum */
  566.     else if (share->options & HA_OPTION_PACK_RECORD)
  567.       share->calc_checksum= mi_checksum;
  568.     else
  569.       share->calc_checksum= mi_static_checksum;
  570.   }
  571.   else if (share->options & HA_OPTION_PACK_RECORD)
  572.   {
  573.     share->read_record=_mi_read_dynamic_record;
  574.     share->read_rnd=_mi_read_rnd_dynamic_record;
  575.     share->delete_record=_mi_delete_dynamic_record;
  576.     share->compare_record=_mi_cmp_dynamic_record;
  577.     share->compare_unique=_mi_cmp_dynamic_unique;
  578.     share->calc_checksum= mi_checksum;
  579.  
  580.     if (share->base.blobs)
  581.     {
  582.       share->update_record=_mi_update_blob_record;
  583.       share->write_record=_mi_write_blob_record;
  584.     }
  585.     else
  586.     {
  587.       share->write_record=_mi_write_dynamic_record;
  588.       share->update_record=_mi_update_dynamic_record;
  589.     }
  590.   }
  591.   else
  592.   {
  593.     share->read_record=_mi_read_static_record;
  594.     share->read_rnd=_mi_read_rnd_static_record;
  595.     share->delete_record=_mi_delete_static_record;
  596.     share->compare_record=_mi_cmp_static_record;
  597.     share->update_record=_mi_update_static_record;
  598.     share->write_record=_mi_write_static_record;
  599.     share->compare_unique=_mi_cmp_static_unique;
  600.     share->calc_checksum= mi_static_checksum;
  601.   }
  602.   if (!(share->options & HA_OPTION_CHECKSUM))
  603.     share->calc_checksum=0;
  604.   return;
  605. }
  606.  
  607.  
  608. static void setup_key_functions(register MI_KEYDEF *keyinfo)
  609. {
  610.   if (keyinfo->flag & HA_BINARY_PACK_KEY)
  611.   {                        /* Simple prefix compression */
  612.     keyinfo->bin_search=_mi_seq_search;
  613.     keyinfo->get_key=_mi_get_binary_pack_key;
  614.     keyinfo->pack_key=_mi_calc_bin_pack_key_length;
  615.     keyinfo->store_key=_mi_store_bin_pack_key;
  616.   }
  617.   else if (keyinfo->flag & HA_VAR_LENGTH_KEY)
  618.   {
  619.     keyinfo->bin_search=_mi_seq_search;
  620.     keyinfo->get_key= _mi_get_pack_key;
  621.     if (keyinfo->seg[0].flag & HA_PACK_KEY)
  622.     {                        /* Prefix compression */
  623.       keyinfo->pack_key=_mi_calc_var_pack_key_length;
  624.       keyinfo->store_key=_mi_store_var_pack_key;
  625.     }
  626.     else
  627.     {
  628.       keyinfo->pack_key=_mi_calc_var_key_length; /* Variable length key */
  629.       keyinfo->store_key=_mi_store_static_key;
  630.     }
  631.   }
  632.   else
  633.   {
  634.     keyinfo->bin_search=_mi_bin_search;
  635.     keyinfo->get_key=_mi_get_static_key;
  636.     keyinfo->pack_key=_mi_calc_static_key_length;
  637.     keyinfo->store_key=_mi_store_static_key;
  638.   }
  639.   return;
  640. }
  641.  
  642.  
  643. /***************************************************************************
  644. ** Function to save and store the header in the index file (.MSI)
  645. ***************************************************************************/
  646.  
  647. uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite)
  648. {
  649.   uchar  buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
  650.   uchar *ptr=buff;
  651.   uint    i, keys= (uint) state->header.keys,
  652.     key_blocks=state->header.max_block_size;
  653.  
  654.   memcpy_fixed(ptr,&state->header,sizeof(state->header));
  655.   ptr+=sizeof(state->header);
  656.  
  657.   /* open_count must be first because of _mi_mark_file_changed ! */
  658.   mi_int2store(ptr,state->open_count);        ptr +=2;
  659.   *ptr++= (uchar)state->changed; *ptr++= state->sortkey;
  660.   mi_rowstore(ptr,state->state.records);    ptr +=8;
  661.   mi_rowstore(ptr,state->state.del);        ptr +=8;
  662.   mi_rowstore(ptr,state->split);        ptr +=8;
  663.   mi_sizestore(ptr,state->dellink);        ptr +=8;
  664.   mi_sizestore(ptr,state->state.key_file_length);    ptr +=8;
  665.   mi_sizestore(ptr,state->state.data_file_length);    ptr +=8;
  666.   mi_sizestore(ptr,state->state.empty);        ptr +=8;
  667.   mi_sizestore(ptr,state->state.key_empty);    ptr +=8;
  668.   mi_int8store(ptr,state->auto_increment);    ptr +=8;
  669.   mi_int8store(ptr,(ulonglong) state->checksum);ptr +=8;
  670.   mi_int4store(ptr,state->process);        ptr +=4;
  671.   mi_int4store(ptr,state->unique);        ptr +=4;
  672.   mi_int4store(ptr,state->status);        ptr +=4;
  673.   mi_int4store(ptr,state->update_count);    ptr +=4;
  674.  
  675.   ptr+=state->state_diff_length;
  676.  
  677.   for (i=0; i < keys; i++)
  678.   {
  679.     mi_sizestore(ptr,state->key_root[i]);    ptr +=8;
  680.   }
  681.   for (i=0; i < key_blocks; i++)
  682.   {
  683.     mi_sizestore(ptr,state->key_del[i]);    ptr +=8;
  684.   }
  685.   if (pWrite & 2)                /* From isamchk */
  686.   {
  687.     uint key_parts= mi_uint2korr(state->header.key_parts);
  688.     mi_int4store(ptr,state->sec_index_changed); ptr +=4;
  689.     mi_int4store(ptr,state->sec_index_used);    ptr +=4;
  690.     mi_int4store(ptr,state->version);        ptr +=4;
  691.     mi_int8store(ptr,state->key_map);        ptr +=8;
  692.     mi_int8store(ptr,(ulonglong) state->create_time);    ptr +=8;
  693.     mi_int8store(ptr,(ulonglong) state->recover_time);    ptr +=8;
  694.     mi_int8store(ptr,(ulonglong) state->check_time);    ptr +=8;
  695.     mi_sizestore(ptr,state->rec_per_key_rows);    ptr+=8;
  696.     for (i=0 ; i < key_parts ; i++)
  697.     {
  698.       mi_int4store(ptr,state->rec_per_key_part[i]);  ptr+=4;
  699.     }
  700.   }
  701.  
  702.   if (pWrite & 1)
  703.      return my_pwrite(file,(char*) buff, (uint) (ptr-buff), 0L,
  704.               MYF(MY_NABP | MY_THREADSAFE));
  705.   else
  706.     return my_write(file,  (char*) buff, (uint) (ptr-buff), MYF(MY_NABP));
  707. }
  708.  
  709.  
  710. char *mi_state_info_read(char *ptr, MI_STATE_INFO *state)
  711. {
  712.   uint i,keys,key_parts,key_blocks;
  713.   memcpy_fixed(&state->header,ptr, sizeof(state->header));
  714.   ptr +=sizeof(state->header);
  715.   keys=(uint) state->header.keys;
  716.   key_parts=mi_uint2korr(state->header.key_parts);
  717.   key_blocks=state->header.max_block_size;
  718.  
  719.   state->open_count = mi_uint2korr(ptr);    ptr +=2;
  720.   state->changed= (bool) *ptr++;
  721.   state->sortkey = (uint) *ptr++;
  722.   state->state.records= mi_rowkorr(ptr);    ptr +=8;
  723.   state->state.del = mi_rowkorr(ptr);        ptr +=8;
  724.   state->split    = mi_rowkorr(ptr);        ptr +=8;
  725.   state->dellink= mi_sizekorr(ptr);        ptr +=8;
  726.   state->state.key_file_length = mi_sizekorr(ptr);    ptr +=8;
  727.   state->state.data_file_length= mi_sizekorr(ptr);    ptr +=8;
  728.   state->state.empty    = mi_sizekorr(ptr);    ptr +=8;
  729.   state->state.key_empty= mi_sizekorr(ptr);    ptr +=8;
  730.   state->auto_increment=mi_uint8korr(ptr);    ptr +=8;
  731.   state->checksum=(ha_checksum) mi_uint8korr(ptr);    ptr +=8;
  732.   state->process= mi_uint4korr(ptr);        ptr +=4;
  733.   state->unique = mi_uint4korr(ptr);        ptr +=4;
  734.   state->status = mi_uint4korr(ptr);        ptr +=4;
  735.   state->update_count=mi_uint4korr(ptr);    ptr +=4;
  736.  
  737.   for (i=0; i < keys; i++)
  738.   {
  739.     state->key_root[i]= mi_sizekorr(ptr);    ptr +=8;
  740.   }
  741.   for (i=0; i < key_blocks; i++)
  742.   {
  743.     state->key_del[i] = mi_sizekorr(ptr);    ptr +=8;
  744.   }
  745.   ptr+= state->state_diff_length;
  746.   state->sec_index_changed = mi_uint4korr(ptr); ptr +=4;
  747.   state->sec_index_used =    mi_uint4korr(ptr); ptr +=4;
  748.   state->version     = mi_uint4korr(ptr);    ptr +=4;
  749.   state->key_map     = mi_uint8korr(ptr);    ptr +=8;
  750.   state->create_time = (time_t) mi_sizekorr(ptr);    ptr +=8;
  751.   state->recover_time =(time_t) mi_sizekorr(ptr);    ptr +=8;
  752.   state->check_time =  (time_t) mi_sizekorr(ptr);    ptr +=8;
  753.   state->rec_per_key_rows=mi_sizekorr(ptr);    ptr +=8;
  754.   for (i=0 ; i < key_parts ; i++)
  755.   {
  756.     state->rec_per_key_part[i]= mi_uint4korr(ptr); ptr+=4;
  757.   }
  758.   return ptr;
  759. }
  760.  
  761.  
  762. uint mi_state_info_read_dsk(File file, MI_STATE_INFO *state, my_bool pRead)
  763. {
  764.   char    buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
  765.  
  766.   if (pRead)
  767.   {
  768.     if (my_pread(file, buff, state->state_length,0L, MYF(MY_NABP)))
  769.       return (MY_FILE_ERROR);
  770.   }
  771.   else if (my_read(file, buff, state->state_length,MYF(MY_NABP)))
  772.     return (MY_FILE_ERROR);
  773.   mi_state_info_read(buff, state);
  774.   return 0;
  775. }
  776.  
  777.  
  778. /****************************************************************************
  779. **  store and read of MI_BASE_INFO
  780. ****************************************************************************/
  781.  
  782. uint mi_base_info_write(File file, MI_BASE_INFO *base)
  783. {
  784.   uchar buff[MI_BASE_INFO_SIZE], *ptr=buff;
  785.  
  786.   mi_sizestore(ptr,base->keystart);            ptr +=8;
  787.   mi_sizestore(ptr,base->max_data_file_length);        ptr +=8;
  788.   mi_sizestore(ptr,base->max_key_file_length);        ptr +=8;
  789.   mi_rowstore(ptr,base->records);            ptr +=8;
  790.   mi_rowstore(ptr,base->reloc);                ptr +=8;
  791.   mi_int4store(ptr,base->mean_row_length);        ptr +=4;
  792.   mi_int4store(ptr,base->reclength);            ptr +=4;
  793.   mi_int4store(ptr,base->pack_reclength);        ptr +=4;
  794.   mi_int4store(ptr,base->min_pack_length);        ptr +=4;
  795.   mi_int4store(ptr,base->max_pack_length);        ptr +=4;
  796.   mi_int4store(ptr,base->min_block_length);        ptr +=4;
  797.   mi_int4store(ptr,base->fields);            ptr +=4;
  798.   mi_int4store(ptr,base->pack_fields);            ptr +=4;
  799.   *ptr++=base->rec_reflength;
  800.   *ptr++=base->key_reflength;
  801.   *ptr++=base->keys;
  802.   *ptr++=base->auto_key;
  803.   mi_int2store(ptr,base->pack_bits);            ptr +=2;
  804.   mi_int2store(ptr,base->blobs);            ptr +=2;
  805.   mi_int2store(ptr,base->max_key_block_length);        ptr +=2;
  806.   mi_int2store(ptr,base->max_key_length);        ptr +=2;
  807.   mi_int2store(ptr,base->extra_alloc_bytes);        ptr +=2;
  808.   *ptr++= base->extra_alloc_procent;
  809.   *ptr++= base->raid_type;
  810.   mi_int2store(ptr,base->raid_chunks);            ptr +=2;
  811.   mi_int4store(ptr,base->raid_chunksize);        ptr +=4;
  812.   bzero(ptr,6);                        ptr +=6; /* extra */
  813.   return my_write(file,(char*) buff, (uint) (ptr-buff), MYF(MY_NABP));
  814. }
  815.  
  816.  
  817. char *my_n_base_info_read(char *ptr, MI_BASE_INFO *base)
  818. {
  819.   base->keystart = mi_sizekorr(ptr);            ptr +=8;
  820.   base->max_data_file_length = mi_sizekorr(ptr);    ptr +=8;
  821.   base->max_key_file_length = mi_sizekorr(ptr);        ptr +=8;
  822.   base->records =  (ha_rows) mi_sizekorr(ptr);        ptr +=8;
  823.   base->reloc = (ha_rows) mi_sizekorr(ptr);        ptr +=8;
  824.   base->mean_row_length = mi_uint4korr(ptr);        ptr +=4;
  825.   base->reclength = mi_uint4korr(ptr);            ptr +=4;
  826.   base->pack_reclength = mi_uint4korr(ptr);        ptr +=4;
  827.   base->min_pack_length = mi_uint4korr(ptr);        ptr +=4;
  828.   base->max_pack_length = mi_uint4korr(ptr);        ptr +=4;
  829.   base->min_block_length = mi_uint4korr(ptr);        ptr +=4;
  830.   base->fields = mi_uint4korr(ptr);            ptr +=4;
  831.   base->pack_fields = mi_uint4korr(ptr);        ptr +=4;
  832.  
  833.   base->rec_reflength = *ptr++;
  834.   base->key_reflength = *ptr++;
  835.   base->keys=        *ptr++;
  836.   base->auto_key=    *ptr++;
  837.   base->pack_bits = mi_uint2korr(ptr);            ptr +=2;
  838.   base->blobs = mi_uint2korr(ptr);            ptr +=2;
  839.   base->max_key_block_length= mi_uint2korr(ptr);    ptr +=2;
  840.   base->max_key_length = mi_uint2korr(ptr);        ptr +=2;
  841.   base->extra_alloc_bytes = mi_uint2korr(ptr);        ptr +=2;
  842.   base->extra_alloc_procent = *ptr++;
  843.   base->raid_type= *ptr++;
  844.   base->raid_chunks= mi_uint2korr(ptr);            ptr +=2;
  845.   base->raid_chunksize= mi_uint4korr(ptr);        ptr +=4;
  846.   /* TO BE REMOVED: Fix for old RAID files */
  847.   if (base->raid_type == 0)
  848.   {
  849.     base->raid_chunks=0;
  850.     base->raid_chunksize=0;
  851.   }
  852.  
  853.   ptr+=6;
  854.   return ptr;
  855. }
  856.  
  857. /*--------------------------------------------------------------------------
  858.   mi_keydef
  859. ---------------------------------------------------------------------------*/
  860.  
  861. uint mi_keydef_write(File file, MI_KEYDEF *keydef)
  862. {
  863.   uchar buff[MI_KEYDEF_SIZE];
  864.   uchar *ptr=buff;
  865.  
  866.   *ptr++ = (uchar) keydef->keysegs;
  867.   *ptr++ = 0;                    /* not used */
  868.   mi_int2store(ptr,keydef->flag);        ptr +=2;
  869.   mi_int2store(ptr,keydef->block_length);    ptr +=2;
  870.   mi_int2store(ptr,keydef->keylength);        ptr +=2;
  871.   mi_int2store(ptr,keydef->minlength);        ptr +=2;
  872.   mi_int2store(ptr,keydef->maxlength);        ptr +=2;
  873.   return my_write(file,(char*) buff, (uint) (ptr-buff), MYF(MY_NABP));
  874. }
  875.  
  876. char *mi_keydef_read(char *ptr, MI_KEYDEF *keydef)
  877. {
  878.    keydef->keysegs    = (uint) *ptr++;
  879.    ptr++;
  880.    keydef->flag        = mi_uint2korr(ptr);    ptr +=2;
  881.    keydef->block_length = mi_uint2korr(ptr);    ptr +=2;
  882.    keydef->keylength    = mi_uint2korr(ptr);    ptr +=2;
  883.    keydef->minlength    = mi_uint2korr(ptr);    ptr +=2;
  884.    keydef->maxlength    = mi_uint2korr(ptr);    ptr +=2;
  885.    keydef->block_size    = keydef->block_length/MI_KEY_BLOCK_LENGTH-1;
  886.    keydef->underflow_block_length=keydef->block_length/3;
  887.    keydef->version    = 0;            /* Not saved */
  888.    return ptr;
  889. }
  890.  
  891. /***************************************************************************
  892. **  mi_keyseg
  893. ***************************************************************************/
  894.  
  895. int mi_keyseg_write(File file, const MI_KEYSEG *keyseg)
  896. {
  897.   uchar buff[MI_KEYSEG_SIZE];
  898.   uchar *ptr=buff;
  899.  
  900.   *ptr++ =keyseg->type;
  901.   *ptr++ =keyseg->language;
  902.   *ptr++ =keyseg->null_bit;
  903.   *ptr++ =keyseg->bit_start;
  904.   *ptr++ =keyseg->bit_end;
  905.   *ptr++ =0;                    /* Not used */
  906.   mi_int2store(ptr,keyseg->flag);    ptr+=2;
  907.   mi_int2store(ptr,keyseg->length);    ptr+=2;
  908.   mi_int4store(ptr,keyseg->start);    ptr+=4;
  909.   mi_int4store(ptr,keyseg->null_pos);    ptr+=4;
  910.  
  911.   return my_write(file,(char*) buff, (uint) (ptr-buff), MYF(MY_NABP));
  912. }
  913.  
  914.  
  915. char *mi_keyseg_read(char *ptr, MI_KEYSEG *keyseg)
  916. {
  917.    keyseg->type        = *ptr++;
  918.    keyseg->language    = *ptr++;
  919.    keyseg->null_bit    = *ptr++;
  920.    keyseg->bit_start    = *ptr++;
  921.    keyseg->bit_end    = *ptr++;
  922.    ptr++;
  923.    keyseg->flag        = mi_uint2korr(ptr);  ptr +=2;
  924.    keyseg->length    = mi_uint2korr(ptr);  ptr +=2;
  925.    keyseg->start    = mi_uint4korr(ptr);  ptr +=4;
  926.    keyseg->null_pos    = mi_uint4korr(ptr);  ptr +=4;
  927.    keyseg->charset=0;                /* Will be filled in later */
  928.    return ptr;
  929. }
  930.  
  931. /*--------------------------------------------------------------------------
  932.   mi_uniquedef
  933. ---------------------------------------------------------------------------*/
  934.  
  935. uint mi_uniquedef_write(File file, MI_UNIQUEDEF *def)
  936. {
  937.   uchar buff[MI_UNIQUEDEF_SIZE];
  938.   uchar *ptr=buff;
  939.  
  940.   mi_int2store(ptr,def->keysegs);        ptr+=2;
  941.   *ptr++=  (uchar) def->key;
  942.   *ptr++ = (uchar) def->null_are_equal;
  943.  
  944.   return my_write(file,(char*) buff, (uint) (ptr-buff), MYF(MY_NABP));
  945. }
  946.  
  947. char *mi_uniquedef_read(char *ptr, MI_UNIQUEDEF *def)
  948. {
  949.    def->keysegs = mi_uint2korr(ptr);
  950.    def->key    = ptr[2];
  951.    def->null_are_equal=ptr[3];
  952.    return ptr+4;                /* 1 extra byte */
  953. }
  954.  
  955. /***************************************************************************
  956. **  MI_COLUMNDEF
  957. ***************************************************************************/
  958.  
  959. uint mi_recinfo_write(File file, MI_COLUMNDEF *recinfo)
  960. {
  961.   uchar buff[MI_COLUMNDEF_SIZE];
  962.   uchar *ptr=buff;
  963.  
  964.   mi_int2store(ptr,recinfo->type);    ptr +=2;
  965.   mi_int2store(ptr,recinfo->length);    ptr +=2;
  966.   *ptr++ = recinfo->null_bit;
  967.   mi_int2store(ptr,recinfo->null_pos);    ptr+= 2;
  968.   return my_write(file,(char*) buff, (uint) (ptr-buff), MYF(MY_NABP));
  969. }
  970.  
  971. char *mi_recinfo_read(char *ptr, MI_COLUMNDEF *recinfo)
  972. {
  973.    recinfo->type=  mi_sint2korr(ptr);    ptr +=2;
  974.    recinfo->length=mi_uint2korr(ptr);    ptr +=2;
  975.    recinfo->null_bit= (uint8) *ptr++;
  976.    recinfo->null_pos=mi_uint2korr(ptr); ptr +=2;
  977.    return ptr;
  978. }
  979.  
  980. /**************************************************************************
  981.  ** Help functions for recover
  982.  *************************************************************************/
  983.  
  984. int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share)
  985. {
  986.   char name_buff[FN_REFLEN];
  987.   (void) fn_format(name_buff, share->filename,"",MI_NAME_DEXT, 2+4);
  988.  
  989. #ifdef USE_RAID
  990.   if (share->base.raid_type)
  991.   {
  992.     if ((info->dfile=my_raid_open(name_buff,
  993.                   share->mode | O_SHARE,
  994.                   share->base.raid_type,
  995.                   share->base.raid_chunks,
  996.                   share->base.raid_chunksize,
  997.                   MYF(MY_WME | MY_RAID))) < 0)
  998.       return 1;
  999.   }
  1000.   else
  1001. #endif
  1002.     if ((info->dfile=my_open(name_buff, share->mode | O_SHARE,
  1003.                  MYF(MY_WME))) < 0)
  1004.       return 1;
  1005.   return 0;
  1006. }
  1007.  
  1008.  
  1009. int mi_open_keyfile(MYISAM_SHARE *share)
  1010. {
  1011.   if ((share->kfile=my_open(share->filename, share->mode | O_SHARE,
  1012.                 MYF(MY_WME))) < 0)
  1013.     return 1;
  1014.   return 0;
  1015. }
  1016.