aboutsummaryrefslogtreecommitdiff
path: root/inotify_c.c
diff options
context:
space:
mode:
Diffstat (limited to 'inotify_c.c')
-rw-r--r--inotify_c.c60
1 files changed, 58 insertions, 2 deletions
diff --git a/inotify_c.c b/inotify_c.c
index c81f57d..e63ebfb 100644
--- a/inotify_c.c
+++ b/inotify_c.c
@@ -9,6 +9,10 @@
#include "Clean.h"
+/**
+ * Cast a CleanString to a char*
+ * The result should be freed.
+ */
char* clstocs(CleanString* cs) {
char* s = calloc(CleanStringLength(cs) + 1, 1);
uint8_t i;
@@ -18,12 +22,20 @@ char* clstocs(CleanString* cs) {
return s;
}
+/** The empty string, as a CleanString */
static struct {int length; char chars[1]; } empty_string = {0,""};
+/**
+ * Get the errno. The parameter is ignored, it is just there because ccalls
+ * need to have an argument.
+ */
int clean_errno(int ignored) {
return errno;
}
+/**
+ * Initialise an inotify file descriptor and change to NONBLOCK mode.
+ */
int clean_inotify_init(int ignored) {
int fd;
fd = inotify_init();
@@ -33,6 +45,15 @@ int clean_inotify_init(int ignored) {
return fd;
}
+/**
+ * Add a watch on some file.
+ *
+ * fd The inotify file descriptor
+ * fname The file to watch
+ * mask A mask of events to watch on
+ * re_watch Will be set to the resulting watch descriptor
+ * re_fd Will be set to fd (needed for uniqueness)
+ */
void clean_inotify_add_watch(int fd, CleanString* fname_, int mask,
int *re_watch, int *re_fd) {
char* fname = clstocs(fname_);
@@ -41,21 +62,56 @@ void clean_inotify_add_watch(int fd, CleanString* fname_, int mask,
*re_fd = fd;
}
+/**
+ * Remove a watch descriptor.
+ *
+ * fd The inotify file descriptor
+ * watch The watch descriptor to remove
+ * re_code Will be set to the return code of inotify_rm_watch
+ * re_fd Will be set to fd (needed for uniqueness)
+ */
void clean_inotify_rm_watch(int fd, int watch, int *re_code, int *re_fd) {
*re_fd = fd;
*re_code = inotify_rm_watch(fd, watch);
}
-void clean_poll(int fd, int *re_nrevents, int *re_fd) {
+/**
+ * Poll an inotify file descriptor
+ *
+ * fd The inotify file descriptor to poll
+ * timeout The timeout (negative for no timeout)
+ * re_nrevents Will be set to the number of polled events
+ * re_fd Will be set to fd (needed for uniqueness)
+ */
+void clean_poll(int fd, int timeout, int *re_nrevents, int *re_fd) {
struct pollfd pfd = {fd, POLLIN, 0};
- *re_nrevents = poll(&pfd, 1, -1);
+ *re_nrevents = poll(&pfd, 1, timeout);
*re_fd = fd;
}
+/**
+ * CleanStrings that are returned from clean_inotify_check (so that we don't
+ * have to malloc all the time.)
+ */
static CleanStringVariable(wds_string, 1024);
static CleanStringVariable(masks_string, 1024);
static CleanStringVariable(names_string, 4096);
+/**
+ * Check for events on an inotify file descriptor.
+ *
+ * fd The inotify file descriptor
+ * re_ok Will be set to 1 on success, 0 on failure
+ * re_wds An array of ints, the watch descriptors that had events
+ * re_masks An array of ints, the events
+ * re_fnames A list of strings, the filenames of the events (may be empty)
+ * re_fd Will be set to fd (needed for uniqueness)
+ *
+ * re_wds, re_masks and re_fnames are hacks because ccall doesn't allow
+ * returning {#Int} or {#String}. The int arrays can be read by taking 4 chars
+ * at a time and casting that to an int. The string array can be read by
+ * splitting on \0 (since they are filenames, \0 cannot occur).
+ */
void clean_inotify_check(int fd,
int *re_ok, CleanString* re_wds, CleanString* re_masks,
CleanString* re_fnames, int *re_fd) {