#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <uv.h>
#ifdef _WIN32
#define PIPENAME "\\\\?\\pipe\\echo.sock"
#else
#define PIPENAME "/tmp/echo.sock"
#endif
uv_loop_t *loop;
typedef
struct
{
uv_write_t req;
uv_buf_t buf;
} write_req_t;
void
free_write_req(uv_write_t *req) {
write_req_t *wr = (write_req_t*) req;
free
(wr->buf.base);
free
(wr);
}
void
alloc_buffer(uv_handle_t *handle,
size_t
suggested_size, uv_buf_t *buf) {
buf->base =
malloc
(suggested_size);
buf->len = suggested_size;
}
void
echo_write(uv_write_t *req,
int
status) {
if
(status < 0) {
fprintf
(stderr,
"Write error %s\n"
, uv_err_name(status));
}
free_write_req(req);
}
void
echo_read(uv_stream_t *client, ssize_t nread,
const
uv_buf_t *buf) {
if
(nread > 0) {
write_req_t *req = (write_req_t*)
malloc
(
sizeof
(write_req_t));
req->buf = uv_buf_init(buf->base, nread);
uv_write((uv_write_t*) req, client, &req->buf, 1, echo_write);
return
;
}
if
(nread < 0) {
if
(nread != UV_EOF)
fprintf
(stderr,
"Read error %s\n"
, uv_err_name(nread));
uv_close((uv_handle_t*) client, NULL);
}
free
(buf->base);
}
void
on_new_connection(uv_stream_t *server,
int
status) {
if
(status == -1) {
return
;
}
uv_pipe_t *client = (uv_pipe_t*)
malloc
(
sizeof
(uv_pipe_t));
uv_pipe_init(loop, client, 0);
if
(uv_accept(server, (uv_stream_t*) client) == 0) {
uv_read_start((uv_stream_t*) client, alloc_buffer, echo_read);
}
else
{
uv_close((uv_handle_t*) client, NULL);
}
}
void
remove_sock(
int
sig) {
uv_fs_t req;
uv_fs_unlink(loop, &req, PIPENAME, NULL);
exit
(0);
}
int
main() {
loop = uv_default_loop();
uv_pipe_t server;
uv_pipe_init(loop, &server, 0);
signal
(SIGINT, remove_sock);
int
r;
if
((r = uv_pipe_bind(&server, PIPENAME))) {
fprintf
(stderr,
"Bind error %s\n"
, uv_err_name(r));
return
1;
}
if
((r = uv_listen((uv_stream_t*) &server, 128, on_new_connection))) {
fprintf
(stderr,
"Listen error %s\n"
, uv_err_name(r));
return
2;
}
return
uv_run(loop, UV_RUN_DEFAULT);
}