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 \
|
range.c \
|
||||||
refpool.c \
|
refpool.c \
|
||||||
stream.c \
|
stream.c \
|
||||||
string.c
|
string.c \
|
||||||
|
tcpsocket.c
|
||||||
|
|
||||||
INCLUDES = ${SRCS:.c=.h} \
|
INCLUDES = ${SRCS:.c=.h} \
|
||||||
corefw.h \
|
corefw.h \
|
||||||
|
|
|
@ -15,5 +15,6 @@
|
||||||
#include "refpool.h"
|
#include "refpool.h"
|
||||||
#include "stream.h"
|
#include "stream.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
#include "tcpsocket.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
@ -129,7 +128,7 @@ file_close(void *ptr)
|
||||||
close(file->fd);
|
close(file->fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct cfw_stream_ops stream_ops = {
|
static struct cfw_stream_ops stream_ops = {
|
||||||
.read = file_read,
|
.read = file_read,
|
||||||
.write = file_write,
|
.write = file_write,
|
||||||
.eof = file_eof,
|
.eof = file_eof,
|
||||||
|
|
|
@ -46,11 +46,15 @@ ssize_t
|
||||||
cfw_stream_read(void *ptr, void *buf, size_t len)
|
cfw_stream_read(void *ptr, void *buf, size_t len)
|
||||||
{
|
{
|
||||||
CFWStream *stream = ptr;
|
CFWStream *stream = ptr;
|
||||||
|
ssize_t ret;
|
||||||
|
|
||||||
if (stream == NULL || stream->ops == NULL)
|
if (stream == NULL || stream->ops == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return stream->ops->read(stream, buf, len);
|
if ((ret = stream->ops->read(stream, buf, len)) < -1)
|
||||||
|
ret = -1;
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
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