change API to align with POSIX
This commit is contained in:
parent
09281732e9
commit
2afb7741d0
|
@ -2,16 +2,21 @@ cmake_minimum_required(VERSION 3.10.0)
|
|||
project(bsock C)
|
||||
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
set(CFLAGS -Wall -Wextra -Werror -std=c17 -march=native -O2 -g)
|
||||
set(LIBVER 1.0.0)
|
||||
set(CFLAGS -Wall -Wextra -Werror -std=c17 -march=native -O3 -g -DNDEBUG)
|
||||
set(CFLAGS_DBG -Wall -Wextra -Werror -std=c17 -march=native -Og -g)
|
||||
set(LIBVER 1.1.0)
|
||||
|
||||
add_library(bsock SHARED bsock.c ringbuf.c)
|
||||
target_compile_options(bsock PRIVATE ${CFLAGS})
|
||||
target_include_directories(bsock PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
add_library(bsock_debug SHARED bsock.c ringbuf.c)
|
||||
target_compile_options(bsock_debug PRIVATE ${CFLAGS_DBG})
|
||||
target_include_directories(bsock_debug PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
add_executable(test test.c)
|
||||
target_link_libraries(test PRIVATE bsock)
|
||||
target_compile_options(test PRIVATE ${CFLAGS})
|
||||
target_link_libraries(test PRIVATE bsock_debug)
|
||||
target_compile_options(test PRIVATE ${CFLAGS_DBG})
|
||||
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/bsock.pc.in
|
||||
|
|
16
bsock.c
16
bsock.c
|
@ -4,25 +4,25 @@
|
|||
#include "ringbuf.h"
|
||||
|
||||
static ssize_t
|
||||
bsock_posix_io_read(void * ctx, void *buf, size_t nbytes)
|
||||
bsock_posix_io_read(void *ctx, void *buf, size_t nbytes)
|
||||
{
|
||||
return read((int)(uintptr_t)ctx, buf, nbytes);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
bsock_posix_io_write(void * ctx, void *buf, size_t nbytes)
|
||||
bsock_posix_io_write(void *ctx, void *buf, size_t nbytes)
|
||||
{
|
||||
return write((int)(uintptr_t)ctx, buf, nbytes);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
bsock_posix_io_readv(void * ctx, const struct iovec *iovec, int nvec)
|
||||
bsock_posix_io_readv(void *ctx, const struct iovec *iovec, int nvec)
|
||||
{
|
||||
return readv((int)(uintptr_t)ctx, iovec, nvec);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
bsock_posix_io_writev(void * ctx, const struct iovec *iovec, int nvec)
|
||||
bsock_posix_io_writev(void *ctx, const struct iovec *iovec, int nvec)
|
||||
{
|
||||
return writev((int)(uintptr_t)ctx, iovec, nvec);
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ bsock_io_posix()
|
|||
}
|
||||
|
||||
struct bsock *
|
||||
bsock_create(void * io_ctx, struct bsock_ringbuf_io *io, size_t rbuf_sz, size_t wbuf_sz)
|
||||
bsock_create(void *io_ctx, struct bsock_ringbuf_io *io, size_t rbuf_sz, size_t wbuf_sz)
|
||||
{
|
||||
struct bsock *bsock = malloc(sizeof(struct bsock));
|
||||
if (bsock == NULL) {
|
||||
|
@ -104,13 +104,15 @@ bsock_peek(struct bsock *bsock, char *buf, size_t len)
|
|||
int
|
||||
bsock_flush(struct bsock *bsock)
|
||||
{
|
||||
return bsock_ringbuf_flush(&bsock->wbuf, bsock->io_ctx, &bsock->io, bsock_ringbuf_size(&bsock->wbuf));
|
||||
return bsock_ringbuf_flush(&bsock->wbuf, bsock->io_ctx, &bsock->io,
|
||||
bsock_ringbuf_size(&bsock->wbuf));
|
||||
}
|
||||
|
||||
int
|
||||
bsock_poll(struct bsock *bsock)
|
||||
{
|
||||
return bsock_ringbuf_poll(&bsock->rbuf, bsock->io_ctx, &bsock->io, bsock_ringbuf_free_size(&bsock->rbuf));
|
||||
return bsock_ringbuf_poll(&bsock->rbuf, bsock->io_ctx, &bsock->io,
|
||||
bsock_ringbuf_free_size(&bsock->rbuf));
|
||||
}
|
||||
|
||||
int
|
||||
|
|
18
bsock.h
18
bsock.h
|
@ -34,15 +34,15 @@ bsock_init(struct bsock *bsock, void *io_ctx, struct bsock_ringbuf_io *io,
|
|||
|
||||
/**
|
||||
* returns:
|
||||
* success: 0
|
||||
* failure: -1 + errno (ERANGE if not enough data present)
|
||||
* success: # of bytes written
|
||||
* failure: -1 + errno
|
||||
*/
|
||||
int bsock_write(struct bsock *sock, char *buf, size_t len);
|
||||
|
||||
/**
|
||||
* returns:
|
||||
* success: 0
|
||||
* failure: -1 + errno (ERANGE if not enough data present)
|
||||
* success: # of bytes read
|
||||
* failure: -1 + errno
|
||||
*/
|
||||
int bsock_read(struct bsock *sock, char *buf, size_t len);
|
||||
|
||||
|
@ -52,28 +52,28 @@ int bsock_read(struct bsock *sock, char *buf, size_t len);
|
|||
int bsock_read_avail_size(struct bsock *sock);
|
||||
|
||||
/**
|
||||
* returns: # of bytes available for write
|
||||
* returns: # of bytes available for write before forcing a flush
|
||||
*/
|
||||
int bsock_write_avail_size(struct bsock *sock);
|
||||
|
||||
/**
|
||||
* returns:
|
||||
* success: 0
|
||||
* failure: -1 + errno (ERANGE if not enough data present)
|
||||
* success: # of bytes read
|
||||
* failure: -1 + errno
|
||||
*/
|
||||
int bsock_peek(struct bsock *sock, char *buf, size_t len);
|
||||
|
||||
/**
|
||||
* returns:
|
||||
* success: # of bytes polled
|
||||
* failure: -1 + errno (ERANGE if not enough data present)
|
||||
* failure: -1 + errno
|
||||
*/
|
||||
int bsock_poll(struct bsock *sock);
|
||||
|
||||
/**
|
||||
* returns:
|
||||
* success: # of bytes flushed
|
||||
* failure: -1 + errno (ERANGE if not enough data present)
|
||||
* failure: -1 + errno
|
||||
*/
|
||||
int bsock_flush(struct bsock *sock);
|
||||
|
||||
|
|
76
ringbuf.c
76
ringbuf.c
|
@ -27,9 +27,9 @@ bsock_ringbuf_wrap_ptr(struct bsock_ringbuf *rb, char *ptr)
|
|||
static void
|
||||
bsock_ringbuf_peek_nochk(struct bsock_ringbuf *rb, char *buf, size_t len)
|
||||
{
|
||||
assert(len <= rb->sz);
|
||||
assert(len <= rb->sz && len > 0);
|
||||
|
||||
if (rb->end > rb->start) {
|
||||
if (rb->end >= rb->start) {
|
||||
// no wrapping
|
||||
memcpy(buf, rb->start, len);
|
||||
} else {
|
||||
|
@ -47,37 +47,52 @@ bsock_ringbuf_peek_nochk(struct bsock_ringbuf *rb, char *buf, size_t len)
|
|||
int
|
||||
bsock_ringbuf_peek(struct bsock_ringbuf *rb, char *buf, size_t len)
|
||||
{
|
||||
if (len > rb->sz) {
|
||||
errno = ERANGE;
|
||||
return -1;
|
||||
if (len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bsock_ringbuf_peek_nochk(rb, buf, len);
|
||||
return 0;
|
||||
if (len > rb->sz) {
|
||||
len = rb->sz;
|
||||
}
|
||||
|
||||
if (len > 0) {
|
||||
bsock_ringbuf_peek_nochk(rb, buf, len);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int
|
||||
bsock_ringbuf_read(struct bsock_ringbuf *rb, char *buf, size_t len)
|
||||
{
|
||||
if (len > rb->sz) {
|
||||
errno = ERANGE;
|
||||
return -1;
|
||||
if (len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bsock_ringbuf_peek_nochk(rb, buf, len);
|
||||
rb->start = bsock_ringbuf_wrap_ptr(rb, rb->start + len);
|
||||
rb->sz -= len;
|
||||
return 0;
|
||||
if (len > rb->sz) {
|
||||
len = rb->sz;
|
||||
}
|
||||
|
||||
if (len > 0) {
|
||||
bsock_ringbuf_peek_nochk(rb, buf, len);
|
||||
rb->start = bsock_ringbuf_wrap_ptr(rb, rb->start + len);
|
||||
rb->sz -= len;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int
|
||||
bsock_ringbuf_write(struct bsock_ringbuf *rb, void * ctx, struct bsock_ringbuf_io * io, char *buf, size_t len)
|
||||
bsock_ringbuf_write(struct bsock_ringbuf *rb, void *ctx, struct bsock_ringbuf_io *io, char *buf,
|
||||
size_t len)
|
||||
{
|
||||
if (len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t free_sz = rb->max_sz - rb->sz;
|
||||
if (len > free_sz) {
|
||||
int ret = bsock_ringbuf_flush(rb, ctx, io, rb->sz);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
assert(rb->sz == 0);
|
||||
|
@ -102,19 +117,23 @@ bsock_ringbuf_write(struct bsock_ringbuf *rb, void * ctx, struct bsock_ringbuf_i
|
|||
rb->sz += len;
|
||||
rb->end = bsock_ringbuf_wrap_ptr(rb, rb->end + len);
|
||||
|
||||
return 0;
|
||||
return len;
|
||||
}
|
||||
|
||||
int
|
||||
bsock_ringbuf_poll(struct bsock_ringbuf *rb, void * ctx, struct bsock_ringbuf_io * io, size_t len)
|
||||
bsock_ringbuf_poll(struct bsock_ringbuf *rb, void *ctx, struct bsock_ringbuf_io *io, size_t len)
|
||||
{
|
||||
size_t free_sz = rb->max_sz - rb->sz;
|
||||
if (len > free_sz) {
|
||||
errno = ERANGE;
|
||||
return -1;
|
||||
|
||||
if (len == 0 || free_sz == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
if (len > free_sz) {
|
||||
len = free_sz;
|
||||
}
|
||||
|
||||
int ret;
|
||||
if (rb->end >= rb->start) {
|
||||
// no wrapping
|
||||
size_t rem_size = rb->buf + rb->max_sz - rb->end;
|
||||
|
@ -141,14 +160,17 @@ bsock_ringbuf_poll(struct bsock_ringbuf *rb, void * ctx, struct bsock_ringbuf_io
|
|||
}
|
||||
|
||||
int
|
||||
bsock_ringbuf_flush(struct bsock_ringbuf *rb, void * ctx, struct bsock_ringbuf_io * io, size_t len)
|
||||
bsock_ringbuf_flush(struct bsock_ringbuf *rb, void *ctx, struct bsock_ringbuf_io *io, size_t len)
|
||||
{
|
||||
if (len > rb->sz) {
|
||||
errno = ERANGE;
|
||||
return -1;
|
||||
if (rb->sz == 0 || len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
if (len > rb->sz) {
|
||||
len = rb->sz;
|
||||
}
|
||||
|
||||
int ret;
|
||||
if (rb->end >= rb->start) {
|
||||
// no wrapping
|
||||
ret = io->write(ctx, rb->start, len);
|
||||
|
|
20
ringbuf.h
20
ringbuf.h
|
@ -1,15 +1,17 @@
|
|||
#pragma once
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
/* Both functions should return -1 on error otherwise the # of bytes written. errno should be used to set the error code */
|
||||
typedef ssize_t (*bsock_ringbuf_io_fn) (void * ctx, void * buf, size_t nbytes);
|
||||
typedef ssize_t (*bsock_ringbuf_iov_fn) (void * ctx, const struct iovec *iov, int iovcnt);
|
||||
/* Both functions should return -1 on error otherwise the # of bytes written. errno should be used
|
||||
* to set the error code */
|
||||
typedef ssize_t (*bsock_ringbuf_io_fn)(void *ctx, void *buf, size_t nbytes);
|
||||
typedef ssize_t (*bsock_ringbuf_iov_fn)(void *ctx, const struct iovec *iov, int iovcnt);
|
||||
|
||||
struct bsock_ringbuf_io {
|
||||
bsock_ringbuf_io_fn read;
|
||||
|
@ -26,7 +28,6 @@ struct bsock_ringbuf {
|
|||
size_t max_sz;
|
||||
};
|
||||
|
||||
|
||||
static inline size_t
|
||||
bsock_ringbuf_size(struct bsock_ringbuf *rb)
|
||||
{
|
||||
|
@ -74,18 +75,21 @@ int bsock_ringbuf_read(struct bsock_ringbuf *rb, char *buf, size_t len);
|
|||
* success: # of bytes written
|
||||
* failure: -1 + errno
|
||||
*/
|
||||
int bsock_ringbuf_write(struct bsock_ringbuf *rb, void * ctx, struct bsock_ringbuf_io * io, char *buf, size_t len);
|
||||
int bsock_ringbuf_write(struct bsock_ringbuf *rb, void *ctx, struct bsock_ringbuf_io *io, char *buf,
|
||||
size_t len);
|
||||
|
||||
/**
|
||||
* returns:
|
||||
* success: # of bytes read
|
||||
* failure: -1 + errno (ERANGE if not enough data present)
|
||||
*/
|
||||
int bsock_ringbuf_poll(struct bsock_ringbuf *rb, void * ctx, struct bsock_ringbuf_io *io, size_t len);
|
||||
int bsock_ringbuf_poll(struct bsock_ringbuf *rb, void *ctx, struct bsock_ringbuf_io *io,
|
||||
size_t len);
|
||||
|
||||
/**
|
||||
* returns:
|
||||
* success: # of bytes written
|
||||
* failure: -1 + errno (ERANGE if not enough data present)
|
||||
*/
|
||||
int bsock_ringbuf_flush(struct bsock_ringbuf *rb, void * ctx, struct bsock_ringbuf_io *io, size_t len);
|
||||
int bsock_ringbuf_flush(struct bsock_ringbuf *rb, void *ctx, struct bsock_ringbuf_io *io,
|
||||
size_t len);
|
||||
|
|
27
test.c
27
test.c
|
@ -5,7 +5,7 @@
|
|||
#include "ringbuf.h"
|
||||
|
||||
static int
|
||||
ringbuf_verify(struct bsock_ringbuf *buf, char * start, size_t sz)
|
||||
ringbuf_verify(struct bsock_ringbuf *buf, char *start, size_t sz)
|
||||
{
|
||||
int ret = 1;
|
||||
|
||||
|
@ -22,11 +22,12 @@ ringbuf_verify(struct bsock_ringbuf *buf, char * start, size_t sz)
|
|||
}
|
||||
|
||||
static void
|
||||
assert_write(struct bsock_ringbuf *rbuf, void * ctx, struct bsock_ringbuf_io * io, char *buf, size_t sz)
|
||||
assert_write(struct bsock_ringbuf *rbuf, void *ctx, struct bsock_ringbuf_io *io, char *buf,
|
||||
size_t sz)
|
||||
{
|
||||
char *start = rbuf->start;
|
||||
size_t ssz = rbuf->sz;
|
||||
assert(bsock_ringbuf_write(rbuf, ctx, io, buf, sz) == 0);
|
||||
assert(bsock_ringbuf_write(rbuf, ctx, io, buf, sz) == (int)sz);
|
||||
assert(ringbuf_verify(rbuf, start, ssz + sz));
|
||||
}
|
||||
|
||||
|
@ -35,7 +36,7 @@ assert_read(struct bsock_ringbuf *rbuf, char *buf, size_t sz)
|
|||
{
|
||||
char *start = rbuf->start;
|
||||
size_t ssz = rbuf->sz;
|
||||
assert(bsock_ringbuf_read(rbuf, buf, sz) == 0);
|
||||
assert(bsock_ringbuf_read(rbuf, buf, sz) == (int)(sz));
|
||||
if (start + sz > rbuf->buf + rbuf->max_sz) {
|
||||
start = start + sz - rbuf->max_sz;
|
||||
} else {
|
||||
|
@ -77,14 +78,13 @@ bsock_test(void)
|
|||
printf("ringbuf - read overflow\n");
|
||||
memset(buf3, 0, 1024);
|
||||
bsock_ringbuf_init(&rbuf, buf, 1024);
|
||||
assert_write(&rbuf, NULL, NULL, sbuf, 128);
|
||||
assert(bsock_ringbuf_read(&rbuf, buf3, 129) == -1);
|
||||
assert(errno == ERANGE);
|
||||
assert_write(&rbuf, NULL, NULL, sbuf, 128);
|
||||
assert(bsock_ringbuf_read(&rbuf, buf3, 129) == 128);
|
||||
|
||||
printf("ringbuf - read/write [1024]\n");
|
||||
memset(buf3, 0, 1024);
|
||||
bsock_ringbuf_init(&rbuf, buf, 1024);
|
||||
assert_write(&rbuf, NULL, NULL, sbuf, 1024);
|
||||
assert_write(&rbuf, NULL, NULL, sbuf, 1024);
|
||||
assert_read(&rbuf, buf3, 1024);
|
||||
assert(memcmp(sbuf, buf3, 128) == 0);
|
||||
|
||||
|
@ -119,9 +119,9 @@ bsock_test(void)
|
|||
assert(pipe(pipes) == 0);
|
||||
memset(buf3, 0, 1024);
|
||||
bsock_ringbuf_init(&rbuf, buf, 1024);
|
||||
assert_write(&rbuf, (void*)(uintptr_t)pipes[1], &io, sbuf, 768);
|
||||
assert(bsock_ringbuf_write(&rbuf, (void*)(uintptr_t)pipes[1], &io, sbuf, 512));
|
||||
assert(ringbuf_verify(&rbuf, 0, 512));
|
||||
assert_write(&rbuf, (void *)(uintptr_t)pipes[1], &io, sbuf, 768);
|
||||
assert(bsock_ringbuf_write(&rbuf, (void *)(uintptr_t)pipes[1], &io, sbuf, 512) == 512);
|
||||
assert(ringbuf_verify(&rbuf, buf + 768, 512));
|
||||
assert(read(pipes[0], buf3, 768) == 768);
|
||||
assert(memcmp(sbuf, buf3, 768) == 0);
|
||||
assert_read(&rbuf, buf3, 512);
|
||||
|
@ -131,9 +131,8 @@ bsock_test(void)
|
|||
assert(pipe(pipes) == 0);
|
||||
memset(buf3, 0, 1024);
|
||||
bsock_ringbuf_init(&rbuf, buf, 768);
|
||||
assert_write(&rbuf, (void*)(uintptr_t)pipes[1], &io, sbuf, 512);
|
||||
assert(bsock_ringbuf_write(&rbuf, (void*)(uintptr_t)pipes[1], &io, sbuf, 1024));
|
||||
assert(ringbuf_verify(struct bsock_ringbuf *buf, char *start, size_t sz))
|
||||
assert_write(&rbuf, (void *)(uintptr_t)pipes[1], &io, sbuf, 512);
|
||||
assert(bsock_ringbuf_write(&rbuf, (void *)(uintptr_t)pipes[1], &io, sbuf, 1024));
|
||||
assert(read(pipes[0], buf3, 512) == 512);
|
||||
assert(memcmp(sbuf, buf3, 512) == 0);
|
||||
assert(read(pipes[0], buf3, 1024) == 1024);
|
||||
|
|
Loading…
Reference in New Issue