* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
- * \author Lars Gullik Bjønnes
+ * \author Lars Gullik Bjønnes
* \author Jean-Marc Lasgouttes
* \author Angus Leeming
* \author John Levon
- * \author João Luis M. Assirati
+ * \author João Luis M. Assirati
*
* Full author contact details are available in file CREDITS.
*/
#include "ServerSocket.h"
-#include "support/debug.h"
+#include "DispatchResult.h"
#include "FuncRequest.h"
+#include "LyX.h"
#include "LyXAction.h"
-#include "LyXFunc.h"
#include "frontends/Application.h"
+#include "support/debug.h"
#include "support/environment.h"
#include "support/FileName.h"
-#include "support/lyxlib.h"
#include "support/socktools.h"
-#include <boost/bind.hpp>
+#include "support/bind.h"
#include <cerrno>
#include <ostream>
# include <io.h>
#endif
-using boost::shared_ptr;
-
using namespace std;
+using namespace lyx::support;
+
namespace lyx {
// Address is the unix address for the socket.
// MAX_CLIENTS is the maximum number of clients
// that can connect at the same time.
-ServerSocket::ServerSocket(LyXFunc * f, support::FileName const & addr)
- : func(f),
- fd_(support::socktools::listen(addr, 3)),
+ServerSocket::ServerSocket(FileName const & addr)
+ : fd_(socktools::listen(addr, 3)),
address_(addr)
{
if (fd_ == -1) {
- lyxerr << "lyx: Disabling LyX socket." << endl;
+ LYXERR(Debug::LYXSERVER, "lyx: Disabling LyX socket.");
return;
}
// These env vars are used by DVI inverse search
// Needed by xdvi
- support::setEnv("XEDITOR", "lyxclient -g %f %l");
+ setEnv("XEDITOR", "lyxclient -g %f %l");
// Needed by lyxclient
- support::setEnv("LYXSOCKET", address_.absFilename());
+ setEnv("LYXSOCKET", address_.absFileName());
theApp()->registerSocketCallback(
fd_,
- boost::bind(&ServerSocket::serverCallback, this)
+ bind(&ServerSocket::serverCallback, this)
);
LYXERR(Debug::LYXSERVER, "lyx: New server socket "
- << fd_ << ' ' << address_.absFilename());
+ << fd_ << ' ' << address_.absFileName());
}
theApp()->unregisterSocketCallback(fd_);
if (::close(fd_) != 0)
lyxerr << "lyx: Server socket " << fd_
- << " IO error on closing: " << strerror(errno);
+ << " IO error on closing: " << strerror(errno)
+ << endl;
}
address_.removeFile();
LYXERR(Debug::LYXSERVER, "lyx: Server socket quitting");
string const ServerSocket::address() const
{
- return address_.absFilename();
+ return address_.absFileName();
}
// is OK and if the number of clients does not exceed MAX_CLIENTS
void ServerSocket::serverCallback()
{
- int const client_fd = support::socktools::accept(fd_);
-
- if (fd_ == -1) {
- LYXERR(Debug::LYXSERVER, "lyx: Failed to accept new client");
+ if (clients.size() >= MAX_CLIENTS) {
+ writeln("BYE:Too many clients connected");
return;
}
- if (clients.size() >= MAX_CLIENTS) {
- writeln("BYE:Too many clients connected");
+ int const client_fd = socktools::accept(fd_);
+
+ if (fd_ == -1) {
+ LYXERR(Debug::LYXSERVER, "lyx: Failed to accept new client");
return;
}
shared_ptr<LyXDataSocket>(new LyXDataSocket(client_fd));
theApp()->registerSocketCallback(
client_fd,
- boost::bind(&ServerSocket::dataCallback,
+ bind(&ServerSocket::dataCallback,
this, client_fd)
);
}
// if the connection has been closed
void ServerSocket::dataCallback(int fd)
{
- shared_ptr<LyXDataSocket> client = clients[fd];
-
+ map<int, shared_ptr<LyXDataSocket> >::const_iterator it = clients.find(fd);
+ if (it == clients.end())
+ return;
+ shared_ptr<LyXDataSocket> client = it->second;
string line;
- size_t pos;
bool saidbye = false;
while (!saidbye && client->readln(line)) {
// The protocol must be programmed here
// Split the key and the data
+ size_t pos;
if ((pos = line.find(':')) == string::npos) {
client->writeln("ERROR:" + line + ":malformed message");
continue;
string const key = line.substr(0, pos);
if (key == "LYXCMD") {
string const cmd = line.substr(pos + 1);
- func->dispatch(lyxaction.lookupFunc(cmd));
- string const rval = to_utf8(func->getMessage());
- if (func->errorStat()) {
+ FuncRequest fr(lyxaction.lookupFunc(cmd));
+ fr.setOrigin(FuncRequest::LYXSERVER);
+ DispatchResult dr;
+ theApp()->dispatch(fr, dr);
+ string const rval = to_utf8(dr.message());
+ if (dr.error())
client->writeln("ERROR:" + cmd + ':' + rval);
- } else {
+ else
client->writeln("INFO:" + cmd + ':' + rval);
- }
} else if (key == "HELLO") {
// no use for client name!
client->writeln("HELLO:");
// void ServerSocket::dump() const
// {
// lyxerr << "ServerSocket debug dump.\n"
-// << "fd = " << fd_ << ", address = " << address_.absFilename() << ".\n"
+// << "fd = " << fd_ << ", address = " << address_.absFileName() << ".\n"
// << "Clients: " << clients.size() << ".\n";
// map<int, shared_ptr<LyXDataSocket> >::const_iterator client = clients.begin();
// map<int, shared_ptr<LyXDataSocket> >::const_iterator end = clients.end();