/* Copyright (C) 2000 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Note that we can't have assertion on file descriptors; The reason for this is that during mysql shutdown, another thread can close a file we are working on. In this case we should just return read errors from the file descriptior. */ #include <my_global.h> #include "mysql_embed.h" #include "mysql.h" #ifndef HAVE_VIO /* is Vio enabled */ #include <errno.h> #include <my_sys.h> #include <violite.h> #include <my_sys.h> #include <my_net.h> #include <m_string.h> #include <dbug.h> #include <assert.h> #ifndef __WIN__ #define HANDLE void * #endif struct st_vio { enum enum_vio_type type; /* Type of connection */ void *dest_thd; char *packets, **last_packet; char *where_in_packet, *end_of_packet; my_bool reading; MEM_ROOT root; }; /* Initialize the communication buffer */ Vio *vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost) { DBUG_ENTER("vio_new"); Vio * vio; if ((vio= (Vio *) my_malloc(sizeof(*vio),MYF(MY_WME|MY_ZEROFILL)))) { init_alloc_root(&vio->root, 8192, 8192); vio->root.min_malloc = sizeof(char *) + 4; vio->last_packet = &vio->packets; vio->type = type; } DBUG_RETURN(vio); } #ifdef __WIN__ Vio *vio_new_win32pipe(HANDLE hPipe) { return (NULL); } #endif void vio_delete(Vio * vio) { DBUG_ENTER("vio_delete"); if (vio) { if (vio->type != VIO_CLOSED) vio_close(vio); free_root(&vio->root, MYF(0)); my_free((gptr) vio, MYF(0)); } DBUG_VOID_RETURN; } void vio_reset(Vio *vio) { DBUG_ENTER("vio_reset"); free_root(&vio->root, MYF(MY_KEEP_PREALLOC)); vio->packets = vio->where_in_packet = vio->end_of_packet = 0; vio->last_packet = &vio->packets; DBUG_VOID_RETURN; } int vio_errno(Vio *vio __attribute__((unused))) { return socket_errno; /* On Win32 this mapped to WSAGetLastError() */ } int vio_read(Vio * vio, gptr buf, int size) { vio->reading = 1; if (vio->where_in_packet >= vio->end_of_packet) { DBUG_ASSERT(vio->packets); vio->where_in_packet = vio->packets + sizeof(char *) + 4; vio->end_of_packet = vio->where_in_packet + uint4korr(vio->packets + sizeof(char *)); vio->packets = *(char **)vio->packets; } if (vio->where_in_packet + size > vio->end_of_packet) size = vio->end_of_packet - vio->where_in_packet; memcpy(buf, vio->where_in_packet, size); vio->where_in_packet += size; return (size); } int vio_write(Vio * vio, const gptr buf, int size) { DBUG_ENTER("vio_write"); char *packet; if (vio->reading) { vio->reading = 0; vio_reset(vio); } if ((packet = alloc_root(&vio->root, sizeof(char*) + 4 + size))) { *vio->last_packet = packet; vio->last_packet = (char **)packet; *((char **)packet) = 0; /* Set forward link to 0 */ packet += sizeof(char *); int4store(packet, size); memcpy(packet + 4, buf, size); } else size= -1; DBUG_RETURN(size); } int vio_blocking(Vio * vio, my_bool set_blocking_mode, my_bool *old_mode) { return (0); } my_bool vio_is_blocking(Vio * vio) { return(0); } int vio_fastsend(Vio * vio) { return(0); } int vio_keepalive(Vio* vio, my_bool set_keep_alive) { return (0); } my_bool vio_should_retry(Vio * vio __attribute__((unused))) { int en = socket_errno; return (en == SOCKET_EAGAIN || en == SOCKET_EINTR || en == SOCKET_EWOULDBLOCK); } int vio_close(Vio * vio) { return(0); } const char *vio_description(Vio * vio) { return "embedded vio"; } enum enum_vio_type vio_type(Vio* vio) { return VIO_CLOSED; } my_socket vio_fd(Vio* vio) { return 0; } my_bool vio_peer_addr(Vio * vio, char *buf) { return(0); } void vio_in_addr(Vio *vio, struct in_addr *in) { } my_bool vio_poll_read(Vio *vio,uint timeout) { return 0; } int create_vio(NET *net, int separate_thread) { Vio * v = net->vio; if (!v) { v = vio_new(0, separate_thread ? VIO_SHARED_MEMORY : VIO_BUFFER, 0); net->vio = v; } return !v; } void set_thd(Vio *v, void *thd) { if (v) { v -> dest_thd = thd; } } #endif /* HAVE_VIO */