On Wed, Oct 01, 2008 at 03:59:59PM +0200, Jean-Marc Lasgouttes wrote:
> 
> Here's a patch for a very old bug. It is not the first time that I try
> to tackle it, but it only occured to me today that the existing code
> tests a value of errno that is probably the result of another IO action
> done in the execution of the lfun (buffer-write, for example).
> 
> The patch is tested and works. But since I do not really now much about
> pipes and read(), I'll wait a few days before committing.

I think that bug 1784 has to be marked as INVALID. Following the steps
of comment #1 in bug 1784, I would say that it is expected behavior.
Indeed, after

$ echo "LYXCMD:test:buffer-write" > .lyx/lyxpipe.in

the pipe gets closed and thus the connection *has* to be restarted.

Try instead the following:

$ cat - > .lyx/lyxpipe.in
LYXCMD:test:buffer-write
LYXCMD:test:open-file
^D

where ^D means hitting Ctrl-D. See? Only after ^D, which closes the
pipe, the connection is restarted.

I admit that the code is not very clear as the test on errno should
only be performed if read() returns -1. So, I would rather propose
the attached patch.

-- 
Enrico
Index: src/Server.cpp
===================================================================
--- src/Server.cpp      (revision 26668)
+++ src/Server.cpp      (working copy)
@@ -273,23 +273,29 @@ void LyXComm::read_ready()
                                        clientcb_(client_, cmd);
                                        //\n or not \n?
                        }
-               }
-               if (errno == EAGAIN) {
-                       errno = 0;
-                       return;
-               }
-               if (errno != 0) {
-                       LYXERR0("LyXComm: " << strerror(errno));
-                       if (!read_buffer_.empty()) {
-                               LYXERR0("LyXComm: truncated command: " << 
read_buffer_);
-                               read_buffer_.erase();
+               } else {
+                       if (errno == EAGAIN) {
+                               // Nothing to read but some process has
+                               // the pipe still opened for writing
+                               errno = 0;
+                               return;
+                       }
+                       if (errno != 0) {
+                               // Something weird occurred, better bailing out
+                               LYXERR0("LyXComm: " << strerror(errno));
+                               if (!read_buffer_.empty()) {
+                                       LYXERR0("LyXComm: truncated command: " 
<< read_buffer_);
+                                       read_buffer_.erase();
+                               }
+                               break; // reset connection
                        }
-                       break; // reset connection
                }
        }
 
-       // The connection gets reset in errno != EAGAIN
-       // Why does it need to be reset if errno == 0?
+       // The connection gets reset when status == 0, meaning that
+       // the pipe opened for writing was now closed, or status < 0
+       // and errno != EAGAIN and errno != 0, meaning that something
+       // weird occurred.
        closeConnection();
        openConnection();
        errno = 0;

Reply via email to