Created
May 9, 2019 22:07
-
-
Save coder3101/37e31ad2c7bcab3f7186ee337ce308d1 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 <sys/types.h> | |
#include <sys/stat.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <fcntl.h> | |
#include <errno.h> | |
#include <unistd.h> | |
#include <syslog.h> | |
#include <string.h> | |
#include <sys/inotify.h> | |
#include <poll.h> | |
#include <sys/wait.h> | |
int compile(){ | |
int stat = -1; | |
int pdd = fork(); | |
if(pdd == -1) { | |
syslog(LOG_ERR, "Cannot create a fork for Compiler Process"); | |
exit(EXIT_FAILURE); | |
} | |
if(pdd == 0){ | |
execl("/bin/g++", "g++", "/home/ashar/Desktop/AutoCompiler/src/sol.cc", "-Wall","-o","/home/ashar/Desktop/AutoCompiler/src/a.out", NULL); | |
} | |
else { | |
syslog(LOG_INFO, "Waiting for compiler process %d to exit", pdd); | |
waitpid(pdd, &stat, 0); | |
syslog(LOG_INFO, "Compiler exited with exit code %d", stat); | |
return 0; | |
} | |
return -1; | |
} | |
void handle_change(int fd){ | |
char buf[4096] __attribute__((aligned(__alignof__(struct inotify_event)))); | |
const struct inotify_event *event = NULL; | |
ssize_t len; | |
char*ptr; | |
while(1){ | |
len = read(fd, buf, sizeof buf); | |
if(len == -1 && errno != EAGAIN){ | |
syslog(LOG_ERR, "Failed to read from inotify fd"); | |
exit(EXIT_FAILURE); | |
} | |
if(len <= 0) break; | |
for(ptr = buf; ptr < buf + len; ptr += sizeof(struct inotify_event) + event->len){ | |
event = (const struct inotify_event *)ptr; | |
if(event->mask & IN_CLOSE_WRITE){ | |
compile(); | |
} | |
else { | |
if(event->mask == IN_IGNORED){ | |
syslog(LOG_ERR, "Watcher was forcefully removed." | |
"Did you used vim to save the file without :set backupcopy=yes"); | |
} | |
else syslog(LOG_WARNING, "Not handling event mask 0x%.8x",event->mask); | |
} | |
} | |
} | |
} | |
int main() { | |
pid_t pid, sid; | |
pid = fork(); | |
if (pid < 0) { | |
syslog(LOG_ERR, "Cannot fork daemon process."); | |
exit(EXIT_FAILURE); | |
} | |
if (pid > 0) { | |
syslog(LOG_INFO, "Fork Success. PID %d", getpid()); | |
exit(EXIT_SUCCESS); | |
} | |
umask(0); | |
int res = setgid(1000); // Run the Daemon on my user group | |
if(res == -1){ | |
perror("setgid failed"); | |
exit(EXIT_FAILURE); | |
} | |
syslog(LOG_INFO, "Starting the AutoCompilerDaemon"); | |
sid = setsid(); | |
if (sid < 0) { | |
syslog(LOG_ERR, "setsid returned an error"); | |
exit(EXIT_FAILURE); | |
} | |
if ((chdir("/")) < 0) { | |
syslog(LOG_ERR, "chdir to root failed"); | |
exit(EXIT_FAILURE); | |
} | |
close(STDIN_FILENO); | |
//close(STDOUT_FILENO); | |
//close(STDERR_FILENO); | |
syslog(LOG_INFO, "Closed all File Descriptors"); | |
syslog(LOG_INFO, "Creating Listener for AutoCompilation of /home/ashar/Desktop/AutoCompiler/src/sol.cc"); | |
int fd = inotify_init1(IN_NONBLOCK); | |
if(fd == -1){ | |
syslog(LOG_ERR, "Failed to create a inotify instance"); | |
exit(EXIT_FAILURE); | |
} | |
int wd = inotify_add_watch(fd, "/home/ashar/Desktop/AutoCompiler/src/sol.cc", IN_CLOSE_WRITE); | |
if(wd == -1){ | |
syslog(LOG_ERR, "Failed to add the file watcher to inotify instance"); | |
exit(EXIT_FAILURE); | |
} | |
syslog(LOG_INFO, "Starting the polling for the change events in the file"); | |
struct pollfd pfd; | |
pfd.fd = fd; | |
pfd.events = POLLIN; | |
syslog(LOG_INFO, "Listening for events on file"); | |
while (1) { | |
int poll_num = poll(&pfd, 1, -1); // Blocking call | |
if(poll_num == -1){ | |
if(errno == EINTR) continue; // Interuppts | |
syslog(LOG_ERR, "Polling Error: Failed to poll for the file for fd changes"); | |
exit(EXIT_FAILURE); | |
} | |
if(poll_num > 0){ | |
if(pfd.revents & POLLIN) { | |
syslog(LOG_INFO, "File Contents have changed. Recompilation begins now"); | |
handle_change(fd); | |
} | |
else syslog(LOG_WARNING, "Polling FD is not POLLIN"); | |
} | |
sleep(30); | |
} | |
syslog(LOG_INFO, "Shutting down AutoCompilerDaemon"); | |
exit(EXIT_SUCCESS); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment