-
-
Save evorion/3cd1790d6b1348b4700cff0c9dcc9b23 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdlib.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <uv.h> | |
#include "s7/s7.h" | |
#define DEFAULT_PORT 7771 | |
#define DEFAULT_BACKLOG 128 | |
uv_loop_t *loop; | |
FILE *memstream; | |
static void s7Print(s7_scheme *sc, unsigned char c, s7_pointer port) { | |
fputc(c, memstream); | |
} | |
void read_cb(uv_stream_t * stream, ssize_t nread, const uv_buf_t *buf) { | |
/* dynamically allocate memory for a new write task */ | |
uv_write_t * req = (uv_write_t *) malloc(sizeof(uv_write_t)); | |
/* if read bytes counter -1 there is an error or EOF */ | |
if (nread == -1) { | |
fprintf(stderr, "Error on reading client stream.\n"); | |
uv_close((uv_handle_t *) stream, NULL); | |
} | |
uv_buf_t outBuffer; | |
memstream = open_memstream(&(outBuffer.base), &(outBuffer.len)); | |
s7_scheme *s7; | |
s7 = s7_init(); | |
s7_set_current_output_port(s7, s7_open_output_function(s7, s7Print)); | |
s7_eval_c_string(s7, buf->base); | |
/* Write sync the output buffer to the socket */ | |
fflush(memstream); | |
int r = uv_write(req, stream, &outBuffer, 1, NULL); | |
if (r < 0) | |
fprintf(stderr, "Error on writing client stream.\n"); | |
/* free the remaining memory */ | |
free(buf->base); | |
} | |
void alloc_cb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) { | |
buf->base = malloc(suggested_size); | |
buf->len = suggested_size; | |
} | |
void connection_cb(uv_stream_t * stream, int status) { | |
if (status < 0) { | |
fprintf(stderr, "New connection error %s\n", uv_strerror(status)); | |
return; | |
} | |
uv_tcp_t *client = malloc(sizeof(uv_tcp_t)); | |
uv_tcp_init(loop, client); | |
if (uv_accept(stream, (uv_stream_t*)client) == 0) { | |
uv_read_start((uv_stream_t*)client, alloc_cb, read_cb); | |
uv_write_t *request = (uv_write_t *)malloc(sizeof(uv_write_t)); | |
uv_buf_t prompt = { .base = "sonodi>", .len = 7 }; | |
if (uv_is_writable(stream)) | |
uv_write(request, stream, &prompt, 1, NULL); | |
} | |
else { | |
uv_close((uv_handle_t*)client, NULL); | |
} | |
} | |
int listenForConnections() { | |
loop = uv_default_loop(); | |
uv_tcp_t *server = (uv_tcp_t *)malloc(sizeof(uv_tcp_t)); | |
uv_tcp_init(loop, server); | |
struct sockaddr_in addr; | |
uv_ip4_addr("127.0.0.1", DEFAULT_PORT, &addr); | |
uv_tcp_bind(server, (const struct sockaddr*)&addr, 0); | |
int r = uv_listen((uv_stream_t*)server, DEFAULT_BACKLOG, connection_cb); | |
if (r) { | |
fprintf(stderr, "Listen error %s\n", uv_strerror(r)); | |
return 1; | |
} | |
return uv_run(loop, UV_RUN_DEFAULT); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment