]> git.lyx.org Git - lyx.git/blobdiff - src/lyxserver.C
bug 183
[lyx.git] / src / lyxserver.C
index 0133d1abc354a9311bcc112ac2ba55c77a42bd65..ba3e0856713dcda4bff3e9da40c60af9b3295dd4 100644 (file)
@@ -108,197 +108,165 @@ void LyXComm::openConnection()
        // We assume that we don't make it
        ready = false;
  
-       if (pipename.empty()) return;
+       if (pipename.empty()) {
+               lyxerr[Debug::LYXSERVER]
+                       << "LyXComm: server is disabled, nothing to do"
+                       << endl;
+               return;
+       }
 
-       // --- prepare input pipe ---------------------------------------
+       if ((infd = startPipe(inPipeName(), false)) == -1)
+               return;
+
+       if ((outfd = startPipe(outPipeName(), true)) == -1) {
+               endPipe(infd, inPipeName());
+               return;
+       }
+       if (fcntl(outfd, F_SETFL, O_NONBLOCK) < 0) {
+               lyxerr << "LyXComm: Could not set flags on pipe " << outPipeName()
+                      << '\n' << strerror(errno) << endl;
+               return;
+       }
+       // We made it!
+       ready = true;
+       lyxerr[Debug::LYXSERVER] << "LyXComm: Connection established" << endl;
+}
+
+       
+/// Close pipes
+void LyXComm::closeConnection()
+{
+               lyxerr[Debug::LYXSERVER] << "LyXComm: Closing connection" << endl;
+
+       if (pipename.empty()) {
+               lyxerr[Debug::LYXSERVER]
+                       << "LyXComm: server is disabled, nothing to do"
+                       << endl;
+               return;
+       }
+
+       if (!ready) {
+               lyxerr << "LyXComm: Already disconnected" << endl;
+               return;
+       }
+       endPipe(infd, inPipeName());
+       endPipe(outfd, outPipeName());
+       ready = false;
+}
+
+int LyXComm::startPipe(string const & filename, bool write)
+{
+       int fd;
  
-       string tmp = pipename + ".in";
-       
 #ifdef __EMX__
-       HPIPE fd;
+       HPIPE os2fd;
        APIRET rc;
        int errnum;
        // Try create one instance of named pipe with the mode O_RDONLY|O_NONBLOCK.
        // The current emx implementation of access() won't work with pipes.
-       rc = DosCreateNPipe(tmp.c_str(), &fd, NP_ACCESS_INBOUND,
+       rc = DosCreateNPipe(filename.c_str(), &os2fd, NP_ACCESS_INBOUND,
                NP_NOWAIT|0x01, 0600, 0600, 0);
-       if (rc == ERROR_PIPE_BUSY)
-#else
-       if (::access(tmp.c_str(), F_OK) == 0)
-#endif
-       {
-               lyxerr << "LyXComm: Pipe " << tmp << " already exists.\n"
+       if (rc == ERROR_PIPE_BUSY) {
+               lyxerr << "LyXComm: Pipe " << filename << " already exists.\n"
                       << "If no other LyX program is active, please delete"
                        " the pipe by hand and try again." << endl;
                pipename.erase();
-               return;
+               return -1;
        }
-#ifndef __EMX__
-       if (::mkfifo(tmp.c_str(), 0600) < 0) {
-               lyxerr << "LyXComm: Could not create pipe " << tmp << '\n'
-                      << strerror(errno) << endl;
-               return;
-       };
-       infd = ::open(tmp.c_str(), O_RDONLY|O_NONBLOCK);
-#else
        if (rc != NO_ERROR) {
                errnum = TranslateOS2Error(rc);
-               lyxerr <<"LyXComm: Could not create pipe " << tmp
+               lyxerr <<"LyXComm: Could not create pipe " << filename
                       << strerror(errnum) << endl;
-               return;
+               return -1;
        };
        // Listen to it.
-       rc = DosConnectNPipe(fd);
+       rc = DosConnectNPipe(os2fd);
        if (rc != NO_ERROR && rc != ERROR_PIPE_NOT_CONNECTED) {
                errnum = TranslateOS2Error(rc);
-               lyxerr <<"LyXComm: Could not create pipe " << tmp
+               lyxerr <<"LyXComm: Could not create pipe " << filename
                       << strerror(errnum) << endl;
-               return;
+               return -1;
        };
        // Imported handles can be used both with OS/2 APIs and emx
        // library functions. 
-       infd = _imphandle(fd);
-#endif
-       if (infd < 0) {
-               lyxerr << "LyXComm: Could not open pipe " << tmp << '\n'
-                      << strerror(errno) << endl;
-               return;
-       }
-       fl_add_io_callback(infd, FL_READ, C_LyXComm_callback, this);
-       // --- prepare output pipe ---------------------------------------
-       tmp = pipename + ".out";
-       
-#ifndef __EMX__       
-       if (::access(tmp.c_str(), F_OK) == 0)
+       fd = _imphandle(os2fd);
 #else
-       rc = DosCreateNPipe(tmp.c_str(), &fd, NP_ACCESS_DUPLEX,
-               NP_NOWAIT|0x01, 0600, 0600, 0);
-
-       if (rc == ERROR_PIPE_BUSY)
-#endif
-       {
-               lyxerr << "LyXComm: Pipe " << tmp << " already exists.\n"
+       if (::access(filename.c_str(), F_OK) == 0) {
+               lyxerr << "LyXComm: Pipe " << filename << " already exists.\n"
                       << "If no other LyX program is active, please delete"
                        " the pipe by hand and try again." << endl;
                pipename.erase();
-               return;
+               return -1;
        }
-#ifndef __EMX__
-       if (::mkfifo(tmp.c_str(), 0600) < 0) {
-               lyxerr << "LyXComm: Could not create pipe " << tmp << '\n'
+       if (::mkfifo(filename.c_str(), 0600) < 0) {
+               lyxerr << "LyXComm: Could not create pipe " << filename << '\n'
                       << strerror(errno) << endl;
-               return;
+               return -1;
        };
-       if (::access(tmp.c_str(), F_OK) != 0) {
-               lyxerr << "LyXComm: Pipe " << tmp
-                      << " does not exist" << endl;
-               return;
-       }
-       outfd = ::open(tmp.c_str(), O_RDWR);
-#else
-       if (rc != NO_ERROR) {
-               errnum = TranslateOS2Error(rc);
-               lyxerr << "LyXComm: Could not create pipe " << tmp << '\n'
-                      << strerror(errnum) << endl;
-               return;
-       }
-       rc = DosConnectNPipe(fd);
-       if (rc == ERROR_BAD_PIPE) {
-               lyxerr << "LyXComm: Pipe " << tmp
-                      << " does not exist" << endl;
-               return;
-       }
-       if (rc != NO_ERROR && rc != ERROR_PIPE_NOT_CONNECTED) {
-               errnum = TranslateOS2Error(rc);
-               lyxerr << "LyXComm: Could not create pipe " << tmp << '\n'
-                      << strerror(errnum) << endl;
-               return;
-       }
-       outfd = _imphandle(fd);
+       fd = ::open(filename.c_str(), write ? (O_RDWR) : (O_RDONLY|O_NONBLOCK));
 #endif
-       if (outfd < 0) {
-               lyxerr << "LyXComm: Could not open pipe " << tmp << '\n'
+       if (fd < 0) {
+               lyxerr << "LyXComm: Could not open pipe " << filename << '\n'
                       << strerror(errno) << endl;
-               return;
-       }
-       if (fcntl(outfd, F_SETFL, O_NONBLOCK) < 0) {
-               lyxerr << "LyXComm: Could not set flags on pipe " << tmp
-                      << '\n' << strerror(errno) << endl;
-               return;
+               lyx::unlink(filename);
+               return -1;
        }
-       // We made it!
-       ready = true;
-       lyxerr[Debug::LYXSERVER] << "LyXComm: Connection established" << endl;
+       if (!write)
+               fl_add_io_callback(fd, FL_READ, C_LyXComm_callback, this);
+       return fd;
 }
 
-       
-/// Close pipes
-void LyXComm::closeConnection()
+
+void LyXComm::endPipe(int & fd, string const & filename)
 {
+       if (fd < 0)
+               return;
+
 #ifdef __EMX__
        APIRET rc;
        int errnum;
-#endif
-               lyxerr[Debug::LYXSERVER] << "LyXComm: Closing connection" << endl;
-
-       if (pipename.empty()) {
-               return;
-       }
-
-       if (!ready) {
-               lyxerr << "LyXComm: Already disconnected" << endl;
+       rc = DosDisConnectNPipe(fd);
+       if (rc != NO_ERROR) {
+               errnum = TranslateOS2Error(rc);
+               lyxerr << "LyXComm: Could not disconnect pipe " << filename
+                      << '\n' << strerror(errnum) << endl;
                return;
        }
-       if (infd > -1) {
-               fl_remove_io_callback(infd, FL_READ, C_LyXComm_callback);
-               string tmp = pipename + ".in";
-#ifdef __EMX__         // Notify the operating system.
-               rc = DosDisConnectNPipe(infd);
-               if (rc != NO_ERROR) {
-                       errnum = TranslateOS2Error(rc);
-                       lyxerr << "LyXComm: Could not disconnect pipe " << tmp
-                              << '\n' << strerror(errnum) << endl;
-                       return;
-               }
-#endif
-               if (close(infd) < 0) {
-                       lyxerr << "LyXComm: Could not close pipe " << tmp
-                              << '\n' << strerror(errno) << endl;
-               }
-#ifndef __EMX__                // OS/2 named pipes will be automatically removed.
-               if (lyx::unlink(tmp) < 0){
-                       lyxerr << "LyXComm: Could not remove pipe " << tmp
-                              << '\n' << strerror(errno) << endl;
-               };
 #endif
+       if (::close(fd) < 0) {
+               lyxerr << "LyXComm: Could not close pipe " << filename
+                      << '\n' << strerror(errno) << endl;
        }
-       if (outfd > -1) {
-               string tmp = pipename + ".out";
-#ifdef __EMX__
-               rc = DosDisConnectNPipe(outfd);
-               if (rc != NO_ERROR) {
-                       errnum = TranslateOS2Error(rc);
-                       lyxerr << "LyXComm: Could not disconnect pipe " << tmp
-                              << '\n' << strerror(errnum) << endl;
-                       return;
-               }
-#endif
-               if (::close(outfd) < 0) {
-                       lyxerr << "LyXComm: Could not close pipe " << tmp
-                              << '\n' << strerror(errno) << endl;
-               }
+// OS/2 pipes are deleted automatically
 #ifndef __EMX__
-               if (lyx::unlink(tmp) < 0){
-                       lyxerr << "LyXComm: Could not remove pipe " << tmp
-                              << '\n' << strerror(errno) << endl;
-               };
+       if (lyx::unlink(filename) < 0){
+               lyxerr << "LyXComm: Could not remove pipe " << filename
+                      << '\n' << strerror(errno) << endl;
+       };
 #endif
+
+       fd = -1;
+}
+
+
+void LyXComm::emergencyCleanup()
+{
+       if (!pipename.empty()) {
+               endPipe(infd, inPipeName());
+               endPipe(outfd, outPipeName());
        }
-       ready = false;
 }
 
 
@@ -320,14 +288,14 @@ void LyXComm::callback(int fd, void *v)
        errno = 0;
        int status;
        // the single = is intended here.
-       while((status = read(fd, charbuf, CMDBUFLEN-1)))
+       while ((status = read(fd, charbuf, CMDBUFLEN-1)))
        {// break and return in loop
                if (status > 0) // got something
                {
                        charbuf[status]= '\0'; // turn it into a c string
                        lsbuf += strip(charbuf, '\r');
                        // commit any commands read
-                       while(lsbuf.find('\n') != string::npos) // while still
+                       while (lsbuf.find('\n') != string::npos) // while still
                                                        // commands
                                                        // left 
                        {
@@ -438,33 +406,33 @@ void LyXServer::callback(LyXServer * serv, string const & msg)
        //  Format: LYXCMD:<client>:<func>:<argstring>\n
        //
        bool server_only = false;
-       while(*p) {
+       while (*p) {
                // --- 1. check 'header' ---
 
                if (compare(p, "LYXSRV:", 7) == 0) {
                        server_only = true; 
                } else if (0 != compare(p, "LYXCMD:", 7)) {
-                       lyxerr << "LyXServer: Unknown request" << endl;
+                       lyxerr << "LyXServer: Unknown request \"" << p << "\"" << endl;
                        return;
                }
                p += 7;
                
                // --- 2. for the moment ignore the client name ---
                string client;
-               while(*p && *p != ':')
+               while (*p && *p != ':')
                        client += char(*p++);
                if (*p == ':') ++p;
                if (!*p) return;
                
                // --- 3. get function name ---
                string cmd;
-               while(*p && *p != ':')
+               while (*p && *p != ':')
                        cmd += char(*p++);
                
                // --- 4. parse the argument ---
                string arg;
                if (!server_only && *p == ':' && *(++p)) {
-                       while(*p && *p != '\n')
+                       while (*p && *p != '\n')
                                arg += char(*p++);
                        if (*p) ++p;
                }
@@ -533,7 +501,7 @@ void LyXServer::callback(LyXServer * serv, string const & msg)
                        // connect to the lyxfunc in the single LyXView we
                        // support currently. (Lgb)
 
-                       int action = lyxaction.LookupFunc(cmd);
+                       kb_action action = static_cast<kb_action>(lyxaction.LookupFunc(cmd));
                        //int action = -1;
                        string rval, buf;