/* * This is free and unencumbered software released into the public domain. * * Anyone is free to copy, modify, publish, use, compile, sell, or * distribute this software, either in source code form or as a compiled * binary, for any purpose, commercial or non-commercial, and by any * means. * * In jurisdictions that recognize copyright laws, the author or authors * of this software dedicate any and all copyright interest in the * software to the public domain. We make this dedication for the benefit * of the public at large and to the detriment of our heirs and * successors. We intend this dedication to be an overt act of * relinquishment in perpetuity of all present and future rights to this * software under copyright law. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * For more information, please refer to <http://unlicense.org/> */ package jxtn.core.unix; import java.nio.ByteBuffer; import java.nio.file.Path; import java.util.function.Consumer; /** * inotify support * * @author aqd */ public final class NativeINotify extends JNIBase { /* init1 flags */ public static final int IN_NONBLOCK = 00004000; public static final int IN_CLOEXEC = 02000000; /* Supported events suitable for mask parameter of inotify_add_watch */ public static final int IN_ACCESS = 0x00000001; /* File was accessed. */ public static final int IN_MODIFY = 0x00000002; /* File was modified. */ public static final int IN_ATTRIB = 0x00000004; /* Metadata changed. */ public static final int IN_CLOSE_WRITE = 0x00000008; /* Writtable file was closed. */ public static final int IN_CLOSE_NOWRITE = 0x00000010; /* Unwrittable file closed. */ public static final int IN_CLOSE = (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE); /* Close. */ public static final int IN_OPEN = 0x00000020; /* File was opened. */ public static final int IN_MOVED_FROM = 0x00000040; /* File was moved from X. */ public static final int IN_MOVED_TO = 0x00000080; /* File was moved to Y. */ public static final int IN_MOVE = (IN_MOVED_FROM | IN_MOVED_TO); /* Moves. */ public static final int IN_CREATE = 0x00000100; /* Subfile was created. */ public static final int IN_DELETE = 0x00000200; /* Subfile was deleted. */ public static final int IN_DELETE_SELF = 0x00000400; /* Self was deleted. */ public static final int IN_MOVE_SELF = 0x00000800; /* Self was moved. */ /* Events sent by the kernel. */ public static final int IN_UNMOUNT = 0x00002000; /* Backing fs was unmounted. */ public static final int IN_Q_OVERFLOW = 0x00004000; /* Event queued overflowed. */ public static final int IN_IGNORED = 0x00008000; /* File was ignored. */ /* Special flags. */ public static final int IN_ONLYDIR = 0x01000000; /* Only watch the path if it is a directory. */ public static final int IN_DONT_FOLLOW = 0x02000000; /* Do not follow a sym link. */ public static final int IN_EXCL_UNLINK = 0x04000000; /* Exclude events on unlinked objects. */ public static final int IN_MASK_ADD = 0x20000000; /* Add to the mask of an already existing watch. */ public static final int IN_ISDIR = 0x40000000; /* Event occurred against dir. */ public static final int IN_ONESHOT = 0x80000000; /* Only send event once. */ public static final int IN_ALL_EVENTS = (IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE | IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM | IN_MOVED_TO | IN_CREATE | IN_DELETE | IN_DELETE_SELF | IN_MOVE_SELF); /* */ private static final int DEFAULT_INOTIFY_BUFFER_SIZE = INotifyEvent.BUFFER_SIZE << 8; /* inotify_init */ public static native int init(); /* inotify_init1 */ public static native int init1(int flags); /* add_watch */ public static int add_watch(int fd, Path pathname, int mask) { return add_watch(fd, tPath(pathname), mask); } public static int add_watch(int fd, String pathname, int mask) { return add_watch(fd, tPath(pathname), mask); } private static native int add_watch(int fd, byte[] pathname, int mask); /* rm_watch */ public static native int rm_watch(int fd, int wd); /* read */ public static long read(int fd, Consumer<INotifyEvent> eventConsumer) { return read(fd, eventConsumer, DEFAULT_INOTIFY_BUFFER_SIZE); } public static long read(int fd, Consumer<INotifyEvent> eventConsumer, int bufferLength) { byte[] inotify_ary = new byte[Math.max(bufferLength, INotifyEvent.BUFFER_SIZE)]; long total = 0; long ret; while ((ret = NativeIO.read(fd, inotify_ary)) > 0) { ByteBuffer inotify_buf = ByteBuffer.wrap(inotify_ary); inotify_buf.limit((int) ret); total += ret; while (inotify_buf.hasRemaining()) { INotifyEvent event = new INotifyEvent(inotify_buf); eventConsumer.accept(event); } } if (ret != -1) { return total; } else { return ret; } } private NativeINotify() { } }