vio.c 6.13 KB
Newer Older
unknown's avatar
unknown committed
1 2
/* Copyright (C) 2000 MySQL AB

3 4 5 6
   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.
unknown's avatar
unknown committed
7

8 9 10 11
   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.
unknown's avatar
unknown committed
12

13 14 15 16 17 18 19 20 21 22 23
   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.
*/

24
#include "vio_priv.h"
25 26

/*
unknown's avatar
unknown committed
27
 * Helper to fill most of the Vio* with defaults.
28 29
 */

unknown's avatar
unknown committed
30
void vio_reset(Vio* vio, enum enum_vio_type type,
31 32 33
		      my_socket sd, HANDLE hPipe,
		      my_bool localhost)
{
unknown's avatar
unknown committed
34 35
  DBUG_ENTER("vio_reset");
  DBUG_PRINT("enter", ("type=%d  sd=%d  localhost=%d", type, sd, localhost));
unknown's avatar
merge  
unknown committed
36

37
  bzero((char*) vio, sizeof(*vio));
38 39 40 41
  vio->type	= type;
  vio->sd	= sd;
  vio->hPipe	= hPipe;
  vio->localhost= localhost;
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
#ifdef HAVE_VIO  
#ifdef __WIN__ 
  if (type == VIO_TYPE_NAMEDPIPE)
  {
    vio->viodelete	=vio_delete;
    vio->vioerrno	=vio_errno;
    vio->read           =vio_read_pipe;
    vio->write          =vio_write_pipe;
    vio->fastsend	=vio_fastsend;
    vio->viokeepalive	=vio_keepalive;
    vio->should_retry	=vio_should_retry;
    vio->vioclose	=vio_close_pipe;
    vio->peer_addr	=vio_peer_addr;
    vio->in_addr	=vio_in_addr;
    vio->vioblocking	=vio_blocking;
    vio->is_blocking	=vio_is_blocking;
58
    vio->timeout	=vio_ignore_timeout;
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
  }
  else					/* default is VIO_TYPE_TCPIP */
#endif
#ifdef HAVE_SMEM 
  if (type == VIO_TYPE_SHARED_MEMORY)
  {
    vio->viodelete	=vio_delete;
    vio->vioerrno	=vio_errno;
    vio->read           =vio_read_shared_memory;
    vio->write          =vio_write_shared_memory;
    vio->fastsend	=vio_fastsend;
    vio->viokeepalive	=vio_keepalive;
    vio->should_retry	=vio_should_retry;
    vio->vioclose	=vio_close_shared_memory;
    vio->peer_addr	=vio_peer_addr;
    vio->in_addr	=vio_in_addr;
    vio->vioblocking	=vio_blocking;
    vio->is_blocking	=vio_is_blocking;
77
    vio->timeout	=vio_ignore_timeout;
78 79 80
  }
  else
#endif   
unknown's avatar
merge  
unknown committed
81
#ifdef HAVE_OPENSSL 
82 83 84 85 86 87 88 89 90 91 92 93
  if (type == VIO_TYPE_SSL)
  {
    vio->viodelete	=vio_ssl_delete;
    vio->vioerrno	=vio_ssl_errno;
    vio->read		=vio_ssl_read;
    vio->write		=vio_ssl_write;
    vio->fastsend	=vio_ssl_fastsend;
    vio->viokeepalive	=vio_ssl_keepalive;
    vio->should_retry	=vio_ssl_should_retry;
    vio->vioclose	=vio_ssl_close;
    vio->peer_addr	=vio_ssl_peer_addr;
    vio->in_addr	=vio_ssl_in_addr;
94
    vio->vioblocking	=vio_ssl_blocking;
unknown's avatar
merge  
unknown committed
95
    vio->is_blocking	=vio_is_blocking;
96
    vio->timeout	=vio_ssl_timeout;
97 98
  }
  else					/* default is VIO_TYPE_TCPIP */
unknown's avatar
unknown committed
99
#endif /* HAVE_OPENSSL */
100 101 102 103 104 105 106 107 108 109 110
  {
    vio->viodelete	=vio_delete;
    vio->vioerrno	=vio_errno;
    vio->read		=vio_read;
    vio->write		=vio_write;
    vio->fastsend	=vio_fastsend;
    vio->viokeepalive	=vio_keepalive;
    vio->should_retry	=vio_should_retry;
    vio->vioclose	=vio_close;
    vio->peer_addr	=vio_peer_addr;
    vio->in_addr	=vio_in_addr;
unknown's avatar
merge  
unknown committed
111 112
    vio->vioblocking	=vio_blocking;
    vio->is_blocking	=vio_is_blocking;
113
    vio->timeout	=vio_timeout;
114
  }
115
#endif /* HAVE_VIO */
unknown's avatar
merge  
unknown committed
116
  DBUG_VOID_RETURN;
117 118
}

