summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/Makefile.am4
-rw-r--r--sql/ha_innobase.cc16
-rw-r--r--sql/ha_isam.cc2
-rw-r--r--sql/ha_isammrg.cc6
-rw-r--r--sql/ha_myisam.cc72
-rw-r--r--sql/ha_myisammrg.cc4
-rw-r--r--sql/handler.cc20
-rw-r--r--sql/item_func.cc3
-rw-r--r--sql/mysql_priv.h4
-rw-r--r--sql/mysqld.cc63
-rw-r--r--sql/sql_parse.cc6
-rw-r--r--sql/sql_select.cc8
-rw-r--r--sql/sql_table.cc10
13 files changed, 126 insertions, 92 deletions
diff --git a/sql/Makefile.am b/sql/Makefile.am
index ea29aa2e5a7..b9289864b3f 100644
--- a/sql/Makefile.am
+++ b/sql/Makefile.am
@@ -29,7 +29,7 @@ WRAPLIBS= @WRAPLIBS@
SUBDIRS = share
libexec_PROGRAMS = mysqld
noinst_PROGRAMS = gen_lex_hash
-gen_lex_hash_LDFLAGS = @NOINST_LDFLAGS@
+gen_lex_hash_LDFLAGS = @NOINST_LDFLAGS@
LDADD = ../isam/libnisam.a \
../merge/libmerge.a \
../myisam/libmyisam.a \
@@ -43,7 +43,7 @@ LDADD = ../isam/libnisam.a \
mysqld_LDADD = @MYSQLD_EXTRA_LDFLAGS@ \
@bdb_libs@ @innodb_libs@ @pstack_libs@ \
- @gemini_libs@ \
+ @gemini_libs@ @innodb_system_libs@ \
$(LDADD) $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@ @openssl_libs@
noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
item_strfunc.h item_timefunc.h item_uniq.h \
diff --git a/sql/ha_innobase.cc b/sql/ha_innobase.cc
index cb76c034749..e7d98dbe406 100644
--- a/sql/ha_innobase.cc
+++ b/sql/ha_innobase.cc
@@ -85,7 +85,7 @@ char *innobase_data_home_dir;
char *innobase_log_group_home_dir, *innobase_log_arch_dir;
char *innobase_unix_file_flush_method;
bool innobase_flush_log_at_trx_commit, innobase_log_archive,
- innobase_use_native_aio;
+ innobase_use_native_aio;
/*
Set default InnoDB size to 64M, to let users use InnoDB without having
@@ -524,7 +524,6 @@ innobase_init(void)
/*===============*/
/* out: TRUE if error */
{
- static char current_dir[3];
int err;
bool ret;
@@ -537,11 +536,6 @@ innobase_init(void)
srv_query_thread_priority = QUERY_PRIOR;
}
- /* Use current_dir if no paths are set */
- current_dir[0]=FN_CURLIB;
- current_dir[1]=FN_LIBCHAR;
- current_dir[2]=0;
-
/* Set InnoDB initialization parameters according to the values
read from MySQL .cnf file */
@@ -550,10 +544,10 @@ innobase_init(void)
MYF(MY_WME));
srv_data_home = (innobase_data_home_dir ? innobase_data_home_dir :
- current_dir);
+ mysql_real_data_home);
srv_logs_home = (char*) "";
srv_arch_dir = (innobase_log_arch_dir ? innobase_log_arch_dir :
- current_dir);
+ mysql_real_data_home);
ret = innobase_parse_data_file_paths_and_sizes();
@@ -563,7 +557,7 @@ innobase_init(void)
}
if (!innobase_log_group_home_dir)
- innobase_log_group_home_dir= current_dir;
+ innobase_log_group_home_dir= mysql_real_data_home;
ret = innobase_parse_log_group_home_dirs();
if (ret == FALSE) {
@@ -591,6 +585,8 @@ innobase_init(void)
srv_lock_wait_timeout = (ulint) innobase_lock_wait_timeout;
+ srv_print_verbose_log = mysql_embedded ? 0 : 1;
+
err = innobase_start_or_create_for_mysql();
if (err != DB_SUCCESS) {
diff --git a/sql/ha_isam.cc b/sql/ha_isam.cc
index 746fdd2f585..2451b8bdaec 100644
--- a/sql/ha_isam.cc
+++ b/sql/ha_isam.cc
@@ -20,6 +20,7 @@
#endif
#include "mysql_priv.h"
+#ifdef HAVE_ISAM
#include <m_ctype.h>
#include <myisampack.h>
#include "ha_isam.h"
@@ -388,3 +389,4 @@ ha_rows ha_isam::records_in_range(int inx,
end_key,end_key_len,
end_search_flag);
}
+#endif /* HAVE_ISAM */
diff --git a/sql/ha_isammrg.cc b/sql/ha_isammrg.cc
index dd2e4e2f723..41fb99fe867 100644
--- a/sql/ha_isammrg.cc
+++ b/sql/ha_isammrg.cc
@@ -20,11 +20,12 @@
#endif
#include "mysql_priv.h"
+#ifdef HAVE_ISAM
#include <m_ctype.h>
#ifndef MASTER
-#include "../srclib/merge/mrgdef.h"
+#include "../srclib/merge/mrg_def.h"
#else
-#include "../merge/mrgdef.h"
+#include "../merge/mrg_def.h"
#endif
#include "ha_isammrg.h"
@@ -208,3 +209,4 @@ int ha_isammrg::create(const char *name, register TABLE *form,
char buff[FN_REFLEN];
return mrg_create(fn_format(buff,name,"","",2+4+16),0);
}
+#endif /* HAVE_ISAM */
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc
index 36d06022d58..ea91a460182 100644
--- a/sql/ha_myisam.cc
+++ b/sql/ha_myisam.cc
@@ -374,14 +374,14 @@ int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt)
char* backup_dir = thd->lex.backup_dir;
char src_path[FN_REFLEN], dst_path[FN_REFLEN];
char* table_name = table->real_name;
+ int error;
+ const char* errmsg;
DBUG_ENTER("restore");
- if (!fn_format(src_path, table_name, backup_dir, MI_NAME_DEXT, 4 + 64))
+ if (fn_format_relative_to_data_home(src_path, table_name, backup_dir,
+ MI_NAME_DEXT))
DBUG_RETURN(HA_ADMIN_INVALID);
- int error = 0;
- const char* errmsg = "";
-
if (my_copy(src_path, fn_format(dst_path, table->path, "",
MI_NAME_DEXT, 4), MYF(MY_WME)))
{
@@ -404,7 +404,7 @@ int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt)
param.db_name = table->table_cache_key;
param.table_name = table->table_name;
param.testflag = 0;
- mi_check_print_error(&param,errmsg, errno );
+ mi_check_print_error(&param,errmsg, my_errno);
DBUG_RETURN(error);
}
}
@@ -415,41 +415,47 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt)
char* backup_dir = thd->lex.backup_dir;
char src_path[FN_REFLEN], dst_path[FN_REFLEN];
char* table_name = table->real_name;
- int error = 0;
- const char* errmsg = "";
-
- if (!fn_format(dst_path, table_name, backup_dir, reg_ext, 4 + 64))
- {
- errmsg = "Failed in fn_format() for .frm file: errno = %d";
- error = HA_ADMIN_INVALID;
- goto err;
- }
+ int error;
+ const char *errmsg;
+ DBUG_ENTER("ha_myisam::backup");
+
+ if (fn_format_relative_to_data_home(dst_path, table_name, backup_dir,
+ reg_ext))
+ {
+ errmsg = "Failed in fn_format() for .frm file: errno = %d";
+ error = HA_ADMIN_INVALID;
+ goto err;
+ }
- if (my_copy(fn_format(src_path, table->path,"", reg_ext, 4),
- dst_path,
- MYF(MY_WME | MY_HOLD_ORIGINAL_MODES )))
+ if (my_copy(fn_format(src_path, table->path,"", reg_ext, MY_UNPACK_FILENAME),
+ dst_path,
+ MYF(MY_WME | MY_HOLD_ORIGINAL_MODES)))
{
error = HA_ADMIN_FAILED;
errmsg = "Failed copying .frm file: errno = %d";
goto err;
}
- if (!fn_format(dst_path, table_name, backup_dir, MI_NAME_DEXT, 4 + 64))
- {
- errmsg = "Failed in fn_format() for .MYD file: errno = %d";
- error = HA_ADMIN_INVALID;
- goto err;
- }
+ /* Change extension */
+ if (!fn_format(dst_path, dst_path, "", MI_NAME_DEXT,
+ MY_REPLACE_EXT | MY_UNPACK_FILENAME | MY_SAFE_PATH))
+ {
+ errmsg = "Failed in fn_format() for .MYD file: errno = %d";
+ error = HA_ADMIN_INVALID;
+ goto err;
+ }
- if (my_copy(fn_format(src_path, table->path,"", MI_NAME_DEXT, 4),
+ if (my_copy(fn_format(src_path, table->path,"", MI_NAME_DEXT,
+ MY_UNPACK_FILENAME),
dst_path,
- MYF(MY_WME | MY_HOLD_ORIGINAL_MODES )) )
- {
- errmsg = "Failed copying .MYD file: errno = %d";
- error= HA_ADMIN_FAILED;
- goto err;
- }
- return HA_ADMIN_OK;
+ MYF(MY_WME | MY_HOLD_ORIGINAL_MODES)))
+ {
+ errmsg = "Failed copying .MYD file: errno = %d";
+ error= HA_ADMIN_FAILED;
+ goto err;
+ }
+ DBUG_RETURN(HA_ADMIN_OK);
+
err:
{
MI_CHECK param;
@@ -459,8 +465,8 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt)
param.db_name = table->table_cache_key;
param.table_name = table->table_name;
param.testflag = 0;
- mi_check_print_error(&param,errmsg, errno );
- return error;
+ mi_check_print_error(&param,errmsg, my_errno);
+ DBUG_RETURN(error);
}
}
diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc
index 88ae8d22f73..0a2ef534ad1 100644
--- a/sql/ha_myisammrg.cc
+++ b/sql/ha_myisammrg.cc
@@ -23,9 +23,9 @@
#include <m_ctype.h>
#include "ha_myisammrg.h"
#ifndef MASTER
-#include "../srclib/myisammrg/mymrgdef.h"
+#include "../srclib/myisammrg/myrg_def.h"
#else
-#include "../myisammrg/mymrgdef.h"
+#include "../myisammrg/myrg_def.h"
#endif
/*****************************************************************************
diff --git a/sql/handler.cc b/sql/handler.cc
index 8b7b7fe6799..5a41498aff1 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -25,7 +25,7 @@
#include "ha_heap.h"
#include "ha_myisam.h"
#include "ha_myisammrg.h"
-#ifndef NO_ISAM
+#ifdef HAVE_ISAM
#include "ha_isam.h"
#include "ha_isammrg.h"
#endif
@@ -88,11 +88,9 @@ enum db_type ha_checktype(enum db_type database_type)
#ifndef NO_HASH
case DB_TYPE_HASH:
#endif
-#ifndef NO_MERGE
- case DB_TYPE_MRG_ISAM:
-#endif
-#ifndef NO_ISAM
+#ifdef HAVE_ISAM
case DB_TYPE_ISAM:
+ case DB_TYPE_MRG_ISAM:
#endif
case DB_TYPE_HEAP:
case DB_TYPE_MYISAM:
@@ -111,11 +109,9 @@ handler *get_new_handler(TABLE *table, enum db_type db_type)
#ifndef NO_HASH
return new ha_hash(table);
#endif
-#ifndef NO_MERGE
+#ifdef HAVE_ISAM
case DB_TYPE_MRG_ISAM:
return new ha_isammrg(table);
-#endif
-#ifndef NO_ISAM
case DB_TYPE_ISAM:
return new ha_isam(table);
#endif
@@ -186,14 +182,14 @@ int ha_init()
int ha_panic(enum ha_panic_function flag)
{
int error=0;
-#ifndef NO_MERGE
- error|=mrg_panic(flag);
-#endif
#ifndef NO_HASH
error|=h_panic(flag); /* fix hash */
#endif
- error|=heap_panic(flag);
+#ifdef HAVE_ISAM
+ error|=mrg_panic(flag);
error|=nisam_panic(flag);
+#endif
+ error|=heap_panic(flag);
error|=mi_panic(flag);
error|=myrg_panic(flag);
#ifdef HAVE_BERKELEY_DB
diff --git a/sql/item_func.cc b/sql/item_func.cc
index e09f81a4b1b..dcc3ecb2560 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -1063,7 +1063,8 @@ udf_handler::~udf_handler()
}
free_udf(u_d);
}
- delete [] buffers;
+ if (buffers) // Because of bug in ecc
+ delete [] buffers;
}
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index f817d53f33e..1ffbb88c7f8 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -504,6 +504,8 @@ void init_errmessage(void);
void sql_perror(const char *message);
void sql_print_error(const char *format,...)
__attribute__ ((format (printf, 1, 2)));
+bool fn_format_relative_to_data_home(my_string to, const char *name,
+ const char *dir, const char *extension);
extern uint32 server_id;
extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH],
@@ -540,7 +542,7 @@ extern pthread_cond_t COND_refresh,COND_thread_count, COND_binlog_update,
COND_slave_stopped, COND_slave_start;
extern pthread_attr_t connection_attrib;
extern bool opt_endinfo, using_udf_functions, locked_in_memory,
- opt_using_transactions, use_temp_pool;
+ opt_using_transactions, use_temp_pool, mysql_embedded;
extern char f_fyllchar;
extern ulong ha_read_count, ha_write_count, ha_delete_count, ha_update_count,
ha_read_key_count, ha_read_next_count, ha_read_prev_count,
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 8854f6b46d2..12fea519db9 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -193,7 +193,7 @@ SHOW_COMP_OPTION have_innodb=SHOW_OPTION_YES;
#else
SHOW_COMP_OPTION have_innodb=SHOW_OPTION_NO;
#endif
-#ifndef NO_ISAM
+#ifdef HAVE_ISAM
SHOW_COMP_OPTION have_isam=SHOW_OPTION_YES;
#else
SHOW_COMP_OPTION have_isam=SHOW_OPTION_NO;
@@ -317,8 +317,10 @@ char mysql_real_data_home[FN_REFLEN],
*opt_init_file;
#ifndef EMBEDDED_LIBRARY
char mysql_data_home_buff[2], *mysql_data_home=mysql_data_home_buff;
+bool mysql_embedded=0;
#else
char *mysql_data_home=mysql_real_data_home;
+bool mysql_embedded=1;
#endif
char *opt_bin_logname = 0; // this one needs to be seen in sql_parse.cc
@@ -333,7 +335,7 @@ enum_tx_isolation default_tx_isolation=ISO_READ_COMMITTED;
#ifdef HAVE_GEMINI_DB
const char *gemini_recovery_options_str="FULL";
#endif
-my_string mysql_unix_port=NULL,mysql_tmpdir=NULL;
+my_string mysql_unix_port=NULL, mysql_tmpdir=NULL, allocated_mysql_tmpdir=NULL;
ulong my_bind_addr; /* the address we bind to */
DATE_FORMAT dayord;
double log_10[32]; /* 10 potences */
@@ -730,8 +732,8 @@ void clean_up(bool print_message)
#endif /* HAVE_OPENSSL */
free_defaults(defaults_argv);
my_free(charsets_list, MYF(MY_ALLOW_ZERO_PTR));
- my_free(mysql_tmpdir,MYF(0));
- my_free(slave_load_tmpdir,MYF(0));
+ my_free(allocated_mysql_tmpdir,MYF(MY_ALLOW_ZERO_PTR));
+ my_free(slave_load_tmpdir,MYF(MY_ALLOW_ZERO_PTR));
x_free(opt_bin_logname);
bitmap_free(&temp_pool);
free_max_user_conn();
@@ -3770,7 +3772,10 @@ static void get_options(int argc,char **argv)
break;
#endif
case (int) OPT_FLUSH:
- nisam_flush=myisam_flush=1;
+#ifdef HAVE_ISAM
+ nisam_flush=1;
+#endif
+ myisam_flush=1;
flush_time=0; // No auto flush
break;
case OPT_LOW_PRIORITY_UPDATES:
@@ -4295,7 +4300,10 @@ static int get_service_parameters()
else if ( lstrcmp(szKeyValueName, TEXT("FlushTables")) == 0 )
{
CHECK_KEY_TYPE( REG_DWORD, szKeyValueName );
- nisam_flush = myisam_flush= *lpdwValue ? 1 : 0;
+#ifdef HAVE_NISAM
+ nisam_flush = 1;
+#endif
+ myisam_flush= *lpdwValue ? 1 : 0;
}
else if ( lstrcmp(szKeyValueName, TEXT("BackLog")) == 0 )
{
@@ -4529,12 +4537,34 @@ static char *get_relative_path(const char *path)
}
+/*
+ Fix filename and replace extension where 'dir' is relative to
+ mysql_real_data_home.
+ Return 1 if len(path) > FN_REFLEN
+*/
+
+bool
+fn_format_relative_to_data_home(my_string to, const char *name,
+ const char *dir, const char *extension)
+{
+ char tmp_path[FN_REFLEN];
+ if (!test_if_hard_path(dir))
+ {
+ strxnmov(tmp_path,sizeof(tmp_path)-1, mysql_real_data_home,
+ dir, NullS);
+ dir=tmp_path;
+ }
+ return !fn_format(to, name, dir, extension,
+ MY_REPLACE_EXT | MY_UNPACK_FILENAME | MY_SAFE_PATH);
+}
+
+
static void fix_paths(void)
{
(void) fn_format(mysql_home,mysql_home,"","",16); // Remove symlinks
- convert_dirname(mysql_home);
- convert_dirname(mysql_real_data_home);
- convert_dirname(language);
+ convert_dirname(mysql_home,mysql_home,NullS);
+ convert_dirname(mysql_real_data_home,mysql_real_data_home,NullS);
+ convert_dirname(language,language,NullS);
(void) my_load_path(mysql_home,mysql_home,""); // Resolve current dir
(void) my_load_path(mysql_real_data_home,mysql_real_data_home,mysql_home);
(void) my_load_path(pidfile_name,pidfile_name,mysql_real_data_home);
@@ -4544,7 +4574,7 @@ static void fix_paths(void)
strmov(buff,sharedir); /* purecov: tested */
else
strxmov(buff,mysql_home,sharedir,NullS);
- convert_dirname(buff);
+ convert_dirname(buff,buff,NullS);
(void) my_load_path(language,language,buff);
/* If --character-sets-dir isn't given, use shared library dir */
@@ -4558,19 +4588,16 @@ static void fix_paths(void)
char *tmp= (char*) my_malloc(FN_REFLEN,MYF(MY_FAE));
if (tmp)
{
- strmov(tmp,mysql_tmpdir);
- mysql_tmpdir=tmp;
- convert_dirname(mysql_tmpdir);
- mysql_tmpdir=(char*) my_realloc(mysql_tmpdir,(uint) strlen(mysql_tmpdir)+1,
+ char *end=convert_dirname(tmp, mysql_tmpdir, NullS);
+
+ mysql_tmpdir=(char*) my_realloc(tmp,(uint) (end-tmp)+1,
MYF(MY_HOLD_ON_ERROR));
+ allocated_mysql_tmpdir=mysql_tmpdir;
}
if (!slave_load_tmpdir)
{
- int copy_len;
- slave_load_tmpdir = (char*) my_malloc((copy_len=strlen(mysql_tmpdir) + 1)
- , MYF(MY_FAE));
// no need to check return value, if we fail, my_malloc() never returns
- memcpy(slave_load_tmpdir, mysql_tmpdir, copy_len);
+ slave_load_tmpdir = (char*) my_strdup(mysql_tmpdir, MYF(MY_FAE));
}
}
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index e930dd2cfcb..35f32d50f46 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -3051,7 +3051,7 @@ static void refresh_status(void)
static bool append_file_to_dir(char **filename_ptr, char *table_name)
{
- char buff[FN_REFLEN],*ptr;
+ char buff[FN_REFLEN],*ptr, *end;
if (!*filename_ptr)
return 0; // nothing to do
@@ -3064,8 +3064,8 @@ static bool append_file_to_dir(char **filename_ptr, char *table_name)
}
/* Fix is using unix filename format on dos */
strmov(buff,*filename_ptr);
- convert_dirname(buff);
- if (!(ptr=sql_alloc(strlen(buff)+strlen(table_name)+1)))
+ end=convert_dirname(buff, *filename_ptr, NullS);
+ if (!(ptr=sql_alloc((uint) (end-buff)+strlen(table_name)+1)))
return 1; // End of memory
*filename_ptr=ptr;
strxmov(ptr,buff,table_name,NullS);
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 14bdd3d7d66..53d83c350ea 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -2645,7 +2645,8 @@ join_free(JOIN *join)
}
join->group_fields.delete_elements();
join->tmp_table_param.copy_funcs.delete_elements();
- delete [] join->tmp_table_param.copy_field;
+ if (join->tmp_table_param.copy_field) // Because of bug in ecc
+ delete [] join->tmp_table_param.copy_field;
join->tmp_table_param.copy_field=0;
DBUG_VOID_RETURN;
}
@@ -6395,7 +6396,7 @@ setup_copy_fields(TMP_TABLE_PARAM *param,List<Item> &fields)
DBUG_ENTER("setup_copy_fields");
if (!(copy=param->copy_field= new Copy_field[param->field_count]))
- goto err;
+ goto err2;
param->copy_funcs.empty();
while ((pos=li++))
@@ -6444,8 +6445,9 @@ setup_copy_fields(TMP_TABLE_PARAM *param,List<Item> &fields)
DBUG_RETURN(0);
err:
- delete [] param->copy_field;
+ delete [] param->copy_field; // This is never 0
param->copy_field=0;
+err2:
DBUG_RETURN(TRUE);
}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index a5e9eec03b1..99c2b837480 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -841,7 +841,8 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table)
char* table_name = table->name;
char* db = thd->db ? thd->db : table->db;
- if (!fn_format(src_path, table_name, backup_dir, reg_ext, 4 + 64))
+ if (fn_format_relative_to_data_home(src_path, table_name, backup_dir,
+ reg_ext))
DBUG_RETURN(-1); // protect buffer overflow
sprintf(dst_path, "%s/%s/%s", mysql_real_data_home, db, table_name);
@@ -850,9 +851,8 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table)
DBUG_RETURN(-1);
if (my_copy(src_path,
- fn_format(dst_path, dst_path,"",
- reg_ext, 4),
- MYF(MY_WME)))
+ fn_format(dst_path, dst_path,"", reg_ext, 4),
+ MYF(MY_WME)))
{
unlock_table_name(thd, table);
DBUG_RETURN(send_check_errmsg(thd, table, "restore",
@@ -1814,7 +1814,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
}
end_read_record(&info);
free_io_cache(from);
- delete [] copy;
+ delete [] copy; // This is never 0
uint tmp_error;
if ((tmp_error=to->file->extra(HA_EXTRA_NO_CACHE)))
{