inotify and recursion
Artur Skawina
art.08.09 at gmail.com
Fri Dec 27 09:05:42 PST 2013
On 12/27/13 15:13, Artur Skawina wrote:
> struct MyInotifyEvent(size_t BS) {
> inotify_event event;
> char[BS] buffer;
> alias event this;
> }
> [...]
> enum bufsiz = inotify_event.sizeof + PATH_MAX + 1;
> auto event = cast(MyInotifyEvent!bufsiz*)malloc(bufsiz);
> [...]
> writeln("Name:", event.buffer[0..event.len-1]); // 2do: strip any extra trailing \0s.
Well, that could get awkward, as the inotify api doesn't really support disabling
event batching. A saner design would be something like the code below.
artur
struct INotify {
Fd fd;
import std.exception;
import core.sys.posix.unistd;
this(cint flags) {
fd = inotify_init(flags);
errnoEnforce(fd!=-1);
}
~this() {
close(fd);
}
Wd add(const char* name, uint mask) { return inotify_add_watch(fd, name, mask); }
Fd remove(Wd wd) { return inotify_rm_watch(fd, wd); }
bool get(CB)(CB cb) {
void[4*1024] buffer = void;
auto got = read(fd, &buffer, buffer.sizeof);
if (got<=inotify_event.sizeof)
return false;
size_t off = 0;
while (off<=got-inotify_event.sizeof) {
auto evp = cast(inotify_event*)&buffer[off];
auto namebuf = evp.len ? (cast(char*)&evp.name)[0..evp.len-1] : null;
while (namebuf.length && !namebuf[namebuf.length-1])
--namebuf.length;
cb(evp, namebuf);
off += inotify_event.sizeof + evp.len;
}
assert(off==got);
return true;
}
}
void main(string argv[]) {
import std.string;
auto ntf = INotify(0);
foreach (arg; argv[1..$])
ntf.add(toStringz(arg), IN_MODIFY);
void myCallback(/*scope*/ const inotify_event* ev, /*scope*/ char[] name) {
/* Don't even think about escaping any of the args. Dup if necessary. */
import std.stdio;
writeln(*ev, " \"", name, "\"");
}
while (1)
ntf.get(&myCallback);
}
// libc i/f follows:
alias uint32_t = uint;
alias cint = int;
alias Fd = cint;
extern(C) {
Fd inotify_init();
Fd inotify_init1(cint flags);
Wd inotify_add_watch(Fd fd, const char* pathname, uint mask);
Fd inotify_rm_watch(Fd fd, Wd wd);
}
Fd inotify_init(cint flags) { return inotify_init1(flags); }
enum IN_MODIFY = 0x00000002; /* DEFINEME */
struct Wd { Fd fd; alias fd this; }
struct inotify_event {
Wd wd; /* Watch descriptor */
uint32_t mask; /* Mask of events */
uint32_t cookie; /* Unique cookie associating related events (for rename(2)) */
uint32_t len; /* Size of name field */
char name[0]; /* Optional null-terminated name */
void toString(DG, FT)(scope DG sink, FT fmt) const @trusted {
import std.format;
foreach (I, E; this.tupleof)
static if (I<this.tupleof.length-1)
formatValue(sink, E, fmt), sink(" ");
}
}
More information about the Digitalmars-d-learn
mailing list