On Mon, Jan 19, 2015 at 05:13:09PM +0100, David Coppa wrote: > On Mon, Jan 19, 2015 at 12:06 AM, LÉVAI Dániel <l...@ecentrum.hu> wrote: > > >> It might be better to look at the kqueue patch that FreeBSD are using. > > > > Now this seems to work for me on i386, at least. It applied almost > > clean, but I've taken the liberty and removed the whitespace-only > > changes from FreeBSD's diff(s). I'll be honest, it got a bit slower, but > > this could very well be because of my rusty hard drives. > > > > Here is my diff: > > I do not use MiniDLNA, but your diff below looks good and, if it > works, then it's ok with me if Stuart wants to commit it.
There seems to be a missing bdep on the autostuffs. > > ciao, > David > > > > > Index: Makefile > > =================================================================== > > RCS file: /cvs/ports/multimedia/minidlna/Makefile,v > > retrieving revision 1.10 > > diff -p -u -r1.10 Makefile > > --- Makefile 3 Sep 2014 21:15:43 -0000 1.10 > > +++ Makefile 18 Jan 2015 22:45:10 -0000 > > @@ -3,6 +3,7 @@ > > COMMENT= lightweight DLNA/UPnP-AV media server > > > > V= 1.1.4 > > +REVISION= 0 > > DISTNAME= minidlna-$V > > PKGNAME= minidlna-$V > > > > @@ -34,9 +35,15 @@ LIB_DEPENDS= audio/flac \ > > graphics/jpeg \ > > graphics/libexif > > > > +AUTOCONF_VERSION= 2.69 > > +AUTOMAKE_VERSION= 1.14 > > + > > NO_TEST= Yes > > E= ${PREFIX}/share/examples/minidlna > > > > +post-patch: > > + @cd ${WRKSRC} && env AUTOCONF_VERSION=${AUTOCONF_VERSION} \ > > + AUTOMAKE_VERSION=${AUTOMAKE_VERSION} ./autogen.sh > > post-install: > > ${INSTALL_DATA_DIR} $E > > ${INSTALL_DATA} ${WRKSRC}/minidlna.conf $E > > Index: patches/patch-configure_ac > > =================================================================== > > RCS file: patches/patch-configure_ac > > diff -N patches/patch-configure_ac > > --- /dev/null 1 Jan 1970 00:00:00 -0000 > > +++ patches/patch-configure_ac 18 Jan 2015 22:45:10 -0000 > > @@ -0,0 +1,12 @@ > > +$OpenBSD$ > > +--- configure.ac.orig Tue Aug 26 23:09:22 2014 > > ++++ configure.ac Sun Jan 18 22:45:07 2015 > > +@@ -481,7 +481,7 @@ AC_CHECK_LIB(vorbisfile, vorbis_comment_query, > > + > > ################################################################################################################ > > + ### Header checks > > + > > +-AC_CHECK_HEADERS([arpa/inet.h asm/unistd.h endian.h machine/endian.h > > fcntl.h libintl.h locale.h netdb.h netinet/in.h stddef.h stdlib.h string.h > > sys/file.h sys/inotify.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h > > unistd.h]) > > ++AC_CHECK_HEADERS([arpa/inet.h asm/unistd.h endian.h machine/endian.h > > fcntl.h libintl.h locale.h netdb.h netinet/in.h stddef.h stdlib.h string.h > > sys/file.h sys/inotify.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h > > unistd.h sys/event.h]) > > + > > + AC_CHECK_FUNCS(inotify_init, AC_DEFINE(HAVE_INOTIFY,1,[Whether kernel has > > inotify support]), [ > > + AC_MSG_CHECKING([for __NR_inotify_init syscall]) > > Index: patches/patch-inotify_c > > =================================================================== > > RCS file: patches/patch-inotify_c > > diff -N patches/patch-inotify_c > > --- /dev/null 1 Jan 1970 00:00:00 -0000 > > +++ patches/patch-inotify_c 18 Jan 2015 22:45:10 -0000 > > @@ -0,0 +1,569 @@ > > +$OpenBSD$ > > +--- inotify.c.orig Sun Jan 18 22:45:24 2015 > > ++++ inotify.c Sun Jan 18 22:45:27 2015 > > +@@ -15,9 +15,9 @@ > > + * You should have received a copy of the GNU General Public License > > + * along with MiniDLNA. If not, see <http://www.gnu.org/licenses/>. > > + */ > > + #include "config.h" > > + > > +-#ifdef HAVE_INOTIFY > > ++#if defined(HAVE_INOTIFY) || defined(HAVE_SYS_EVENT_H) > > + #include <stdio.h> > > + #include <string.h> > > + #include <stdlib.h> > > +@@ -31,11 +31,16 @@ > > + #include <sys/time.h> > > + #include <sys/resource.h> > > + #include <poll.h> > > ++#ifdef HAVE_INOTIFY > > + #ifdef HAVE_SYS_INOTIFY_H > > + #include <sys/inotify.h> > > +-#else > > ++#else /*HAVE_SYS_INOTIFY_H*/ > > + #include "linux/inotify.h" > > + #include "linux/inotify-syscalls.h" > > ++#endif /*HAVE_SYS_INOTIFY_H*/ > > ++#else > > ++#include <sys/event.h> > > ++#include <fcntl.h> > > + #endif > > + #include "libav.h" > > + > > +@@ -49,11 +54,13 @@ > > + #include "playlist.h" > > + #include "log.h" > > + > > ++#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 > > ++#endif > > + > > + struct watch > > + { > > +@@ -86,13 +93,35 @@ add_watch(int fd, const char * path) > > + struct watch *nw; > > + int wd; > > + > > ++#ifdef HAVE_INOTIFY > > + 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 -1; > > + } > > ++#else /*HAVE_INOTIFY*/ > > ++ wd = open(path, O_RDONLY); > > ++ if (wd == -1) > > ++ { > > ++ DPRINTF(E_ERROR, L_INOTIFY, > > "inotify_add_watch[kqueue,open](%s) [%s]\n", path, strerror(errno)); > > ++ return -1; > > ++ } > > + > > ++ struct kevent ke; > > ++ EV_SET(&ke, wd, > > ++ EVFILT_VNODE, > > ++ EV_ADD | EV_ENABLE | EV_CLEAR, > > ++ NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND /*| NOTE_ATTRB*/, > > ++ 0, NULL); > > ++ > > ++ if( kevent(fd, &ke, 1, NULL, 0, NULL) == -1 ) > > ++ { > > ++ DPRINTF(E_ERROR, L_INOTIFY, "inotify_add_watch[kqueue](%s) > > [%s]\n", path, strerror(errno)); > > ++ return -1; > > ++ } > > ++#endif > > ++ > > + nw = malloc(sizeof(struct watch)); > > + if( nw == NULL ) > > + { > > +@@ -125,7 +154,12 @@ remove_watch(int fd, const char * path) > > + for( w = watches; w; w = w->next ) > > + { > > + if( strcmp(path, w->path) == 0 ) > > ++#ifdef HAVE_INOTIFY > > + return(inotify_rm_watch(fd, w->wd)); > > ++#else > > ++ close(w->wd); /* kqueue cleans up events when > > handle dies*/ > > ++ return(0); > > ++#endif > > + } > > + > > + return 1; > > +@@ -145,15 +179,14 @@ next_highest(unsigned int num) > > + int > > + inotify_create_watches(int fd) > > + { > > +- FILE * max_watches; > > +- unsigned int num_watches = 0, watch_limit; > > ++ unsigned int num_watches = 0; > > + 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); > > ++ DPRINTF(E_DEBUG, L_INOTIFY, "Setting up monitoring on > > %s\n", media_path->path); > > + add_watch(fd, media_path->path); > > + num_watches++; > > + } > > +@@ -165,7 +198,11 @@ inotify_create_watches(int fd) > > + num_watches++; > > + } > > + sqlite3_free_table(result); > > + > > ++#ifdef HAVE_INOTIFY > > ++ FILE * max_watches; > > ++ unsigned int watch_limit; > > ++ > > + max_watches = fopen("/proc/sys/fs/inotify/max_user_watches", "r"); > > + if( max_watches ) > > + { > > +@@ -194,16 +231,17 @@ inotify_create_watches(int fd) > > + 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); > > + } > > ++#endif > > + > > + return rows; > > + } > > +@@ -218,7 +256,11 @@ inotify_remove_watches(int fd) > > + while( w ) > > + { > > + last_w = w; > > ++#ifdef HAVE_INOTIFY > > + inotify_rm_watch(fd, w->wd); > > ++#else > > ++ close(w->wd); /*kqueue cleans up after fhandle dies*/ > > ++#endif > > + free(w->path); > > + rm_watches++; > > + w = w->next; > > +@@ -261,10 +303,10 @@ int add_dir_watch(int fd, char * path, char * > > filename > > + while( (e = readdir(ds)) ) > > + { > > + if( strcmp(e->d_name, ".") == 0 || > > + strcmp(e->d_name, "..") == 0 ) > > + continue; > > + if( (e->d_type == DT_DIR) || > > + (e->d_type == DT_UNKNOWN && > > resolve_unknown_type(dir, NO_MEDIA) == TYPE_DIR) ) > > + i += add_dir_watch(fd, dir, e->d_name); > > + } > > + } > > +@@ -293,7 +335,10 @@ inotify_insert_file(char * name, const char * path) > > + media_types types = ALL_MEDIA; > > + struct media_dir_s * media_path = media_dirs; > > + struct stat st; > > ++ struct timeval now; > > + > > ++ DPRINTF(E_DEBUG, L_INOTIFY, "inotify_insert_file: %s @ %s\n", name, > > path); > > ++ > > + /* Is it cover art for another file? */ > > + if( is_image(path) ) > > + update_if_album_art(path); > > +@@ -357,6 +402,16 @@ inotify_insert_file(char * name, const char * path) > > + if( stat(path, &st) != 0 ) > > + return -1; > > + > > ++ (void)gettimeofday(&now, NULL); > > ++ while (now.tv_sec < st.st_mtime + 3) > > ++ { > > ++ DPRINTF(E_DEBUG, L_INOTIFY, "Sleeping until %s is stable > > for a few seconds ...\n", path); > > ++ sleep(1); > > ++ (void)gettimeofday(&now, NULL); > > ++ if (stat(path, &st) != 0) > > ++ return -1; > > ++ } > > ++ > > + ts = sql_get_int_field(db, "SELECT TIMESTAMP from DETAILS where > > PATH = '%q'", path); > > + if( !ts && is_playlist(path) && (sql_get_int_field(db, "SELECT ID > > from PLAYLISTS where PATH = '%q'", path) > 0) ) > > + { > > +@@ -386,9 +441,9 @@ inotify_insert_file(char * name, const char * path) > > + > > + do > > + { > > +- //DEBUG DPRINTF(E_DEBUG, L_INOTIFY, "Checking > > %s\n", parent_buf); > > ++ /*DEBUG DPRINTF(E_DEBUG, L_INOTIFY, "Checking > > %s\n", parent_buf);*/ > > + id = sql_get_text_field(db, "SELECT OBJECT_ID from > > OBJECTS o left join DETAILS d on (d.ID = o.DETAIL_ID)" > > + " where d.PATH = '%q' > > and REF_ID is NULL", parent_buf); > > + if( id ) > > + { > > + if( !depth ) > > +@@ -446,6 +501,8 @@ inotify_insert_directory(int fd, char *name, const cha > > + struct media_dir_s* media_path; > > + struct stat st; > > + > > ++ DPRINTF(E_DEBUG, L_INOTIFY, "inotify_insert_directory: %s @ %s\n", > > name, path); > > ++ > > + if( access(path, R_OK|X_OK) != 0 ) > > + { > > + DPRINTF(E_WARN, L_INOTIFY, "Could not access %s [%s]\n", > > path, strerror(errno)); > > +@@ -459,7 +516,7 @@ inotify_insert_directory(int fd, char *name, const cha > > + > > + parent_buf = strdup(path); > > + id = sql_get_text_field(db, "SELECT OBJECT_ID from OBJECTS o left > > join DETAILS d on (d.ID = o.DETAIL_ID)" > > + " where d.PATH = '%q' and REF_ID is > > NULL", dirname(parent_buf)); > > + if( !id ) > > + id = sqlite3_mprintf("%s", BROWSEDIR_ID); > > + insert_directory(name, path, BROWSEDIR_ID, id+2, > > get_next_available_id("OBJECTS", id)); > > +@@ -554,27 +611,25 @@ inotify_remove_file(const char * path) > > + { > > + sql_exec(db, "DELETE from PLAYLISTS where ID = %lld", > > detailID); > > + sql_exec(db, "DELETE from DETAILS where ID =" > > + " (SELECT DETAIL_ID from OBJECTS where > > OBJECT_ID = '%s$%llX')", > > + MUSIC_PLIST_ID, detailID); > > + sql_exec(db, "DELETE from OBJECTS where OBJECT_ID = > > '%s$%llX' or PARENT_ID = '%s$%llX'", > > + MUSIC_PLIST_ID, detailID, MUSIC_PLIST_ID, > > detailID); > > + } > > + else > > + { > > + /* Delete the parent containers if we are about to empty > > them. */ > > +- snprintf(sql, sizeof(sql), "SELECT PARENT_ID from OBJECTS > > where DETAIL_ID = %lld" > > +- " and PARENT_ID not like > > '64$%%'", > > +- (long long int)detailID); > > ++ snprintf(sql, sizeof(sql), "SELECT PARENT_ID from OBJECTS > > where DETAIL_ID = %lld", (long long int)detailID); > > + if( (sql_get_table(db, sql, &result, &rows, NULL) == > > SQLITE_OK) ) > > + { > > + int i, children; > > + for( i = 1; i <= rows; i++ ) > > + { > > + /* If it's a playlist item, adjust the item > > count of the playlist */ > > + if( strncmp(result[i], MUSIC_PLIST_ID, > > strlen(MUSIC_PLIST_ID)) == 0 ) > > + { > > + sql_exec(db, "UPDATE PLAYLISTS set > > FOUND = (FOUND-1) where ID = %d", > > + atoi(strrchr(result[i], > > '$') + 1)); > > + } > > + > > + children = sql_get_int_field(db, "SELECT > > count(*) from OBJECTS where PARENT_ID = '%s'", result[i]); > > +@@ -582,6 +637,8 @@ inotify_remove_file(const char * path) > > + continue; > > + if( children < 2 ) > > + { > > ++ sql_exec(db, "DELETE from DETAILS > > where ID =" > > ++ > > " (SELECT DETAIL_ID from OBJECTS where OBJECT_ID = '%s')", > > result[i]); > > + sql_exec(db, "DELETE from OBJECTS > > where OBJECT_ID = '%s'", result[i]); > > + > > + ptr = strrchr(result[i], '$'); > > +@@ -589,6 +646,8 @@ inotify_remove_file(const char * path) > > + *ptr = '\0'; > > + if( sql_get_int_field(db, "SELECT > > count(*) from OBJECTS where PARENT_ID = '%s'", result[i]) == 0 ) > > + { > > ++ sql_exec(db, "DELETE from > > DETAILS where ID =" > > ++ > > " (SELECT DETAIL_ID from OBJECTS where OBJECT_ID = > > '%s')", result[i]); > > + sql_exec(db, "DELETE from > > OBJECTS where OBJECT_ID = '%s'", result[i]); > > + } > > + } > > +@@ -613,11 +672,13 @@ inotify_remove_directory(int fd, const char * path) > > + int64_t detailID = 0; > > + int rows, i, ret = 1; > > + > > ++ DPRINTF(E_DEBUG, L_INOTIFY, "inotify_remove_directory: %s\n", path); > > ++ > > + /* Invalidate the scanner cache so we don't insert files into > > non-existent containers */ > > + valid_cache = 0; > > + remove_watch(fd, path); > > + 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) ) > > + { > > + if( rows ) > > +@@ -639,6 +700,7 @@ inotify_remove_directory(int fd, const char * path) > > + return ret; > > + } > > + > > ++#ifdef HAVE_INOTIFY > > + void * > > + start_inotify() > > + { > > +@@ -649,7 +711,7 @@ start_inotify() > > + int length, i = 0; > > + char * esc_name = NULL; > > + struct stat st; > > + > > + pollfds[0].fd = inotify_init(); > > + pollfds[0].events = POLLIN; > > + > > +@@ -664,13 +726,13 @@ start_inotify() > > + } > > + 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); > > + av_register_all(); > > + > > + while( !quitting ) > > + { > > + length = poll(pollfds, 1, timeout); > > + if( !length ) > > + { > > + if( next_pl_fill && (time(NULL) >= next_pl_fill) ) > > +@@ -708,12 +770,12 @@ start_inotify() > > + 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")); > > + > > inotify_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( S_ISLNK(st.st_mode) ) > > + { > > +@@ -727,7 +789,7 @@ start_inotify() > > + 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")); > > +@@ -756,4 +818,234 @@ quitting: > > + > > + return 0; > > + } > > ++#else > > ++void * > > ++start_kqueue() > > ++{ > > ++ int global_kqueue_handle = -1; > > ++ > > ++ global_kqueue_handle = kqueue(); > > ++ if ( global_kqueue_handle < 0 ) > > ++ { > > ++ DPRINTF(E_ERROR, L_INOTIFY, "kqueue() failed: %s\n", > > strerror(errno)); > > ++ return 0; > > ++ } > > ++ > > ++ while( scanning ) > > ++ { > > ++ if( quitting ) > > ++ goto quitting; > > ++ > > ++ DPRINTF(E_DEBUG, L_INOTIFY, "..waiting for scanning to > > complete...\n"); > > ++ sleep(1); > > ++ } > > ++ > > ++ DPRINTF(E_DEBUG, L_INOTIFY, "GOING WILD!\n"); > > ++ > > ++ inotify_create_watches(global_kqueue_handle); > > ++ if (setpriority(PRIO_PROCESS, 0, 19) == -1) > > ++ DPRINTF(E_WARN, L_INOTIFY, "Failed to reduce kqueue > > thread priority\n"); > > ++ sqlite3_release_memory(1<<31); > > ++ av_register_all(); > > ++ > > ++ while( !quitting ) > > ++ { > > ++ struct kevent ke; > > ++ if ( kevent(global_kqueue_handle, NULL, 0, &ke, 1, NULL) == > > -1 ) > > ++ { > > ++ DPRINTF(E_WARN, L_INOTIFY, "kevent polling > > failure: %s\n", strerror(errno)); > > ++ continue; > > ++ } > > ++ > > ++ /*DPRINTF(E_DEBUG, L_INOTIFY, "GOT KEVENT:\n" > > ++ "ident=0x%X, filter=0x%X, flags=0x%X, fflags=0x%X, > > data=0x%X, udata=0x%X\n", > > ++ ke.ident, ke.filter, ke.flags, ke.fflags, ke.data, > > ke.udata);*/ > > ++ > > ++ char* dir_path = get_path_from_wd(ke.ident); > > ++ if (dir_path == NULL) > > ++ { > > ++ DPRINTF(E_ERROR, L_INOTIFY, "Path with FD=0x%X > > can't be resolved.\n", ke.ident); > > ++ continue; > > ++ } > > ++ > > ++ if (ke.fflags & NOTE_DELETE) > > ++ { > > ++ DPRINTF(E_DEBUG, L_INOTIFY, "Path [%s] deleted.\n", > > dir_path); > > ++ inotify_remove_directory(ke.ident, dir_path); > > ++ } > > ++ else if ((ke.fflags & (NOTE_WRITE | NOTE_LINK)) == > > (NOTE_WRITE | NOTE_LINK)) > > ++ { > > ++ DPRINTF(E_DEBUG, L_INOTIFY, "Path [%s] content > > updated (directory).\n", dir_path); > > ++ > > ++ char * sql; > > ++ char **result; > > ++ int i, rows; > > ++ sql = sqlite3_mprintf("SELECT PATH from DETAILS > > where (PATH > '%q/' and PATH <= '%q/%c')" > > ++ " and SIZE = ''", dir_path, dir_path, 0xFF); > > ++ if( (sql_get_table(db, sql, &result, &rows, NULL) > > != SQLITE_OK) ) > > ++ { > > ++ DPRINTF(E_WARN, L_INOTIFY, "Read state > > [%s]: Query failed, not updating\n", dir_path); > > ++ sqlite3_free(sql); > > ++ continue; > > ++ } > > ++ > > ++ for( i=1; i <= rows; i++ ) > > ++ { > > ++ DPRINTF(E_DEBUG, L_INOTIFY, "Indexed > > content: %s\n", result[i]); > > ++ if (access(result[i], R_OK) == -1) > > ++ { > > ++ /* actually, global_kqueue_handle > > is not used here */ > > ++ > > inotify_remove_directory(global_kqueue_handle, result[i]); > > ++ } > > ++ } > > ++ > > ++ DIR* d; > > ++ struct dirent * entry; > > ++ d = opendir(dir_path); > > ++ if (!d) > > ++ { > > ++ DPRINTF(E_ERROR, L_INOTIFY, "Can't list > > [%s] (%s)\n", dir_path, strerror(errno)); > > ++ continue; > > ++ } > > ++ > > ++ for ( entry = readdir(d); entry != NULL; entry = > > readdir(d) ) > > ++ { > > ++ if ( (entry->d_type == DT_DIR) && > > ++ (strcmp(entry->d_name, "..") != 0) > > && > > ++ (strcmp(entry->d_name, ".") != 0) ) > > ++ { > > ++ char tmp_path[PATH_MAX]; > > ++ int result_path_len; > > ++ > > ++ result_path_len = > > snprintf(tmp_path, PATH_MAX, > > ++ "%s/%s", dir_path, > > entry->d_name); > > ++ if (result_path_len >= PATH_MAX) > > ++ { > > ++ DPRINTF(E_ERROR, L_INOTIFY, > > "File path too long for %s!", entry->d_name); > > ++ continue; > > ++ } > > ++ > > ++ DPRINTF(E_DEBUG, L_INOTIFY, > > "Walking %s\n", tmp_path); > > ++ char found_flag = 0; > > ++ for( i=1; i <= rows; i++ ) > > ++ { > > ++ if (strcmp(result[i], > > tmp_path) == 0) > > ++ { > > ++ found_flag = 1; > > ++ break; > > ++ } > > ++ } > > ++ > > ++ if ( !found_flag ) > > ++ { > > ++ char * esc_name = NULL; > > ++ esc_name = > > modifyString(strdup(entry->d_name), "&", "&amp;", 0); > > ++ > > inotify_insert_directory(global_kqueue_handle, esc_name, tmp_path); > > ++ free(esc_name); > > ++ } > > ++ } > > ++ } > > ++ > > ++ closedir(d); > > ++ > > ++ sqlite3_free_table(result); > > ++ sqlite3_free(sql); > > ++ } > > ++ else if (ke.fflags & NOTE_WRITE) > > ++ { > > ++ DPRINTF(E_DEBUG, L_INOTIFY, "Path [%s] content > > updated (file).\n", dir_path); > > ++ > > ++ char * sql; > > ++ char **result; > > ++ int i, rows; > > ++ sql = sqlite3_mprintf("SELECT PATH from DETAILS > > where (PATH > '%q/' and PATH <= '%q/%c')" > > ++ " and SIZE <> ''", dir_path, dir_path, > > 0xFF); > > ++ if( (sql_get_table(db, sql, &result, &rows, NULL) > > != SQLITE_OK) ) > > ++ { > > ++ DPRINTF(E_WARN, L_INOTIFY, "Read state > > [%s]: Query failed, not updating\n", dir_path); > > ++ sqlite3_free(sql); > > ++ continue; > > ++ } > > ++ > > ++ for( i=1; i <= rows; i++ ) > > ++ { > > ++ DPRINTF(E_DEBUG, L_INOTIFY, "Indexed > > content: %s\n", result[i]); > > ++ if (access(result[i], R_OK) == -1) /*oops, > > our file is gone*/ > > ++ { > > ++ inotify_remove_file(result[i]); > > ++ } > > ++ } > > ++ > > ++ DIR* d; > > ++ struct dirent * entry; > > ++ d = opendir(dir_path); > > ++ if (!d) > > ++ { > > ++ DPRINTF(E_ERROR, L_INOTIFY, "Can't list > > [%s] (%s)\n", dir_path, strerror(errno)); > > ++ continue; > > ++ } > > ++ > > ++ for ( entry = readdir(d); entry != NULL; entry = > > readdir(d) ) > > ++ { > > ++ if ( (entry->d_type == DT_REG) || > > ++ (entry->d_type == DT_LNK) ) > > ++ { > > ++ char tmp_path[PATH_MAX]; > > ++ int result_path_len; > > ++ > > ++ result_path_len = > > snprintf(tmp_path, PATH_MAX, > > ++ "%s/%s", dir_path, > > entry->d_name); > > ++ if (result_path_len >= PATH_MAX) > > ++ { > > ++ DPRINTF(E_ERROR, L_INOTIFY, > > "File path too long for %s!", entry->d_name); > > ++ continue; > > ++ } > > ++ > > ++ DPRINTF(E_DEBUG, L_INOTIFY, > > "Walking %s\n", tmp_path); > > ++ > > ++ char found_flag = 0; > > ++ for( i=1; i <= rows; i++ ) > > ++ { > > ++ if (strcmp(result[i], > > tmp_path) == 0) > > ++ { > > ++ found_flag = 1; > > ++ break; > > ++ } > > ++ } > > ++ > > ++ if ( !found_flag ) > > ++ { > > ++ char * esc_name = NULL; > > ++ struct stat st; > > ++ > > ++ if( stat(tmp_path, &st) != > > 0 ) > > ++ { > > ++ DPRINTF(E_ERROR, > > L_INOTIFY, "'%s' disappeared!", tmp_path); > > ++ continue; > > ++ } > > ++ > > ++ esc_name = > > modifyString(strdup(entry->d_name), "&", "&amp;", 0); > > ++ if ( S_ISDIR(st.st_mode) ) > > ++ > > inotify_insert_directory(global_kqueue_handle, esc_name, tmp_path); > > ++ else > > ++ > > inotify_insert_file(esc_name, tmp_path); > > ++ free(esc_name); > > ++ } > > ++ } > > ++ } > > ++ > > ++ closedir(d); > > ++ > > ++ sqlite3_free_table(result); > > ++ sqlite3_free(sql); > > ++ } > > ++ } > > ++ inotify_remove_watches(global_kqueue_handle); > > ++quitting: > > ++ > > ++ return 0; > > ++} > > + #endif > > ++ > > ++#endif // defined(HAVE_INOTIFY) || defined(HAVE_SYS_EVENT_H) > > ++ > > Index: patches/patch-inotify_h > > =================================================================== > > RCS file: patches/patch-inotify_h > > diff -N patches/patch-inotify_h > > --- /dev/null 1 Jan 1970 00:00:00 -0000 > > +++ patches/patch-inotify_h 18 Jan 2015 22:45:10 -0000 > > @@ -0,0 +1,14 @@ > > +$OpenBSD$ > > +--- inotify.h.orig Tue Aug 26 23:09:22 2014 > > ++++ inotify.h Sun Jan 18 22:45:07 2015 > > +@@ -4,4 +4,10 @@ inotify_remove_file(const char * path); > > + > > + void * > > + start_inotify(); > > ++#elif defined(HAVE_SYS_EVENT_H) > > ++int > > ++inotify_remove_file(const char* path); > > ++ > > ++void * > > ++start_kqueue(); > > + #endif > > Index: patches/patch-metadata_c > > =================================================================== > > RCS file: patches/patch-metadata_c > > diff -N patches/patch-metadata_c > > --- /dev/null 1 Jan 1970 00:00:00 -0000 > > +++ patches/patch-metadata_c 18 Jan 2015 22:45:10 -0000 > > @@ -0,0 +1,12 @@ > > +$OpenBSD$ > > +--- metadata.c.orig Tue Aug 26 23:09:22 2014 > > ++++ metadata.c Sun Jan 18 22:45:07 2015 > > +@@ -149,7 +149,7 @@ check_for_captions(const char *path, int64_t detailID) > > + > > + if (ret == 0) > > + { > > +- sql_exec(db, "INSERT into CAPTIONS" > > ++ sql_exec(db, "INSERT OR REPLACE into CAPTIONS" > > + " (ID, PATH) " > > + "VALUES" > > + " (%lld, %Q)", detailID, file); > > Index: patches/patch-minidlna_c > > =================================================================== > > RCS file: patches/patch-minidlna_c > > diff -N patches/patch-minidlna_c > > --- /dev/null 1 Jan 1970 00:00:00 -0000 > > +++ patches/patch-minidlna_c 18 Jan 2015 22:45:10 -0000 > > @@ -0,0 +1,43 @@ > > +$OpenBSD$ > > +--- minidlna.c.orig Tue Aug 26 23:09:22 2014 > > ++++ minidlna.c Sun Jan 18 22:45:07 2015 > > +@@ -46,6 +46,7 @@ > > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > > THE > > + * POSSIBILITY OF SUCH DAMAGE. > > + */ > > ++#define FD_SETSIZE 8192 > > + #include <stdlib.h> > > + #include <unistd.h> > > + #include <string.h> > > +@@ -376,6 +377,7 @@ rescan: > > + open_db(&db); > > + if (*scanner_pid == 0) /* child (scanner) process */ > > + { > > ++ DPRINTF(E_DEBUG, L_GENERAL, "Starting scanner in > > forked child\n"); > > + start_scanner(); > > + sqlite3_close(db); > > + log_close(); > > +@@ -384,6 +386,7 @@ rescan: > > + } > > + else if (*scanner_pid < 0) > > + { > > ++ DPRINTF(E_DEBUG, L_GENERAL, "Starting scanner in > > parent\n"); > > + start_scanner(); > > + } > > + #else > > +@@ -1047,6 +1050,15 @@ main(int argc, char **argv) > > + "Inotify will be > > disabled.\n"); > > + else if (pthread_create(&inotify_thread, NULL, > > start_inotify, NULL) != 0) > > + DPRINTF(E_FATAL, L_GENERAL, "ERROR: > > pthread_create() failed for start_inotify. EXITING\n"); > > ++ } > > ++#elif defined(HAVE_SYS_EVENT_H) > > ++ if( GETFLAG(INOTIFY_MASK) ) > > ++ { > > ++ if (!sqlite3_threadsafe() || sqlite3_libversion_number() < > > 3005001) > > ++ DPRINTF(E_ERROR, L_GENERAL, "SQLite library is not > > threadsafe! " > > ++ "Kqueue will be disabled.\n"); > > ++ else if (pthread_create(&inotify_thread, NULL, > > start_kqueue, NULL) != 0) > > ++ DPRINTF(E_FATAL, L_GENERAL, "ERROR: > > pthread_create() failed for start_kqueue. EXITING\n"); > > + } > > + #endif > > + smonitor = OpenAndConfMonitorSocket(); > > Index: patches/patch-minidlna_conf > > =================================================================== > > RCS file: /cvs/ports/multimedia/minidlna/patches/patch-minidlna_conf,v > > retrieving revision 1.4 > > diff -p -u -r1.4 patch-minidlna_conf > > --- patches/patch-minidlna_conf 11 Jun 2014 00:26:59 -0000 1.4 > > +++ patches/patch-minidlna_conf 18 Jan 2015 22:45:10 -0000 > > @@ -28,7 +28,7 @@ default directories, plus we don't use i > > > > # set this to merge all media_dir base contents into the root container > > # note: the default is no > > -@@ -25,22 +26,18 @@ media_dir=/opt > > +@@ -25,22 +26,22 @@ media_dir=/opt > > #friendly_name=My DLNA Server > > > > # set this if you would like to specify the directory where you want > > MiniDLNA to store its database and album art cache > > @@ -47,10 +47,10 @@ default directories, plus we don't use i > > # this should be a list of file names to check for when searching for > > album art > > # note: names should be delimited with a forward slash ("/") > > > > album_art_names=Cover.jpg/cover.jpg/AlbumArtSmall.jpg/albumartsmall.jpg/AlbumArt.jpg/albumart.jpg/Album.jpg/album.jpg/Folder.jpg/folder.jpg/Thumb.jpg/thumb.jpg > > -- > > --# set this to no to disable inotify monitoring to automatically discover > > new files > > --# note: the default is yes > > --inotify=yes > > + > > + # set this to no to disable inotify monitoring to automatically discover > > new files > > + # note: the default is yes > > + inotify=yes > > > > # set this to yes to enable support for streaming .jpg and .mp3 files to > > a TiVo supporting HMO > > enable_tivo=no > > Index: patches/patch-upnpevents_c > > =================================================================== > > RCS file: patches/patch-upnpevents_c > > diff -N patches/patch-upnpevents_c > > --- /dev/null 1 Jan 1970 00:00:00 -0000 > > +++ patches/patch-upnpevents_c 18 Jan 2015 22:45:10 -0000 > > @@ -0,0 +1,14 @@ > > +$OpenBSD$ > > +--- upnpevents.c.orig Tue Aug 26 23:09:22 2014 > > ++++ upnpevents.c Sun Jan 18 22:45:07 2015 > > +@@ -417,6 +417,10 @@ void upnpevents_selectfds(fd_set *readset, fd_set *wri > > + { > > + struct upnp_event_notify * obj; > > + for(obj = notifylist.lh_first; obj != NULL; obj = > > obj->entries.le_next) { > > ++ if (obj->s > FD_SETSIZE) > > ++ DPRINTF(E_FATAL, L_HTTP, > > ++ "upnpevents_selectfds: file descriptor %d too > > big for select, limit is %d\n", > > ++ obj->s, FD_SETSIZE); > > + DPRINTF(E_DEBUG, L_HTTP, "upnpevents_selectfds: %p %d %d\n", > > + obj, obj->state, obj->s); > > + if(obj->s >= 0) { > > > > > > Comments, tests? > > > > > > Daniel > > > > -- > > LÉVAI Dániel > > PGP key ID = 0x83B63A8F > > Key fingerprint = DBEC C66B A47A DFA2 792D 650C C69B BE4C 83B6 3A8F > > > > > > -- > "If you try a few times and give up, you'll never get there. But if > you keep at it... There's a lot of problems in the world which can > really be solved by applying two or three times the persistence that > other people will." > -- Stewart Nelson > -- Antoine