aboutsummaryrefslogtreecommitdiffstats
path: root/src/w32notify.c
diff options
context:
space:
mode:
authorEli Zaretskii2013-12-08 20:29:12 +0200
committerEli Zaretskii2013-12-08 20:29:12 +0200
commit439b1ae89e7c0660ef0a8fa540b12977e38dedf8 (patch)
treef9edeb7b81ce8be31142e9235f88c378ab41bac4 /src/w32notify.c
parent4ba5c243d0c3e29ef2373247464fbf925def8164 (diff)
downloademacs-439b1ae89e7c0660ef0a8fa540b12977e38dedf8.tar.gz
emacs-439b1ae89e7c0660ef0a8fa540b12977e38dedf8.zip
Converted and tested w32notify.c.
Diffstat (limited to 'src/w32notify.c')
-rw-r--r--src/w32notify.c96
1 files changed, 53 insertions, 43 deletions
diff --git a/src/w32notify.c b/src/w32notify.c
index 373e20e8e92..da7c5513dc3 100644
--- a/src/w32notify.c
+++ b/src/w32notify.c
@@ -105,7 +105,7 @@ struct notification {
105 OVERLAPPED *io_info; /* the OVERLAPPED structure for async I/O */ 105 OVERLAPPED *io_info; /* the OVERLAPPED structure for async I/O */
106 BOOL subtree; /* whether to watch subdirectories */ 106 BOOL subtree; /* whether to watch subdirectories */
107 DWORD filter; /* bit mask for events to watch */ 107 DWORD filter; /* bit mask for events to watch */
108 char *watchee; /* the file we are interested in */ 108 char *watchee; /* the file we are interested in, UTF-8 encoded */
109 HANDLE dir; /* handle to the watched directory */ 109 HANDLE dir; /* handle to the watched directory */
110 HANDLE thr; /* handle to the thread that watches */ 110 HANDLE thr; /* handle to the thread that watches */
111 volatile int terminate; /* if non-zero, request for the thread to terminate */ 111 volatile int terminate; /* if non-zero, request for the thread to terminate */
@@ -332,15 +332,43 @@ add_watch (const char *parent_dir, const char *file, BOOL subdirs, DWORD flags)
332 if (!file) 332 if (!file)
333 return NULL; 333 return NULL;
334 334
335 hdir = CreateFile (parent_dir, 335 if (w32_unicode_filenames)
336 FILE_LIST_DIRECTORY, 336 {
337 /* FILE_SHARE_DELETE doesn't preclude other 337 wchar_t dir_w[MAX_PATH], file_w[MAX_PATH];
338 processes from deleting files inside 338
339 parent_dir. */ 339 filename_to_utf16 (parent_dir, dir_w);
340 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 340 if (*file)
341 NULL, OPEN_EXISTING, 341 filename_to_utf16 (file, file_w);
342 FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, 342 else
343 NULL); 343 file_w[0] = 0;
344
345 hdir = CreateFileW (dir_w,
346 FILE_LIST_DIRECTORY,
347 /* FILE_SHARE_DELETE doesn't preclude other
348 processes from deleting files inside
349 parent_dir. */
350 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
351 NULL, OPEN_EXISTING,
352 FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
353 NULL);
354 }
355 else
356 {
357 char dir_a[MAX_PATH], file_a[MAX_PATH];
358
359 filename_to_ansi (parent_dir, dir_a);
360 if (*file)
361 filename_to_ansi (file, file_a);
362 else
363 file_a[0] = '\0';
364
365 hdir = CreateFileA (dir_a,
366 FILE_LIST_DIRECTORY,
367 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
368 NULL, OPEN_EXISTING,
369 FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
370 NULL);
371 }
344 if (hdir == INVALID_HANDLE_VALUE) 372 if (hdir == INVALID_HANDLE_VALUE)
345 return NULL; 373 return NULL;
346 374
@@ -490,9 +518,7 @@ will never come in. Volumes shared from remote Windows machines do
490generate notifications correctly, though. */) 518generate notifications correctly, though. */)
491 (Lisp_Object file, Lisp_Object filter, Lisp_Object callback) 519 (Lisp_Object file, Lisp_Object filter, Lisp_Object callback)
492{ 520{
493 Lisp_Object encoded_file, watch_object, watch_descriptor; 521 Lisp_Object dirfn, basefn, watch_object, watch_descriptor;
494 char parent_dir[MAX_PATH], *basename;
495 size_t fn_len;
496 DWORD flags; 522 DWORD flags;
497 BOOL subdirs = FALSE; 523 BOOL subdirs = FALSE;
498 struct notification *dirwatch = NULL; 524 struct notification *dirwatch = NULL;
@@ -510,49 +536,33 @@ generate notifications correctly, though. */)
510 Qnil); 536 Qnil);
511 } 537 }
512 538
513 /* We need a full absolute file name of FILE, and we need to remove
514 any trailing slashes from it, so that GetFullPathName below gets
515 the basename part correctly. */
516 file = Fdirectory_file_name (Fexpand_file_name (file, Qnil));
517 encoded_file = ENCODE_FILE (file);
518
519 fn_len = GetFullPathName (SDATA (encoded_file), MAX_PATH, parent_dir,
520 &basename);
521 if (!fn_len)
522 {
523 errstr = w32_strerror (0);
524 errno = EINVAL;
525 if (!NILP (Vlocale_coding_system))
526 lisp_errstr
527 = code_convert_string_norecord (build_unibyte_string (errstr),
528 Vlocale_coding_system, 0);
529 else
530 lisp_errstr = build_string (errstr);
531 report_file_error ("GetFullPathName failed",
532 Fcons (lisp_errstr, Fcons (file, Qnil)));
533 }
534 /* filenotify.el always passes us a directory, either the parent 539 /* filenotify.el always passes us a directory, either the parent
535 directory of a file to be watched, or the directory to be 540 directory of a file to be watched, or the directory to be
536 watched. */ 541 watched. */
537 if (file_directory_p (parent_dir)) 542 file = Fdirectory_file_name (Fexpand_file_name (file, Qnil));
538 basename = ""; 543 if (NILP (Ffile_directory_p (file)))
539 else
540 { 544 {
541 /* This should only happen if we are called directly, not via 545 /* This should only happen if we are called directly, not via
542 filenotify.el. If BASENAME is NULL, the argument was the 546 filenotify.el. If BASEFN is empty, the argument was the root
543 root directory on its drive. */ 547 directory on its drive. */
544 if (basename) 548 dirfn = ENCODE_FILE (Ffile_name_directory (file));
545 basename[-1] = '\0'; 549 basefn = ENCODE_FILE (Ffile_name_nondirectory (file));
546 else 550 if (*SDATA (basefn) == '\0')
547 subdirs = TRUE; 551 subdirs = TRUE;
548 } 552 }
553 else
554 {
555 dirfn = ENCODE_FILE (file);
556 basefn = Qnil;
557 }
549 558
550 if (!NILP (Fmember (Qsubtree, filter))) 559 if (!NILP (Fmember (Qsubtree, filter)))
551 subdirs = TRUE; 560 subdirs = TRUE;
552 561
553 flags = filter_list_to_flags (filter); 562 flags = filter_list_to_flags (filter);
554 563
555 dirwatch = add_watch (parent_dir, basename, subdirs, flags); 564 dirwatch = add_watch (SSDATA (dirfn), NILP (basefn) ? "" : SSDATA (basefn),
565 subdirs, flags);
556 if (!dirwatch) 566 if (!dirwatch)
557 { 567 {
558 DWORD err = GetLastError (); 568 DWORD err = GetLastError ();