efm2/src/backends/common/fs_backend_core.c

131 lines
2.6 KiB
C

// this is a template file to drive any fs backend that sets up stdin/out
// and the core parsers and init/shutdown funcs. the expectation is you build
// this along with an implementation file that implements that fs
#include <Eina.h>
#include <Ecore.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include "cmd.h"
void do_handle_cmd(Cmd *c);
int do_init(int argc, const char **argv);
void do_shutdown(void);
static Ecore_Fd_Handler *fdh = NULL;
static Eina_Strbuf *strbuf = NULL;
static Eina_Bool
_cb_stdio_in_read(void *data EINA_UNUSED, Ecore_Fd_Handler *fd_handler EINA_UNUSED)
{
ssize_t ret;
char buf[4096 + 1];
errno = 0;
ret = read(0, buf, sizeof(buf) - 1);
if (ret < 1)
{
int e = errno;
if ((e == EIO) || (e == EBADF) || (e == EPIPE) || (e == EINVAL) ||
(e == ENOSPC) || (!((e == EAGAIN) || (e == EINTR))))
{
ecore_main_loop_quit();
goto done;
}
goto done;
}
else
{
const char *nl, *str;
buf[ret] = '\0';
eina_strbuf_append(strbuf, buf);
for (;;)
{
char *s;
Cmd *c;
str = eina_strbuf_string_get(strbuf);
nl = strchr(str, '\n');
if (!nl) break;
s = strndup(str, nl - str);
if (!s) break;
c = cmd_parse(s);
if (c)
{
do_handle_cmd(c);
cmd_free(c);
}
free(s);
eina_strbuf_remove(strbuf, 0, nl - str + 1);
}
}
done:
return EINA_TRUE;
}
static void
_init(void)
{
strbuf = eina_strbuf_new();
if (!strbuf)
{
fprintf(stderr, "ERR: Can't allocate strbuf\n");
goto err;
}
if (fcntl(0, F_SETFL, O_NONBLOCK) != 0)
{
fprintf(stderr, "ERR: Can't set stdin to O_NONBLOCK\n");
goto err;
}
fdh = ecore_main_fd_handler_add(0, ECORE_FD_READ, _cb_stdio_in_read,
NULL, NULL, NULL);
if (!fdh) goto err;
return;
err:
exit(-1);
}
static void
_shutdown(void)
{
ecore_main_fd_handler_del(fdh);
fdh = NULL;
eina_strbuf_free(strbuf);
strbuf = NULL;
}
int
main(int argc, const char **argv)
{
int ret;
eina_init();
ecore_init();
_init();
ret = do_init(argc, argv);
if (ret == 0)
{
ecore_main_loop_begin();
do_shutdown();
}
_shutdown();
ecore_shutdown();
eina_shutdown();
return ret;
}