diff options
Diffstat (limited to 'common/inotify_helpers.h')
-rw-r--r-- | common/inotify_helpers.h | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/common/inotify_helpers.h b/common/inotify_helpers.h new file mode 100644 index 0000000..5bb7647 --- /dev/null +++ b/common/inotify_helpers.h @@ -0,0 +1,80 @@ +/* inotify_helper.h - Simple iteration for inotify events + * + * Copyright (C) 2014 Luke Shumaker + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* The usage is pretty simple: + * + * int my_filedesc = inotify_init(); + * ... + * struct inotify_event *my_event; + * for (INOTIFY_ITR(my_filedesc, my_event)) { + * ... + * } + * + * Easy, right? + */ + +#ifndef _INOTIFY_HELPER_H +#define _INOTIFY_HELPER_H + +#include <sys/inotify.h> +#include <limits.h> /* for NAME_MAX */ +#include <string.h> /* for memset(3) */ +#include <unistd.h> /* for read(3) */ + +struct _inotify_buffer { + ssize_t len; + ssize_t pos; + char dat[sizeof(struct inotify_event)+NAME_MAX+1]; +}; + +#define _INOTIFY_ITR_EVENT(BUF) \ + ((struct inotify_event *)&((BUF).dat[(BUF).pos])) +#define _INOTIFY_ITR_EVENT_SIZE(BUF) \ + (sizeof(struct inotify_event) + _INOTIFY_ITR_EVENT(BUF)->len) + +#define _INOTIFY_ITR_INIT(FD, BUF, EVENT) \ + struct _inotify_buffer BUF = ({ \ + struct _inotify_buffer tmp; \ + memset(&tmp, 0, sizeof(tmp)); \ + do { \ + tmp.len = read(FD, tmp.dat, sizeof(tmp.dat)); \ + } while (tmp.len == 0); \ + EVENT = (struct inotify_event *)&BUF; \ + tmp; \ + }) +#define _INOTIFY_ITR_CHECK(FD, BUF, EVENT) \ + BUF.len > -1 +#define _INOTIFY_ITR_UPDATE(FD, BUF, EVENT) \ + EVENT = ({ \ + if (BUF.len-(BUF.pos+_INOTIFY_ITR_EVENT_SIZE(BUF)) < 1) { \ + do { \ + BUF.len = read(FD, BUF.dat, sizeof(BUF.dat)); \ + } while (BUF.len == 0); \ + BUF.pos = 0; \ + } else { \ + BUF.pos += _INOTIFY_ITR_EVENT_SIZE(BUF); \ + } \ + _INOTIFY_ITR_EVENT(BUF); \ + }) + +#define INOTIFY_ITR(FD, EVENT) \ + _INOTIFY_ITR_INIT(FD, _buf, EVENT); \ + _INOTIFY_ITR_CHECK(FD, _buf, EVENT); \ + _INOTIFY_ITR_UPDATE(FD, _buf, EVENT) + +#endif |