clib package
This commit is contained in:
180
packages/clib/sockcommon.c
Normal file
180
packages/clib/sockcommon.c
Normal file
@@ -0,0 +1,180 @@
|
||||
/* $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;
|
||||
}
|
Reference in New Issue
Block a user