--- libaitio/src/aitio.c 2016/08/10 14:33:23 1.17.8.4 +++ libaitio/src/aitio.c 2016/08/10 15:18:23 1.17.8.5 @@ -3,7 +3,7 @@ * by Michael Pounov * * $Author: misho $ -* $Id: aitio.c,v 1.17.8.4 2016/08/10 14:33:23 misho Exp $ +* $Id: aitio.c,v 1.17.8.5 2016/08/10 15:18:23 misho Exp $ * ************************************************************************** The ELWIX and AITNET software is distributed under the following @@ -300,26 +300,14 @@ end: return cx; } -/* - * ioWatchDirLoop() - Function for watching changes in directory and fire callback - * - * @csDir = Full directory path - * @callback = Callback if raise event! nOp -1 delete, 0 change/move, 1 create - * return: -1 error, !=-1 ok, number of total signaled events -*/ -int -ioWatchDirLoop(const char *csDir, int (*callback)(const char *csName, int nOp)) +#ifndef __linux__ +static int +watchDirLoop(const char *csDir, int (*callback)(const char *csName, int nOp)) { glob_t g[2] = {{ 0 }, { 0 }}; - int d, n = 0; + int d, kq, n = 0; register int j, i; -#ifndef __linux__ - int kq; struct kevent req, chg; -#else - int in; - struct inotify_event evt; -#endif char wrk[MAXPATHLEN * 2], str[MAXPATHLEN] = { 0 }; if (!csDir || !callback) @@ -328,7 +316,6 @@ ioWatchDirLoop(const char *csDir, int (*callback)(cons strlcpy(str, csDir, MAXPATHLEN); strlcat(str, "/*", MAXPATHLEN); -#ifndef __linux__ d = open(csDir, O_RDONLY); if (d == -1) { LOGERR; @@ -343,30 +330,15 @@ ioWatchDirLoop(const char *csDir, int (*callback)(cons } EV_SET(&req, d, EVFILT_VNODE, EV_ADD | EV_CLEAR, NOTE_WRITE, 0, 0); -#else - in = inotify_init(); - if (in == -1) { - LOGERR; - return -1; - } - d = inotify_add_watch(in, csDir, IN_CREATE | IN_DELETE); -#endif - if ((n = glob(str, GLOB_NOCHECK, NULL, &g[0]))) { LOGERR; -#ifndef __linux__ close(kq); close(d); -#else - inotify_rm_watch(in, d); - close(in); -#endif return -1; } /*else ioDEBUG(3, "Start files %d in %s\n", g[0].gl_matchc, str);*/ -#ifndef __linux__ while (kevent(kq, &req, 1, &chg, 1, NULL) > 0) { /*ioDEBUG(1, "Event:: req=0x%x -> chg=0x%x data=%x\n", req.fflags, chg.fflags, chg.data);*/ @@ -428,17 +400,77 @@ ioWatchDirLoop(const char *csDir, int (*callback)(cons g[0] = g[1]; } } -#endif globfree(&g[0]); -#ifndef __linux__ close(kq); close(d); + return n; +} #else +static int +watchDirLoop(const char *csDir, int (*callback)(const char *csName, int nOp)) +{ + int d, in, rlen, n = 0; + register int i = 0; + struct inotify_event *evt; + char buf[BUFSIZ * (sizeof(struct inotify_event) + 16)]; + + if (!csDir || !callback) + return 0; + + in = inotify_init(); + if (in == -1) { + LOGERR; + return -1; + } + + d = inotify_add_watch(in, csDir, IN_CREATE | IN_DELETE | IN_MOVE); + + while ((rlen = read(in, buf, sizeof buf)) > 0) { + if (i >= rlen) + break; + else + evt = (struct inotify_event*) &buf[i]; + + if (evt->len) { + if (evt->mask & IN_CREATE) { + if (callback(evt->name, 1) < 0) + break; + else + n++; + } else if (evt->mask & IN_DELETE) { + if (callback(evt->name, -1) < 0) + break; + else + n++; + } else if (evt->mask & IN_MOVE) { + if (callback(evt->name, 0) < 0) + break; + else + n++; + } + } + + i += sizeof (struct inotify_event) + evt->len; + } + inotify_rm_watch(in, d); close(in); -#endif return n; +} +#endif + +/* + * ioWatchDirLoop() - Function for watching changes in directory and fire callback + * + * @csDir = Full directory path + * @callback = Callback if raise event! nOp -1 delete, 0 change/move, 1 create + * return: -1 error, !=-1 ok, number of total signaled events +*/ +int +ioWatchDirLoop(const char *csDir, int (*callback)(const char *csName, int nOp)) +{ + return watchDirLoop(csDir, callback); } /*