diff options
Diffstat (limited to 'daemon.c')
| -rw-r--r-- | daemon.c | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/daemon.c b/daemon.c new file mode 100644 index 0000000..7b6ba09 --- /dev/null +++ b/daemon.c @@ -0,0 +1,114 @@ +#include "daemon.h" + +#include "timer.h" + +#include <signal.h> +#include <errno.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <pthread.h> +#include <assert.h> + +static struct sockaddr_un addr = (struct sockaddr_un){.sun_path = "/tmp/pomo.sock", .sun_family = AF_UNIX}; + +int socket_create() { + errno = 0; + int fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd == -1) { + printf("Socket creation failed! %s\n", strerror(errno)); + fflush(stdout); + exit(1); + } + return fd; +} + +void socket_set_server(int sockfd) { + errno = 0; + if (bind(sockfd, (struct sockaddr*)&addr, sizeof(addr)) == -1) { + printf("Socket bind failed! %s\n", strerror(errno)); + fflush(stdout); + exit(1); + } + errno = 0; + if (listen(sockfd, 1) == -1) { + printf("Socket listen() failed! %s\n", strerror(errno)); + exit(1); + } +} + +void socket_set_client(int sockfd) { + errno = 0; + if(connect(sockfd, (struct sockaddr*)&addr, sizeof(addr)) == -1) { + printf("Socket connect failed! %s\n", strerror(errno)); + fflush(stdout); + exit(1); + } +} + +void socket_bind_clean(int sig) { + unlink("/tmp/pomo.sock"); + exit(0); +} + +void daemon_init(Daemon* d) { + assert(d != NULL); + socket_set_server(d->sockfd); + signal(SIGINT, socket_bind_clean); + signal(SIGTERM, socket_bind_clean); + atexit((void *)socket_bind_clean); +} + +void* daemon_listener_loop(void *d) { + assert(d != NULL); + while(1) { + int clientfd = accept(((Daemon *)d)->sockfd, NULL, NULL); + + if (clientfd == -1) { + printf("Incoming connection failed.\n"); + continue; + } + + char buffer[1024]; + read(clientfd, buffer, 1024 - 1); + + // TODO: Create a mechanism to fetch commands without writing everything again. + // TODO: Make it so that a more efficient approach is used instead of a string. + if(strncmp(buffer, "start", sizeof("start")) == 0) { + timer_start(((Daemon *)d)->timer); + } + + if(strncmp(buffer, "toggle", sizeof("toggle")) == 0) { + timer_toggle_state(((Daemon *)d)->timer); + } + + if(strncmp(buffer, "reset", sizeof("reset")) == 0) { + timer_reset(((Daemon *)d)->timer); + } + + /* send(clientfd, "done", sizeof("done"), 0); */ + close(clientfd); + } + return NULL; +} + +void daemon_run(Daemon* d) { + assert(d != NULL); + + Timer t; + timer_init(&t, 3000); + d->timer = &t; + pthread_t thread; + if(pthread_create(&thread, NULL, daemon_listener_loop, d) != 0) { + printf("Error: daemon_listener_loop thread cannot be created!"); + exit(1); + } + + timer_loop(&t); + + void* retval; + pthread_join(thread, &retval); +} |
