diff --git a/Makefile.am b/Makefile.am index 74859c1..1e33833 100644 --- a/Makefile.am +++ b/Makefile.am @@ -36,6 +36,10 @@ else minidlnad_SOURCES += select.c endif +if HAVE_INOTIFY +minidlnad_SOURCES += monitor_inotify.c +endif + if HAVE_VORBISFILE vorbislibs = -lvorbis -logg else diff --git a/configure.ac b/configure.ac index cb596b9..cd1beef 100644 --- a/configure.ac +++ b/configure.ac @@ -490,7 +490,12 @@ AC_CHECK_HEADERS([arpa/inet.h asm/unistd.h endian.h machine/endian.h fcntl.h lib test x"$ac_cv_header_poll_h" != x"yes" && AC_MSG_ERROR([poll.h not found or not usable]) test x"$ac_cv_header_sys_queue_h" != x"yes" && AC_MSG_ERROR([sys/queue.h not found or not usable]) -AC_CHECK_FUNCS(inotify_init, AC_DEFINE(HAVE_INOTIFY,1,[Whether kernel has inotify support]), [ +AC_CHECK_FUNCS(inotify_init, +[ + AC_DEFINE(HAVE_INOTIFY,1,[Whether kernel has inotify support]) + AM_CONDITIONAL(HAVE_INOTIFY, true) +], +[ AC_MSG_CHECKING([for __NR_inotify_init syscall]) AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( @@ -506,9 +511,11 @@ AC_CHECK_FUNCS(inotify_init, AC_DEFINE(HAVE_INOTIFY,1,[Whether kernel has inotif [ AC_MSG_RESULT([yes]) AC_DEFINE(HAVE_INOTIFY,1,[Whether kernel has inotify support]) + AM_CONDITIONAL(HAVE_INOTIFY, true) ], [ AC_MSG_RESULT([no]) + AM_CONDITIONAL(HAVE_INOTIFY, false) ]) ]) diff --git a/monitor.c b/monitor.c index 9e56bc7..edbe308 100644 --- a/monitor.c +++ b/monitor.c @@ -30,16 +30,6 @@ #include #include #include -#ifdef HAVE_INOTIFY -#include -#include -#ifdef HAVE_SYS_INOTIFY_H -#include -#else -#include "linux/inotify.h" -#include "linux/inotify-syscalls.h" -#endif -#endif #include "libav.h" #include "upnpglobalvars.h" @@ -52,208 +42,7 @@ #include "playlist.h" #include "log.h" -static time_t next_pl_fill = 0; - -#ifdef HAVE_INOTIFY -#define EVENT_SIZE ( sizeof (struct inotify_event) ) -#define BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) ) -#define DESIRED_WATCH_LIMIT 65536 - -#define PATH_BUF_SIZE PATH_MAX - -struct watch -{ - int wd; /* watch descriptor */ - char *path; /* watched path */ - struct watch *next; -}; - -static struct watch *watches; -static struct watch *lastwatch = NULL; - -static char * -get_path_from_wd(int wd) -{ - struct watch *w = watches; - - while( w != NULL ) - { - if( w->wd == wd ) - return w->path; - w = w->next; - } - - return NULL; -} - -static unsigned int -next_highest(unsigned int num) -{ - num |= num >> 1; - num |= num >> 2; - num |= num >> 4; - num |= num >> 8; - num |= num >> 16; - return ++num; -} - -static void -raise_watch_limit(unsigned int limit) -{ - FILE *max_watches = fopen("/proc/sys/fs/inotify/max_user_watches", "r+"); - if (!max_watches) - return; - if (!limit) - { - if (fscanf(max_watches, "%10u", &limit) < 1) - limit = 8192; - rewind(max_watches); - } - fprintf(max_watches, "%u", next_highest(limit)); - fclose(max_watches); -} - -int -add_watch(int fd, const char * path) -{ - struct watch *nw; - int wd; - - wd = inotify_add_watch(fd, path, IN_CREATE|IN_CLOSE_WRITE|IN_DELETE|IN_MOVE); - if( wd < 0 && errno == ENOSPC) - { - raise_watch_limit(0); - wd = inotify_add_watch(fd, path, IN_CREATE|IN_CLOSE_WRITE|IN_DELETE|IN_MOVE); - } - if( wd < 0 ) - { - DPRINTF(E_ERROR, L_INOTIFY, "inotify_add_watch(%s) [%s]\n", path, strerror(errno)); - return (errno); - } - - nw = malloc(sizeof(struct watch)); - if( nw == NULL ) - { - DPRINTF(E_ERROR, L_INOTIFY, "malloc() error\n"); - return (ENOMEM); - } - nw->wd = wd; - nw->next = NULL; - nw->path = strdup(path); - - if( watches == NULL ) - { - watches = nw; - } - - if( lastwatch != NULL ) - { - lastwatch->next = nw; - } - lastwatch = nw; - - DPRINTF(E_INFO, L_INOTIFY, "Added watch to %s [%d]\n", path, wd); - return (0); -} - -static int -remove_watch(int fd, const char * path) -{ - struct watch *w; - - for( w = watches; w; w = w->next ) - { - if( strcmp(path, w->path) == 0 ) - return(inotify_rm_watch(fd, w->wd)); - } - - return 1; -} - -static int -inotify_create_watches(int fd) -{ - FILE * max_watches; - unsigned int num_watches = 0, watch_limit; - char **result; - int i, rows = 0; - struct media_dir_s * media_path; - - for( media_path = media_dirs; media_path != NULL; media_path = media_path->next ) - { - DPRINTF(E_DEBUG, L_INOTIFY, "Add watch to %s\n", media_path->path); - add_watch(fd, media_path->path); - num_watches++; - } - sql_get_table(db, "SELECT PATH from DETAILS where MIME is NULL and PATH is not NULL", &result, &rows, NULL); - for( i=1; i <= rows; i++ ) - { - DPRINTF(E_DEBUG, L_INOTIFY, "Add watch to %s\n", result[i]); - add_watch(fd, result[i]); - num_watches++; - } - sqlite3_free_table(result); - - max_watches = fopen("/proc/sys/fs/inotify/max_user_watches", "r"); - if( max_watches ) - { - if( fscanf(max_watches, "%10u", &watch_limit) < 1 ) - watch_limit = 8192; - fclose(max_watches); - if( (watch_limit < DESIRED_WATCH_LIMIT) || (watch_limit < (num_watches*4/3)) ) - { - if (access("/proc/sys/fs/inotify/max_user_watches", W_OK) == 0) - { - if( DESIRED_WATCH_LIMIT >= (num_watches*3/4) ) - { - raise_watch_limit(8191U); - } - else if( next_highest(num_watches) >= (num_watches*3/4) ) - { - raise_watch_limit(num_watches); - } - else - { - raise_watch_limit(next_highest(num_watches)); - } - } - else - { - DPRINTF(E_WARN, L_INOTIFY, "WARNING: Inotify max_user_watches [%u] is low or close to the number of used watches [%u] " - "and I do not have permission to increase this limit. Please do so manually by " - "writing a higher value into /proc/sys/fs/inotify/max_user_watches.\n", watch_limit, num_watches); - } - } - } - else - { - DPRINTF(E_WARN, L_INOTIFY, "WARNING: Could not read inotify max_user_watches! " - "Hopefully it is enough to cover %u current directories plus any new ones added.\n", num_watches); - } - - return rows; -} - -static int -inotify_remove_watches(int fd) -{ - struct watch *w = watches; - struct watch *last_w; - int rm_watches = 0; - - while( w ) - { - last_w = w; - inotify_rm_watch(fd, w->wd); - free(w->path); - rm_watches++; - w = w->next; - free(last_w); - } - - return rm_watches; -} -#endif +time_t next_pl_fill = 0; int monitor_remove_file(const char * path) @@ -535,7 +324,7 @@ monitor_insert_directory(int fd, char *name, const char * path) #ifdef HAVE_WATCH if( fd > 0 ) - add_watch(fd, path); + monitor_add_watch(fd, path); #endif dir_types = valid_media_types(path); @@ -586,12 +375,12 @@ monitor_remove_directory(int fd, const char * path) /* Invalidate the scanner cache so we don't insert files into non-existent containers */ valid_cache = 0; - #ifdef HAVE_INOTIFY +#ifdef HAVE_WATCH if( fd > 0 ) { - remove_watch(fd, path); + monitor_remove_watch(fd, path); } - #endif +#endif sql = sqlite3_mprintf("SELECT ID from DETAILS where (PATH > '%q/' and PATH <= '%q/%c')" " or PATH = '%q'", path, path, 0xFF, path); if( (sql_get_table(db, sql, &result, &rows, NULL) == SQLITE_OK) ) @@ -614,137 +403,3 @@ monitor_remove_directory(int fd, const char * path) return ret; } - -#ifdef HAVE_INOTIFY -void * -start_inotify(void) -{ - struct pollfd pollfds[1]; - char buffer[BUF_LEN]; - char path_buf[PATH_MAX]; - int length, i = 0; - char * esc_name = NULL; - struct stat st; - sigset_t set; - - sigfillset(&set); - sigdelset(&set, SIGCHLD); - pthread_sigmask(SIG_BLOCK, &set, NULL); - - pollfds[0].fd = inotify_init(); - pollfds[0].events = POLLIN; - - if ( pollfds[0].fd < 0 ) - DPRINTF(E_ERROR, L_INOTIFY, "inotify_init() failed!\n"); - - while( GETFLAG(SCANNING_MASK) ) - { - if( quitting ) - goto quitting; - sleep(1); - } - inotify_create_watches(pollfds[0].fd); - if (setpriority(PRIO_PROCESS, 0, 19) == -1) - DPRINTF(E_WARN, L_INOTIFY, "Failed to reduce inotify thread priority\n"); - sqlite3_release_memory(1<<31); - lav_register_all(); - - while( !quitting ) - { - int timeout = -1; - if (next_pl_fill) - { - time_t diff = next_pl_fill - time(NULL); - if (diff < 0) - timeout = 0; - else - timeout = diff * 1000; - } - length = poll(pollfds, 1, timeout); - if( !length ) - { - if( next_pl_fill && (time(NULL) >= next_pl_fill) ) - { - fill_playlists(); - next_pl_fill = 0; - } - continue; - } - else if( length < 0 ) - { - if( (errno == EINTR) || (errno == EAGAIN) ) - continue; - else - DPRINTF(E_ERROR, L_INOTIFY, "read failed!\n"); - } - else - { - length = read(pollfds[0].fd, buffer, BUF_LEN); - buffer[BUF_LEN-1] = '\0'; - } - - i = 0; - while( !quitting && i < length ) - { - struct inotify_event * event = (struct inotify_event *) &buffer[i]; - if( event->len ) - { - if( *(event->name) == '.' ) - { - i += EVENT_SIZE + event->len; - continue; - } - esc_name = modifyString(strdup(event->name), "&", "&amp;", 0); - snprintf(path_buf, sizeof(path_buf), "%s/%s", get_path_from_wd(event->wd), event->name); - if ( event->mask & IN_ISDIR && (event->mask & (IN_CREATE|IN_MOVED_TO)) ) - { - DPRINTF(E_DEBUG, L_INOTIFY, "The directory %s was %s.\n", - path_buf, (event->mask & IN_MOVED_TO ? "moved here" : "created")); - monitor_insert_directory(pollfds[0].fd, esc_name, path_buf); - } - else if ( (event->mask & (IN_CLOSE_WRITE|IN_MOVED_TO|IN_CREATE)) && - (lstat(path_buf, &st) == 0) ) - { - if( (event->mask & (IN_MOVED_TO|IN_CREATE)) && (S_ISLNK(st.st_mode) || st.st_nlink > 1) ) - { - DPRINTF(E_DEBUG, L_INOTIFY, "The %s link %s was %s.\n", - (S_ISLNK(st.st_mode) ? "symbolic" : "hard"), - path_buf, (event->mask & IN_MOVED_TO ? "moved here" : "created")); - if( stat(path_buf, &st) == 0 && S_ISDIR(st.st_mode) ) - monitor_insert_directory(pollfds[0].fd, esc_name, path_buf); - else - monitor_insert_file(esc_name, path_buf); - } - else if( event->mask & (IN_CLOSE_WRITE|IN_MOVED_TO) && st.st_size > 0 ) - { - if( (event->mask & IN_MOVED_TO) || - (sql_get_int_field(db, "SELECT TIMESTAMP from DETAILS where PATH = '%q'", path_buf) != st.st_mtime) ) - { - DPRINTF(E_DEBUG, L_INOTIFY, "The file %s was %s.\n", - path_buf, (event->mask & IN_MOVED_TO ? "moved here" : "changed")); - monitor_insert_file(esc_name, path_buf); - } - } - } - else if ( event->mask & (IN_DELETE|IN_MOVED_FROM) ) - { - DPRINTF(E_DEBUG, L_INOTIFY, "The %s %s was %s.\n", - (event->mask & IN_ISDIR ? "directory" : "file"), - path_buf, (event->mask & IN_MOVED_FROM ? "moved away" : "deleted")); - if ( event->mask & IN_ISDIR ) - monitor_remove_directory(pollfds[0].fd, path_buf); - else - monitor_remove_file(path_buf); - } - free(esc_name); - } - i += EVENT_SIZE + event->len; - } - } - inotify_remove_watches(pollfds[0].fd); -quitting: - close(pollfds[0].fd); - - return 0; -} -#endif diff --git a/monitor.h b/monitor.h index c5e7b99..af30670 100644 --- a/monitor.h +++ b/monitor.h @@ -5,7 +5,8 @@ int monitor_remove_directory(int fd, const char * path); #if defined(HAVE_INOTIFY) || defined(HAVE_KQUEUE) #define HAVE_WATCH 1 -int add_watch(int, const char *); +int monitor_add_watch(int, const char *); +int monitor_remove_watch(int, const char *); #endif #ifdef HAVE_INOTIFY diff --git a/monitor_inotify.c b/monitor_inotify.c new file mode 100644 index 0000000..cfc20e8 --- /dev/null +++ b/monitor_inotify.c @@ -0,0 +1,386 @@ +/* MiniDLNA media server + * Copyright (C) 2008-2010 Justin Maggard + * + * This file is part of MiniDLNA. + * + * MiniDLNA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * MiniDLNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MiniDLNA. If not, see . + */ +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_INOTIFY +#include +#include +#ifdef HAVE_SYS_INOTIFY_H +#include +#else +#include "linux/inotify.h" +#include "linux/inotify-syscalls.h" +#endif +#endif +#include "libav.h" + +#include "upnpglobalvars.h" +#include "monitor.h" +#include "utils.h" +#include "sql.h" +#include "scanner.h" +#include "metadata.h" +#include "albumart.h" +#include "playlist.h" +#include "log.h" + +extern time_t next_pl_fill; + +#define EVENT_SIZE ( sizeof (struct inotify_event) ) +#define BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) ) +#define DESIRED_WATCH_LIMIT 65536 + +#define PATH_BUF_SIZE PATH_MAX + +struct watch +{ + int wd; /* watch descriptor */ + char *path; /* watched path */ + struct watch *next; +}; + +static struct watch *watches; +static struct watch *lastwatch = NULL; + +static char * +get_path_from_wd(int wd) +{ + struct watch *w = watches; + + while( w != NULL ) + { + if( w->wd == wd ) + return w->path; + w = w->next; + } + + return NULL; +} + +static unsigned int +next_highest(unsigned int num) +{ + num |= num >> 1; + num |= num >> 2; + num |= num >> 4; + num |= num >> 8; + num |= num >> 16; + return ++num; +} + +static void +raise_watch_limit(unsigned int limit) +{ + FILE *max_watches = fopen("/proc/sys/fs/inotify/max_user_watches", "r+"); + if (!max_watches) + return; + if (!limit) + { + if (fscanf(max_watches, "%u", &limit) < 1) + limit = 8192; + rewind(max_watches); + } + fprintf(max_watches, "%u", next_highest(limit)); + fclose(max_watches); +} + +int +monitor_add_watch(int fd, const char * path) +{ + struct watch *nw; + int wd; + + wd = inotify_add_watch(fd, path, IN_CREATE|IN_CLOSE_WRITE|IN_DELETE|IN_MOVE); + if( wd < 0 && errno == ENOSPC) + { + raise_watch_limit(0); + wd = inotify_add_watch(fd, path, IN_CREATE|IN_CLOSE_WRITE|IN_DELETE|IN_MOVE); + } + if( wd < 0 ) + { + DPRINTF(E_ERROR, L_INOTIFY, "inotify_add_watch(%s) [%s]\n", path, strerror(errno)); + return (errno); + } + + nw = malloc(sizeof(struct watch)); + if( nw == NULL ) + { + DPRINTF(E_ERROR, L_INOTIFY, "malloc() error\n"); + return (ENOMEM); + } + nw->wd = wd; + nw->next = NULL; + nw->path = strdup(path); + + if( watches == NULL ) + { + watches = nw; + } + + if( lastwatch != NULL ) + { + lastwatch->next = nw; + } + lastwatch = nw; + + DPRINTF(E_INFO, L_INOTIFY, "Added watch to %s [%d]\n", path, wd); + return (0); +} + +int +monitor_remove_watch(int fd, const char * path) +{ + struct watch *w; + + for( w = watches; w; w = w->next ) + { + if( strcmp(path, w->path) == 0 ) + return(inotify_rm_watch(fd, w->wd)); + } + + return 1; +} + +static int +inotify_create_watches(int fd) +{ + FILE * max_watches; + unsigned int num_watches = 0, watch_limit; + char **result; + int i, rows = 0; + struct media_dir_s * media_path; + + for( media_path = media_dirs; media_path != NULL; media_path = media_path->next ) + { + DPRINTF(E_DEBUG, L_INOTIFY, "Add watch to %s\n", media_path->path); + monitor_add_watch(fd, media_path->path); + num_watches++; + } + sql_get_table(db, "SELECT PATH from DETAILS where MIME is NULL and PATH is not NULL", &result, &rows, NULL); + for( i=1; i <= rows; i++ ) + { + DPRINTF(E_DEBUG, L_INOTIFY, "Add watch to %s\n", result[i]); + monitor_add_watch(fd, result[i]); + num_watches++; + } + sqlite3_free_table(result); + + max_watches = fopen("/proc/sys/fs/inotify/max_user_watches", "r"); + if( max_watches ) + { + if( fscanf(max_watches, "%10u", &watch_limit) < 1 ) + watch_limit = 8192; + fclose(max_watches); + if( (watch_limit < DESIRED_WATCH_LIMIT) || (watch_limit < (num_watches*4/3)) ) + { + if (access("/proc/sys/fs/inotify/max_user_watches", W_OK) == 0) + { + if( DESIRED_WATCH_LIMIT >= (num_watches*3/4) ) + { + raise_watch_limit(8191U); + } + else if( next_highest(num_watches) >= (num_watches*3/4) ) + { + raise_watch_limit(num_watches); + } + else + { + raise_watch_limit(next_highest(num_watches)); + } + } + else + { + DPRINTF(E_WARN, L_INOTIFY, "WARNING: Inotify max_user_watches [%u] is low or close to the number of used watches [%u] " + "and I do not have permission to increase this limit. Please do so manually by " + "writing a higher value into /proc/sys/fs/inotify/max_user_watches.\n", watch_limit, num_watches); + } + } + } + else + { + DPRINTF(E_WARN, L_INOTIFY, "WARNING: Could not read inotify max_user_watches! " + "Hopefully it is enough to cover %u current directories plus any new ones added.\n", num_watches); + } + + return rows; +} + +static int +inotify_remove_watches(int fd) +{ + struct watch *w = watches; + struct watch *last_w; + int rm_watches = 0; + + while( w ) + { + last_w = w; + inotify_rm_watch(fd, w->wd); + free(w->path); + rm_watches++; + w = w->next; + free(last_w); + } + + return rm_watches; +} + +void * +start_inotify(void) +{ + struct pollfd pollfds[1]; + char buffer[BUF_LEN]; + char path_buf[PATH_MAX]; + int length, i = 0; + char * esc_name = NULL; + struct stat st; + sigset_t set; + + sigfillset(&set); + sigdelset(&set, SIGCHLD); + pthread_sigmask(SIG_BLOCK, &set, NULL); + + pollfds[0].fd = inotify_init(); + pollfds[0].events = POLLIN; + + if ( pollfds[0].fd < 0 ) + DPRINTF(E_ERROR, L_INOTIFY, "inotify_init() failed!\n"); + + while( GETFLAG(SCANNING_MASK) ) + { + if( quitting ) + goto quitting; + sleep(1); + } + inotify_create_watches(pollfds[0].fd); + if (setpriority(PRIO_PROCESS, 0, 19) == -1) + DPRINTF(E_WARN, L_INOTIFY, "Failed to reduce inotify thread priority\n"); + sqlite3_release_memory(1<<31); + lav_register_all(); + + while( !quitting ) + { + int timeout = -1; + if (next_pl_fill) + { + time_t diff = next_pl_fill - time(NULL); + if (diff < 0) + timeout = 0; + else + timeout = diff * 1000; + } + length = poll(pollfds, 1, timeout); + if( !length ) + { + if( next_pl_fill && (time(NULL) >= next_pl_fill) ) + { + fill_playlists(); + next_pl_fill = 0; + } + continue; + } + else if( length < 0 ) + { + if( (errno == EINTR) || (errno == EAGAIN) ) + continue; + else + DPRINTF(E_ERROR, L_INOTIFY, "read failed!\n"); + } + else + { + length = read(pollfds[0].fd, buffer, BUF_LEN); + buffer[BUF_LEN-1] = '\0'; + } + + i = 0; + while( !quitting && i < length ) + { + struct inotify_event * event = (struct inotify_event *) &buffer[i]; + if( event->len ) + { + if( *(event->name) == '.' ) + { + i += EVENT_SIZE + event->len; + continue; + } + esc_name = modifyString(strdup(event->name), "&", "&amp;", 0); + snprintf(path_buf, sizeof(path_buf), "%s/%s", get_path_from_wd(event->wd), event->name); + if ( event->mask & IN_ISDIR && (event->mask & (IN_CREATE|IN_MOVED_TO)) ) + { + DPRINTF(E_DEBUG, L_INOTIFY, "The directory %s was %s.\n", + path_buf, (event->mask & IN_MOVED_TO ? "moved here" : "created")); + monitor_insert_directory(pollfds[0].fd, esc_name, path_buf); + } + else if ( (event->mask & (IN_CLOSE_WRITE|IN_MOVED_TO|IN_CREATE)) && + (lstat(path_buf, &st) == 0) ) + { + if( (event->mask & (IN_MOVED_TO|IN_CREATE)) && (S_ISLNK(st.st_mode) || st.st_nlink > 1) ) + { + DPRINTF(E_DEBUG, L_INOTIFY, "The %s link %s was %s.\n", + (S_ISLNK(st.st_mode) ? "symbolic" : "hard"), + path_buf, (event->mask & IN_MOVED_TO ? "moved here" : "created")); + if( stat(path_buf, &st) == 0 && S_ISDIR(st.st_mode) ) + monitor_insert_directory(pollfds[0].fd, esc_name, path_buf); + else + monitor_insert_file(esc_name, path_buf); + } + else if( event->mask & (IN_CLOSE_WRITE|IN_MOVED_TO) && st.st_size > 0 ) + { + if( (event->mask & IN_MOVED_TO) || + (sql_get_int_field(db, "SELECT TIMESTAMP from DETAILS where PATH = '%q'", path_buf) != st.st_mtime) ) + { + DPRINTF(E_DEBUG, L_INOTIFY, "The file %s was %s.\n", + path_buf, (event->mask & IN_MOVED_TO ? "moved here" : "changed")); + monitor_insert_file(esc_name, path_buf); + } + } + } + else if ( event->mask & (IN_DELETE|IN_MOVED_FROM) ) + { + DPRINTF(E_DEBUG, L_INOTIFY, "The %s %s was %s.\n", + (event->mask & IN_ISDIR ? "directory" : "file"), + path_buf, (event->mask & IN_MOVED_FROM ? "moved away" : "deleted")); + if ( event->mask & IN_ISDIR ) + monitor_remove_directory(pollfds[0].fd, path_buf); + else + monitor_remove_file(path_buf); + } + free(esc_name); + } + i += EVENT_SIZE + event->len; + } + } + inotify_remove_watches(pollfds[0].fd); +quitting: + close(pollfds[0].fd); + + return 0; +} diff --git a/monitor_kqueue.c b/monitor_kqueue.c index 34026d5..eba34a7 100644 --- a/monitor_kqueue.c +++ b/monitor_kqueue.c @@ -214,7 +214,7 @@ err1: } int -add_watch(int fd __unused, const char *path) +monitor_add_watch(int fd __unused, const char *path) { struct watch *wt; struct event *ev; @@ -251,6 +251,13 @@ add_watch(int fd __unused, const char *path) return (0); } +int +monitor_remove_watch(int fd __unused, const char *path __unused) +{ + + return (0); +} + /* * XXXGL: this function has too much copypaste of inotify_create_watches(). * We need to split out inotify stuff from monitor.c into monitor_inotify.c, @@ -267,9 +274,9 @@ kqueue_monitor_start() DPRINTF(E_DEBUG, L_INOTIFY, "kqueue monitoring starting\n"); for (media_path = media_dirs; media_path != NULL; media_path = media_path->next) - add_watch(0, media_path->path); + monitor_add_watch(0, media_path->path); sql_get_table(db, "SELECT PATH from DETAILS where MIME is NULL and PATH is not NULL", &result, &rows, NULL); for (i = 1; i <= rows; i++ ) - add_watch(0, result[i]); + monitor_add_watch(0, result[i]); sqlite3_free_table(result); }