help-emacs-windows
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[h-e-w] Re: emacsclientw.exe bug: random exit status


From: Kai Tetzlaff
Subject: [h-e-w] Re: emacsclientw.exe bug: random exit status
Date: Fri, 16 Oct 2009 10:02:18 +0200
User-agent: Thunderbird 2.0.0.23 (Windows/20090812)

Kai Tetzlaff wrote:
>> Hah, there's a lot of stuff in main which i did not yet have a closer
>> look at ;-) and i'm not really familiar with the code. But (as a quick
>> shot) how about checking emacs_socket in addition to connected:
>>
>> if (connected || emacs_socket != INVALID_SOCKET) {
>>   exit(exitval);
>> else
>>   exit(EXIT_FAILURE);
>>
>> Maybe even forgetting about connected at all...
> 
> I've bow compiled a version with the fix above. It's working in first
> tests. I'll do some further testing and let you know how it goes. I can
> also email the compiled binaries (emacsclient/emacsclientw) to anyone
> who's interested.

After a closer look to the sources of both the patched and the original
GNU version of emacsclient.c i would say that the following:

if (INVALID_SOCKET != emacs_socket) {
  exit(exitval);
else
  exit(EXIT_FAILURE);

is a bit simpler and should work exactly like my original proposal above
(if connected is different from 0, emacs_socket will always also be !=
INVALID_SOCKET). The original GNU version returns a non zero value only
when called without a file name. So by doing the socket check and by
using exitval the patched version is already doing more checking than
the GNU original.

(Actually i'm a bit curious: exitval has been added to the patched
version, but it currently seems to have no real function. It's using a
global/static variable g_exit_value which could be used to set exit
codes from anywhere in the sources. But this is actually never done.
g_exit_value gets initialized with EXIT_SUCCESS and that's about it as
far as i can tell. Its value is never changed afterwards.)

Both proposed changes will miss out on errors reported back from emacs
to emacsclient in:

  /* Now, wait for an answer and print any messages.  */
  trace ("before while.");
  while ((rl = recv (emacs_socket, string, BUFSIZ, 0)) > 0)
    {
      trace ("while rl");
      char *p;
      string[rl] = '\0';

      p = string + strlen (string) - 1;
      while (p > string && *p == '\n')
        *p-- = 0;

...
      else if (strprefix ("-error ", string))
        {
          /* -error DESCRIPTION: Signal an error on the terminal. */
          str = unquote_argument (string + strlen ("-error "));
          if (needlf)
            add_to_wait_message ("\n");
          fprintf (stderr, "*ERROR*: %s", str);
          add_to_wait_message ("*ERROR*: %s", str);
          needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n';
        }

...
      else
        {
          /* Unknown command. */
          if (needlf)
            add_to_wait_message ("\n");
          add_to_wait_message ("*ERROR*: Unknown message: %s", string);
          needlf = string[0] == '\0' ? needlf : string[strlen (string) -
1] != '\n';
        }
    }

I could provide a patch which improves on this a bit. But since the GNU
version also just ignores these errors and just prints them to the
terminal i guess we should do just the same and also keep ignoring those.

> 
>> Not sure though if this would work for all cases (or at all). If you
>> want i can have a closer look. But then i would probably also like to
>> set up a dev env to compile emacs on windows. Any good tips how to
>> start? I already have msys/mingw running and have been using it to port
>> some other stuff to windows ...
>>
>> /Kai
>>
>>> Hm, you are right ... ;-)
>>>
>>> Did you find out how to fix it?
>>>
>>>
>>> On Tue, Oct 13, 2009 at 1:03 AM, Kai Tetzlaff <address@hidden> wrote:
>>>> Gary Oberbrunner wrote:
>>>>> emacsclientw exits with a random exit status when called from a win32 
>>>>> window app (such as emacs itself).  The reason is an uninitialized 
>>>>> variable in w32_teardown_window in w32emacsclient.h.  I suspect if "ret" 
>>>>> is initialized to zero (exit status success) in this function it would 
>>>>> just work.  I don't have mingw so I can't compile it here myself, sorry.
>>>>>
>>>>> This is on emacs 23.1.50, also happens on the latest CVS test version.  
>>>>> I'm using the EmacsW32 patched version on XP, but don't think that 
>>>>> matters either.
>>>>>
>>>>> The symptom is easy to reproduce.  In a shell window inside emacs (I use 
>>>>> cygwin zsh, but any shell will work), run
>>>>>   emacsclient foo || echo BAD
>>>>> then C-x # to close the server buffer, and then look back in the shell 
>>>>> window:
>>>>> % emacsclientw foo || echo BAD
>>>>> Waiting for Emacs...
>>>>> BAD
>>>>> %
>>>>>
>>>>> (I'm sure you already know that "emacsclient", the non-windows version, 
>>>>> is totally broken, gives "Unknown&_command:&"... but emacsclientw is fine 
>>>>> so it doesn't really matter.)
>>>>>
>>>>> Here's the affected code:
>>>>> ===========
>>>>> int
>>>>> w32_teardown_window (int connected)
>>>>> {
>>>>>   int ret;                    <<<<<<<<<<====== FIX HERE to int ret=0;
>>>>>   if (w32_window_app ())
>>>>>     {
>>>>>       w32_check_not_synced();
>>>>>       w32_wait_threads_fin(connected);
>>>>>       ret = W32_SYNC_get_g_exit_value();
>>>>>       DeleteCriticalSection(&g_cs.cs);
>>>>>       return ret;
>>>>>     }
>>>>>   else
>>>>>     ret = g_exit_value;
>>>>>   return ret;
>>>>> }
>>>>> ============
>>>>>
>>>>>
>>>> I've also been running into this. Now, when looking at the code of what
>>>> i believe should be the patched version of emacsclient.c, the main
>>>> function looks like this:
>>>>
>>>> int
>>>> main (argc, argv)
>>>>     int argc;
>>>>     char **argv;
>>>> {
>>>>  int i, rl, needlf = 0;
>>>>  char *cwd, *str;
>>>>  char string[BUFSIZ+1];
>>>>  int connected = 0;
>>>>
>>>>  ...
>>>>
>>>>  if ((emacs_socket = set_socket ( alternate_editor ||
>>>> (start_timeout_int > 0) , &islocal)) == INVALID_SOCKET)
>>>>    {
>>>>      ...
>>>>      connected = 1;
>>>>    }
>>>>
>>>>  ...
>>>>
>>>>  int exitval = finish_messages (connected);
>>>>
>>>>  if (connected)
>>>>    exit(exitval);
>>>>  else
>>>>    exit(EXIT_FAILURE);
>>>> }
>>>>
>>>> I.e. if connected is not set to a non-zero value somewhere after it gets
>>>> initialized, main will always exit with EXIT_FAILURE.
>>>>
>>>> The only place in main which sets connected is the if block included
>>>> above. This block is only entered if set_socket returns INVALID_SOCKET
>>>> which seems to be the case only if the server has not been started yet.
>>>> So if you use emacsclient to send files to the server when it is already
>>>> running, it will always seem to be failing.
>>>>
>>>> BR,
>>>> Kai
>>>>
>>>>
>>>>
>>>>
>>
>>
>>
> 
> 
> 
> 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]