This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
yap-6.3/packages/clib/sockcommon.c
Vítor Santos Costa 40febfdf9b clib package
2010-06-17 00:40:25 +01:00

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;
}