From: Eli Zaretskii Date: Thu, 18 Oct 2012 05:13:29 +0000 (+0200) Subject: Use XIL/XLI instead of make_number/XINT for converting descriptor to a ptr. X-Git-Tag: emacs-24.3.90~173^2~7^2~661 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=0b86d359eb52cef840345f7fd09b5f4342aede03;p=emacs.git Use XIL/XLI instead of make_number/XINT for converting descriptor to a ptr. More safety checks in using the pointer obtained from descriptor. Not tested yet. --- diff --git a/src/w32inevt.c b/src/w32inevt.c index 878106d7070..06629d37cf6 100644 --- a/src/w32inevt.c +++ b/src/w32inevt.c @@ -599,7 +599,7 @@ handle_file_notifications (struct input_event *hold_quit) { DWORD info_size = notifications_size; Lisp_Object cs = intern ("utf-16le"); - Lisp_Object obj = w32_get_watch_object (make_number (notifications_desc)); + Lisp_Object obj = w32_get_watch_object (notifications_desc); /* notifications_size could be zero when the buffer of notifications overflowed on the OS level, or when the diff --git a/src/w32notify.c b/src/w32notify.c index 244b0b872bf..f14621001a8 100644 --- a/src/w32notify.c +++ b/src/w32notify.c @@ -103,12 +103,12 @@ struct notification { char *watchee; /* the file we are interested in */ HANDLE dir; /* handle to the watched directory */ HANDLE thr; /* handle to the thread that watches */ - int terminate; /* if non-zero, request for the thread to terminate */ + volatile int terminate; /* if non-zero, request for the thread to terminate */ unsigned signature; }; /* Used for communicating notifications to the main thread. */ -int notification_buffer_in_use; +volatile int notification_buffer_in_use; BYTE file_notifications[16384]; DWORD notifications_size; void *notifications_desc; @@ -120,7 +120,8 @@ static Lisp_Object Qsecurity_desc, Qsubtree, watch_list; /* Signal to the main thread that we have file notifications for it to process. */ static void -send_notifications (BYTE *info, DWORD info_size, void *desc, int *terminate) +send_notifications (BYTE *info, DWORD info_size, void *desc, + volatile int *terminate) { int done = 0; FRAME_PTR f = SELECTED_FRAME (); @@ -557,7 +558,7 @@ FILE is the name of the file whose event is being reported. */) report_file_error ("Cannot watch file", Fcons (file, Qnil)); } /* Store watch object in watch list. */ - watch_descriptor = make_number (dirwatch); + watch_descriptor = XIL ((EMACS_INT)dirwatch); watch_object = Fcons (watch_descriptor, callback); watch_list = Fcons (watch_object, watch_list); @@ -572,17 +573,22 @@ WATCH-DESCRIPTOR should be an object returned by `w32notify-add-watch'. */) (Lisp_Object watch_descriptor) { Lisp_Object watch_object; - struct notification *dirwatch = - (struct notification *)XINT (watch_descriptor); + struct notification *dirwatch; + int status = -1; /* Remove the watch object from watch list. Do this before freeing the object, do that even if we fail to free it, watch_list is kept free of junk. */ watch_object = Fassoc (watch_descriptor, watch_list); if (!NILP (watch_object)) - watch_list = Fdelete (watch_object, watch_list); + { + watch_list = Fdelete (watch_object, watch_list); + dirwatch = (struct notification *)XLI (watch_descriptor); + if (w32_valid_pointer_p (dirwatch, sizeof(struct notification))) + status = remove_watch (dirwatch); + } - if (remove_watch (dirwatch) == -1) + if (status == -1) report_file_error ("Invalid watch descriptor", Fcons (watch_descriptor, Qnil)); @@ -590,9 +596,13 @@ WATCH-DESCRIPTOR should be an object returned by `w32notify-add-watch'. */) } Lisp_Object -w32_get_watch_object (Lisp_Object desc) +w32_get_watch_object (void *desc) { - return NILP (watch_list) ? Qnil : assoc_no_quit (desc, watch_list); + Lisp_Object descriptor = XIL ((EMACS_INT)desc); + + /* This is called from the input queue handling code, so we cannot + possibly QUIT if watch_list is not in the right condition. */ + return NILP (watch_list) ? Qnil : assoc_no_quit (descriptor, watch_list); } void diff --git a/src/w32term.c b/src/w32term.c index 1285b5a06f6..c00bbe0f3cd 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -3282,7 +3282,7 @@ queue_notifications (struct input_event *event, W32Msg *msg, struct frame *f, { DWORD info_size = notifications_size; Lisp_Object cs = intern ("utf-16le"); - Lisp_Object obj = w32_get_watch_object (make_number (notifications_desc)); + Lisp_Object obj = w32_get_watch_object (notifications_desc); /* notifications_size could be zero when the buffer of notifications overflowed on the OS level, or when the diff --git a/src/w32term.h b/src/w32term.h index 94ef9624351..14b3d1ffc42 100644 --- a/src/w32term.h +++ b/src/w32term.h @@ -683,11 +683,11 @@ extern BOOL parse_button (int, int, int *, int *); extern void w32_sys_ring_bell (struct frame *f); extern void x_delete_display (struct w32_display_info *dpyinfo); -extern int notification_buffer_in_use; +extern volatile int notification_buffer_in_use; extern BYTE file_notifications[16384]; extern DWORD notifications_size; extern void *notifications_desc; -extern Lisp_Object w32_get_watch_object (Lisp_Object); +extern Lisp_Object w32_get_watch_object (void *); extern Lisp_Object lispy_file_action (DWORD); extern void w32_initialize_display_info (Lisp_Object);