181 lines
4.0 KiB
C
181 lines
4.0 KiB
C
|
/* $Id$
|
||
|
|
||
|
Part of SWI-Prolog
|
||
|
|
||
|
Author: Jan Wielemaker
|
||
|
E-mail: J.Wielemaker@uva.nl
|
||
|
WWW: http://www.swi-prolog.org
|
||
|
Copyright (C): 2000-2008, University of Amsterdam
|
||
|
|
||
|
This library is free software; you can redistribute it and/or
|
||
|
modify it under the terms of the GNU Lesser General Public
|
||
|
License as published by the Free Software Foundation; either
|
||
|
version 2.1 of the License, or (at your option) any later version.
|
||
|
|
||
|
This library 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
|
||
|
Lesser General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU Lesser General Public
|
||
|
License along with this library; if not, write to the Free Software
|
||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||
|
*/
|
||
|
|
||
|
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||
|
Shared stuff between the normal socket interface and the TIPC one.
|
||
|
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||
|
|
||
|
|
||
|
/*******************************
|
||
|
* IO-STREAM STUFF *
|
||
|
*******************************/
|
||
|
|
||
|
#define fdFromHandle(p) ((nbio_sock_t)((long)(p)))
|
||
|
|
||
|
static ssize_t
|
||
|
tcp_read_handle(void *handle, char *buf, size_t bufSize)
|
||
|
{ nbio_sock_t sock = fdFromHandle(handle);
|
||
|
|
||
|
return nbio_read(sock, buf, bufSize);
|
||
|
}
|
||
|
|
||
|
|
||
|
static ssize_t
|
||
|
tcp_write_handle(void *handle, char *buf, size_t bufSize)
|
||
|
{ nbio_sock_t sock = fdFromHandle(handle);
|
||
|
|
||
|
return nbio_write(sock, buf, bufSize);
|
||
|
}
|
||
|
|
||
|
|
||
|
static long
|
||
|
tcp_seek_null(void *handle, long offset, int whence)
|
||
|
{ return -1;
|
||
|
}
|
||
|
|
||
|
|
||
|
static int
|
||
|
tcp_close_input_handle(void *handle)
|
||
|
{ nbio_sock_t socket = fdFromHandle(handle);
|
||
|
|
||
|
return nbio_close_input(socket);
|
||
|
}
|
||
|
|
||
|
|
||
|
static int
|
||
|
tcp_close_output_handle(void *handle)
|
||
|
{ nbio_sock_t socket = fdFromHandle(handle);
|
||
|
|
||
|
return nbio_close_output(socket);
|
||
|
}
|
||
|
|
||
|
|
||
|
static int
|
||
|
tcp_control(void *handle, int action, void *arg)
|
||
|
{ nbio_sock_t socket = fdFromHandle(handle);
|
||
|
|
||
|
switch(action)
|
||
|
{ case SIO_GETFILENO:
|
||
|
{ SOCKET fd = nbio_fd(socket);
|
||
|
SOCKET *fdp = arg;
|
||
|
*fdp = fd;
|
||
|
return 0;
|
||
|
}
|
||
|
case SIO_LASTERROR:
|
||
|
{ const char *s;
|
||
|
|
||
|
if ( (s=nbio_last_error(socket)) )
|
||
|
{ const char **sp = arg;
|
||
|
*sp = s;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
return -1;
|
||
|
}
|
||
|
case SIO_SETENCODING:
|
||
|
case SIO_FLUSHOUTPUT:
|
||
|
return 0;
|
||
|
default:
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
static IOFUNCTIONS readFunctions =
|
||
|
{ tcp_read_handle,
|
||
|
tcp_write_handle,
|
||
|
tcp_seek_null,
|
||
|
tcp_close_input_handle,
|
||
|
tcp_control
|
||
|
};
|
||
|
|
||
|
|
||
|
static IOFUNCTIONS writeFunctions =
|
||
|
{ tcp_read_handle,
|
||
|
tcp_write_handle,
|
||
|
tcp_seek_null,
|
||
|
tcp_close_output_handle,
|
||
|
tcp_control
|
||
|
};
|
||
|
|
||
|
|
||
|
static foreign_t
|
||
|
pl_open_socket(term_t Socket, term_t Read, term_t Write)
|
||
|
{ IOSTREAM *in, *out;
|
||
|
int socket;
|
||
|
void *handle;
|
||
|
|
||
|
if ( !tcp_get_socket(Socket, &socket) )
|
||
|
return FALSE;
|
||
|
handle = (void *)(long)socket;
|
||
|
|
||
|
in = Snew(handle, SIO_INPUT|SIO_RECORDPOS|SIO_FBUF, &readFunctions);
|
||
|
in->encoding = ENC_OCTET;
|
||
|
if ( !PL_open_stream(Read, in) )
|
||
|
return FALSE;
|
||
|
nbio_setopt(socket, TCP_INSTREAM, in);
|
||
|
|
||
|
if ( !(nbio_get_flags(socket) & PLSOCK_LISTEN) )
|
||
|
{ out = Snew(handle, SIO_OUTPUT|SIO_RECORDPOS|SIO_FBUF, &writeFunctions);
|
||
|
out->encoding = ENC_OCTET;
|
||
|
if ( !PL_open_stream(Write, out) )
|
||
|
return FALSE;
|
||
|
nbio_setopt(socket, TCP_OUTSTREAM, out);
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
static foreign_t
|
||
|
pl_listen(term_t Sock, term_t BackLog)
|
||
|
{ int socket;
|
||
|
int backlog;
|
||
|
|
||
|
if ( !tcp_get_socket(Sock, &socket) )
|
||
|
return FALSE;
|
||
|
|
||
|
if ( !PL_get_integer(BackLog, &backlog) )
|
||
|
return pl_error(NULL, 0, NULL, ERR_ARGTYPE, -1, BackLog, "integer");
|
||
|
|
||
|
if ( nbio_listen(socket, backlog) < 0 )
|
||
|
return FALSE;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
static foreign_t
|
||
|
pl_close_socket(term_t socket)
|
||
|
{ int sock;
|
||
|
|
||
|
if ( !tcp_get_socket(socket, &sock) )
|
||
|
return FALSE;
|
||
|
|
||
|
if ( nbio_closesocket(sock) < 0 )
|
||
|
return nbio_error(errno, TCP_ERRNO);;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|