Add tcpsocket.
TODO: * check for getaddrinfo() in configure * fallback if getaddrinfo() is unavailable
This commit is contained in:
parent
0452bfc9ef
commit
c18e55e2ff
6 changed files with 198 additions and 4 deletions
|
@ -14,7 +14,8 @@ SRCS = array.c \
|
|||
range.c \
|
||||
refpool.c \
|
||||
stream.c \
|
||||
string.c
|
||||
string.c \
|
||||
tcpsocket.c
|
||||
|
||||
INCLUDES = ${SRCS:.c=.h} \
|
||||
corefw.h \
|
||||
|
|
|
@ -15,5 +15,6 @@
|
|||
#include "refpool.h"
|
||||
#include "stream.h"
|
||||
#include "string.h"
|
||||
#include "tcpsocket.h"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
|
@ -129,7 +128,7 @@ file_close(void *ptr)
|
|||
close(file->fd);
|
||||
}
|
||||
|
||||
struct cfw_stream_ops stream_ops = {
|
||||
static struct cfw_stream_ops stream_ops = {
|
||||
.read = file_read,
|
||||
.write = file_write,
|
||||
.eof = file_eof,
|
||||
|
|
|
@ -46,11 +46,15 @@ ssize_t
|
|||
cfw_stream_read(void *ptr, void *buf, size_t len)
|
||||
{
|
||||
CFWStream *stream = ptr;
|
||||
ssize_t ret;
|
||||
|
||||
if (stream == NULL || stream->ops == NULL)
|
||||
return -1;
|
||||
|
||||
return stream->ops->read(stream, buf, len);
|
||||
if ((ret = stream->ops->read(stream, buf, len)) < -1)
|
||||
ret = -1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
154
src/tcpsocket.c
Normal file
154
src/tcpsocket.c
Normal file
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* Copyright (c) 2012, Jonathan Schleifer <js@webkeks.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include "stream.h"
|
||||
#include "tcpsocket.h"
|
||||
|
||||
struct CFWTCPSocket {
|
||||
CFWStream stream;
|
||||
int fd;
|
||||
bool eof;
|
||||
};
|
||||
|
||||
static ssize_t
|
||||
sock_read(void *ptr, void *buf, size_t len)
|
||||
{
|
||||
CFWTCPSocket *sock = ptr;
|
||||
ssize_t ret;
|
||||
|
||||
if ((ret = recv(sock->fd, buf, len, 0)) == 0)
|
||||
sock->eof = true;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool
|
||||
sock_write(void *ptr, const void *buf, size_t len)
|
||||
{
|
||||
CFWTCPSocket *sock = ptr;
|
||||
ssize_t ret;
|
||||
|
||||
if ((ret = send(sock->fd, buf, len, 0)) < len)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
sock_eof(void *ptr)
|
||||
{
|
||||
CFWTCPSocket *sock = ptr;
|
||||
|
||||
return sock->eof;
|
||||
}
|
||||
|
||||
static void
|
||||
sock_close(void *ptr)
|
||||
{
|
||||
CFWTCPSocket *sock = ptr;
|
||||
|
||||
if (sock->fd != -1)
|
||||
close(sock->fd);
|
||||
}
|
||||
|
||||
static struct cfw_stream_ops stream_ops = {
|
||||
.read = sock_read,
|
||||
.write = sock_write,
|
||||
.eof = sock_eof,
|
||||
.close = sock_close
|
||||
};
|
||||
|
||||
static bool
|
||||
ctor(void *ptr, va_list args)
|
||||
{
|
||||
CFWTCPSocket *sock = ptr;
|
||||
|
||||
sock->fd = -1;
|
||||
sock->stream.ops = &stream_ops;
|
||||
sock->eof = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
dtor(void *ptr)
|
||||
{
|
||||
cfw_stream_close(ptr);
|
||||
}
|
||||
|
||||
bool
|
||||
cfw_tcpsocket_connect(CFWTCPSocket *sock, const char *host, uint16_t port)
|
||||
{
|
||||
struct addrinfo hints, *res, *res0;
|
||||
char portstr[7];
|
||||
|
||||
if (sock->fd != -1)
|
||||
return false;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
snprintf(portstr, 7, "%" PRIu16, port);
|
||||
|
||||
if (getaddrinfo(host, portstr, &hints, &res0))
|
||||
return false;
|
||||
|
||||
for (res = res0; res != NULL; res = res->ai_next) {
|
||||
if ((sock->fd = socket(res->ai_family, res->ai_socktype,
|
||||
res->ai_protocol)) == -1)
|
||||
continue;
|
||||
|
||||
if (connect(sock->fd, res->ai_addr, res->ai_addrlen) == -1) {
|
||||
close(sock->fd);
|
||||
sock->fd = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
freeaddrinfo(res0);
|
||||
|
||||
return (sock->fd != -1);
|
||||
}
|
||||
|
||||
static CFWClass class = {
|
||||
.name = "CFWTCPSocket",
|
||||
.size = sizeof(CFWTCPSocket),
|
||||
.ctor = ctor,
|
||||
.dtor = dtor
|
||||
};
|
||||
CFWClass *cfw_tcpsocket = &class;
|
35
src/tcpsocket.h
Normal file
35
src/tcpsocket.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2012, Jonathan Schleifer <js@webkeks.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __COREFW_TCPSOCKET_H__
|
||||
#define __COREFW_TCPSOCKET_H__
|
||||
|
||||
typedef struct CFWTCPSocket CFWTCPSocket;
|
||||
|
||||
extern CFWClass *cfw_tcpsocket;
|
||||
extern bool cfw_tcpsocket_connect(CFWTCPSocket*, const char*, uint16_t);
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue