Skip to content

Instantly share code, notes, and snippets.

@evorion
Created August 24, 2016 11:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save evorion/3cd1790d6b1348b4700cff0c9dcc9b23 to your computer and use it in GitHub Desktop.
Save evorion/3cd1790d6b1348b4700cff0c9dcc9b23 to your computer and use it in GitHub Desktop.
#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