Skip to content

Instantly share code, notes, and snippets.

@kingsleyh
Created March 28, 2017 13:28
Show Gist options
  • Save kingsleyh/7e5e97746e11a5836507efeae08e2c6d to your computer and use it in GitHub Desktop.
Save kingsleyh/7e5e97746e11a5836507efeae08e2c6d to your computer and use it in GitHub Desktop.
watcher
import std.algorithm;
import std.array;
import std.conv;
import std.exception;
import std.file;
import std.process;
import std.string;
import std.encoding : sanitize;
import std.stdio;
class Watch {
public void watchTarget(string file){
Watcher watcher;
watcher.addFile(file);
while(true){
watcher.readChanges();
writeln("rebuilding....");
watcher.wait();
}
}
}
struct Watcher
{
import core.stdc.errno;
import core.sys.darwin.sys.event;
import core.sys.posix.fcntl;
void addFile(string path)
{
if (!eventfd)
eventfd = kqueue();
enum O_EVTONLY = 0x8000;
enum O_CLOEXEC = 0x1000000;
enum oflags = O_EVTONLY | O_CLOEXEC;
auto fd = open(path.toStringz(), oflags);
watches[path] = fd;
enum fflags = NOTE_WRITE;
kevent_t event;
EV_SET(&event, fd, EVFILT_VNODE, EV_ADD | EV_CLEAR, fflags, 0, null);
errnoEnforce(kevent(eventfd, &event, 1, null, 0, null) != -1);
}
void wait()
{
import core.sys.posix.sys.select;
fd_set rfds=void;
FD_ZERO(&rfds);
FD_SET(eventfd, &rfds);
writeln("Waiting for file changes.");
auto res = select(eventfd+1, &rfds, null, null, null);
}
void readChanges()
{
import core.stdc.errno, core.sys.posix.unistd;
import core.sys.posix.time;
timespec ts;
kevent_t[8] buf=void;
while (true) {
auto res = kevent(eventfd, null, 0, buf.ptr, buf.length, &ts);
if (res > 0)
continue;
else if (res == 0)
return;
else
errnoEnforce(false);
}
}
~this()
{
import core.sys.posix.unistd;
if (eventfd)
close(eventfd);
}
int eventfd;
int[string] watches;
}
void main(){
auto b = new Watch();
b.watchTarget("/path/to/some/directory");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment