2011-11-23 10:22:10 +00:00
|
|
|
|
/**
|
2010-11-22 21:17:08 +00:00
|
|
|
|
* inotify.c from Lsyncd - Live (Mirror) Syncing Demon
|
2010-11-22 20:09:52 +00:00
|
|
|
|
*
|
|
|
|
|
* License: GPLv2 (see COPYING) or any later version
|
|
|
|
|
*
|
|
|
|
|
* Authors: Axel Kittenberger <axkibe@gmail.com>
|
|
|
|
|
*
|
2010-11-22 21:17:08 +00:00
|
|
|
|
* -----------------------------------------------------------------------
|
|
|
|
|
*
|
2010-11-22 20:09:52 +00:00
|
|
|
|
* Event interface for Lsyncd to Linux´ inotify.
|
|
|
|
|
*/
|
2010-11-22 21:17:08 +00:00
|
|
|
|
|
2010-11-22 20:09:52 +00:00
|
|
|
|
#include "lsyncd.h"
|
|
|
|
|
|
|
|
|
|
#ifndef HAVE_SYS_INOTIFY_H
|
|
|
|
|
# error Missing <sys/inotify.h>; supply kernel-headers and rerun configure.
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
#include <sys/times.h>
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
#include <sys/wait.h>
|
|
|
|
|
#include <sys/inotify.h>
|
|
|
|
|
#include <dirent.h>
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
#include <limits.h>
|
|
|
|
|
#include <signal.h>
|
|
|
|
|
#include <stdbool.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <syslog.h>
|
|
|
|
|
#include <math.h>
|
|
|
|
|
#include <time.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
|
|
#include <lua.h>
|
|
|
|
|
#include <lualib.h>
|
|
|
|
|
#include <lauxlib.h>
|
|
|
|
|
|
2010-11-24 18:19:13 +00:00
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
|
|
|
* Event types.
|
|
|
|
|
*/
|
2010-11-24 21:38:48 +00:00
|
|
|
|
static const char * ATTRIB = "Attrib";
|
|
|
|
|
static const char * MODIFY = "Modify";
|
|
|
|
|
static const char * CREATE = "Create";
|
|
|
|
|
static const char * DELETE = "Delete";
|
|
|
|
|
static const char * MOVE = "Move";
|
2010-11-24 18:19:13 +00:00
|
|
|
|
|
2010-11-22 20:09:52 +00:00
|
|
|
|
/**
|
|
|
|
|
* The inotify file descriptor.
|
|
|
|
|
*/
|
2010-11-22 21:17:08 +00:00
|
|
|
|
static int inotify_fd = -1;
|
2010-11-22 20:09:52 +00:00
|
|
|
|
|
|
|
|
|
/**
|
2011-06-11 16:38:47 +00:00
|
|
|
|
* Standard inotify events to listen to.
|
2010-11-22 20:09:52 +00:00
|
|
|
|
*/
|
2011-11-23 10:22:10 +00:00
|
|
|
|
static const uint32_t standard_event_mask =
|
2010-11-22 20:09:52 +00:00
|
|
|
|
IN_ATTRIB | IN_CLOSE_WRITE | IN_CREATE |
|
|
|
|
|
IN_DELETE | IN_DELETE_SELF | IN_MOVED_FROM |
|
|
|
|
|
IN_MOVED_TO | IN_DONT_FOLLOW | IN_ONLYDIR;
|
|
|
|
|
|
2011-06-11 16:38:47 +00:00
|
|
|
|
|
2010-11-22 20:09:52 +00:00
|
|
|
|
/**
|
|
|
|
|
* Adds an inotify watch
|
2011-11-23 10:22:10 +00:00
|
|
|
|
*
|
2011-06-11 16:38:47 +00:00
|
|
|
|
* @param dir (Lua stack) path to directory
|
|
|
|
|
* @param inotifyMode (Lua stack) path to directory
|
|
|
|
|
* @return (Lua stack) numeric watch descriptor
|
2010-11-22 20:09:52 +00:00
|
|
|
|
*/
|
|
|
|
|
static int
|
|
|
|
|
l_addwatch(lua_State *L)
|
|
|
|
|
{
|
2011-06-11 16:38:47 +00:00
|
|
|
|
const char *path = luaL_checkstring(L, 1);
|
|
|
|
|
const char *imode = luaL_checkstring(L, 2);
|
|
|
|
|
uint32_t mask = standard_event_mask;
|
|
|
|
|
if (*imode) {
|
|
|
|
|
if (!strcmp(imode, "Modify")) {
|
2012-02-16 15:49:34 +00:00
|
|
|
|
// act on modify instead of closeWrite
|
2011-06-11 16:38:47 +00:00
|
|
|
|
mask |= IN_MODIFY;
|
|
|
|
|
mask &= ~IN_CLOSE_WRITE;
|
|
|
|
|
} else if (!strcmp(imode, "CloseWrite")) {
|
2012-02-16 15:49:34 +00:00
|
|
|
|
// default
|
2011-06-11 16:38:47 +00:00
|
|
|
|
} else if (!strcmp(imode, "CloseWrite or Modify")) {
|
2012-02-16 15:49:34 +00:00
|
|
|
|
// acts on modify and closeWrite
|
2011-06-11 16:38:47 +00:00
|
|
|
|
mask |= IN_MODIFY;
|
|
|
|
|
} else if (!strcmp(imode, "CloseWrite after Modify")) {
|
2012-02-16 15:49:34 +00:00
|
|
|
|
// might be done in future
|
|
|
|
|
printlogf(L, "Error", "'CloseWrite after Modify' not implemented.");
|
2011-06-11 16:38:47 +00:00
|
|
|
|
exit(-1); // ERRNO
|
|
|
|
|
} else {
|
2012-02-16 15:49:34 +00:00
|
|
|
|
printlogf(L, "Error", "'%s' not a valid inotfiyMode.", imode);
|
2011-06-11 16:38:47 +00:00
|
|
|
|
exit(-1); // ERRNO
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int wd = inotify_add_watch(inotify_fd, path, mask);
|
2011-01-25 11:16:07 +00:00
|
|
|
|
if (wd < 0) {
|
2011-08-17 11:28:32 +00:00
|
|
|
|
if (errno == ENOSPC) {
|
2012-02-16 15:49:34 +00:00
|
|
|
|
printlogf(L, "Error", "Terminating since out of inotify watches.");
|
|
|
|
|
printlogf(L, "Error", "Consider increasing /proc/sys/fs/inotify/max_user_watches");
|
2011-08-17 11:28:32 +00:00
|
|
|
|
exit(-1); // ERRNO.
|
|
|
|
|
}
|
2012-02-16 15:49:34 +00:00
|
|
|
|
printlogf(L, "Inotify", "addwatch(%s)->%d; err=%d:%s", path, wd, errno, strerror(errno));
|
2011-01-25 11:16:07 +00:00
|
|
|
|
} else {
|
|
|
|
|
printlogf(L, "Inotify", "addwatch(%s)->%d", path, wd);
|
|
|
|
|
}
|
2010-11-22 20:09:52 +00:00
|
|
|
|
lua_pushinteger(L, wd);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Removes an inotify watch
|
2012-01-27 11:08:10 +00:00
|
|
|
|
*
|
2010-11-22 20:09:52 +00:00
|
|
|
|
* @param dir (Lua stack) numeric watch descriptor
|
|
|
|
|
* @return nil
|
|
|
|
|
*/
|
|
|
|
|
static int
|
|
|
|
|
l_rmwatch(lua_State *L)
|
|
|
|
|
{
|
2010-11-29 16:12:13 +00:00
|
|
|
|
int wd = luaL_checkinteger(L, 1);
|
2010-11-22 20:09:52 +00:00
|
|
|
|
inotify_rm_watch(inotify_fd, wd);
|
2010-11-24 18:19:13 +00:00
|
|
|
|
printlogf(L, "Inotify", "rmwatch()<-%d", wd);
|
2010-11-22 20:09:52 +00:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2010-11-28 09:15:54 +00:00
|
|
|
|
/**
|
|
|
|
|
* Cores inotify functions.
|
|
|
|
|
*/
|
2012-09-25 15:29:12 +00:00
|
|
|
|
static const luaL_Reg linotfylib[] = {
|
2010-11-22 20:09:52 +00:00
|
|
|
|
{"addwatch", l_addwatch },
|
|
|
|
|
{"rmwatch", l_rmwatch },
|
|
|
|
|
{NULL, NULL}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Buffer for MOVE_FROM events.
|
2010-11-22 21:17:08 +00:00
|
|
|
|
* Lsyncd buffers MOVE_FROM events to check if
|
|
|
|
|
* they are followed by MOVE_TO events with identical cookie
|
|
|
|
|
* then they are condensed into one move event to be sent to the
|
|
|
|
|
* runner
|
2010-11-22 20:09:52 +00:00
|
|
|
|
*/
|
|
|
|
|
static struct inotify_event * move_event_buf = NULL;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Memory allocated for move_event_buf
|
|
|
|
|
*/
|
|
|
|
|
static size_t move_event_buf_size = 0;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* true if the buffer is used.
|
|
|
|
|
*/
|
|
|
|
|
static bool move_event = false;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Handles an inotify event.
|
|
|
|
|
*/
|
2011-11-23 10:22:10 +00:00
|
|
|
|
static void
|
|
|
|
|
handle_event(lua_State *L,
|
|
|
|
|
struct inotify_event *event)
|
2010-11-22 20:09:52 +00:00
|
|
|
|
{
|
2010-11-24 18:19:13 +00:00
|
|
|
|
const char *event_type = NULL;
|
2010-11-22 20:09:52 +00:00
|
|
|
|
|
2012-02-16 15:49:34 +00:00
|
|
|
|
// used to execute two events in case of unmatched MOVE_FROM buffer
|
2010-11-22 20:09:52 +00:00
|
|
|
|
struct inotify_event *after_buf = NULL;
|
|
|
|
|
if (event && (IN_Q_OVERFLOW & event->mask)) {
|
|
|
|
|
/* and overflow happened, tells the runner */
|
|
|
|
|
load_runner_func(L, "overflow");
|
|
|
|
|
if (lua_pcall(L, 0, 0, -2)) {
|
|
|
|
|
exit(-1); // ERRNO
|
|
|
|
|
}
|
|
|
|
|
lua_pop(L, 1);
|
|
|
|
|
hup = 1;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2012-02-16 15:49:34 +00:00
|
|
|
|
// cancel on ignored or resetting
|
2010-11-22 20:09:52 +00:00
|
|
|
|
if (event && (IN_IGNORED & event->mask)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (event && event->len == 0) {
|
2012-02-16 15:49:34 +00:00
|
|
|
|
// sometimes inotify sends such strange events,
|
|
|
|
|
// (e.g. when touching a dir
|
2010-11-22 20:09:52 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (event == NULL) {
|
2012-02-16 15:49:34 +00:00
|
|
|
|
// a buffered MOVE_FROM is not followed by anything,
|
|
|
|
|
// thus it is unary
|
2010-11-22 20:09:52 +00:00
|
|
|
|
event = move_event_buf;
|
2010-11-24 18:19:13 +00:00
|
|
|
|
event_type = "Delete";
|
2010-11-22 20:09:52 +00:00
|
|
|
|
move_event = false;
|
2011-11-23 10:22:10 +00:00
|
|
|
|
} else if (move_event &&
|
|
|
|
|
( !(IN_MOVED_TO & event->mask) ||
|
2010-11-22 20:09:52 +00:00
|
|
|
|
event->cookie != move_event_buf->cookie) ) {
|
2012-02-16 15:49:34 +00:00
|
|
|
|
// there is a MOVE_FROM event in the buffer and this is not the match
|
|
|
|
|
// continue in this function iteration to handle the buffer instead */
|
2010-11-24 18:19:13 +00:00
|
|
|
|
logstring("Inotify", "icore, changing unary MOVE_FROM into DELETE")
|
2010-11-22 20:09:52 +00:00
|
|
|
|
after_buf = event;
|
|
|
|
|
event = move_event_buf;
|
2010-11-24 18:19:13 +00:00
|
|
|
|
event_type = "Delete";
|
2010-11-22 20:09:52 +00:00
|
|
|
|
move_event = false;
|
2011-11-23 10:22:10 +00:00
|
|
|
|
} else if ( move_event &&
|
|
|
|
|
(IN_MOVED_TO & event->mask) &&
|
2010-11-22 20:09:52 +00:00
|
|
|
|
event->cookie == move_event_buf->cookie ) {
|
2012-02-16 15:49:34 +00:00
|
|
|
|
// this is indeed a matched move */
|
2010-11-24 18:19:13 +00:00
|
|
|
|
event_type = "Move";
|
2010-11-22 20:09:52 +00:00
|
|
|
|
move_event = false;
|
|
|
|
|
} else if (IN_MOVED_FROM & event->mask) {
|
2012-02-16 15:49:34 +00:00
|
|
|
|
// just the MOVE_FROM, buffers this event, and wait if next event is
|
|
|
|
|
// a matching MOVED_TO of this was an unary move out of the watched
|
|
|
|
|
// tree.
|
2010-11-22 20:09:52 +00:00
|
|
|
|
size_t el = sizeof(struct inotify_event) + event->len;
|
|
|
|
|
if (move_event_buf_size < el) {
|
|
|
|
|
move_event_buf_size = el;
|
|
|
|
|
move_event_buf = s_realloc(move_event_buf, el);
|
|
|
|
|
}
|
|
|
|
|
memcpy(move_event_buf, event, el);
|
|
|
|
|
move_event = true;
|
|
|
|
|
return;
|
|
|
|
|
} else if (IN_MOVED_TO & event->mask) {
|
2012-02-16 15:49:34 +00:00
|
|
|
|
// must be an unary move-to
|
2010-11-22 20:09:52 +00:00
|
|
|
|
event_type = CREATE;
|
|
|
|
|
} else if (IN_ATTRIB & event->mask) {
|
2012-02-16 15:49:34 +00:00
|
|
|
|
// just attrib change
|
2010-11-22 20:09:52 +00:00
|
|
|
|
event_type = ATTRIB;
|
2012-03-16 15:30:55 +00:00
|
|
|
|
} else if ((IN_CLOSE_WRITE | IN_MODIFY) & event->mask) {
|
|
|
|
|
// modify, or closed after written something
|
|
|
|
|
// the event type received depends settings.inotifyMode
|
2010-11-22 20:09:52 +00:00
|
|
|
|
event_type = MODIFY;
|
|
|
|
|
} else if (IN_CREATE & event->mask) {
|
2012-02-16 15:49:34 +00:00
|
|
|
|
// a new file
|
2010-11-22 20:09:52 +00:00
|
|
|
|
event_type = CREATE;
|
|
|
|
|
} else if (IN_DELETE & event->mask) {
|
2012-02-16 15:49:34 +00:00
|
|
|
|
// rm'ed
|
2010-11-22 20:09:52 +00:00
|
|
|
|
event_type = DELETE;
|
|
|
|
|
} else {
|
2010-11-24 18:19:13 +00:00
|
|
|
|
logstring("Inotify", "icore, skipped some inotify event.");
|
2010-11-22 20:09:52 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-16 15:49:34 +00:00
|
|
|
|
// and hands over to runner
|
2011-11-23 10:22:10 +00:00
|
|
|
|
load_runner_func(L, "inotifyEvent");
|
2010-11-24 18:19:13 +00:00
|
|
|
|
if (!event_type) {
|
2011-11-23 10:22:10 +00:00
|
|
|
|
logstring("Error", "Internal: unknown event in handle_event()");
|
2010-11-22 20:09:52 +00:00
|
|
|
|
exit(-1); // ERRNO
|
|
|
|
|
}
|
2011-11-23 10:22:10 +00:00
|
|
|
|
lua_pushstring(L, event_type);
|
2010-11-22 20:09:52 +00:00
|
|
|
|
if (event_type != MOVE) {
|
|
|
|
|
lua_pushnumber(L, event->wd);
|
|
|
|
|
} else {
|
|
|
|
|
lua_pushnumber(L, move_event_buf->wd);
|
|
|
|
|
}
|
|
|
|
|
lua_pushboolean(L, (event->mask & IN_ISDIR) != 0);
|
2010-11-29 10:56:39 +00:00
|
|
|
|
l_now(L);
|
2010-11-22 20:09:52 +00:00
|
|
|
|
if (event_type == MOVE) {
|
|
|
|
|
lua_pushstring(L, move_event_buf->name);
|
|
|
|
|
lua_pushnumber(L, event->wd);
|
|
|
|
|
lua_pushstring(L, event->name);
|
|
|
|
|
} else {
|
|
|
|
|
lua_pushstring(L, event->name);
|
|
|
|
|
lua_pushnil(L);
|
|
|
|
|
lua_pushnil(L);
|
|
|
|
|
}
|
|
|
|
|
if (lua_pcall(L, 7, 0, -9)) {
|
|
|
|
|
exit(-1); // ERRNO
|
|
|
|
|
}
|
|
|
|
|
lua_pop(L, 1);
|
2010-11-23 23:19:01 +00:00
|
|
|
|
|
2012-02-16 15:49:34 +00:00
|
|
|
|
// if there is a buffered event, executes it
|
2010-11-22 20:09:52 +00:00
|
|
|
|
if (after_buf) {
|
2010-11-24 18:19:13 +00:00
|
|
|
|
logstring("Inotify", "icore, handling buffered event.");
|
2010-11-22 20:09:52 +00:00
|
|
|
|
handle_event(L, after_buf);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-23 10:22:10 +00:00
|
|
|
|
/**
|
2010-11-22 21:17:08 +00:00
|
|
|
|
* buffer to read inotify events into
|
|
|
|
|
*/
|
|
|
|
|
static size_t readbuf_size = 2048;
|
|
|
|
|
static char * readbuf = NULL;
|
2010-11-22 20:09:52 +00:00
|
|
|
|
|
|
|
|
|
/**
|
2011-11-23 10:22:10 +00:00
|
|
|
|
* Called by function pointer from when the inotify file descriptor
|
2010-11-22 21:17:08 +00:00
|
|
|
|
* became ready. Reads it contents and forward all received events
|
|
|
|
|
* to the runner.
|
2010-11-22 20:09:52 +00:00
|
|
|
|
*/
|
|
|
|
|
static void
|
2010-11-28 10:47:57 +00:00
|
|
|
|
inotify_ready(lua_State *L, struct observance *obs)
|
2010-11-22 20:09:52 +00:00
|
|
|
|
{
|
2010-11-28 10:47:57 +00:00
|
|
|
|
if (obs->fd != inotify_fd) {
|
|
|
|
|
logstring("Error", "Internal, inotify_fd != ob->fd");
|
|
|
|
|
exit(-1); // ERRNO
|
|
|
|
|
}
|
2010-11-22 20:09:52 +00:00
|
|
|
|
while(true) {
|
2011-11-23 10:22:10 +00:00
|
|
|
|
ptrdiff_t len;
|
2010-11-23 23:19:01 +00:00
|
|
|
|
int err;
|
2010-11-22 20:09:52 +00:00
|
|
|
|
do {
|
|
|
|
|
len = read (inotify_fd, readbuf, readbuf_size);
|
2010-11-23 23:19:01 +00:00
|
|
|
|
err = errno;
|
|
|
|
|
if (len < 0 && err == EINVAL) {
|
2012-02-16 15:49:34 +00:00
|
|
|
|
// kernel > 2.6.21 indicates that way that way that
|
|
|
|
|
// the buffer was too small to fit a filename.
|
|
|
|
|
// double its size and try again. When using a lower
|
|
|
|
|
// kernel and a filename > 2KB appears lsyncd
|
|
|
|
|
// will fail. (but does a 2KB filename really happen?)
|
|
|
|
|
//
|
2010-11-22 20:09:52 +00:00
|
|
|
|
readbuf_size *= 2;
|
|
|
|
|
readbuf = s_realloc(readbuf, readbuf_size);
|
|
|
|
|
}
|
2011-11-23 10:22:10 +00:00
|
|
|
|
} while(len < 0 && err == EINVAL);
|
2010-11-22 20:09:52 +00:00
|
|
|
|
if (len == 0) {
|
2012-02-16 15:49:34 +00:00
|
|
|
|
// nothing more inotify
|
2010-11-22 20:09:52 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (len < 0) {
|
2010-11-23 23:19:01 +00:00
|
|
|
|
if (err == EAGAIN) {
|
2012-02-16 15:49:34 +00:00
|
|
|
|
// nothing more inotify
|
2010-11-22 20:09:52 +00:00
|
|
|
|
break;
|
|
|
|
|
} else {
|
|
|
|
|
printlogf(L, "Error", "Read fail on inotify");
|
|
|
|
|
exit(-1); // ERRNO
|
|
|
|
|
}
|
|
|
|
|
}
|
2010-11-22 21:17:08 +00:00
|
|
|
|
{
|
|
|
|
|
int i = 0;
|
|
|
|
|
while (i < len && !hup && !term) {
|
2011-11-23 10:22:10 +00:00
|
|
|
|
struct inotify_event *event =
|
2010-11-22 21:17:08 +00:00
|
|
|
|
(struct inotify_event *) &readbuf[i];
|
|
|
|
|
handle_event(L, event);
|
|
|
|
|
i += sizeof(struct inotify_event) + event->len;
|
|
|
|
|
}
|
2010-11-22 20:09:52 +00:00
|
|
|
|
}
|
|
|
|
|
if (!move_event) {
|
2012-02-16 15:49:34 +00:00
|
|
|
|
// give it a pause if not endangering splitting a move
|
2010-11-22 20:09:52 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
2010-11-22 21:17:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-02-16 15:49:34 +00:00
|
|
|
|
// checks if there is an unary MOVE_FROM left in the buffer
|
2010-11-22 20:09:52 +00:00
|
|
|
|
if (move_event) {
|
2010-11-24 18:19:13 +00:00
|
|
|
|
logstring("Inotify", "icore, handling unary move from.");
|
2011-11-23 10:22:10 +00:00
|
|
|
|
handle_event(L, NULL);
|
2010-11-22 20:09:52 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-23 10:22:10 +00:00
|
|
|
|
/**
|
2010-11-22 20:09:52 +00:00
|
|
|
|
* registers inotify functions.
|
|
|
|
|
*/
|
|
|
|
|
extern void
|
2011-11-23 10:22:10 +00:00
|
|
|
|
register_inotify(lua_State *L)
|
2010-12-01 16:12:15 +00:00
|
|
|
|
{
|
2012-10-02 00:56:29 +00:00
|
|
|
|
luaL_register(L, LSYNCD_INOTIFYLIBNAME, linotfylib);
|
2010-11-22 20:09:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2011-11-23 10:22:10 +00:00
|
|
|
|
/**
|
|
|
|
|
* closes inotify
|
2010-11-28 09:15:54 +00:00
|
|
|
|
*/
|
|
|
|
|
static void
|
2011-11-23 10:22:10 +00:00
|
|
|
|
inotify_tidy(struct observance *obs)
|
2010-12-01 16:12:15 +00:00
|
|
|
|
{
|
2010-11-28 10:47:57 +00:00
|
|
|
|
if (obs->fd != inotify_fd) {
|
2010-11-28 09:15:54 +00:00
|
|
|
|
logstring("Error", "Internal, inotify_fd != ob->fd");
|
|
|
|
|
exit(-1); // ERRNO
|
|
|
|
|
}
|
|
|
|
|
close(inotify_fd);
|
|
|
|
|
free(readbuf);
|
|
|
|
|
readbuf = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-23 10:22:10 +00:00
|
|
|
|
/**
|
2010-11-22 20:09:52 +00:00
|
|
|
|
* opens and initalizes inotify.
|
|
|
|
|
*/
|
|
|
|
|
extern void
|
2011-11-23 10:22:10 +00:00
|
|
|
|
open_inotify(lua_State *L)
|
2010-12-01 16:12:15 +00:00
|
|
|
|
{
|
2010-11-22 21:17:08 +00:00
|
|
|
|
if (readbuf) {
|
2011-11-23 10:22:10 +00:00
|
|
|
|
logstring("Error",
|
|
|
|
|
"internal fail, inotify readbuf!=NULL in open_inotify()")
|
2010-11-22 21:17:08 +00:00
|
|
|
|
exit(-1); // ERRNO
|
|
|
|
|
}
|
2010-11-22 20:09:52 +00:00
|
|
|
|
readbuf = s_malloc(readbuf_size);
|
|
|
|
|
|
|
|
|
|
inotify_fd = inotify_init();
|
2010-11-29 16:12:13 +00:00
|
|
|
|
if (inotify_fd < 0) {
|
2011-11-23 10:22:10 +00:00
|
|
|
|
printlogf(L, "Error",
|
|
|
|
|
"Cannot access inotify monitor! (%d:%s)",
|
2010-11-22 20:09:52 +00:00
|
|
|
|
errno, strerror(errno));
|
|
|
|
|
exit(-1); // ERRNO
|
|
|
|
|
}
|
2010-12-01 12:19:17 +00:00
|
|
|
|
printlogf(L, "Inotify", "inotify fd = %d", inotify_fd);
|
2010-11-22 20:09:52 +00:00
|
|
|
|
|
|
|
|
|
close_exec_fd(inotify_fd);
|
|
|
|
|
non_block_fd(inotify_fd);
|
2010-11-28 09:15:54 +00:00
|
|
|
|
observe_fd(inotify_fd, inotify_ready, NULL, inotify_tidy, NULL);
|
2010-11-22 20:09:52 +00:00
|
|
|
|
}
|
|
|
|
|
|