119

120 121
/* Open the socket or TCP/IP connection and read the fnctl() status */

unknown's avatar
unknown committed
122
Vio *vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost)
123
{
unknown's avatar
unknown committed
124
  Vio *vio;
125 126
  DBUG_ENTER("vio_new");
  DBUG_PRINT("enter", ("sd=%d", sd));
unknown's avatar
unknown committed
127
  if ((vio = (Vio*) my_malloc(sizeof(*vio),MYF(MY_WME))))
128 129 130 131 132
  {
    vio_reset(vio, type, sd, 0, localhost);
    sprintf(vio->desc,
	    (vio->type == VIO_TYPE_SOCKET ? "socket (%d)" : "TCP/IP (%d)"),
	    vio->sd);
133
#if !defined(___WIN__) && !defined(__EMX__) && !defined(OS2)
134
#if !defined(NO_FCNTL_NONBLOCK)
unknown's avatar
unknown committed
135 136 137
#if defined(__FreeBSD__)
    fcntl(sd, F_SETFL, vio->fcntl_mode); /* Yahoo! FreeBSD patch */
#endif
138 139 140 141
    vio->fcntl_mode = fcntl(sd, F_GETFL);
#elif defined(HAVE_SYS_IOCTL_H)			/* hpux */
    /* Non blocking sockets doesn't work good on HPUX 11.0 */
    (void) ioctl(sd,FIOSNBIO,0);
142
    vio->fcntl_mode &= ~O_NONBLOCK;
143 144 145 146 147 148
#endif
#else /* !defined(__WIN__) && !defined(__EMX__) */
    {
      /* set to blocking mode by default */
      ulong arg=0, r;
      r = ioctlsocket(sd,FIONBIO,(void*) &arg, sizeof(arg));
149
      vio->fcntl_mode &= ~O_NONBLOCK;
150 151 152 153 154 155 156 157 158
    }
#endif
  }
  DBUG_RETURN(vio);
}


#ifdef __WIN__

unknown's avatar
unknown committed
159
Vio *vio_new_win32pipe(HANDLE hPipe)
160
{
unknown's avatar
unknown committed
161
  Vio *vio;
162
  DBUG_ENTER("vio_new_handle");
unknown's avatar
unknown committed
163
  if ((vio = (Vio*) my_malloc(sizeof(Vio),MYF(MY_WME))))
164 165 166 167 168 169 170
  {
    vio_reset(vio, VIO_TYPE_NAMEDPIPE, 0, hPipe, TRUE);
    strmov(vio->desc, "named pipe");
  }
  DBUG_RETURN(vio);
}

171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
#ifdef HAVE_SMEM
Vio *vio_new_win32shared_memory(NET *net,HANDLE handle_file_map, HANDLE handle_map,
                                HANDLE event_server_wrote, HANDLE event_server_read,
                                HANDLE event_client_wrote, HANDLE event_client_read)
{
  Vio *vio;
  DBUG_ENTER("vio_new_win32shared_memory");
  if ((vio = (Vio*) my_malloc(sizeof(Vio),MYF(MY_WME))))
  {
    vio_reset(vio, VIO_TYPE_SHARED_MEMORY, 0, 0, TRUE);
    vio->handle_file_map = handle_file_map;
    vio->handle_map = handle_map;
    vio->event_server_wrote = event_server_wrote;
    vio->event_server_read = event_server_read;
    vio->event_client_wrote = event_client_wrote;
    vio->event_client_read = event_client_read;
    vio->shared_memory_remain = 0;
    vio->shared_memory_pos = handle_map;
    vio->net = net;
    strmov(vio->desc, "shared memory");
  }
  DBUG_RETURN(vio);
}
#endif
195
#endif
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211

void vio_delete(Vio* vio)
{
  /* It must be safe to delete null pointers. */
  /* This matches the semantics of C++'s delete operator. */
  if (vio)
  {
    if (vio->type != VIO_CLOSED)
#ifdef HAVE_VIO /*WAX*/
      vio->vioclose(vio);
#else
      vio_close(vio);
#endif
    my_free((gptr) vio,MYF(0));
  }
}