mirror of
https://github.com/octoleo/lsyncd.git
synced 2024-12-13 14:43:09 +00:00
splitted inotify into own c-file to be optional later.
This commit is contained in:
parent
ea0fce13e3
commit
45c7f3665f
@ -1,7 +1,7 @@
|
|||||||
AUTOMAKE_OPTIONS = foreign
|
AUTOMAKE_OPTIONS = foreign
|
||||||
CFLAGS = -Wall $(LIBLUA_CFLAGS)
|
CFLAGS = -Wall $(LIBLUA_CFLAGS)
|
||||||
bin_PROGRAMS = lsyncd
|
bin_PROGRAMS = lsyncd
|
||||||
lsyncd_SOURCES = lsyncd.c lsyncd.lua
|
lsyncd_SOURCES = lsyncd.c lsyncd.lua inotify.c
|
||||||
lsyncd_LDADD = $(LIBLUA_LIBS)
|
lsyncd_LDADD = $(LIBLUA_LIBS)
|
||||||
exampledir = $(datarootdir)/doc/@PACKAGE@
|
exampledir = $(datarootdir)/doc/@PACKAGE@
|
||||||
dist_example_DATA = \
|
dist_example_DATA = \
|
||||||
@ -23,7 +23,8 @@ runner_DATA = lsyncd.lua
|
|||||||
else
|
else
|
||||||
|
|
||||||
# or compiles it into the binary
|
# or compiles it into the binary
|
||||||
lsyncd: luac.o $(lsyncd_LDADD)
|
|
||||||
|
lsyncd_LDADD += luac.o
|
||||||
|
|
||||||
objarch: | lsyncd.o
|
objarch: | lsyncd.o
|
||||||
objdump -f lsyncd.o | grep architecture | \
|
objdump -f lsyncd.o | grep architecture | \
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
# Process this file with autoconf to produce a configure script.
|
# Process this file with autoconf to produce a configure script.
|
||||||
#AC_PREREQ(2.60)
|
#AC_PREREQ(2.60)
|
||||||
AC_INIT(lsyncd, 2.0beta2, axkibe@gmail.com)
|
AC_INIT(lsyncd, 2.0beta2, axkibe@gmail.com)
|
||||||
AC_CONFIG_SRCDIR([lsyncd.c],[lsyncd.lua])
|
AC_CONFIG_SRCDIR([lsyncd.c],[lsyncd.lua],[inotify.c])
|
||||||
AC_CONFIG_HEADER([config.h])
|
AC_CONFIG_HEADER([config.h],[lsyncd.h])
|
||||||
AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
|
AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
|
||||||
# Checks for programs.
|
# Checks for programs.
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
|
324
inotify.c
Normal file
324
inotify.c
Normal file
@ -0,0 +1,324 @@
|
|||||||
|
/**
|
||||||
|
* lsyncd.c Live (Mirror) Syncing Demon
|
||||||
|
*
|
||||||
|
* License: GPLv2 (see COPYING) or any later version
|
||||||
|
*
|
||||||
|
* Authors: Axel Kittenberger <axkibe@gmail.com>
|
||||||
|
*
|
||||||
|
* Event interface for Lsyncd to Linux´ inotify.
|
||||||
|
*/
|
||||||
|
#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>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The inotify file descriptor.
|
||||||
|
*/
|
||||||
|
static int inotify_fd;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO allow configure.
|
||||||
|
*/
|
||||||
|
static const uint32_t standard_event_mask =
|
||||||
|
IN_ATTRIB | IN_CLOSE_WRITE | IN_CREATE |
|
||||||
|
IN_DELETE | IN_DELETE_SELF | IN_MOVED_FROM |
|
||||||
|
IN_MOVED_TO | IN_DONT_FOLLOW | IN_ONLYDIR;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an inotify watch
|
||||||
|
*
|
||||||
|
* @param dir (Lua stack) path to directory
|
||||||
|
* @return (Lua stack) numeric watch descriptor
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
l_addwatch(lua_State *L)
|
||||||
|
{
|
||||||
|
const char *path = luaL_checkstring(L, 1);
|
||||||
|
lua_Integer wd = inotify_add_watch(inotify_fd, path, standard_event_mask);
|
||||||
|
lua_pushinteger(L, wd);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes an inotify watch
|
||||||
|
*
|
||||||
|
* @param dir (Lua stack) numeric watch descriptor
|
||||||
|
* @return nil
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
l_rmwatch(lua_State *L)
|
||||||
|
{
|
||||||
|
lua_Integer wd = luaL_checkinteger(L, 1);
|
||||||
|
inotify_rm_watch(inotify_fd, wd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const luaL_reg linotfylib[] = {
|
||||||
|
{"addwatch", l_addwatch },
|
||||||
|
{"rmwatch", l_rmwatch },
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Buffer for MOVE_FROM events.
|
||||||
|
* Lsyncd buffers MOVE_FROM events to check if
|
||||||
|
*/
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
handle_event(lua_State *L,
|
||||||
|
struct inotify_event *event)
|
||||||
|
{
|
||||||
|
int event_type;
|
||||||
|
|
||||||
|
/* used to execute two events in case of unmatched MOVE_FROM buffer */
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
/* cancel on ignored or resetting */
|
||||||
|
if (event && (IN_IGNORED & event->mask)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (event && event->len == 0) {
|
||||||
|
/* sometimes inotify sends such strange events,
|
||||||
|
* (e.g. when touching a dir */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event == NULL) {
|
||||||
|
/* a buffered MOVE_FROM is not followed by anything,
|
||||||
|
thus it is unary */
|
||||||
|
event = move_event_buf;
|
||||||
|
event_type = DELETE;
|
||||||
|
move_event = false;
|
||||||
|
} else if (move_event &&
|
||||||
|
( !(IN_MOVED_TO & event->mask) ||
|
||||||
|
event->cookie != move_event_buf->cookie) ) {
|
||||||
|
/* there is a MOVE_FROM event in the buffer and this is not the match
|
||||||
|
* continue in this function iteration to handler the buffer instead */
|
||||||
|
after_buf = event;
|
||||||
|
event = move_event_buf;
|
||||||
|
event_type = DELETE;
|
||||||
|
move_event = false;
|
||||||
|
} else if ( move_event &&
|
||||||
|
(IN_MOVED_TO & event->mask) &&
|
||||||
|
event->cookie == move_event_buf->cookie ) {
|
||||||
|
/* this is indeed a matched move */
|
||||||
|
event_type = MOVE;
|
||||||
|
move_event = false;
|
||||||
|
} else if (IN_MOVED_FROM & event->mask) {
|
||||||
|
/* 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. */
|
||||||
|
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) {
|
||||||
|
/* must be an unary move-to */
|
||||||
|
event_type = CREATE;
|
||||||
|
} else if (IN_MOVED_FROM & event->mask) {
|
||||||
|
/* must be an unary move-from */
|
||||||
|
event_type = DELETE;
|
||||||
|
} else if (IN_ATTRIB & event->mask) {
|
||||||
|
/* just attrib change */
|
||||||
|
event_type = ATTRIB;
|
||||||
|
} else if (IN_CLOSE_WRITE & event->mask) {
|
||||||
|
/* closed after written something */
|
||||||
|
event_type = MODIFY;
|
||||||
|
} else if (IN_CREATE & event->mask) {
|
||||||
|
/* a new file */
|
||||||
|
event_type = CREATE;
|
||||||
|
} else if (IN_DELETE & event->mask) {
|
||||||
|
/* rm'ed */
|
||||||
|
event_type = DELETE;
|
||||||
|
} else {
|
||||||
|
logstring("Inotify", "skipped some inotify event.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* and hands over to runner */
|
||||||
|
load_runner_func(L, "inotifyEvent");
|
||||||
|
switch(event_type) {
|
||||||
|
case ATTRIB : lua_pushstring(L, "Attrib"); break;
|
||||||
|
case MODIFY : lua_pushstring(L, "Modify"); break;
|
||||||
|
case CREATE : lua_pushstring(L, "Create"); break;
|
||||||
|
case DELETE : lua_pushstring(L, "Delete"); break;
|
||||||
|
case MOVE : lua_pushstring(L, "Move"); break;
|
||||||
|
default :
|
||||||
|
logstring("Error", "Internal: unknown event in handle_event()");
|
||||||
|
exit(-1); // ERRNO
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
lua_pushinteger(L, times(NULL));
|
||||||
|
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);
|
||||||
|
/* if there is a buffered event executes it */
|
||||||
|
if (after_buf) {
|
||||||
|
logstring("Inotify", "handling buffered event.");
|
||||||
|
handle_event(L, after_buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t readbuf_size = 2048;
|
||||||
|
char *readbuf = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* inotify file descriptor became ready.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
inotify_ready(lua_State *L, int fd, void *extra)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
int i = 0;
|
||||||
|
do {
|
||||||
|
len = read (inotify_fd, readbuf, readbuf_size);
|
||||||
|
if (len < 0 && errno == EINVAL) {
|
||||||
|
/* 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?)
|
||||||
|
*/
|
||||||
|
readbuf_size *= 2;
|
||||||
|
readbuf = s_realloc(readbuf, readbuf_size);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} while(0);
|
||||||
|
if (len == 0) {
|
||||||
|
/* nothing more inotify */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (len < 0) {
|
||||||
|
if (errno == EAGAIN) {
|
||||||
|
/* nothing more inotify */
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
printlogf(L, "Error", "Read fail on inotify");
|
||||||
|
exit(-1); // ERRNO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (i < len && !hup && !term) {
|
||||||
|
struct inotify_event *event =
|
||||||
|
(struct inotify_event *) &readbuf[i];
|
||||||
|
handle_event(L, event);
|
||||||
|
i += sizeof(struct inotify_event) + event->len;
|
||||||
|
}
|
||||||
|
if (!move_event) {
|
||||||
|
/* give it a pause if not endangering splitting a move */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* checks if there is an unary MOVE_FROM left in the buffer */
|
||||||
|
if (move_event) {
|
||||||
|
logstring("Inotify", "handling unary move from.");
|
||||||
|
handle_event(L, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* registers inotify functions.
|
||||||
|
*/
|
||||||
|
extern void
|
||||||
|
register_inotify(lua_State *L) {
|
||||||
|
lua_pushstring(L, "inotify");
|
||||||
|
luaL_register(L, "inotify", linotfylib);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* opens and initalizes inotify.
|
||||||
|
*/
|
||||||
|
extern void
|
||||||
|
open_inotify(lua_State *L) {
|
||||||
|
readbuf = s_malloc(readbuf_size);
|
||||||
|
|
||||||
|
inotify_fd = inotify_init();
|
||||||
|
if (inotify_fd == -1) {
|
||||||
|
printlogf(L, "Error",
|
||||||
|
"Cannot create inotify instance! (%d:%s)",
|
||||||
|
errno, strerror(errno));
|
||||||
|
exit(-1); // ERRNO
|
||||||
|
}
|
||||||
|
|
||||||
|
close_exec_fd(inotify_fd);
|
||||||
|
non_block_fd(inotify_fd);
|
||||||
|
observe_fd(inotify_fd, inotify_ready, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* closes inotify
|
||||||
|
*/
|
||||||
|
extern void
|
||||||
|
close_inotify() {
|
||||||
|
close(inotify_fd);
|
||||||
|
free(readbuf);
|
||||||
|
}
|
||||||
|
|
539
lsyncd.c
539
lsyncd.c
@ -11,12 +11,6 @@
|
|||||||
*/
|
*/
|
||||||
#include "lsyncd.h"
|
#include "lsyncd.h"
|
||||||
|
|
||||||
#ifdef HAVE_SYS_INOTIFY_H
|
|
||||||
# include <sys/inotify.h>
|
|
||||||
#else
|
|
||||||
# error Missing <sys/inotify.h>; supply kernel-headers and rerun configure.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/times.h>
|
#include <sys/times.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -47,50 +41,10 @@ extern char _binary_luac_out_start;
|
|||||||
extern char _binary_luac_out_end;
|
extern char _binary_luac_out_end;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
|
||||||
* The inotify file descriptor.
|
|
||||||
*/
|
|
||||||
static int inotify_fd;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO allow configure.
|
|
||||||
*/
|
|
||||||
static const uint32_t standard_event_mask =
|
|
||||||
IN_ATTRIB | IN_CLOSE_WRITE | IN_CREATE |
|
|
||||||
IN_DELETE | IN_DELETE_SELF | IN_MOVED_FROM |
|
|
||||||
IN_MOVED_TO | IN_DONT_FOLLOW | IN_ONLYDIR;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* configuration parameters
|
* configuration parameters
|
||||||
*/
|
*/
|
||||||
static struct settings {
|
struct settings settings = {
|
||||||
/**
|
|
||||||
* If not NULL Lsyncd logs into this file.
|
|
||||||
*/
|
|
||||||
char * log_file;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If true Lsyncd sends log messages to syslog
|
|
||||||
*/
|
|
||||||
bool log_syslog;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* -1 logs everything, 0 normal mode,
|
|
||||||
* LOG_ERROR logs errors only.
|
|
||||||
*/
|
|
||||||
int log_level;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* True if Lsyncd shall not daemonize.
|
|
||||||
*/
|
|
||||||
bool nodaemon;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If not NULL Lsyncd writes its pid into this file.
|
|
||||||
*/
|
|
||||||
char * pidfile;
|
|
||||||
|
|
||||||
} settings = {
|
|
||||||
.log_file = NULL,
|
.log_file = NULL,
|
||||||
.log_syslog = false,
|
.log_syslog = false,
|
||||||
.log_level = 0,
|
.log_level = 0,
|
||||||
@ -113,8 +67,8 @@ static bool running = false;
|
|||||||
/**
|
/**
|
||||||
* Set to TERM or HUP in signal handler, when lsyncd should end or reset ASAP.
|
* Set to TERM or HUP in signal handler, when lsyncd should end or reset ASAP.
|
||||||
*/
|
*/
|
||||||
static volatile sig_atomic_t hup = 0;
|
volatile sig_atomic_t hup = 0;
|
||||||
static volatile sig_atomic_t term = 0;
|
volatile sig_atomic_t term = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The kernels clock ticks per second.
|
* The kernels clock ticks per second.
|
||||||
@ -168,7 +122,7 @@ static struct logcat *logcats[26] = {0,};
|
|||||||
* Returns the positive priority if category is configured to be logged.
|
* Returns the positive priority if category is configured to be logged.
|
||||||
* or -1
|
* or -1
|
||||||
*/
|
*/
|
||||||
static int
|
extern int
|
||||||
check_logcat(const char *name)
|
check_logcat(const char *name)
|
||||||
{
|
{
|
||||||
struct logcat *lc;
|
struct logcat *lc;
|
||||||
@ -323,7 +277,6 @@ printlogf0(lua_State *L,
|
|||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Simple memory management
|
* Simple memory management
|
||||||
*
|
|
||||||
* TODO: call the garbace collector in case of out of memory.
|
* TODO: call the garbace collector in case of out of memory.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
@ -393,9 +346,6 @@ s_strdup(const char *src)
|
|||||||
* write() can manage.
|
* write() can manage.
|
||||||
*/
|
*/
|
||||||
struct pipemsg {
|
struct pipemsg {
|
||||||
/* pipe file descriptor */
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
/* message to send */
|
/* message to send */
|
||||||
char *text;
|
char *text;
|
||||||
|
|
||||||
@ -407,19 +357,29 @@ struct pipemsg {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All pipes currently active.
|
* Called by the core whenever a pipe becomes
|
||||||
|
* writeable again
|
||||||
*/
|
*/
|
||||||
static struct pipemsg *pipes = NULL;
|
static void
|
||||||
|
pipe_writey(lua_State *L, int fd, void *extra) {
|
||||||
/**
|
struct pipemsg *pm = (struct pipemsg *) extra;
|
||||||
* amount of pipes allocated.
|
int len = write(fd, pm->text + pm->pos, pm->tlen - pm->pos);
|
||||||
*/
|
bool do_close = false;
|
||||||
size_t pipes_size = 0;
|
pm->pos += len;
|
||||||
|
if (len < 0) {
|
||||||
/**
|
logstring("Normal", "broken pipe.");
|
||||||
* number of pipes used.
|
do_close = true;
|
||||||
*/
|
} else if (pm->pos >= pm->tlen) {
|
||||||
size_t pipes_len = 0;
|
logstring("Debug", "finished pipe.");
|
||||||
|
do_close = true;
|
||||||
|
}
|
||||||
|
if (do_close) {
|
||||||
|
close(fd);
|
||||||
|
free(pm->text);
|
||||||
|
free(extra);
|
||||||
|
unobserve_fd(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@ -489,35 +449,6 @@ write_pidfile(lua_State *L, const char *pidfile) {
|
|||||||
|
|
||||||
static int l_stackdump(lua_State* L);
|
static int l_stackdump(lua_State* L);
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an inotify watch
|
|
||||||
*
|
|
||||||
* @param dir (Lua stack) path to directory
|
|
||||||
* @return (Lua stack) numeric watch descriptor
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
l_inotifyadd(lua_State *L)
|
|
||||||
{
|
|
||||||
const char *path = luaL_checkstring(L, 1);
|
|
||||||
lua_Integer wd = inotify_add_watch(inotify_fd, path, standard_event_mask);
|
|
||||||
lua_pushinteger(L, wd);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes an inotify watch
|
|
||||||
*
|
|
||||||
* @param dir (Lua stack) numeric watch descriptor
|
|
||||||
* @return nil
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
l_inotifyrm(lua_State *L)
|
|
||||||
{
|
|
||||||
lua_Integer wd = luaL_checkinteger(L, 1);
|
|
||||||
inotify_rm_watch(inotify_fd, wd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs a message.
|
* Logs a message.
|
||||||
*
|
*
|
||||||
@ -764,17 +695,13 @@ l_exec(lua_State *L)
|
|||||||
close(pipefd[1]);
|
close(pipefd[1]);
|
||||||
logstring("Exec", "one-sweeped pipe");
|
logstring("Exec", "one-sweeped pipe");
|
||||||
} else {
|
} else {
|
||||||
int p = pipes_len;
|
struct pipemsg *pm;
|
||||||
logstring("Exec", "adding delayed pipe");
|
logstring("Exec", "adding pipe observer");
|
||||||
pipes_len++;
|
pm = s_calloc(1, sizeof(struct pipemsg));
|
||||||
if (pipes_len > pipes_size) {
|
pm->text = s_strdup(pipe_text);
|
||||||
pipes_size = pipes_len;
|
pm->tlen = tlen;
|
||||||
pipes = s_realloc(pipes, pipes_size*sizeof(struct pipemsg));
|
pm->pos = len;
|
||||||
}
|
observe_fd(pipefd[1], NULL, pipe_writey, pm);
|
||||||
pipes[p].fd = pipefd[1];
|
|
||||||
pipes[p].tlen = tlen;
|
|
||||||
pipes[p].pos = len;
|
|
||||||
pipes[p].text = s_strdup(pipe_text);
|
|
||||||
}
|
}
|
||||||
close(pipefd[0]);
|
close(pipefd[0]);
|
||||||
}
|
}
|
||||||
@ -783,7 +710,6 @@ l_exec(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a relative directory path to an absolute.
|
* Converts a relative directory path to an absolute.
|
||||||
*
|
*
|
||||||
@ -996,8 +922,6 @@ static const luaL_reg lsyncdlib[] = {
|
|||||||
{"configure", l_configure },
|
{"configure", l_configure },
|
||||||
{"earlier", l_earlier },
|
{"earlier", l_earlier },
|
||||||
{"exec", l_exec },
|
{"exec", l_exec },
|
||||||
{"inotifyadd", l_inotifyadd },
|
|
||||||
{"inotifyrm", l_inotifyrm },
|
|
||||||
{"log", l_log },
|
{"log", l_log },
|
||||||
{"now", l_now },
|
{"now", l_now },
|
||||||
{"readdir", l_readdir },
|
{"readdir", l_readdir },
|
||||||
@ -1027,7 +951,7 @@ static int callError;
|
|||||||
* Pushes a function from the runner on the stack.
|
* Pushes a function from the runner on the stack.
|
||||||
* Prior it pushed the callError handler.
|
* Prior it pushed the callError handler.
|
||||||
*/
|
*/
|
||||||
static void
|
extern void
|
||||||
load_runner_func(lua_State *L,
|
load_runner_func(lua_State *L,
|
||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
@ -1045,149 +969,138 @@ load_runner_func(lua_State *L,
|
|||||||
lua_remove(L, -2);
|
lua_remove(L, -2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Buffer for MOVE_FROM events.
|
|
||||||
* Lsyncd buffers MOVE_FROM events to check if
|
|
||||||
*/
|
|
||||||
struct inotify_event * move_event_buf = NULL;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Memory allocated for move_event_buf
|
* An observer to be called when a file descritor becomes
|
||||||
|
* read-ready or write-ready.
|
||||||
*/
|
*/
|
||||||
size_t move_event_buf_size = 0;
|
struct observer {
|
||||||
|
/**
|
||||||
|
* The file descriptor to observe.
|
||||||
|
*/
|
||||||
|
int fd;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* true if the buffer is used.
|
* Function to call when read becomes ready.
|
||||||
*/
|
*/
|
||||||
bool move_event = false;
|
void (*ready)(lua_State *L, int fd, void *extra);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles an inotify event.
|
* Function to call when write becomes ready.
|
||||||
*/
|
*/
|
||||||
static void
|
void (*writey)(lua_State *L, int fd, void *extra);
|
||||||
handle_event(lua_State *L,
|
|
||||||
struct inotify_event *event)
|
/**
|
||||||
|
* Extra tokens to pass to the functions-
|
||||||
|
*/
|
||||||
|
void *extra;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of file descriptor watches.
|
||||||
|
*/
|
||||||
|
static struct observer * observers = NULL;
|
||||||
|
static int observers_len = 0;
|
||||||
|
static int observers_size = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of file descriptors to unobserve.
|
||||||
|
* While working for the oberver lists, it may
|
||||||
|
* not be altered, thus unobserve stores here the
|
||||||
|
* actions that will be delayed.
|
||||||
|
*/
|
||||||
|
static int *unobservers = NULL;
|
||||||
|
static int unobservers_len = 0;
|
||||||
|
static int unobservers_size = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* true while the observers list is being handled.
|
||||||
|
*/
|
||||||
|
static bool observer_action = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Core watches a filedescriptor to become ready,
|
||||||
|
* one of read_ready or write_ready may be zero
|
||||||
|
*/
|
||||||
|
extern void
|
||||||
|
observe_fd(int fd,
|
||||||
|
void (*ready)(lua_State *L, int fd, void *extra),
|
||||||
|
void (*writey)(lua_State *L, int fd, void *extra),
|
||||||
|
void *extra)
|
||||||
{
|
{
|
||||||
int event_type;
|
int pos;
|
||||||
|
if (observer_action) {
|
||||||
/* used to execute two events in case of unmatched MOVE_FROM buffer */
|
// TODO
|
||||||
struct inotify_event *after_buf = NULL;
|
logstring("Error",
|
||||||
if (hup || term) {
|
"Adding observers in ready/writey handlers not yet supported");
|
||||||
return;
|
|
||||||
}
|
|
||||||
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
|
exit(-1); // ERRNO
|
||||||
}
|
}
|
||||||
lua_pop(L, 1);
|
|
||||||
hup = 1;
|
if (observers_len + 1 > observers_size) {
|
||||||
return;
|
observers_size = observers_len + 1;
|
||||||
|
observers = s_realloc(observers,
|
||||||
|
observers_size * sizeof(struct observer));
|
||||||
}
|
}
|
||||||
/* cancel on ignored or resetting */
|
for(pos = 0; pos < observers_len; pos++) {
|
||||||
if (event && (IN_IGNORED & event->mask)) {
|
if (observers[pos].fd <= fd) {
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
if (event && event->len == 0) {
|
}
|
||||||
/* sometimes inotify sends such strange events,
|
if (observers[pos].fd == fd) {
|
||||||
* (e.g. when touching a dir */
|
logstring("Error",
|
||||||
|
"Observing already an observed file descriptor.");
|
||||||
|
exit(-1); // ERRNO
|
||||||
|
}
|
||||||
|
memmove(observers + pos + 1, observers + pos,
|
||||||
|
(observers_len - pos) * (sizeof(struct observer)));
|
||||||
|
|
||||||
|
observers_len++;
|
||||||
|
observers[pos].fd = fd;
|
||||||
|
observers[pos].ready = ready;
|
||||||
|
observers[pos].writey = writey;
|
||||||
|
observers[pos].extra = extra;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes core no longer watch fd.
|
||||||
|
*/
|
||||||
|
extern void
|
||||||
|
unobserve_fd(int fd)
|
||||||
|
{
|
||||||
|
int pos;
|
||||||
|
|
||||||
|
if (observer_action) {
|
||||||
|
/* this function is called through a ready/writey handler
|
||||||
|
* while the core works through the observer list, thus
|
||||||
|
* it does not alter the list, but stores this actions
|
||||||
|
* on a stack
|
||||||
|
*/
|
||||||
|
unobservers_len++;
|
||||||
|
if (unobservers_len > unobservers_size) {
|
||||||
|
unobservers_size = unobservers_len;
|
||||||
|
unobservers = s_realloc(unobservers,
|
||||||
|
unobservers_size * sizeof(int));
|
||||||
|
}
|
||||||
|
unobservers[unobservers_len - 1] = fd;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event == NULL) {
|
/* looks for the fd */
|
||||||
/* a buffered MOVE_FROM is not followed by anything,
|
for(pos = 0; pos < observers_len; pos++) {
|
||||||
thus it is unary */
|
if (observers[pos].fd == fd) {
|
||||||
event = move_event_buf;
|
break;
|
||||||
event_type = DELETE;
|
|
||||||
move_event = false;
|
|
||||||
} else if (move_event &&
|
|
||||||
( !(IN_MOVED_TO & event->mask) ||
|
|
||||||
event->cookie != move_event_buf->cookie) ) {
|
|
||||||
/* there is a MOVE_FROM event in the buffer and this is not the match
|
|
||||||
* continue in this function iteration to handler the buffer instead */
|
|
||||||
after_buf = event;
|
|
||||||
event = move_event_buf;
|
|
||||||
event_type = DELETE;
|
|
||||||
move_event = false;
|
|
||||||
} else if ( move_event &&
|
|
||||||
(IN_MOVED_TO & event->mask) &&
|
|
||||||
event->cookie == move_event_buf->cookie ) {
|
|
||||||
/* this is indeed a matched move */
|
|
||||||
event_type = MOVE;
|
|
||||||
move_event = false;
|
|
||||||
} else if (IN_MOVED_FROM & event->mask) {
|
|
||||||
/* 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. */
|
|
||||||
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;
|
if (pos >= observers_len) {
|
||||||
return;
|
logstring("Error",
|
||||||
} else if (IN_MOVED_TO & event->mask) {
|
"internal fail, not observer file descriptor in unobserve");
|
||||||
/* must be an unary move-to */
|
exit(-1); //ERRNO
|
||||||
event_type = CREATE;
|
|
||||||
} else if (IN_MOVED_FROM & event->mask) {
|
|
||||||
/* must be an unary move-from */
|
|
||||||
event_type = DELETE;
|
|
||||||
} else if (IN_ATTRIB & event->mask) {
|
|
||||||
/* just attrib change */
|
|
||||||
event_type = ATTRIB;
|
|
||||||
} else if (IN_CLOSE_WRITE & event->mask) {
|
|
||||||
/* closed after written something */
|
|
||||||
event_type = MODIFY;
|
|
||||||
} else if (IN_CREATE & event->mask) {
|
|
||||||
/* a new file */
|
|
||||||
event_type = CREATE;
|
|
||||||
} else if (IN_DELETE & event->mask) {
|
|
||||||
/* rm'ed */
|
|
||||||
event_type = DELETE;
|
|
||||||
} else {
|
|
||||||
logstring("Inotify", "skipped some inotify event.");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* and hands over to runner */
|
/* and moves the list down */
|
||||||
load_runner_func(L, "inotifyEvent");
|
memmove(observers + pos, observers + pos + 1,
|
||||||
switch(event_type) {
|
(observers_len - pos) * (sizeof(struct observer)));
|
||||||
case ATTRIB : lua_pushstring(L, "Attrib"); break;
|
observers_len--;
|
||||||
case MODIFY : lua_pushstring(L, "Modify"); break;
|
|
||||||
case CREATE : lua_pushstring(L, "Create"); break;
|
|
||||||
case DELETE : lua_pushstring(L, "Delete"); break;
|
|
||||||
case MOVE : lua_pushstring(L, "Move"); break;
|
|
||||||
default :
|
|
||||||
logstring("Error", "Internal: unknown event in handle_event()");
|
|
||||||
exit(-1); // ERRNO
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
lua_pushinteger(L, times(NULL));
|
|
||||||
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);
|
|
||||||
/* if there is a buffered event executes it */
|
|
||||||
if (after_buf) {
|
|
||||||
logstring("Inotify", "handling buffered event.");
|
|
||||||
handle_event(L, after_buf);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1196,14 +1109,10 @@ handle_event(lua_State *L,
|
|||||||
static void
|
static void
|
||||||
masterloop(lua_State *L)
|
masterloop(lua_State *L)
|
||||||
{
|
{
|
||||||
size_t readbuf_size = 2048;
|
|
||||||
char *readbuf = s_malloc(readbuf_size);
|
|
||||||
while(true) {
|
while(true) {
|
||||||
bool have_alarm;
|
bool have_alarm;
|
||||||
clock_t now = times(NULL);
|
clock_t now = times(NULL);
|
||||||
clock_t alarm_time;
|
clock_t alarm_time;
|
||||||
bool do_read = false;
|
|
||||||
ssize_t len;
|
|
||||||
|
|
||||||
/* queries runner about soonest alarm */
|
/* queries runner about soonest alarm */
|
||||||
load_runner_func(L, "getAlarm");
|
load_runner_func(L, "getAlarm");
|
||||||
@ -1239,109 +1148,65 @@ masterloop(lua_State *L)
|
|||||||
} else {
|
} else {
|
||||||
logstring("Masterloop", "going into select (no timeout).");
|
logstring("Masterloop", "going into select (no timeout).");
|
||||||
}
|
}
|
||||||
/* if select returns a positive number there is data on inotify
|
/* time for Lsyncd to try to put itself to rest into a select(),
|
||||||
* on zero the timemout occured. */
|
* configures timeouts, filedescriptors and signals
|
||||||
|
* that will wake it */
|
||||||
{
|
{
|
||||||
fd_set rfds;
|
fd_set rfds;
|
||||||
fd_set wfds;
|
fd_set wfds;
|
||||||
sigset_t sigset;
|
sigset_t sigset;
|
||||||
sigemptyset(&sigset);
|
int pi, pr;
|
||||||
int nfds = inotify_fd;
|
|
||||||
int pi;
|
|
||||||
|
|
||||||
|
sigemptyset(&sigset);
|
||||||
FD_ZERO(&rfds);
|
FD_ZERO(&rfds);
|
||||||
FD_ZERO(&wfds);
|
FD_ZERO(&wfds);
|
||||||
FD_SET(inotify_fd, &rfds);
|
|
||||||
for(pi = 0; pi < pipes_len; pi++) {
|
for(pi = 0; pi < observers_len; pi++) {
|
||||||
int pfd = pipes[pi].fd;
|
int fd = observers[pi].fd;
|
||||||
nfds = pfd > nfds ? pfd : nfds;
|
if (observers[pi].ready) {
|
||||||
FD_SET(pfd, &wfds);
|
FD_SET(fd, &rfds);
|
||||||
|
}
|
||||||
|
if (observers[pi].writey) {
|
||||||
|
FD_SET(fd, &wfds);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reuse pi for result */
|
/* the great select */
|
||||||
pi = pselect(nfds + 1, &rfds, &wfds, NULL,
|
pr = pselect(
|
||||||
|
observers[observers_len - 1].fd + 1,
|
||||||
|
&rfds, &wfds, NULL,
|
||||||
have_alarm ? &tv : NULL, &sigset);
|
have_alarm ? &tv : NULL, &sigset);
|
||||||
if (pi >= 0) {
|
|
||||||
do_read = FD_ISSET(inotify_fd, &rfds);
|
|
||||||
}
|
|
||||||
if (do_read) {
|
|
||||||
logstring("Masterloop", do_read > 0 ?
|
|
||||||
"theres data on inotify." :
|
|
||||||
"core: select() timeout or signal.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* reads possible events from inotify stream */
|
if (pr >= 0) {
|
||||||
while(do_read) {
|
/* walks through the observers calling ready/writey fds */
|
||||||
int i = 0;
|
observer_action = true;
|
||||||
do {
|
for(pi = 0; pi < observers_len; pi++) {
|
||||||
len = read (inotify_fd, readbuf, readbuf_size);
|
int fd = observers[pi].fd;
|
||||||
if (len < 0 && errno == EINVAL) {
|
void *extra = observers[pi].extra;
|
||||||
/* kernel > 2.6.21 indicates that way that way that
|
if (hup || term) {
|
||||||
* the buffer was too small to fit a filename.
|
break;
|
||||||
* double its size and try again. When using a lower
|
}
|
||||||
* kernel and a filename > 2KB appears lsyncd
|
if (observers[pi].ready && FD_ISSET(fd, &rfds)) {
|
||||||
* will fail. (but does a 2KB filename really happen?)
|
observers[pi].ready(L, fd, extra);
|
||||||
*/
|
}
|
||||||
readbuf_size *= 2;
|
if (hup || term) {
|
||||||
readbuf = s_realloc(readbuf, readbuf_size);
|
break;
|
||||||
|
}
|
||||||
|
if (unobservers_len > 0 &&
|
||||||
|
unobservers[unobservers_len - 1] == fd) {
|
||||||
|
/* ready() unobserved itself */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} while(0);
|
if (observers[pi].writey && FD_ISSET(fd, &wfds)) {
|
||||||
if (len == 0) {
|
observers[pi].writey(L, fd, extra);
|
||||||
/* nothing more inotify */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (len < 0) {
|
|
||||||
if (errno == EAGAIN) {
|
|
||||||
/* nothing more inotify */
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
printlogf(L, "Error", "Read fail on inotify");
|
|
||||||
exit(-1); // ERRNO
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (i < len && !hup && !term) {
|
observer_action = false;
|
||||||
struct inotify_event *event =
|
/* work through delayed unobserve_fd() calls */
|
||||||
(struct inotify_event *) &readbuf[i];
|
for (pi = 0; pi < unobservers_len; pi++) {
|
||||||
handle_event(L, event);
|
unobserve_fd(unobservers[pi]);
|
||||||
i += sizeof(struct inotify_event) + event->len;
|
|
||||||
}
|
}
|
||||||
if (!move_event) {
|
unobservers_len = 0;
|
||||||
/* give it a pause if not endangering splitting a move */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* checks if there is an unary MOVE_FROM left in the buffer */
|
|
||||||
if (move_event) {
|
|
||||||
logstring("Inotify", "handling unary move from.");
|
|
||||||
handle_event(L, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
/* writes into pipes if any */
|
|
||||||
int pi;
|
|
||||||
for(pi = 0; pi < pipes_len; pi++) {
|
|
||||||
struct pipemsg *pm = pipes + pi;
|
|
||||||
int len = write(pm->fd, pm->text + pm->pos, pm->tlen - pm->pos);
|
|
||||||
bool do_close = false;
|
|
||||||
pm->pos += len;
|
|
||||||
if (len < 0) {
|
|
||||||
logstring("Normal", "broken pipe.");
|
|
||||||
do_close = true;
|
|
||||||
} else if (pm->pos >= pm->tlen) {
|
|
||||||
logstring("Debug", "finished pipe.");
|
|
||||||
do_close = true;
|
|
||||||
}
|
|
||||||
if (do_close) {
|
|
||||||
close(pm->fd);
|
|
||||||
free(pm->text);
|
|
||||||
pipes_len--;
|
|
||||||
memmove(pipes + pi, pipes + pi + 1,
|
|
||||||
(pipes_len - pi) * sizeof(struct pipemsg));
|
|
||||||
pi--;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1362,6 +1227,7 @@ masterloop(lua_State *L)
|
|||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* reacts on signals */
|
||||||
if (hup) {
|
if (hup) {
|
||||||
load_runner_func(L, "hup");
|
load_runner_func(L, "hup");
|
||||||
if (lua_pcall(L, 0, 0, -2)) {
|
if (lua_pcall(L, 0, 0, -2)) {
|
||||||
@ -1371,6 +1237,7 @@ masterloop(lua_State *L)
|
|||||||
hup = 0;
|
hup = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* reacts on signals */
|
||||||
if (term == 1) {
|
if (term == 1) {
|
||||||
load_runner_func(L, "term");
|
load_runner_func(L, "term");
|
||||||
if (lua_pcall(L, 0, 0, -2)) {
|
if (lua_pcall(L, 0, 0, -2)) {
|
||||||
@ -1389,7 +1256,6 @@ masterloop(lua_State *L)
|
|||||||
}
|
}
|
||||||
if (!lua_toboolean(L, -1)) {
|
if (!lua_toboolean(L, -1)) {
|
||||||
/* cycle told core to break mainloop */
|
/* cycle told core to break mainloop */
|
||||||
free(readbuf);
|
|
||||||
lua_pop(L, 2);
|
lua_pop(L, 2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1456,6 +1322,12 @@ main1(int argc, char *argv[])
|
|||||||
luaL_register(L, "lsyncd", lsyncdlib);
|
luaL_register(L, "lsyncd", lsyncdlib);
|
||||||
lua_setglobal(L, "lysncd");
|
lua_setglobal(L, "lysncd");
|
||||||
|
|
||||||
|
lua_getglobal(L, "lysncd");
|
||||||
|
register_inotify(L);
|
||||||
|
lua_settable(L, -3);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
l_stackdump(L);
|
||||||
|
|
||||||
if (check_logcat("Debug") >= settings.log_level) {
|
if (check_logcat("Debug") >= settings.log_level) {
|
||||||
/* printlogf doesnt support %ld :-( */
|
/* printlogf doesnt support %ld :-( */
|
||||||
printf("kernels clocks_per_sec=%ld\n", clocks_per_sec);
|
printf("kernels clocks_per_sec=%ld\n", clocks_per_sec);
|
||||||
@ -1601,7 +1473,7 @@ main1(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (lsyncd_config_file) {
|
if (lsyncd_config_file) {
|
||||||
/* checks for the configuration and existence of the config file */
|
/* checks existence of the config file */
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (stat(lsyncd_config_file, &st)) {
|
if (stat(lsyncd_config_file, &st)) {
|
||||||
printlogf(L, "Error",
|
printlogf(L, "Error",
|
||||||
@ -1625,16 +1497,8 @@ main1(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* opens inotify */
|
open_inotify(L);
|
||||||
inotify_fd = inotify_init();
|
l_stackdump(L);
|
||||||
if (inotify_fd == -1) {
|
|
||||||
printlogf(L, "Error",
|
|
||||||
"Cannot create inotify instance! (%d:%s)",
|
|
||||||
errno, strerror(errno));
|
|
||||||
exit(-1); // ERRNO
|
|
||||||
}
|
|
||||||
close_exec_fd(inotify_fd);
|
|
||||||
non_block_fd(inotify_fd);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
/* adds signal handlers *
|
/* adds signal handlers *
|
||||||
@ -1691,8 +1555,7 @@ main1(int argc, char *argv[])
|
|||||||
settings.log_level = 0,
|
settings.log_level = 0,
|
||||||
settings.nodaemon = false,
|
settings.nodaemon = false,
|
||||||
|
|
||||||
/* closes inotify */
|
close_inotify();
|
||||||
close(inotify_fd);
|
|
||||||
lua_close(L);
|
lua_close(L);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1493,7 +1493,7 @@ local Inotifies = (function()
|
|||||||
local wd = pathwds[path]
|
local wd = pathwds[path]
|
||||||
if not wd then
|
if not wd then
|
||||||
-- lets the core registers watch with the kernel
|
-- lets the core registers watch with the kernel
|
||||||
local wd = lsyncd.inotifyadd(path);
|
local wd = lsyncd.inotify.addwatch(path);
|
||||||
if wd < 0 then
|
if wd < 0 then
|
||||||
log("Error","Failure adding watch ",path," -> ignored ")
|
log("Error","Failure adding watch ",path," -> ignored ")
|
||||||
return
|
return
|
||||||
@ -1540,7 +1540,7 @@ local Inotifies = (function()
|
|||||||
if not wd then
|
if not wd then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
lsyncd.inotifyrm(wd)
|
lsyncd.inotify.rmwatch(wd)
|
||||||
wdpaths[wd] = nil
|
wdpaths[wd] = nil
|
||||||
pathwds[path] = nil
|
pathwds[path] = nil
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user