mirror of
https://github.com/cesanta/mongoose
synced 2026-08-25 22:26:06 -04:00
make BSD C++ compatible,survive to FreeRTOS not being so
This commit is contained in:
parent
282ae0d968
commit
f58f29b9a0
6 changed files with 58 additions and 20 deletions
4
.github/workflows/nightly.yml
vendored
4
.github/workflows/nightly.yml
vendored
|
|
@ -281,10 +281,10 @@ jobs:
|
|||
make -C test/bsd shm_tap_bridge
|
||||
test/bsd/shm_tap_bridge &
|
||||
sleep 2
|
||||
set -o pipefail; make -C test/bsd CC=${{ matrix.cc }} | tee log
|
||||
make -C test/bsd CC=${{ matrix.cc }} > log
|
||||
- if: success() || failure()
|
||||
run: |
|
||||
# cat log
|
||||
cat log
|
||||
test/health.awk < log > json
|
||||
scp -o "StrictHostKeyChecking=no" json "root@176.9.217.245:/data/downloads/health/bsd_${{ matrix.cc }}_$(date +"%Y%m%d").json"
|
||||
|
||||
|
|
|
|||
|
|
@ -294,7 +294,8 @@ int listen(int fd, int backlog) {
|
|||
int accept(int fd, struct sockaddr *addr, socklen_t *addrlen) {
|
||||
struct mg_bsd_sock *ls = get(fd);
|
||||
if (!ls) return -1;
|
||||
struct sockaddr_in peer = {0};
|
||||
struct sockaddr_in peer;
|
||||
memset(&peer, 0, sizeof(peer));
|
||||
void *t = mg_bsd_transport_accept(ls->t, &peer, ls->nonblock);
|
||||
if (!t) return -1; // errno was set by transport_accept()
|
||||
struct mg_bsd_sock *ns = (struct mg_bsd_sock *) calloc(1, sizeof(*ns));
|
||||
|
|
@ -417,7 +418,8 @@ void freeaddrinfo(struct addrinfo *res) { (void) res; }
|
|||
#endif
|
||||
|
||||
int inet_pton(int af, const char *src, void *dst) {
|
||||
struct mg_addr a = {0};
|
||||
struct mg_addr a;
|
||||
memset(&a, 0, sizeof(a));
|
||||
if (af == AF_INET && mg_aton(mg_str_s(src), &a)) { memcpy(dst, &a.addr.ip4, 4); return 1; }
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -432,7 +434,8 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t size) {
|
|||
}
|
||||
|
||||
in_addr_t inet_addr(const char *cp) {
|
||||
struct mg_addr a = {0};
|
||||
struct mg_addr a;
|
||||
memset(&a, 0, sizeof(a));
|
||||
return mg_aton(mg_str_s(cp), &a) ? a.addr.ip4 : (in_addr_t) -1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -127,7 +127,8 @@ int listen(int fd, int backlog) {
|
|||
int accept(int fd, struct sockaddr *addr, socklen_t *addrlen) {
|
||||
struct mg_bsd_sock *ls = get(fd);
|
||||
if (!ls) return -1;
|
||||
struct sockaddr_in peer = {0};
|
||||
struct sockaddr_in peer;
|
||||
memset(&peer, 0, sizeof(peer));
|
||||
void *t = mg_bsd_transport_accept(ls->t, &peer, ls->nonblock);
|
||||
if (!t) return -1; // errno was set by transport_accept()
|
||||
struct mg_bsd_sock *ns = (struct mg_bsd_sock *) calloc(1, sizeof(*ns));
|
||||
|
|
@ -250,7 +251,8 @@ void freeaddrinfo(struct addrinfo *res) { (void) res; }
|
|||
#endif
|
||||
|
||||
int inet_pton(int af, const char *src, void *dst) {
|
||||
struct mg_addr a = {0};
|
||||
struct mg_addr a;
|
||||
memset(&a, 0, sizeof(a));
|
||||
if (af == AF_INET && mg_aton(mg_str_s(src), &a)) { memcpy(dst, &a.addr.ip4, 4); return 1; }
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -265,7 +267,8 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t size) {
|
|||
}
|
||||
|
||||
in_addr_t inet_addr(const char *cp) {
|
||||
struct mg_addr a = {0};
|
||||
struct mg_addr a;
|
||||
memset(&a, 0, sizeof(a));
|
||||
return mg_aton(mg_str_s(cp), &a) ? a.addr.ip4 : (in_addr_t) -1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,15 +15,25 @@ endif
|
|||
|
||||
.PHONY: all bsd_test bsd_client shm_tap_bridge shm_port_bridge bsd_s390 clean
|
||||
|
||||
SOURCES = bsd_shm_test.c ../../mongoose.c
|
||||
|
||||
# FreeRTOS
|
||||
SOURCES += FreeRTOS-Kernel/portable/MemMang/heap_4.c
|
||||
SOURCES += FreeRTOS-Kernel/portable/ThirdParty/GCC/Posix/port.c
|
||||
SOURCES += FreeRTOS-Kernel/portable/ThirdParty/GCC/Posix/utils/wait_for_event.c
|
||||
TEST_SOURCES = bsd_shm_test.c
|
||||
# A C++ application compiles its sources as C++, linking Mongoose and FreeRTOS as C.
|
||||
# FreeRTOS does not build as C++, so C sources are compiled separately.
|
||||
C_SOURCES = ../../mongoose.c
|
||||
C_SOURCES += FreeRTOS-Kernel/portable/MemMang/heap_4.c
|
||||
C_SOURCES += FreeRTOS-Kernel/portable/ThirdParty/GCC/Posix/port.c
|
||||
C_SOURCES += FreeRTOS-Kernel/portable/ThirdParty/GCC/Posix/utils/wait_for_event.c
|
||||
C_SOURCES += $(wildcard FreeRTOS-Kernel/*.c)
|
||||
C_OBJECTS = $(notdir $(C_SOURCES:.c=.o))
|
||||
C_INPUTS = $(foreach S,$(C_SOURCES),-x c $(S))
|
||||
CFLAGS += -IFreeRTOS-Kernel/include
|
||||
CFLAGS += -IFreeRTOS-Kernel/portable/ThirdParty/GCC/Posix -Wno-conversion -Wno-undef
|
||||
|
||||
ifeq "$(findstring ++,$(CC))" ""
|
||||
TEST_LANGUAGE = c
|
||||
else
|
||||
TEST_LANGUAGE = c++
|
||||
endif
|
||||
|
||||
DOCKER_BIN ?= docker
|
||||
CWD ?= $(realpath $(CURDIR))
|
||||
ROOT_DIR = $(realpath $(CWD)/../..)
|
||||
|
|
@ -38,8 +48,10 @@ all bsd: shm_tap_bridge bsd_client FreeRTOS-Kernel bsd_test
|
|||
ASAN_OPTIONS=$(ASAN_OPTIONS) $(RUN) ./bsd_test $(ARGS)
|
||||
|
||||
# requires shm_tap_bridge to be running
|
||||
bsd_test: $(SOURCES) bsd_x_test.c ../../mongoose.h shm_queue.h
|
||||
$(CC) $(SOURCES) $(wildcard FreeRTOS-Kernel/*.c) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA) -o $@
|
||||
bsd_test: FreeRTOS-Kernel
|
||||
$(CC) $(C_INPUTS) -c $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA)
|
||||
$(CC) -x $(TEST_LANGUAGE) -c $(TEST_SOURCES) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA)
|
||||
$(CC) $(C_OBJECTS) $(TEST_SOURCES:.c=.o) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA) -o $@
|
||||
|
||||
bsd_client: bsd_client.c
|
||||
$(CC) bsd_client.c -pthread -o $@
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define PORT 1234
|
||||
|
|
@ -46,6 +47,7 @@ static void *worker(void *arg) {
|
|||
const char *host = (const char *) arg;
|
||||
char tx[DATA_SIZE], rx[DATA_SIZE];
|
||||
struct sockaddr_in sa;
|
||||
struct timeval timeout;
|
||||
unsigned port = 0;
|
||||
int fd;
|
||||
|
||||
|
|
@ -54,6 +56,11 @@ static void *worker(void *arg) {
|
|||
|
||||
fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (fd < 0) goto fail;
|
||||
timeout.tv_sec = 5;
|
||||
timeout.tv_usec = 0;
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) != 0 ||
|
||||
setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)) != 0)
|
||||
goto fail_close;
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sin_family = AF_INET;
|
||||
|
|
|
|||
|
|
@ -42,7 +42,10 @@ static void client_task(void *args) {
|
|||
struct client_data *d = (struct client_data *) args;
|
||||
char req[256];
|
||||
fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
struct sockaddr_in sa = {.sin_family = AF_INET, .sin_port = htons(80)};
|
||||
struct sockaddr_in sa;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sin_family = AF_INET;
|
||||
sa.sin_port = htons(80);
|
||||
memcpy(&sa.sin_addr, &d->ip, 4);
|
||||
c = connect(fd, (struct sockaddr *) &sa, sizeof(sa));
|
||||
ASSERT(c >= 0);
|
||||
|
|
@ -73,6 +76,7 @@ static void echo_task(void *args) {
|
|||
char buf[512];
|
||||
size_t i = 0;
|
||||
ssize_t n;
|
||||
MG_INFO(("Echo task started: %d", fd));
|
||||
while ((n = recv(fd, buf, sizes[i++ % (sizeof(sizes) / sizeof(sizes[0]))], 0)) > 0)
|
||||
send(fd, buf, (size_t) n, 0);
|
||||
close(fd);
|
||||
|
|
@ -82,9 +86,14 @@ static void echo_task(void *args) {
|
|||
// accept loop. Waits for incoming connections on port 1234 and spawns
|
||||
// an echo_task for each one, allowing concurrent clients.
|
||||
static void atask(void *args) {
|
||||
BaseType_t result;
|
||||
mg_bsd_init();
|
||||
int lfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
struct sockaddr_in sa = {.sin_family = AF_INET, .sin_port = htons(1234), .sin_addr = {INADDR_ANY}};
|
||||
struct sockaddr_in sa;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sin_family = AF_INET;
|
||||
sa.sin_port = htons(1234);
|
||||
sa.sin_addr.s_addr = INADDR_ANY;
|
||||
bind(lfd, (struct sockaddr *) &sa, sizeof(sa));
|
||||
listen(lfd, 5);
|
||||
fcntl(lfd, F_SETFL, O_NONBLOCK);
|
||||
|
|
@ -93,7 +102,10 @@ static void atask(void *args) {
|
|||
int fd = accept(lfd, NULL, NULL);
|
||||
if (fd < 0) { vTaskDelay(pdMS_TO_TICKS(10)); continue; }
|
||||
// echo_task at higher priority than task1
|
||||
xTaskCreate(echo_task, "echo", 512, (void *) (uintptr_t) fd, configMAX_PRIORITIES - 1, NULL);
|
||||
result = xTaskCreate(echo_task, "echo", 512, (void *) (uintptr_t) fd,
|
||||
configMAX_PRIORITIES - 1, NULL);
|
||||
MG_INFO(("Echo task %d: %s", fd, result == pdPASS ? "created" : "FAILED"));
|
||||
ASSERT(result == pdPASS);
|
||||
}
|
||||
close(lfd);
|
||||
s_wait = false;
|
||||
|
|
@ -118,7 +130,7 @@ static void task2(void *args) {
|
|||
// atask at higher priority than task1
|
||||
xTaskCreate(atask, "atask", 256, NULL, configMAX_PRIORITIES - 1, NULL);
|
||||
ip = mg_mprintf("%M", mg_print_ip4, &mgr->ifp->ip);
|
||||
cmd[0] = "./bsd_client";
|
||||
cmd[0] = (char *) "./bsd_client";
|
||||
cmd[1] = ip;
|
||||
cmd[2] = NULL;
|
||||
ASSERT(posix_spawn(&pid, cmd[0], NULL, NULL, cmd, environ) == 0);
|
||||
|
|
@ -217,6 +229,7 @@ static void task1(void *args) {
|
|||
while (!s_done) {
|
||||
mg_mgr_poll(mgr, 0);
|
||||
mg_bsd_poll(mgr);
|
||||
vTaskDelay(1); // Let idle reclaim deleted echo tasks
|
||||
}
|
||||
s_done = false;
|
||||
vTaskDelete(NULL);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue