1/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
2 Copyright (c) 2010, 2017, MariaDB Corporation.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
16
17#ifndef _my_sys_h
18#define _my_sys_h
19
20#include <m_string.h>
21
22C_MODE_START
23
24#ifdef HAVE_AIOWAIT
25#include <sys/asynch.h> /* Used by record-cache */
26typedef struct my_aio_result {
27 aio_result_t result;
28 int pending;
29} my_aio_result;
30#endif
31
32#include <my_valgrind.h>
33
34#include <my_pthread.h>
35
36#include <m_ctype.h> /* for CHARSET_INFO */
37#include <stdarg.h>
38#include <typelib.h>
39#ifdef _WIN32
40#include <malloc.h> /*for alloca*/
41#endif
42#include <mysql/plugin.h>
43#include <mysql/service_my_print_error.h>
44
45#define MY_INIT(name) { my_progname= name; my_init(); }
46
47/**
48 Max length of an error message generated by mysys utilities.
49 Some mysys functions produce error messages. These mostly go
50 to stderr.
51 This constant defines the size of the buffer used to format
52 the message. It should be kept in sync with MYSQL_ERRMSG_SIZE,
53 since sometimes mysys errors are stored in the server diagnostics
54 area, and we would like to avoid unexpected truncation.
55*/
56#define MYSYS_ERRMSG_SIZE (512)
57#define MYSYS_STRERROR_SIZE (128)
58
59#define MY_FILE_ERROR ((size_t) -1)
60
61 /* General bitmaps for my_func's */
62#define MY_FFNF 1U /* Fatal if file not found */
63#define MY_FNABP 2U /* Fatal if not all bytes read/written */
64#define MY_NABP 4U /* Error if not all bytes read/written */
65#define MY_FAE 8U /* Fatal if any error */
66#define MY_WME 16U /* Write message on error */
67#define MY_WAIT_IF_FULL 32U /* Wait and try again if disk full error */
68#define MY_IGNORE_BADFD 32U /* my_sync(): ignore 'bad descriptor' errors */
69#define MY_ENCRYPT 64U /* Encrypt IO_CACHE temporary files */
70#define MY_TEMPORARY 64U /* create_temp_file(): delete file at once */
71#define MY_NOSYMLINKS 512U /* my_open(): don't follow symlinks */
72#define MY_FULL_IO 512U /* my_read(): loop until I/O is complete */
73#define MY_DONT_CHECK_FILESIZE 128U /* Option to init_io_cache() */
74#define MY_LINK_WARNING 32U /* my_redel() gives warning if links */
75#define MY_COPYTIME 64U /* my_redel() copies time */
76#define MY_DELETE_OLD 256U /* my_create_with_symlink() */
77#define MY_RESOLVE_LINK 128U /* my_realpath(); Only resolve links */
78#define MY_HOLD_ORIGINAL_MODES 128U /* my_copy() holds to file modes */
79#define MY_REDEL_MAKE_BACKUP 256U
80#define MY_SEEK_NOT_DONE 32U /* my_lock may have to do a seek */
81#define MY_SHORT_WAIT 64U /* my_lock() don't wait if can't lock */
82#define MY_FORCE_LOCK 128U /* use my_lock() even if disable_locking */
83#define MY_NO_WAIT 256U /* my_lock() don't wait at all */
84/*
85 init_dynamic_array() has init buffer; Internal flag, not to be used by
86 caller.
87*/
88#define MY_INIT_BUFFER_USED 256U
89#define MY_ZEROFILL 32U /* my_malloc(), fill array with zero */
90#define MY_ALLOW_ZERO_PTR 64U /* my_realloc() ; zero ptr -> malloc */
91#define MY_FREE_ON_ERROR 128U /* my_realloc() ; Free old ptr on error */
92#define MY_HOLD_ON_ERROR 256U /* my_realloc() ; Return old ptr on error */
93#define MY_DONT_OVERWRITE_FILE 2048U /* my_copy: Don't overwrite file */
94#define MY_THREADSAFE 2048U /* my_seek(): lock fd mutex */
95#define MY_SYNC 4096U /* my_copy(): sync dst file */
96#define MY_SYNC_DIR 32768U /* my_create/delete/rename: sync directory */
97#define MY_SYNC_FILESIZE 65536U /* my_sync(): safe sync when file is extended */
98#define MY_THREAD_SPECIFIC 0x10000U /* my_malloc(): thread specific */
99#define MY_THREAD_MOVE 0x20000U /* realloc(); Memory can move */
100/* Tree that should delete things automatically */
101#define MY_TREE_WITH_DELETE 0x40000U
102
103#define MY_CHECK_ERROR 1U /* Params to my_end; Check open-close */
104#define MY_GIVE_INFO 2U /* Give time info about process*/
105#define MY_DONT_FREE_DBUG 4U /* Do not call DBUG_END() in my_end() */
106
107#define ME_BELL 4U /* Ring bell then printing message */
108#define ME_WAITTANG 0 /* Wait for a user action */
109#define ME_NOREFRESH 64U /* Write the error message to error log */
110#define ME_NOINPUT 0 /* Don't use the input library */
111#define ME_JUST_INFO 1024U /**< not error but just info */
112#define ME_JUST_WARNING 2048U /**< not error but just warning */
113#define ME_FATALERROR 4096U /* Fatal statement error */
114
115 /* Bits in last argument to fn_format */
116#define MY_REPLACE_DIR 1U /* replace dir in name with 'dir' */
117#define MY_REPLACE_EXT 2U /* replace extension with 'ext' */
118#define MY_UNPACK_FILENAME 4U /* Unpack name (~ -> home) */
119#define MY_PACK_FILENAME 8U /* Pack name (home -> ~) */
120#define MY_RESOLVE_SYMLINKS 16U /* Resolve all symbolic links */
121#define MY_RETURN_REAL_PATH 32U /* return full path for file */
122#define MY_SAFE_PATH 64U /* Return NULL if too long path */
123#define MY_RELATIVE_PATH 128U /* name is relative to 'dir' */
124#define MY_APPEND_EXT 256U /* add 'ext' as additional extension*/
125
126
127 /* My seek flags */
128#define MY_SEEK_SET 0
129#define MY_SEEK_CUR 1
130#define MY_SEEK_END 2
131
132 /* Some constants */
133#define MY_WAIT_FOR_USER_TO_FIX_PANIC 60 /* in seconds */
134#define MY_WAIT_GIVE_USER_A_MESSAGE 10 /* Every 10 times of prev */
135#define MIN_COMPRESS_LENGTH 50 /* Don't compress small bl. */
136#define DFLT_INIT_HITS 3
137
138 /* root_alloc flags */
139#define MY_KEEP_PREALLOC 1U
140#define MY_MARK_BLOCKS_FREE 2U /* move used to free list and reuse them */
141
142 /* Internal error numbers (for assembler functions) */
143#define MY_ERRNO_EDOM 33
144#define MY_ERRNO_ERANGE 34
145
146 /* Bits for get_date timeflag */
147#define GETDATE_DATE_TIME 1U
148#define GETDATE_SHORT_DATE 2U
149#define GETDATE_HHMMSSTIME 4U
150#define GETDATE_GMT 8U
151#define GETDATE_FIXEDLENGTH 16U
152
153/* Extra length needed for filename if one calls my_create_backup_name */
154#define MY_BACKUP_NAME_EXTRA_LENGTH 17
155
156char *guess_malloc_library();
157
158/* If we have our own safemalloc (for debugging) */
159#if defined(SAFEMALLOC)
160void sf_report_leaked_memory(my_thread_id id);
161int sf_sanity();
162extern my_thread_id (*sf_malloc_dbug_id)(void);
163#define SAFEMALLOC_REPORT_MEMORY(X) sf_report_leaked_memory(X)
164#else
165#define SAFEMALLOC_REPORT_MEMORY(X) do {} while(0)
166#endif
167
168typedef void (*MALLOC_SIZE_CB) (long long size, my_bool is_thread_specific);
169extern void set_malloc_size_cb(MALLOC_SIZE_CB func);
170
171 /* defines when allocating data */
172extern void *my_malloc(size_t Size,myf MyFlags);
173extern void *my_multi_malloc(myf MyFlags, ...);
174extern void *my_multi_malloc_large(myf MyFlags, ...);
175extern void *my_realloc(void *oldpoint, size_t Size, myf MyFlags);
176extern void my_free(void *ptr);
177extern void *my_memdup(const void *from,size_t length,myf MyFlags);
178extern char *my_strdup(const char *from,myf MyFlags);
179extern char *my_strndup(const char *from, size_t length, myf MyFlags);
180
181#ifdef HAVE_LINUX_LARGE_PAGES
182extern uint my_get_large_page_size(void);
183extern uchar * my_large_malloc(size_t size, myf my_flags);
184extern void my_large_free(uchar *ptr);
185#else
186#define my_get_large_page_size() (0)
187#define my_large_malloc(A,B) my_malloc_lock((A),(B))
188#define my_large_free(A) my_free_lock((A))
189#endif /* HAVE_LINUX_LARGE_PAGES */
190
191void my_init_atomic_write(void);
192#ifdef __linux__
193my_bool my_test_if_atomic_write(File handle, int pagesize);
194#else
195#define my_test_if_atomic_write(A, B) 0
196#endif /* __linux__ */
197extern my_bool my_may_have_atomic_write;
198
199#if defined(HAVE_ALLOCA) && !defined(HAVE_valgrind)
200#if defined(_AIX) && !defined(__GNUC__) && !defined(_AIX43)
201#pragma alloca
202#endif /* _AIX */
203#if defined(__MWERKS__)
204#undef alloca
205#define alloca _alloca
206#endif /* __MWERKS__ */
207#if defined(__GNUC__) && !defined(HAVE_ALLOCA_H) && ! defined(alloca)
208#define alloca __builtin_alloca
209#endif /* GNUC */
210#define my_alloca(SZ) alloca((size_t) (SZ))
211#define my_afree(PTR) ((void)0)
212#define MAX_ALLOCA_SZ 4096
213#define my_safe_alloca(size) (((size) <= MAX_ALLOCA_SZ) ? \
214 my_alloca(size) : \
215 my_malloc((size), MYF(MY_THREAD_SPECIFIC|MY_WME)))
216#define my_safe_afree(ptr, size) \
217 do { if ((size) > MAX_ALLOCA_SZ) my_free(ptr); } while(0)
218#else
219#define my_alloca(SZ) my_malloc(SZ,MYF(MY_FAE))
220#define my_afree(PTR) my_free(PTR)
221#define my_safe_alloca(size) my_alloca(size)
222#define my_safe_afree(ptr, size) my_afree(ptr)
223#endif /* HAVE_ALLOCA */
224
225#ifndef errno /* did we already get it? */
226#ifdef HAVE_ERRNO_AS_DEFINE
227#include <errno.h> /* errno is a define */
228#else
229extern int errno; /* declare errno */
230#endif
231#endif /* #ifndef errno */
232extern char *home_dir; /* Home directory for user */
233extern MYSQL_PLUGIN_IMPORT char *mysql_data_home;
234extern const char *my_progname; /* program-name (printed in errors) */
235extern const char *my_progname_short; /* like above but without directory */
236extern char curr_dir[]; /* Current directory for user */
237extern void (*error_handler_hook)(uint my_err, const char *str,myf MyFlags);
238extern void (*fatal_error_handler_hook)(uint my_err, const char *str,
239 myf MyFlags);
240extern uint my_file_limit;
241extern ulonglong my_thread_stack_size;
242extern int sf_leaking_memory; /* set to 1 to disable memleak detection */
243
244extern void (*proc_info_hook)(void *, const PSI_stage_info *, PSI_stage_info *,
245 const char *, const char *, const unsigned int);
246
247#ifdef HAVE_LINUX_LARGE_PAGES
248extern my_bool my_use_large_pages;
249extern uint my_large_page_size;
250#endif
251
252/* charsets */
253#define MY_ALL_CHARSETS_SIZE 2048
254extern MYSQL_PLUGIN_IMPORT CHARSET_INFO *default_charset_info;
255extern MYSQL_PLUGIN_IMPORT CHARSET_INFO *all_charsets[MY_ALL_CHARSETS_SIZE];
256extern struct charset_info_st compiled_charsets[];
257
258/* Collation properties and use statistics */
259extern my_bool my_collation_is_known_id(uint id);
260extern ulonglong my_collation_statistics_get_use_count(uint id);
261extern const char *my_collation_get_tailoring(uint id);
262
263/* statistics */
264extern ulong my_file_opened,my_stream_opened, my_tmp_file_created;
265extern ulong my_file_total_opened;
266extern ulong my_sync_count;
267extern uint mysys_usage_id;
268extern my_bool my_init_done, my_thr_key_mysys_exists;
269extern my_bool my_assert_on_error;
270extern myf my_global_flags; /* Set to MY_WME for more error messages */
271 /* Point to current my_message() */
272extern void (*my_sigtstp_cleanup)(void),
273 /* Executed before jump to shell */
274 (*my_sigtstp_restart)(void);
275 /* Executed when coming from shell */
276extern MYSQL_PLUGIN_IMPORT int my_umask; /* Default creation mask */
277extern int my_umask_dir,
278 my_recived_signals, /* Signals we have got */
279 my_safe_to_handle_signal, /* Set when allowed to SIGTSTP */
280 my_dont_interrupt; /* call remember_intr when set */
281extern my_bool my_use_symdir;
282
283extern ulong my_default_record_cache_size;
284extern my_bool my_disable_locking, my_disable_async_io,
285 my_disable_flush_key_blocks, my_disable_symlinks;
286extern my_bool my_disable_sync, my_disable_copystat_in_redel;
287extern char wild_many,wild_one,wild_prefix;
288extern const char *charsets_dir;
289extern my_bool timed_mutexes;
290
291enum cache_type
292{
293 TYPE_NOT_SET= 0, READ_CACHE, WRITE_CACHE,
294 SEQ_READ_APPEND /* sequential read or append */,
295 READ_FIFO, READ_NET};
296
297enum flush_type
298{
299 FLUSH_KEEP, /* flush block and keep it in the cache */
300 FLUSH_RELEASE, /* flush block and remove it from the cache */
301 FLUSH_IGNORE_CHANGED, /* remove block from the cache */
302 /*
303 As my_disable_flush_pagecache_blocks is always 0, the following option
304 is strictly equivalent to FLUSH_KEEP
305 */
306 FLUSH_FORCE_WRITE,
307 /**
308 @brief like FLUSH_KEEP but return immediately if file is already being
309 flushed (even partially) by another thread; only for page cache,
310 forbidden for key cache.
311 */
312 FLUSH_KEEP_LAZY
313};
314
315typedef struct st_record_cache /* Used when caching records */
316{
317 File file;
318 int rc_seek,error,inited;
319 uint rc_length,read_length,reclength;
320 my_off_t rc_record_pos,end_of_file;
321 uchar *rc_buff,*rc_buff2,*rc_pos,*rc_end,*rc_request_pos;
322#ifdef HAVE_AIOWAIT
323 int use_async_io;
324 my_aio_result aio_result;
325#endif
326 enum cache_type type;
327} RECORD_CACHE;
328
329enum file_type
330{
331 UNOPEN = 0, FILE_BY_OPEN, FILE_BY_CREATE, STREAM_BY_FOPEN, STREAM_BY_FDOPEN,
332 FILE_BY_MKSTEMP, FILE_BY_DUP
333};
334
335struct st_my_file_info
336{
337 char *name;
338#ifdef _WIN32
339 HANDLE fhandle; /* win32 file handle */
340 int oflag; /* open flags, e.g O_APPEND */
341#endif
342 enum file_type type;
343};
344
345extern struct st_my_file_info *my_file_info;
346
347/* Free function pointer */
348typedef void (*FREE_FUNC)(void *);
349
350typedef struct st_dynamic_array
351{
352 uchar *buffer;
353 uint elements,max_element;
354 uint alloc_increment;
355 uint size_of_element;
356 myf malloc_flags;
357} DYNAMIC_ARRAY;
358
359typedef struct st_my_tmpdir
360{
361 DYNAMIC_ARRAY full_list;
362 char **list;
363 uint cur, max;
364 mysql_mutex_t mutex;
365} MY_TMPDIR;
366
367typedef struct st_dynamic_string
368{
369 char *str;
370 size_t length,max_length,alloc_increment;
371} DYNAMIC_STRING;
372
373struct st_io_cache;
374
375typedef struct st_io_cache_share
376{
377 mysql_mutex_t mutex; /* To sync on reads into buffer. */
378 mysql_cond_t cond; /* To wait for signals. */
379 mysql_cond_t cond_writer; /* For a synchronized writer. */
380 /* Offset in file corresponding to the first byte of buffer. */
381 my_off_t pos_in_file;
382 /* If a synchronized write cache is the source of the data. */
383 struct st_io_cache *source_cache;
384 uchar *buffer; /* The read buffer. */
385 uchar *read_end; /* Behind last valid byte of buffer. */
386 int running_threads; /* threads not in lock. */
387 int total_threads; /* threads sharing the cache. */
388 int error; /* Last error. */
389#ifdef NOT_YET_IMPLEMENTED
390 /* whether the structure should be free'd */
391 my_bool alloced;
392#endif
393} IO_CACHE_SHARE;
394
395typedef struct st_io_cache /* Used when caching files */
396{
397 /* Offset in file corresponding to the first byte of uchar* buffer. */
398 my_off_t pos_in_file;
399 /*
400 The offset of end of file for READ_CACHE and WRITE_CACHE.
401 For SEQ_READ_APPEND it the maximum of the actual end of file and
402 the position represented by read_end.
403 */
404 my_off_t end_of_file;
405 /* Points to current read position in the buffer */
406 uchar *read_pos;
407 /* the non-inclusive boundary in the buffer for the currently valid read */
408 uchar *read_end;
409 uchar *buffer; /* The read buffer */
410 /* Used in ASYNC_IO */
411 uchar *request_pos;
412
413 /* Only used in WRITE caches and in SEQ_READ_APPEND to buffer writes */
414 uchar *write_buffer;
415 /*
416 Only used in SEQ_READ_APPEND, and points to the current read position
417 in the write buffer. Note that reads in SEQ_READ_APPEND caches can
418 happen from both read buffer (uchar* buffer) and write buffer
419 (uchar* write_buffer).
420 */
421 uchar *append_read_pos;
422 /* Points to current write position in the write buffer */
423 uchar *write_pos;
424 /* The non-inclusive boundary of the valid write area */
425 uchar *write_end;
426
427 /*
428 The lock is for append buffer used in SEQ_READ_APPEND cache
429 need mutex copying from append buffer to read buffer.
430 */
431 mysql_mutex_t append_buffer_lock;
432 /*
433 The following is used when several threads are reading the
434 same file in parallel. They are synchronized on disk
435 accesses reading the cached part of the file asynchronously.
436 It should be set to NULL to disable the feature. Only
437 READ_CACHE mode is supported.
438 */
439 IO_CACHE_SHARE *share;
440
441 /*
442 A caller will use my_b_read() macro to read from the cache
443 if the data is already in cache, it will be simply copied with
444 memcpy() and internal variables will be accordinging updated with
445 no functions invoked. However, if the data is not fully in the cache,
446 my_b_read() will call read_function to fetch the data. read_function
447 must never be invoked directly.
448 */
449 int (*read_function)(struct st_io_cache *,uchar *,size_t);
450 /*
451 Same idea as in the case of read_function, except my_b_write() needs to
452 be replaced with my_b_append() for a SEQ_READ_APPEND cache
453 */
454 int (*write_function)(struct st_io_cache *,const uchar *,size_t);
455 /*
456 Specifies the type of the cache. Depending on the type of the cache
457 certain operations might not be available and yield unpredicatable
458 results. Details to be documented later
459 */
460 enum cache_type type;
461 /*
462 Counts the number of times, when we were forced to use disk. We use it to
463 increase the binlog_cache_disk_use and binlog_stmt_cache_disk_use status
464 variables.
465 */
466 ulong disk_writes;
467 char *file_name; /* if used with 'open_cached_file' */
468 const char *dir;
469 char prefix[3];
470 File file; /* file descriptor */
471
472 struct st_io_cache *next_file_user;
473 /*
474 seek_not_done is set by my_b_seek() to inform the upcoming read/write
475 operation that a seek needs to be preformed prior to the actual I/O
476 error is 0 if the cache operation was successful, -1 if there was a
477 "hard" error, and the actual number of I/O-ed bytes if the read/write was
478 partial.
479 */
480 int seek_not_done,error;
481 /* buffer_length is memory size allocated for buffer or write_buffer */
482 size_t buffer_length;
483 /* read_length is the same as buffer_length except when we use async io */
484 size_t read_length;
485 myf myflags; /* Flags used to my_read/my_write */
486 /*
487 alloced_buffer is 1 if the buffer was allocated by init_io_cache() and
488 0 if it was supplied by the user.
489 Currently READ_NET is the only one that will use a buffer allocated
490 somewhere else
491 */
492 my_bool alloced_buffer;
493#ifdef HAVE_AIOWAIT
494 /*
495 As inidicated by ifdef, this is for async I/O, which is not currently
496 used (because it's not reliable on all systems)
497 */
498 uint inited;
499 my_off_t aio_read_pos;
500 my_aio_result aio_result;
501#endif
502} IO_CACHE;
503
504typedef int (*qsort2_cmp)(const void *, const void *, const void *);
505
506typedef void (*my_error_reporter)(enum loglevel level, const char *format, ...)
507 ATTRIBUTE_FORMAT_FPTR(printf, 2, 3);
508
509extern my_error_reporter my_charset_error_reporter;
510
511/* inline functions for mf_iocache */
512
513extern int my_b_flush_io_cache(IO_CACHE *info, int need_append_buffer_lock);
514extern int _my_b_get(IO_CACHE *info);
515extern int _my_b_read(IO_CACHE *info,uchar *Buffer,size_t Count);
516extern int _my_b_write(IO_CACHE *info,const uchar *Buffer,size_t Count);
517
518/* Test if buffer is inited */
519static inline void my_b_clear(IO_CACHE *info) { info->buffer= 0; }
520static inline int my_b_inited(IO_CACHE *info) { return MY_TEST(info->buffer); }
521#define my_b_EOF INT_MIN
522
523static inline int my_b_read(IO_CACHE *info, uchar *Buffer, size_t Count)
524{
525 if (info->read_pos + Count <= info->read_end)
526 {
527 memcpy(Buffer, info->read_pos, Count);
528 info->read_pos+= Count;
529 return 0;
530 }
531 return _my_b_read(info, Buffer, Count);
532}
533
534static inline int my_b_write(IO_CACHE *info, const uchar *Buffer, size_t Count)
535{
536 if (info->write_pos + Count <= info->write_end)
537 {
538 memcpy(info->write_pos, Buffer, Count);
539 info->write_pos+= Count;
540 return 0;
541 }
542 return _my_b_write(info, Buffer, Count);
543}
544
545static inline int my_b_get(IO_CACHE *info)
546{
547 if (info->read_pos != info->read_end)
548 {
549 info->read_pos++;
550 return info->read_pos[-1];
551 }
552 return _my_b_get(info);
553}
554
555static inline my_bool my_b_write_byte(IO_CACHE *info, uchar chr)
556{
557 if (info->write_pos >= info->write_end)
558 if (my_b_flush_io_cache(info, 1))
559 return 1;
560 *info->write_pos++= chr;
561 return 0;
562}
563
564/**
565 Fill buffer of the cache.
566
567 @note It assumes that you have already used all characters in the CACHE,
568 independent of the read_pos value!
569
570 @returns
571 0 On error or EOF (info->error = -1 on error)
572 # Number of characters
573*/
574static inline size_t my_b_fill(IO_CACHE *info)
575{
576 info->read_pos= info->read_end;
577 return _my_b_read(info,0,0) ? 0 : (size_t) (info->read_end - info->read_pos);
578}
579
580static inline my_off_t my_b_tell(const IO_CACHE *info)
581{
582 if (info->type == WRITE_CACHE) {
583 return info->pos_in_file + (my_off_t)(info->write_pos - info->request_pos);
584
585 }
586 return info->pos_in_file + (my_off_t) (info->read_pos - info->request_pos);
587}
588
589static inline my_off_t my_b_write_tell(const IO_CACHE *info)
590{
591 return info->pos_in_file + (my_off_t) (info->write_pos - info->write_buffer);
592}
593
594static inline uchar* my_b_get_buffer_start(const IO_CACHE *info)
595{
596 return info->request_pos;
597}
598
599static inline size_t my_b_get_bytes_in_buffer(const IO_CACHE *info)
600{
601 return (size_t) (info->read_end - info->request_pos);
602}
603
604static inline my_off_t my_b_get_pos_in_file(const IO_CACHE *info)
605{
606 return info->pos_in_file;
607}
608
609static inline size_t my_b_bytes_in_cache(const IO_CACHE *info)
610{
611 if (info->type == WRITE_CACHE) {
612 return (size_t) (info->write_end - info->write_pos);
613 }
614 return (size_t) (info->read_end - info->read_pos);
615}
616
617int my_b_copy_to_file(IO_CACHE *cache, FILE *file);
618my_off_t my_b_append_tell(IO_CACHE* info);
619my_off_t my_b_safe_tell(IO_CACHE* info); /* picks the correct tell() */
620int my_b_pread(IO_CACHE *info, uchar *Buffer, size_t Count, my_off_t pos);
621
622typedef uint32 ha_checksum;
623
624extern int (*mysys_test_invalid_symlink)(const char *filename);
625#include <my_alloc.h>
626
627 /* Prototypes for mysys and my_func functions */
628
629extern int my_copy(const char *from,const char *to,myf MyFlags);
630extern int my_delete(const char *name,myf MyFlags);
631extern int my_getwd(char * buf,size_t size,myf MyFlags);
632extern int my_setwd(const char *dir,myf MyFlags);
633extern int my_lock(File fd,int op,my_off_t start, my_off_t length,myf MyFlags);
634extern void *my_once_alloc(size_t Size,myf MyFlags);
635extern void my_once_free(void);
636extern char *my_once_strdup(const char *src,myf myflags);
637extern void *my_once_memdup(const void *src, size_t len, myf myflags);
638extern File my_open(const char *FileName,int Flags,myf MyFlags);
639extern File my_register_filename(File fd, const char *FileName,
640 enum file_type type_of_file,
641 uint error_message_number, myf MyFlags);
642extern File my_create(const char *FileName,int CreateFlags,
643 int AccessFlags, myf MyFlags);
644extern int my_close(File Filedes,myf MyFlags);
645extern int my_mkdir(const char *dir, int Flags, myf MyFlags);
646extern int my_readlink(char *to, const char *filename, myf MyFlags);
647extern int my_is_symlink(const char *filename);
648extern int my_realpath(char *to, const char *filename, myf MyFlags);
649extern File my_create_with_symlink(const char *linkname, const char *filename,
650 int createflags, int access_flags,
651 myf MyFlags);
652extern int my_rename_with_symlink(const char *from,const char *to,myf MyFlags);
653extern int my_symlink(const char *content, const char *linkname, myf MyFlags);
654extern int my_handler_delete_with_symlink(const char *filename, myf sync_dir);
655
656extern size_t my_read(File Filedes,uchar *Buffer,size_t Count,myf MyFlags);
657extern size_t my_pread(File Filedes,uchar *Buffer,size_t Count,my_off_t offset,
658 myf MyFlags);
659extern int my_rename(const char *from,const char *to,myf MyFlags);
660extern my_off_t my_seek(File fd,my_off_t pos,int whence,myf MyFlags);
661extern my_off_t my_tell(File fd,myf MyFlags);
662extern size_t my_write(File Filedes,const uchar *Buffer,size_t Count,
663 myf MyFlags);
664extern size_t my_pwrite(File Filedes,const uchar *Buffer,size_t Count,
665 my_off_t offset,myf MyFlags);
666extern size_t my_fread(FILE *stream,uchar *Buffer,size_t Count,myf MyFlags);
667extern size_t my_fwrite(FILE *stream,const uchar *Buffer,size_t Count,
668 myf MyFlags);
669extern my_off_t my_fseek(FILE *stream,my_off_t pos,int whence,myf MyFlags);
670extern my_off_t my_ftell(FILE *stream,myf MyFlags);
671
672/* implemented in my_memmem.c */
673extern void *my_memmem(const void *haystack, size_t haystacklen,
674 const void *needle, size_t needlelen);
675
676
677#ifdef _WIN32
678extern int my_access(const char *path, int amode);
679#define my_check_user(A,B) (NULL)
680#define my_set_user(A,B,C) (0)
681#else
682#define my_access access
683struct passwd *my_check_user(const char *user, myf MyFlags);
684int my_set_user(const char *user, struct passwd *user_info, myf MyFlags);
685#endif
686
687extern int check_if_legal_filename(const char *path);
688extern int check_if_legal_tablename(const char *path);
689
690#ifdef __WIN__
691extern my_bool is_filename_allowed(const char *name, size_t length,
692 my_bool allow_current_dir);
693#else /* __WIN__ */
694# define is_filename_allowed(name, length, allow_cwd) (TRUE)
695#endif /* __WIN__ */
696
697#ifdef _WIN32
698/* Windows-only functions (CRT equivalents)*/
699extern HANDLE my_get_osfhandle(File fd);
700extern void my_osmaperr(unsigned long last_error);
701#endif
702
703extern void init_glob_errs(void);
704extern const char** get_global_errmsgs(int nr);
705extern void wait_for_free_space(const char *filename, int errors);
706extern FILE *my_fopen(const char *FileName,int Flags,myf MyFlags);
707extern FILE *my_fdopen(File Filedes,const char *name, int Flags,myf MyFlags);
708extern FILE *my_freopen(const char *path, const char *mode, FILE *stream);
709extern int my_fclose(FILE *fd,myf MyFlags);
710extern int my_vfprintf(FILE *stream, const char* format, va_list args);
711extern const char* my_strerror(char *buf, size_t len, int nr);
712extern int my_fprintf(FILE *stream, const char* format, ...);
713extern File my_fileno(FILE *fd);
714extern int my_chsize(File fd,my_off_t newlength, int filler, myf MyFlags);
715extern int my_chmod(const char *name, mode_t mode, myf my_flags);
716extern const char *my_basename(const char *filename);
717extern void thr_set_sync_wait_callback(void (*before_sync)(void),
718 void (*after_sync)(void));
719extern int my_sync(File fd, myf my_flags);
720extern int my_sync_dir(const char *dir_name, myf my_flags);
721extern int my_sync_dir_by_file(const char *file_name, myf my_flags);
722extern const char *my_get_err_msg(uint nr);
723extern int my_error_register(const char** (*get_errmsgs) (int nr),
724 uint first, uint last);
725extern my_bool my_error_unregister(uint first, uint last);
726extern void my_message(uint my_err, const char *str,myf MyFlags);
727extern void my_message_stderr(uint my_err, const char *str, myf MyFlags);
728extern my_bool my_init(void);
729extern void my_end(int infoflag);
730extern int my_redel(const char *from, const char *to, time_t backup_time_stamp,
731 myf MyFlags);
732void my_create_backup_name(char *to, const char *from,
733 time_t backup_time_stamp);
734extern int my_copystat(const char *from, const char *to, int MyFlags);
735extern char * my_filename(File fd);
736
737extern my_bool init_tmpdir(MY_TMPDIR *tmpdir, const char *pathlist);
738extern char *my_tmpdir(MY_TMPDIR *tmpdir);
739extern void free_tmpdir(MY_TMPDIR *tmpdir);
740
741extern void my_remember_signal(int signal_number,sig_handler (*func)(int));
742extern size_t dirname_part(char * to,const char *name, size_t *to_res_length);
743extern size_t dirname_length(const char *name);
744#define base_name(A) (A+dirname_length(A))
745extern int test_if_hard_path(const char *dir_name);
746extern my_bool has_path(const char *name);
747extern char *convert_dirname(char *to, const char *from, const char *from_end);
748extern void to_unix_path(char * name);
749extern char * fn_ext(const char *name);
750extern char * fn_ext2(const char *name);
751extern char * fn_same(char * toname,const char *name,int flag);
752extern char * fn_format(char * to,const char *name,const char *dir,
753 const char *form, uint flag);
754extern size_t strlength(const char *str);
755extern void pack_dirname(char * to,const char *from);
756extern size_t normalize_dirname(char * to, const char *from);
757extern size_t unpack_dirname(char * to,const char *from);
758extern size_t cleanup_dirname(char * to,const char *from);
759extern size_t system_filename(char * to,const char *from);
760extern size_t unpack_filename(char * to,const char *from);
761extern char * intern_filename(char * to,const char *from);
762extern int pack_filename(char * to, const char *name, size_t max_length);
763extern char * my_path(char * to,const char *progname,
764 const char *own_pathname_part);
765extern char * my_load_path(char * to, const char *path,
766 const char *own_path_prefix);
767extern int wild_compare(const char *str,const char *wildstr,
768 pbool str_is_pattern);
769extern my_bool array_append_string_unique(const char *str,
770 const char **array, size_t size);
771extern void get_date(char * to,int timeflag,time_t use_time);
772extern void soundex(CHARSET_INFO *, char * out_pntr, char * in_pntr,
773 pbool remove_garbage);
774extern int init_record_cache(RECORD_CACHE *info,size_t cachesize,File file,
775 size_t reclength,enum cache_type type,
776 pbool use_async_io);
777extern int read_cache_record(RECORD_CACHE *info,uchar *to);
778extern int end_record_cache(RECORD_CACHE *info);
779extern int write_cache_record(RECORD_CACHE *info,my_off_t filepos,
780 const uchar *record,size_t length);
781extern int flush_write_cache(RECORD_CACHE *info);
782extern void handle_recived_signals(void);
783
784extern sig_handler my_set_alarm_variable(int signo);
785extern my_bool radixsort_is_appliccable(uint n_items, size_t size_of_element);
786extern void my_string_ptr_sort(uchar *base,uint items,size_t size);
787extern void radixsort_for_str_ptr(uchar* base[], uint number_of_elements,
788 size_t size_of_element,uchar *buffer[]);
789extern qsort_t my_qsort(void *base_ptr, size_t total_elems, size_t size,
790 qsort_cmp cmp);
791extern qsort_t my_qsort2(void *base_ptr, size_t total_elems, size_t size,
792 qsort2_cmp cmp, void *cmp_argument);
793extern qsort2_cmp get_ptr_compare(size_t);
794void my_store_ptr(uchar *buff, size_t pack_length, my_off_t pos);
795my_off_t my_get_ptr(uchar *ptr, size_t pack_length);
796extern int init_io_cache(IO_CACHE *info,File file,size_t cachesize,
797 enum cache_type type,my_off_t seek_offset,
798 my_bool use_async_io, myf cache_myflags);
799extern my_bool reinit_io_cache(IO_CACHE *info,enum cache_type type,
800 my_off_t seek_offset, my_bool use_async_io,
801 my_bool clear_cache);
802extern void init_io_cache_share(IO_CACHE *read_cache, IO_CACHE_SHARE *cshare,
803 IO_CACHE *write_cache, uint num_threads);
804
805extern int init_slave_io_cache(IO_CACHE *master, IO_CACHE *slave);
806void end_slave_io_cache(IO_CACHE *cache);
807void seek_io_cache(IO_CACHE *cache, my_off_t needed_offset);
808
809extern void remove_io_thread(IO_CACHE *info);
810extern int _my_b_async_read(IO_CACHE *info,uchar *Buffer,size_t Count);
811extern int my_b_append(IO_CACHE *info,const uchar *Buffer,size_t Count);
812extern int my_b_safe_write(IO_CACHE *info,const uchar *Buffer,size_t Count);
813
814extern int my_block_write(IO_CACHE *info, const uchar *Buffer,
815 size_t Count, my_off_t pos);
816
817#define flush_io_cache(info) my_b_flush_io_cache((info),1)
818
819extern int end_io_cache(IO_CACHE *info);
820extern void my_b_seek(IO_CACHE *info,my_off_t pos);
821extern size_t my_b_gets(IO_CACHE *info, char *to, size_t max_length);
822extern my_off_t my_b_filelength(IO_CACHE *info);
823extern my_bool my_b_write_backtick_quote(IO_CACHE *info, const char *str,
824 size_t len);
825extern my_bool my_b_printf(IO_CACHE *info, const char* fmt, ...);
826extern size_t my_b_vprintf(IO_CACHE *info, const char* fmt, va_list ap);
827extern my_bool open_cached_file(IO_CACHE *cache,const char *dir,
828 const char *prefix, size_t cache_size,
829 myf cache_myflags);
830extern my_bool real_open_cached_file(IO_CACHE *cache);
831extern void close_cached_file(IO_CACHE *cache);
832File create_temp_file(char *to, const char *dir, const char *pfx,
833 int mode, myf MyFlags);
834#define my_init_dynamic_array(A,B,C,D,E) init_dynamic_array2(A,B,NULL,C,D,E)
835#define my_init_dynamic_array2(A,B,C,D,E,F) init_dynamic_array2(A,B,C,D,E,F)
836extern my_bool init_dynamic_array2(DYNAMIC_ARRAY *array, uint element_size,
837 void *init_buffer, uint init_alloc,
838 uint alloc_increment, myf my_flags);
839extern my_bool insert_dynamic(DYNAMIC_ARRAY *array, const void* element);
840extern void *alloc_dynamic(DYNAMIC_ARRAY *array);
841extern void *pop_dynamic(DYNAMIC_ARRAY*);
842extern my_bool set_dynamic(DYNAMIC_ARRAY *array, const void *element,
843 uint array_index);
844extern my_bool allocate_dynamic(DYNAMIC_ARRAY *array, uint max_elements);
845extern void get_dynamic(DYNAMIC_ARRAY *array, void *element, uint array_index);
846extern void delete_dynamic(DYNAMIC_ARRAY *array);
847extern void delete_dynamic_element(DYNAMIC_ARRAY *array, uint array_index);
848extern void delete_dynamic_with_callback(DYNAMIC_ARRAY *array, FREE_FUNC f);
849extern void freeze_size(DYNAMIC_ARRAY *array);
850extern int get_index_dynamic(DYNAMIC_ARRAY *array, void *element);
851#define dynamic_array_ptr(array,array_index) ((array)->buffer+(array_index)*(array)->size_of_element)
852#define dynamic_element(array,array_index,type) ((type)((array)->buffer) +(array_index))
853#define push_dynamic(A,B) insert_dynamic((A),(B))
854#define reset_dynamic(array) ((array)->elements= 0)
855#define sort_dynamic(A,cmp) my_qsort((A)->buffer, (A)->elements, (A)->size_of_element, (cmp))
856
857extern my_bool init_dynamic_string(DYNAMIC_STRING *str, const char *init_str,
858 size_t init_alloc,size_t alloc_increment);
859extern my_bool dynstr_append(DYNAMIC_STRING *str, const char *append);
860my_bool dynstr_append_mem(DYNAMIC_STRING *str, const char *append,
861 size_t length);
862extern my_bool dynstr_append_os_quoted(DYNAMIC_STRING *str, const char *append,
863 ...);
864extern my_bool dynstr_append_quoted(DYNAMIC_STRING *str,
865 const char *append, size_t len,
866 char quote);
867extern my_bool dynstr_set(DYNAMIC_STRING *str, const char *init_str);
868extern my_bool dynstr_realloc(DYNAMIC_STRING *str, size_t additional_size);
869extern my_bool dynstr_trunc(DYNAMIC_STRING *str, size_t n);
870extern void dynstr_free(DYNAMIC_STRING *str);
871extern uint32 copy_and_convert_extended(char *to, uint32 to_length,
872 CHARSET_INFO *to_cs,
873 const char *from, uint32 from_length,
874 CHARSET_INFO *from_cs, uint *errors);
875extern void dynstr_reassociate(DYNAMIC_STRING *str, char **res, size_t *length,
876 size_t *alloc_length);
877extern uint32 copy_and_convert_extended(char *to, uint32 to_length,
878 CHARSET_INFO *to_cs,
879 const char *from, uint32 from_length,
880 CHARSET_INFO *from_cs, uint *errors);
881#ifdef HAVE_MLOCK
882extern void *my_malloc_lock(size_t length,myf flags);
883extern void my_free_lock(void *ptr);
884#else
885#define my_malloc_lock(A,B) my_malloc((A),(B))
886#define my_free_lock(A) my_free((A))
887#endif
888#define alloc_root_inited(A) ((A)->min_malloc != 0)
889#define ALLOC_ROOT_MIN_BLOCK_SIZE (MALLOC_OVERHEAD + sizeof(USED_MEM) + 8)
890#define clear_alloc_root(A) do { (A)->free= (A)->used= (A)->pre_alloc= 0; (A)->min_malloc=0;} while(0)
891extern void init_alloc_root(MEM_ROOT *mem_root, const char *name,
892 size_t block_size, size_t pre_alloc_size,
893 myf my_flags);
894extern void *alloc_root(MEM_ROOT *mem_root, size_t Size);
895extern void *multi_alloc_root(MEM_ROOT *mem_root, ...);
896extern void free_root(MEM_ROOT *root, myf MyFLAGS);
897extern void set_prealloc_root(MEM_ROOT *root, char *ptr);
898extern void reset_root_defaults(MEM_ROOT *mem_root, size_t block_size,
899 size_t prealloc_size);
900extern char *strdup_root(MEM_ROOT *root,const char *str);
901static inline char *safe_strdup_root(MEM_ROOT *root, const char *str)
902{
903 return str ? strdup_root(root, str) : 0;
904}
905extern char *strmake_root(MEM_ROOT *root,const char *str,size_t len);
906extern void *memdup_root(MEM_ROOT *root,const void *str, size_t len);
907extern my_bool my_compress(uchar *, size_t *, size_t *);
908extern my_bool my_uncompress(uchar *, size_t , size_t *);
909extern uchar *my_compress_alloc(const uchar *packet, size_t *len,
910 size_t *complen);
911extern void *my_az_allocator(void *dummy, unsigned int items, unsigned int size);
912extern void my_az_free(void *dummy, void *address);
913extern int my_compress_buffer(uchar *dest, size_t *destLen,
914 const uchar *source, size_t sourceLen);
915extern int packfrm(const uchar *, size_t, uchar **, size_t *);
916extern int unpackfrm(uchar **, size_t *, const uchar *);
917
918extern ha_checksum my_checksum(ha_checksum crc, const uchar *mem,
919 size_t count);
920#ifdef DBUG_ASSERT_EXISTS
921extern void my_debug_put_break_here(void);
922#else
923#define my_debug_put_break_here() do {} while(0)
924#endif
925
926extern void my_sleep(ulong m_seconds);
927extern ulong crc32(ulong crc, const uchar *buf, uint len);
928extern uint my_set_max_open_files(uint files);
929void my_free_open_file_info(void);
930
931extern my_bool my_gethwaddr(uchar *to);
932extern int my_getncpus(void);
933
934#define HRTIME_RESOLUTION 1000000ULL /* microseconds */
935typedef struct {ulonglong val;} my_hrtime_t;
936void my_time_init(void);
937extern my_hrtime_t my_hrtime(void);
938
939#ifdef _WIN32
940extern my_hrtime_t my_hrtime_coarse();
941#else
942#define my_hrtime_coarse() my_hrtime()
943#endif
944
945extern ulonglong my_interval_timer(void);
946extern ulonglong my_getcputime(void);
947
948#define microsecond_interval_timer() (my_interval_timer()/1000)
949#define hrtime_to_time(X) ((X).val/HRTIME_RESOLUTION)
950#define hrtime_from_time(X) ((ulonglong)((X)*HRTIME_RESOLUTION))
951#define hrtime_to_double(X) ((X).val/(double)HRTIME_RESOLUTION)
952#define hrtime_sec_part(X) ((ulong)((X).val % HRTIME_RESOLUTION))
953#define my_time(X) hrtime_to_time(my_hrtime_coarse())
954
955#if STACK_DIRECTION < 0
956#define available_stack_size(CUR,END) (long) ((char*)(CUR) - (char*)(END))
957#else
958#define available_stack_size(CUR,END) (long) ((char*)(END) - (char*)(CUR))
959#endif
960
961#ifdef HAVE_SYS_MMAN_H
962#include <sys/mman.h>
963
964#ifndef MAP_NOSYNC
965#define MAP_NOSYNC 0
966#endif
967#ifndef MAP_NORESERVE
968#define MAP_NORESERVE 0 /* For irix and AIX */
969#endif
970
971#ifdef HAVE_MMAP64
972#define my_mmap(a,b,c,d,e,f) mmap64(a,b,c,d,e,f)
973#else
974#define my_mmap(a,b,c,d,e,f) mmap(a,b,c,d,e,f)
975#endif
976#define my_munmap(a,b) munmap((a),(b))
977
978#else
979/* not a complete set of mmap() flags, but only those that nesessary */
980#define PROT_READ 1
981#define PROT_WRITE 2
982#define MAP_NORESERVE 0
983#define MAP_SHARED 0x0001
984#define MAP_PRIVATE 0x0002
985#define MAP_NOSYNC 0x0800
986#define MAP_FAILED ((void *)-1)
987#define MS_SYNC 0x0000
988
989#define HAVE_MMAP
990void *my_mmap(void *, size_t, int, int, int, my_off_t);
991int my_munmap(void *, size_t);
992#endif
993
994/* my_getpagesize */
995#ifdef HAVE_GETPAGESIZE
996#define my_getpagesize() getpagesize()
997#else
998int my_getpagesize(void);
999#endif
1000
1001int my_msync(int, void *, size_t, int);
1002
1003#define MY_UUID_SIZE 16
1004#define MY_UUID_STRING_LENGTH (8+1+4+1+4+1+4+1+12)
1005
1006void my_uuid_init(ulong seed1, ulong seed2);
1007void my_uuid(uchar *guid);
1008void my_uuid2str(const uchar *guid, char *s);
1009void my_uuid_end(void);
1010
1011const char *my_dlerror(const char *dlpath);
1012
1013/* character sets */
1014extern void my_charset_loader_init_mysys(MY_CHARSET_LOADER *loader);
1015extern uint get_charset_number(const char *cs_name, uint cs_flags);
1016extern uint get_collation_number(const char *name);
1017extern const char *get_charset_name(uint cs_number);
1018
1019extern CHARSET_INFO *get_charset(uint cs_number, myf flags);
1020extern CHARSET_INFO *get_charset_by_name(const char *cs_name, myf flags);
1021extern CHARSET_INFO *my_collation_get_by_name(MY_CHARSET_LOADER *loader,
1022 const char *name, myf flags);
1023extern CHARSET_INFO *get_charset_by_csname(const char *cs_name,
1024 uint cs_flags, myf my_flags);
1025extern CHARSET_INFO *my_charset_get_by_name(MY_CHARSET_LOADER *loader,
1026 const char *name,
1027 uint cs_flags, myf my_flags);
1028extern my_bool resolve_charset(const char *cs_name,
1029 CHARSET_INFO *default_cs,
1030 CHARSET_INFO **cs);
1031extern my_bool resolve_collation(const char *cl_name,
1032 CHARSET_INFO *default_cl,
1033 CHARSET_INFO **cl);
1034extern void free_charsets(void);
1035extern char *get_charsets_dir(char *buf);
1036extern my_bool my_charset_same(CHARSET_INFO *cs1, CHARSET_INFO *cs2);
1037extern my_bool init_compiled_charsets(myf flags);
1038extern void add_compiled_collation(struct charset_info_st *cs);
1039extern size_t escape_string_for_mysql(CHARSET_INFO *charset_info,
1040 char *to, size_t to_length,
1041 const char *from, size_t length);
1042extern char *get_tty_password(const char *opt_message);
1043#ifdef __WIN__
1044#define BACKSLASH_MBTAIL
1045/* File system character set */
1046extern CHARSET_INFO *fs_character_set(void);
1047#endif
1048extern size_t escape_quotes_for_mysql(CHARSET_INFO *charset_info,
1049 char *to, size_t to_length,
1050 const char *from, size_t length);
1051
1052extern void thd_increment_bytes_sent(void *thd, size_t length);
1053extern void thd_increment_bytes_received(void *thd, size_t length);
1054extern void thd_increment_net_big_packet_count(void *thd, size_t length);
1055
1056#ifdef __WIN__
1057extern my_bool have_tcpip; /* Is set if tcpip is used */
1058
1059/* implemented in my_windac.c */
1060
1061int my_security_attr_create(SECURITY_ATTRIBUTES **psa, const char **perror,
1062 DWORD owner_rights, DWORD everybody_rights);
1063
1064void my_security_attr_free(SECURITY_ATTRIBUTES *sa);
1065
1066/* implemented in my_conio.c */
1067char* my_cgets(char *string, size_t clen, size_t* plen);
1068
1069#endif
1070
1071#include <mysql/psi/psi.h>
1072
1073#ifdef HAVE_PSI_INTERFACE
1074extern MYSQL_PLUGIN_IMPORT struct PSI_bootstrap *PSI_hook;
1075extern void set_psi_server(PSI *psi);
1076void my_init_mysys_psi_keys(void);
1077#endif
1078
1079struct st_mysql_file;
1080extern struct st_mysql_file *mysql_stdin;
1081C_MODE_END
1082#endif /* _my_sys_h */
1083