all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Ken Brown <kbrown@cornell.edu>
To: Eli Zaretskii <eliz@gnu.org>
Cc: 19909@debbugs.gnu.org, rpluim@gmail.com
Subject: bug#19909: [PATCH] Error out if	with-file-notification=w32	is specified on cygwin
Date: Fri, 27 Feb 2015 17:25:54 -0500	[thread overview]
Message-ID: <54F0EEF2.1030908@cornell.edu> (raw)
In-Reply-To: <83twygcxif.fsf@gnu.org>

[-- Attachment #1: Type: text/plain, Size: 1118 bytes --]

On 2/20/2015 12:18 PM, Eli Zaretskii wrote:
>> Date: Fri, 20 Feb 2015 11:15:18 -0500
>> From: Ken Brown <kbrown@cornell.edu>
>> CC: bug-gnu-emacs@gnu.org, Robert Pluim <rpluim@gmail.com>
>>
>> I'm busy with other things at the moment and can't get to it right away.
>>    If it's easy for you to suggest a patch, why don't you go ahead, and
>> Robert can test it.  Or you can wait a couple weeks until I can look at it.
>
> OK, I will try to find time.
>
>> BTW, file-notification=gfile works fine in the Cygwin-w32 build, so I'm
>> not sure there's any need to put a lot of effort into this.
>
> If it turns out to need a lot of effort, I'll agree with you.

It looks like it might not take much effort.  What I did for now, just 
for testing purposes, is to copy into w32notify.c whatever was necessary 
to make the Cygwin-w32 build compile with w32 file notification.  I 
tested it briefly and it seems to work.  Obviously it needs much more 
testing to make sure this doesn't break anything else, and then we can 
worry about how to do this right.

Robert, please test when you get a chance (patch attached).

Ken

[-- Attachment #2: cygw32_notify.patch --]
[-- Type: text/plain, Size: 5852 bytes --]

diff --git a/src/w32notify.c b/src/w32notify.c
index ab6cd12..71ee1a3 100644
--- a/src/w32notify.c
+++ b/src/w32notify.c
@@ -92,12 +92,216 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "lisp.h"
 #include "w32term.h"	/* for enter_crit/leave_crit and WM_EMACS_FILENOTIFY */
 #include "w32common.h"	/* for OS version data */
-#include "w32.h"	/* for w32_strerror */
 #include "coding.h"
 #include "keyboard.h"
 #include "frame.h"	/* needed by termhooks.h */
 #include "termhooks.h"	/* for FILE_NOTIFY_EVENT */
 
+/* Experimental code for Cygwin-w32 build */
+
+extern char * w32_strerror (int error_no);
+
+int (WINAPI *pMultiByteToWideChar)(UINT,DWORD,LPCSTR,int,LPWSTR,int);
+int (WINAPI *pWideCharToMultiByte)(UINT,DWORD,LPCWSTR,int,LPSTR,int,LPCSTR,LPBOOL);
+
+#define MAXPATHLEN      MAX_PATH
+#define MAX_UTF8_PATH   (MAXPATHLEN * 4)
+
+static int file_name_codepage;
+
+static int
+codepage_for_filenames (CPINFO *cp_info)
+{
+  /* A simple cache to avoid calling GetCPInfo every time we need to
+     encode/decode a file name.  The file-name encoding is not
+     supposed to be changed too frequently, if ever.  */
+  static Lisp_Object last_file_name_encoding;
+  static CPINFO cp;
+  Lisp_Object current_encoding;
+
+  current_encoding = Vfile_name_coding_system;
+  if (NILP (current_encoding))
+    current_encoding = Vdefault_file_name_coding_system;
+
+  if (!EQ (last_file_name_encoding, current_encoding))
+    {
+      /* Default to the current ANSI codepage.  */
+      file_name_codepage = w32_ansi_code_page;
+
+      if (NILP (current_encoding))
+	{
+	  char *cpname = SDATA (SYMBOL_NAME (current_encoding));
+	  char *cp = NULL, *end;
+	  int cpnum;
+
+	  if (strncmp (cpname, "cp", 2) == 0)
+	    cp = cpname + 2;
+	  else if (strncmp (cpname, "windows-", 8) == 0)
+	    cp = cpname + 8;
+
+	  if (cp)
+	    {
+	      end = cp;
+	      cpnum = strtol (cp, &end, 10);
+	      if (cpnum && *end == '\0' && end - cp >= 2)
+		file_name_codepage = cpnum;
+	    }
+	}
+
+      if (!file_name_codepage)
+	file_name_codepage = CP_ACP; /* CP_ACP = 0, but let's not assume that */
+
+      if (!GetCPInfo (file_name_codepage, &cp))
+	{
+	  file_name_codepage = CP_ACP;
+	  if (!GetCPInfo (file_name_codepage, &cp))
+	    emacs_abort ();
+	}
+    }
+  if (cp_info)
+    *cp_info = cp;
+
+  return file_name_codepage;
+}
+
+int
+filename_to_utf16 (const char *fn_in, wchar_t *fn_out)
+{
+  int result = pMultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, fn_in, -1,
+				     fn_out, MAX_PATH);
+
+  if (!result)
+    {
+      DWORD err = GetLastError ();
+
+      switch (err)
+	{
+	case ERROR_INVALID_FLAGS:
+	case ERROR_INVALID_PARAMETER:
+	  errno = EINVAL;
+	  break;
+	case ERROR_INSUFFICIENT_BUFFER:
+	case ERROR_NO_UNICODE_TRANSLATION:
+	default:
+	  errno = ENOENT;
+	  break;
+	}
+      return -1;
+    }
+  return 0;
+}
+
+int
+filename_from_utf16 (const wchar_t *fn_in, char *fn_out)
+{
+  int result = pWideCharToMultiByte (CP_UTF8, 0, fn_in, -1,
+				     fn_out, MAX_UTF8_PATH, NULL, NULL);
+
+  if (!result)
+    {
+      DWORD err = GetLastError ();
+
+      switch (err)
+	{
+	case ERROR_INVALID_FLAGS:
+	case ERROR_INVALID_PARAMETER:
+	  errno = EINVAL;
+	  break;
+	case ERROR_INSUFFICIENT_BUFFER:
+	case ERROR_NO_UNICODE_TRANSLATION:
+	default:
+	  errno = ENOENT;
+	  break;
+	}
+      return -1;
+    }
+  return 0;
+}
+
+int
+filename_to_ansi (const char *fn_in, char *fn_out)
+{
+  wchar_t fn_utf16[MAX_PATH];
+
+  if (filename_to_utf16 (fn_in, fn_utf16) == 0)
+    {
+      int result;
+      int codepage = codepage_for_filenames (NULL);
+
+      result  = pWideCharToMultiByte (codepage, 0, fn_utf16, -1,
+				      fn_out, MAX_PATH, NULL, NULL);
+      if (!result)
+	{
+	  DWORD err = GetLastError ();
+
+	  switch (err)
+	    {
+	    case ERROR_INVALID_FLAGS:
+	    case ERROR_INVALID_PARAMETER:
+	      errno = EINVAL;
+	      break;
+	    case ERROR_INSUFFICIENT_BUFFER:
+	    case ERROR_NO_UNICODE_TRANSLATION:
+	    default:
+	      errno = ENOENT;
+	      break;
+	    }
+	  return -1;
+	}
+      return 0;
+    }
+  return -1;
+}
+
+int
+filename_from_ansi (const char *fn_in, char *fn_out)
+{
+  wchar_t fn_utf16[MAX_PATH];
+  int codepage = codepage_for_filenames (NULL);
+  int result = pMultiByteToWideChar (codepage, MB_ERR_INVALID_CHARS, fn_in, -1,
+				     fn_utf16, MAX_PATH);
+
+  if (!result)
+    {
+      DWORD err = GetLastError ();
+
+      switch (err)
+	{
+	case ERROR_INVALID_FLAGS:
+	case ERROR_INVALID_PARAMETER:
+	  errno = EINVAL;
+	  break;
+	case ERROR_INSUFFICIENT_BUFFER:
+	case ERROR_NO_UNICODE_TRANSLATION:
+	default:
+	  errno = ENOENT;
+	  break;
+	}
+      return -1;
+    }
+  return filename_from_utf16 (fn_utf16, fn_out);
+}
+
+int
+w32_valid_pointer_p (void *p, int size)
+{
+  SIZE_T done;
+  HANDLE h = OpenProcess (PROCESS_VM_READ, FALSE, GetCurrentProcessId ());
+
+  if (h)
+    {
+      unsigned char *buf = alloca (size);
+      int retval = ReadProcessMemory (h, p, buf, size, &done);
+
+      CloseHandle (h);
+      return retval;
+    }
+  else
+    return -1;
+}
+
+/* End experimental code for Cygwin-w32 build */
+
 #define DIRWATCH_SIGNATURE 0x01233210
 
 struct notification {
diff --git a/src/w32term.c b/src/w32term.c
index d415b13..061c9c3 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -3195,7 +3195,6 @@ lispy_file_action (DWORD action)
   return retval;
 }
 
-#ifdef WINDOWSNT
 /* Put file notifications into the Emacs input event queue.  This
    function runs when the WM_EMACS_FILENOTIFY message arrives from a
    watcher thread.  */
@@ -3271,7 +3270,6 @@ queue_notifications (struct input_event *event, W32Msg *msg, struct frame *f,
   /* We've stuffed all the events ourselves, so w32_read_socket shouldn't.  */
   event->kind = NO_EVENT;
 }
-#endif	/* WINDOWSNT */
 #endif	/* HAVE_W32NOTIFY */
 
 \f

  reply	other threads:[~2015-02-27 22:25 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-02-20  9:47 bug#19909: [PATCH] Error out if with-file-notification=w32 is specified on cygwin Robert Pluim
2015-02-20 10:06 ` Eli Zaretskii
2015-02-20 10:19   ` Robert Pluim
2015-02-20 10:46     ` Eli Zaretskii
2015-02-20 14:16       ` Robert Pluim
2015-02-20 15:10         ` Eli Zaretskii
2015-02-20 15:46           ` Robert Pluim
2015-02-20 16:17             ` Eli Zaretskii
2015-02-20 16:44               ` Robert Pluim
2015-02-20 17:16                 ` Eli Zaretskii
2015-02-20 16:15           ` Ken Brown
2015-02-20 17:06             ` Robert Pluim
2015-02-20 17:18             ` Eli Zaretskii
2015-02-27 22:25               ` Ken Brown [this message]
2015-02-28  7:59                 ` Eli Zaretskii
2015-02-28 16:32                   ` Ken Brown
2015-02-28 16:41                     ` Eli Zaretskii
2015-02-28 16:53                       ` Robert Pluim
2015-02-28 16:56                       ` Robert Pluim
2015-02-28 17:57                         ` Eli Zaretskii
2015-02-28 18:44                           ` Ken Brown
2015-02-28 19:14                             ` Eli Zaretskii
2015-02-28 20:14                               ` Ken Brown
2015-03-02  9:35                                 ` Robert Pluim
2015-03-02 14:05                                   ` Ken Brown
2015-03-02 14:06 ` bug#19909: closed (Re: bug#19909: [PATCH] Error out if with-file-notification=w32 is specified on cygwin) GNU bug Tracking System

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=54F0EEF2.1030908@cornell.edu \
    --to=kbrown@cornell.edu \
    --cc=19909@debbugs.gnu.org \
    --cc=eliz@gnu.org \
    --cc=rpluim@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.