// -*- C++ -*- /* This file is part of *====================================================== * *LyX,TheDocumentProcessor * *Copyright(C)1995MatthiasEttrich *Copyright(C)1995-1998TheLyXTeam. *
*======================================================*/
#ifdef __EMX__
HPIPE fd;
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,
NP_NOWAIT|0x01, 0600, 0600, 0); if (rc == ERROR_PIPE_BUSY) { #else if (access(tmp.c_str(), F_OK) == 0) { #endif
lyxerr.print("LyXComm: Pipe " + tmp + " already exists.");
lyxerr.print("If no other LyX program is active, please delete" " the pipe by hand and try again.");
pipename = LString(); return;
} #ifndef __EMX__ if (mkfifo(tmp.c_str(), 0600) < 0) {
lyxerr.print("LyXComm: Could not create pipe " + tmp);
lyxerr.print(strerror(errno)); return;
};
infd = open(tmp.c_str(), O_RDONLY|O_NONBLOCK); #else if (rc != NO_ERROR) {
errnum = TranslateOS2Error(rc);
lyxerr.print("LyXComm: Could not create pipe " + tmp);
lyxerr.print(strerror(errnum)); return;
}; // Listen to it.
rc = DosConnectNPipe(fd); if (rc != NO_ERROR && rc != ERROR_PIPE_NOT_CONNECTED) {
errnum = TranslateOS2Error(rc);
lyxerr.print("LyXComm: Could not create pipe " + tmp);
lyxerr.print(strerror(errnum)); return;
}; // Imported handles can be used both with OS/2 APIs and emx // library functions.
infd = _imphandle(fd); #endif if (infd < 0) {
lyxerr.print("LyXComm: Could not open pipe " + tmp);
lyxerr.print(strerror(errno)); return;
}
fl_add_io_callback(infd, FL_READ, callback, (void*)this);
LString tmp = pipename + ".in"; #ifdef __EMX__ // Notify the operating system.
rc = DosDisConnectNPipe(infd); if (rc != NO_ERROR) {
errnum = TranslateOS2Error(rc);
lyxerr.print("LyXComm: Could not disconnect pipe " + tmp);
lyxerr.print(strerror(errnum)); return;
} #endif if (close(infd) < 0) {
lyxerr.print("LyXComm: Could not close pipe " + tmp);
lyxerr.print(strerror(errno));
} #ifndef __EMX__ // OS/2 named pipes will be automatically removed. if (unlink(tmp.c_str()) < 0){
lyxerr.print("LyXComm: Could not remove pipe " + tmp);
lyxerr.print(strerror(errno));
}; #endif
} if(outfd > -1) {
LString tmp = pipename + ".out"; #ifdef __EMX__
rc = DosDisConnectNPipe(outfd); if (rc != NO_ERROR) {
errnum = TranslateOS2Error(rc);
lyxerr.print("LyXComm: Could not disconnect pipe " + tmp);
lyxerr.print(strerror(errnum)); return;
} #endif if (close(outfd) < 0) {
lyxerr.print("LyXComm: Could not close pipe " + tmp);
lyxerr.print(strerror(errno));
} #ifndef __EMX__ if (unlink(tmp.c_str()) < 0){
lyxerr.print("LyXComm: Could not remove pipe " + tmp);
lyxerr.print(strerror(errno));
}; #endif
}
ready = false;
}
// Receives messages and sends then to client void LyXComm::callback(int fd, void *v)
{
LyXComm * c = (LyXComm *) v;
if (lyxerr.debugging(Error::LYXSERVER)) {
lyxerr.print(LString("LyXComm: Receiving from fd ") + int(fd));
}
constint CMDBUFLEN = 100; char charbuf[CMDBUFLEN];
LString cmd; // nb! make lsbuf a class-member for multiple sessions static LString lsbuf;
errno = 0; int status; // the single = is intended here. 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 += charbuf;
lsbuf.strip('\r'); // commit any commands read while(lsbuf.charPos('\n') >= 0) // while still // commands // left
{ // split() grabs the entire string if // the delim /wasn't/ found. ?:-P
lsbuf.split(cmd,'\n');
lyxerr.debug(LString("LyXComm: status:")
+ status + ", lsbuf:" + lsbuf
+ ", cmd:" + cmd,
Error::LYXSERVER); if(!cmd.empty())
c->clientcb(c->client, cmd); //\n or not \n?
}
} if(errno == EAGAIN)
{ // EAGAIN is not really an error , it means we're // only reading too fast for the writing process on // the other end of the pipe.
errno = 0; return; // up to libforms select-loop (*crunch*)
} if(errno != 0 )
{
lyxerr.print(LString("LyXComm: ") + strerror(errno)); if(!lsbuf.empty())
{
lyxerr.print("LyxComm: truncated command: "
+ lsbuf);
lsbuf.clean();
} break; // reset connection
}
}
c->closeConnection();
c->openConnection();
errno=0;
}
void LyXComm::send(LString const & msg) { if (msg.empty()) {
lyxerr.print("LyXComm: Request to send empty string. Ignoring."); return;
}
// --- lookup and exec the command ------------------
if (server_only) {
LString buf; // return the greeting to inform the client that // we are listening. if (cmd == "hello") { // One more client
serv->clients++;
buf = "LYXSRV:" + client + ":hello";
lyxerr.debug("LyXServer: Greeting " + client, Error::LYXSERVER);
serv->pipes.send(buf);
} elseif (cmd == "bye") { // If clients==0 maybe we should reset the pipes // to prevent fake callbacks
serv->clients--;
lyxerr.debug("LyXServer: Client " + client + " said goodbye",
Error::LYXSERVER);
} else {
lyxerr.print("LyXServer: Undefined server command " + cmd + ".");
} return;
}
if (!cmd.empty()) { // which lyxfunc should we let it connect to? // The correct solution would be to have a // specialized (non-gui) BufferView. But how do // we do it now? Probably we should just let it // connect to the lyxfunc in the single LyXView we // support currently. (Lgb)
if(!rval.empty()) { if (action<0 || serv->func->errorStat())
buf = "ERROR:"; else
buf = "INFO:";
buf += LString(client) + ":" + cmd + ":" + rval + "\n";
serv->pipes.send(buf); // !!! we don't do any error checking - // if the client won't listen, the // message is lost and others too // maybe; so the client should empty // the outpipe before issuing a request.
} // not found
}
} /* while *p */
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.