aboutsummaryrefslogtreecommitdiffstats
path: root/src/kqueue.c
diff options
context:
space:
mode:
authorMichael Albinus2015-11-16 09:47:26 +0000
committerMichael Albinus2015-11-25 15:07:11 +0100
commit8deebe1ab8d79c3a3fbc3043f99af76802f60bd6 (patch)
treef4db5c8dd8856e0c45c31140f643d06a332b1cb2 /src/kqueue.c
parent90d6c698da735cf3e54d69816995f70e53060bac (diff)
downloademacs-8deebe1ab8d79c3a3fbc3043f99af76802f60bd6.tar.gz
emacs-8deebe1ab8d79c3a3fbc3043f99af76802f60bd6.zip
Finish implementation in kqueue.c
* src/kqueue.c (kqueue_directory_listing, kqueue_callback): Simplify access to list. (kqueue_compare_dir_list): Simplify access to list. Raise `delete' event if directory does not exist any longer. Otherwise, wait until directory contents has changed. Fix error in check.
Diffstat (limited to 'src/kqueue.c')
-rw-r--r--src/kqueue.c58
1 files changed, 35 insertions, 23 deletions
diff --git a/src/kqueue.c b/src/kqueue.c
index 2097b7ed492..dfd91397370 100644
--- a/src/kqueue.c
+++ b/src/kqueue.c
@@ -32,11 +32,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
32/* File handle for kqueue. */ 32/* File handle for kqueue. */
33static int kqueuefd = -1; 33static int kqueuefd = -1;
34 34
35/* This is a list, elements are (DESCRIPTOR FILE FLAGS CALLBACK [DIRLIST]) */ 35/* This is a list, elements are (DESCRIPTOR FILE FLAGS CALLBACK [DIRLIST]). */
36static Lisp_Object watch_list; 36static Lisp_Object watch_list;
37 37
38/* Generate a temporary list from the directory_files_internal output. 38/* Generate a temporary list from the directory_files_internal output.
39 Items are (INODE FILE_NAME LAST_MOD LAST_STATUS_MOD SIZE). */ 39 Items are (INODE FILE-NAME LAST-MOD LAST-STATUS-MOD SIZE). */
40Lisp_Object 40Lisp_Object
41kqueue_directory_listing (Lisp_Object directory_files) 41kqueue_directory_listing (Lisp_Object directory_files)
42{ 42{
@@ -44,15 +44,15 @@ kqueue_directory_listing (Lisp_Object directory_files)
44 for (dl = directory_files; ! NILP (dl); dl = XCDR (dl)) { 44 for (dl = directory_files; ! NILP (dl); dl = XCDR (dl)) {
45 result = Fcons 45 result = Fcons
46 (list5 (/* inode. */ 46 (list5 (/* inode. */
47 XCAR (Fnthcdr (make_number (11), XCAR (dl))), 47 Fnth (make_number (11), XCAR (dl)),
48 /* filename. */ 48 /* filename. */
49 XCAR (XCAR (dl)), 49 XCAR (XCAR (dl)),
50 /* last modification time. */ 50 /* last modification time. */
51 XCAR (Fnthcdr (make_number (6), XCAR (dl))), 51 Fnth (make_number (6), XCAR (dl)),
52 /* last status change time. */ 52 /* last status change time. */
53 XCAR (Fnthcdr (make_number (7), XCAR (dl))), 53 Fnth (make_number (7), XCAR (dl)),
54 /* size. */ 54 /* size. */
55 XCAR (Fnthcdr (make_number (8), XCAR (dl)))), 55 Fnth (make_number (8), XCAR (dl))),
56 result); 56 result);
57 } 57 }
58 return result; 58 return result;
@@ -89,11 +89,23 @@ kqueue_compare_dir_list
89 Lisp_Object old_directory_files, old_dl, new_directory_files, new_dl, dl; 89 Lisp_Object old_directory_files, old_dl, new_directory_files, new_dl, dl;
90 90
91 dir = XCAR (XCDR (watch_object)); 91 dir = XCAR (XCDR (watch_object));
92 callback = XCAR (Fnthcdr (make_number (3), watch_object)); 92 callback = Fnth (make_number (3), watch_object);
93 old_directory_files = XCAR (Fnthcdr (make_number (4), watch_object)); 93
94 old_directory_files = Fnth (make_number (4), watch_object);
94 old_dl = kqueue_directory_listing (old_directory_files); 95 old_dl = kqueue_directory_listing (old_directory_files);
95 new_directory_files = 96
96 directory_files_internal (dir, Qnil, Qnil, Qnil, 1, Qnil); 97 /* Sometimes, the directory write event is triggered when the change
98 is not visible yet in the directory itself. So we must wait a
99 little bit. */
100 if (NILP (Ffile_directory_p (dir))) {
101 kqueue_generate_event
102 (XCAR (watch_object), Fcons (Qdelete, Qnil), dir, Qnil, callback);
103 return;
104 }
105 do {
106 new_directory_files =
107 directory_files_internal (dir, Qnil, Qnil, Qnil, 1, Qnil);
108 } while (! NILP (Fequal (old_directory_files, new_directory_files)));
97 new_dl = kqueue_directory_listing (new_directory_files); 109 new_dl = kqueue_directory_listing (new_directory_files);
98 110
99 /* Parse through the old list. */ 111 /* Parse through the old list. */
@@ -117,21 +129,21 @@ kqueue_compare_dir_list
117 goto the_end; 129 goto the_end;
118 } 130 }
119 131
132 /* Both entries have the same inode. */
120 if (! NILP (new_entry)) { 133 if (! NILP (new_entry)) {
121 /* Both entries have the same inode. */ 134 /* Both entries have the same file name. */
122 if (strcmp (SSDATA (XCAR (XCDR (old_entry))), 135 if (strcmp (SSDATA (XCAR (XCDR (old_entry))),
123 SSDATA (XCAR (XCDR (new_entry)))) == 0) { 136 SSDATA (XCAR (XCDR (new_entry)))) == 0) {
124 /* Both entries have the same file name. */ 137 /* Modification time has been changed, the file has been written. */
125 if (! NILP (Fequal (XCAR (Fnthcdr (make_number (2), old_entry)), 138 if (NILP (Fequal (Fnth (make_number (2), old_entry),
126 XCAR (Fnthcdr (make_number (2), new_entry))))) 139 Fnth (make_number (2), new_entry))))
127 /* Modification time has been changed, the file has been written. */
128 kqueue_generate_event 140 kqueue_generate_event
129 (XCAR (watch_object), Fcons (Qwrite, Qnil), 141 (XCAR (watch_object), Fcons (Qwrite, Qnil),
130 XCAR (XCDR (old_entry)), Qnil, callback); 142 XCAR (XCDR (old_entry)), Qnil, callback);
131 if (! NILP (Fequal (XCAR (Fnthcdr (make_number (3), old_entry)), 143 /* Status change time has been changed, the file attributes
132 XCAR (Fnthcdr (make_number (3), new_entry))))) 144 have changed. */
133 /* Status change time has been changed, the file attributes 145 if (NILP (Fequal (Fnth (make_number (3), old_entry),
134 have changed. */ 146 Fnth (make_number (3), new_entry))))
135 kqueue_generate_event 147 kqueue_generate_event
136 (XCAR (watch_object), Fcons (Qattrib, Qnil), 148 (XCAR (watch_object), Fcons (Qattrib, Qnil),
137 XCAR (XCDR (old_entry)), Qnil, callback); 149 XCAR (XCDR (old_entry)), Qnil, callback);
@@ -193,7 +205,7 @@ kqueue_compare_dir_list
193 XCAR (XCDR (new_entry)), Qnil, callback); 205 XCAR (XCDR (new_entry)), Qnil, callback);
194 206
195 /* Check size of that file. */ 207 /* Check size of that file. */
196 Lisp_Object size = XCAR (Fnthcdr (make_number (4), new_entry)); 208 Lisp_Object size = Fnth (make_number (4), new_entry);
197 if (FLOATP (size) || (XINT (size) > 0)) 209 if (FLOATP (size) || (XINT (size) > 0))
198 kqueue_generate_event 210 kqueue_generate_event
199 (XCAR (watch_object), Fcons (Qwrite, Qnil), 211 (XCAR (watch_object), Fcons (Qwrite, Qnil),
@@ -211,7 +223,7 @@ kqueue_compare_dir_list
211 report_file_error ("New list not empty", new_dl); 223 report_file_error ("New list not empty", new_dl);
212 224
213 /* Replace directory listing with the new one. */ 225 /* Replace directory listing with the new one. */
214 XSETCDR (XCDR (XCDR (XCDR (watch_object))), 226 XSETCDR (Fnthcdr (make_number (3), watch_object),
215 Fcons (new_directory_files, Qnil)); 227 Fcons (new_directory_files, Qnil));
216 return; 228 return;
217} 229}
@@ -239,8 +251,8 @@ kqueue_callback (int fd, void *data)
239 251
240 if (CONSP (watch_object)) { 252 if (CONSP (watch_object)) {
241 file = XCAR (XCDR (watch_object)); 253 file = XCAR (XCDR (watch_object));
242 callback = XCAR (XCDR (XCDR (XCDR (watch_object)))); 254 callback = Fnth (make_number (3), watch_object);
243 dirp = XCDR (XCDR (XCDR (XCDR (watch_object)))); 255 dirp = Fnth (make_number (4), watch_object);
244 } 256 }
245 else 257 else
246 continue; 258 continue;