From owner-freebsd-questions@FreeBSD.ORG Thu Apr 3 21:04:43 2008 Return-Path: Delivered-To: freebsd-questions@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B5D34106567C for ; Thu, 3 Apr 2008 21:04:43 +0000 (UTC) (envelope-from fbsd.questions@rachie.is-a-geek.net) Received: from snoogles.rachie.is-a-geek.net (rachie.is-a-geek.net [66.230.99.27]) by mx1.freebsd.org (Postfix) with ESMTP id 7DA698FC14 for ; Thu, 3 Apr 2008 21:04:43 +0000 (UTC) (envelope-from fbsd.questions@rachie.is-a-geek.net) Received: from localhost (localhost [127.0.0.1]) by snoogles.rachie.is-a-geek.net (Postfix) with ESMTP id B8E4C1CC91; Thu, 3 Apr 2008 13:04:42 -0800 (AKDT) From: Mel To: freebsd-questions@freebsd.org Date: Thu, 3 Apr 2008 23:04:40 +0200 User-Agent: KMail/1.9.7 References: <20080403102555.9941.qmail@rahul.net> <200804031612.00718.fbsd.questions@rachie.is-a-geek.net> In-Reply-To: <200804031612.00718.fbsd.questions@rachie.is-a-geek.net> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200804032304.41149.fbsd.questions@rachie.is-a-geek.net> Cc: John Conover Subject: Re: F_NOTIFY in fcntl(2)? X-BeenThere: freebsd-questions@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: User questions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 03 Apr 2008 21:04:43 -0000 On Thursday 03 April 2008 16:11:59 Mel wrote: > On Thursday 03 April 2008 12:25:55 John Conover wrote: > > Does freebsd support the F_NOTIFY, (i.e., File and directory change > > notification,) in fcntl(2)? > > > > I get that it doesn't, but its an old 5X version, and I might have to > > upgrade. > > Nope, this is a GNU extension to fcntl. File change notifications are done > with EVFILT_VNODE using kqueue(2). Directory changes have no interface that > I know of. You might wanna take a look at how devel/gamin handles this, > specifically the kqueue implementation. Figured I'd give an example of how it can be done (as in: works for me for file deletion/creation and renames). Doesn't work for utimes(2) operations on a file, as in "touch /tmp/this_file_exists" will not fire. Code inlined below sig. -- Mel #include #include #include #include #include #include #include #include #include int main(int argc, char **argv) { int kq, fd; struct kevent changes, events; time_t *mtime; struct stat sb; if( -1 == (fd = open("/tmp/.", O_RDONLY)) ) err(EX_OSERR, "Cannot open dir /tmp"); if( NULL == (mtime = malloc(sizeof(time_t))) ) err(EX_OSERR, "Failed to allocate %d bytes", sizeof(time_t)); if( -1 == fstat(fd, &sb) ) err(EX_OSERR, "Cannot stat fd %u", fd); *mtime = sb.st_mtime; if( -1 == (kq = kqueue()) ) err(EX_OSERR, "Cannot get a kqueue"); EV_SET(&changes, fd, EVFILT_TIMER, EV_ADD|EV_ENABLE, 0, 500, (void *)mtime); for( ;; ) { /* we can only get one event, really. */ if( -1 == kevent(kq, &changes, 1, &events, 1, NULL) ) err(EX_OSERR, "kevent"); if( events.flags & EV_ERROR ) errc(EX_OSERR, events.data, "Event error"); /* secretly, our timer is an fd, we probably should use udata for this * though. */ if( -1 == fstat(events.ident, &sb) ) { warn("Failed to stat fd %u", events.ident); break; } else { if( *mtime && *mtime != sb.st_mtime ) printf("Mtime changed: %u => %u\n", *mtime, sb.st_mtime); else printf("Mtime unchanged: %u\n", *mtime); *mtime = sb.st_mtime; } } close(kq); return 0; }