This repository was archived by the owner on Aug 29, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinotify.c
More file actions
96 lines (80 loc) · 2.42 KB
/
inotify.c
File metadata and controls
96 lines (80 loc) · 2.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/* ============================================================================
* inotify.c: inotify backend for autograder.
* Copyright (C) 2013, Tyler J. Stachecki.
* All rights reserved.
*
* This file is subject to the terms and conditions defined in
* file 'LICENSE', which is part of this source code package.
* ========================================================================= */
#include "common.h"
#include "inotify.h"
#include "notify.h"
#include <limits.h>
#include <stddef.h>
#include <stdlib.h>
#include <sys/inotify.h>
#include <unistd.h>
#define BUF_LEN (sizeof(struct inotify_event) + NAME_MAX + 1)
static int deinit(struct notify_backend *backend);
static int init(struct notify_backend *backend, const char *pathname);
static int next(struct notify_backend *backend, const char **name);
struct inotify_private {
char buf[BUF_LEN];
int size;
int fd;
int wd;
};
const struct notify_backend inotify_backend = {
deinit,
init,
next,
"inotify",
NULL,
};
/* Releases any resources used for the backend. */
static int deinit(struct notify_backend *backend) {
struct inotify_private *opaque = (struct inotify_private*) (backend->opaque);
inotify_rm_watch(opaque->fd, opaque->wd);
close(opaque->fd);
free(opaque);
return 0;
}
/* Initializes an inotify fd, binds it to the backend. */
static int init(struct notify_backend *backend, const char *pathname) {
struct inotify_private *opaque;
int fd, wd;
if ((fd = inotify_init()) < 0) {
dperror("inotify_init");
return -1;
}
if ((opaque = (struct inotify_private*) malloc(sizeof(*opaque))) == NULL) {
dperror("malloc");
close(fd);
return -2;
}
if ((wd = inotify_add_watch(fd, pathname, IN_CLOSE_WRITE | IN_ATTRIB)) < 0) {
dperror("inotify_add_watch");
close(fd);
return -3;
}
backend->opaque = opaque;
opaque->fd = fd;
opaque->wd = wd;
return 0;
}
/* Checks if inotify has any events for us. Blocks on input. */
static int next(struct notify_backend *backend, const char **name) {
struct inotify_private *opaque = (struct inotify_private*) (backend->opaque);
struct inotify_event *event = (struct inotify_event*) (opaque->buf);
int ret;
/* TODO: Handle short reads from inotify. */
/* TODO: It shouldn't ever happen, but... */
if ((ret = read(opaque->fd, opaque->buf, sizeof(opaque->buf))) < 0) {
dperror("read");
*name = NULL;
return -1;
}
*name = opaque->buf + sizeof(struct inotify_event);
opaque->size = ret;
return 0;
}