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 <kai.tetzl...@gmx.de> 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 >>>> >>>> >>>> >>>> >> >> >> > > > >