diff options
| author | Michael Albinus | 2015-11-16 09:47:26 +0000 |
|---|---|---|
| committer | Michael Albinus | 2015-11-25 15:07:11 +0100 |
| commit | 8deebe1ab8d79c3a3fbc3043f99af76802f60bd6 (patch) | |
| tree | f4db5c8dd8856e0c45c31140f643d06a332b1cb2 /src/kqueue.c | |
| parent | 90d6c698da735cf3e54d69816995f70e53060bac (diff) | |
| download | emacs-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.c | 58 |
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. */ |
| 33 | static int kqueuefd = -1; | 33 | static 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]). */ |
| 36 | static Lisp_Object watch_list; | 36 | static 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). */ |
| 40 | Lisp_Object | 40 | Lisp_Object |
| 41 | kqueue_directory_listing (Lisp_Object directory_files) | 41 | kqueue_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; |