#ifndef _INOTIFY_H_
#define _INOTIFY_H_
#include <sys/_types.h>
#define IN_NONBLOCK 0x00000004
#define IN_CLOEXEC 0x00100000
struct inotify_event {
int wd;
__uint32_t mask;
__uint32_t cookie;
__uint32_t len;
char name[0];
};
#define IN_ACCESS 0x00000001
#define IN_MODIFY 0x00000002
#define IN_ATTRIB 0x00000004
#define IN_CLOSE_WRITE 0x00000008
#define IN_CLOSE_NOWRITE 0x00000010
#define IN_CLOSE (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)
#define IN_OPEN 0x00000020
#define IN_MOVED_FROM 0x00000040
#define IN_MOVED_TO 0x00000080
#define IN_MOVE (IN_MOVED_FROM | IN_MOVED_TO)
#define IN_CREATE 0x00000100
#define IN_DELETE 0x00000200
#define IN_DELETE_SELF 0x00000400
#define IN_MOVE_SELF 0x00000800
#define IN_ALL_EVENTS 0x00000fff
#define _IN_DIR_EVENTS (IN_CLOSE_WRITE | IN_DELETE | IN_MODIFY | \
IN_MOVED_FROM | IN_MOVED_TO)
#ifdef _KERNEL
#define _IN_MOVE_DELETE 0x40000000
#define _IN_ATTRIB_LINKCOUNT 0x80000000
#endif
#define IN_ONLYDIR 0x01000000
#define IN_DONT_FOLLOW 0x02000000
#define IN_EXCL_UNLINK 0x04000000
#define IN_MASK_CREATE 0x10000000
#define IN_MASK_ADD 0x20000000
#define IN_ONESHOT 0x80000000
#define _IN_ALL_FLAGS (IN_ONLYDIR | IN_DONT_FOLLOW | \
IN_EXCL_UNLINK | IN_MASK_CREATE | \
IN_MASK_ADD | IN_ONESHOT)
#define IN_UNMOUNT 0x00002000
#define IN_Q_OVERFLOW 0x00004000
#define IN_IGNORED 0x00008000
#define IN_ISDIR 0x40000000
#define _IN_ALL_RETFLAGS (IN_Q_OVERFLOW | IN_UNMOUNT | IN_IGNORED | \
IN_ISDIR)
#define _IN_ALIGN _Alignof(struct inotify_event)
#define _IN_NAMESIZE(namelen) \
((namelen) == 0 ? 0 : __align_up((namelen) + 1, _IN_ALIGN))
#ifdef _KERNEL
struct componentname;
struct file;
struct inotify_softc;
struct thread;
struct vnode;
int inotify_create_file(struct thread *, struct file *, int, int *);
void inotify_log(struct vnode *, const char *, size_t, int, __uint32_t);
int kern_inotify_rm_watch(int, uint32_t, struct thread *);
int kern_inotify_add_watch(int, int, const char *, uint32_t,
struct thread *);
void vn_inotify(struct vnode *, struct vnode *, struct componentname *, int,
uint32_t);
int vn_inotify_add_watch(struct vnode *, struct inotify_softc *,
__uint32_t, __uint32_t *, struct thread *);
void vn_inotify_revoke(struct vnode *);
#define INOTIFY(vp, ev) do { \
if (__predict_false((vn_irflag_read(vp) & (VIRF_INOTIFY | \
VIRF_INOTIFY_PARENT)) != 0)) \
VOP_INOTIFY((vp), NULL, NULL, (ev), 0); \
} while (0)
#define INOTIFY_NAME_LOCK(vp, dvp, cnp, ev, lock) do { \
if (__predict_false((vn_irflag_read(vp) & VIRF_INOTIFY) != 0 || \
(vn_irflag_read(dvp) & VIRF_INOTIFY) != 0)) { \
if (lock) \
vn_lock((vp), LK_SHARED | LK_RETRY); \
VOP_INOTIFY((vp), (dvp), (cnp), (ev), 0); \
if (lock) \
VOP_UNLOCK(vp); \
} \
} while (0)
#define INOTIFY_NAME(vp, dvp, cnp, ev) \
INOTIFY_NAME_LOCK((vp), (dvp), (cnp), (ev), false)
extern __uint32_t inotify_rename_cookie;
#define INOTIFY_MOVE(vp, fdvp, fcnp, tvp, tdvp, tcnp) do { \
if (__predict_false((vn_irflag_read(fdvp) & VIRF_INOTIFY) != 0 || \
(vn_irflag_read(tdvp) & VIRF_INOTIFY) != 0 || \
(vn_irflag_read(vp) & VIRF_INOTIFY) != 0)) { \
__uint32_t cookie; \
\
cookie = atomic_fetchadd_32(&inotify_rename_cookie, 1); \
VOP_INOTIFY((vp), (fdvp), (fcnp), IN_MOVED_FROM, cookie); \
VOP_INOTIFY((vp), (tdvp), (tcnp), IN_MOVED_TO, cookie); \
} \
if ((tvp) != NULL) \
INOTIFY_NAME_LOCK((tvp), (tdvp), (tcnp), \
_IN_MOVE_DELETE, true); \
} while (0)
#define INOTIFY_REVOKE(vp) do { \
if (__predict_false((vn_irflag_read(vp) & VIRF_INOTIFY) != 0)) \
vn_inotify_revoke((vp)); \
} while (0)
#else
#include <sys/cdefs.h>
__BEGIN_DECLS
int inotify_init(void);
int inotify_init1(int flags);
int inotify_add_watch(int fd, const char *pathname, __uint32_t mask);
int inotify_add_watch_at(int fd, int dfd, const char *pathname,
__uint32_t mask);
int inotify_rm_watch(int fd, int wd);
__END_DECLS
#endif
#endif