summaryrefslogtreecommitdiff
path: root/x11/ipc
Side-by-side diff
Diffstat (limited to 'x11/ipc') (more/less context) (ignore whitespace changes)
-rw-r--r--x11/ipc/client/ocopclient.cpp25
-rw-r--r--x11/ipc/client/ocopclient.h4
2 files changed, 26 insertions, 3 deletions
diff --git a/x11/ipc/client/ocopclient.cpp b/x11/ipc/client/ocopclient.cpp
index 43e426c..ac6e4a3 100644
--- a/x11/ipc/client/ocopclient.cpp
+++ b/x11/ipc/client/ocopclient.cpp
@@ -1,129 +1,150 @@
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
+#include <sys/types.h>
#include <sys/un.h>
#include <qfile.h>
#include <qtimer.h>
#include "../common/ocoppacket.h"
#include "ocopclient.h"
OCOPClient::OCOPClient( const QString& path, QObject* obj )
: QObject( obj )
{
+ m_tries = 0;
init(QFile::encodeName(path) );
}
OCOPClient::~OCOPClient() {
+ delete m_notify;
close( m_socket );
}
+void OCOPClient::init() {
+ // failed start ther server NOW!!!
+ startUP();
+ QCString str;
+ init(str );
+}
void OCOPClient::init( const QCString& ) {
+ m_tries++;
struct sockaddr_un unix_adr;
if ( (m_socket = socket(PF_UNIX, SOCK_STREAM, 0) ) < 0 ) {
qWarning("could not socket");
- QTimer::singleShot(400, this,SLOT(init() ) );
+ if ( m_tries < 8 )
+ QTimer::singleShot(400, this,SLOT(init() ) );
return;
}
memset(&unix_adr, 0, sizeof(unix_adr ) );
unix_adr.sun_family = AF_UNIX;
sprintf(unix_adr.sun_path,"%s/.opie.cop", getenv("HOME") );
int length = sizeof(unix_adr.sun_family) + strlen(unix_adr.sun_path);
if ( ::connect(m_socket, (struct sockaddr*)&unix_adr, length ) < 0 ) {
qWarning("could not connect %d", errno );
close( m_socket );
- QTimer::singleShot(400, this, SLOT(init() ) );
+ if ( m_tries < 8 )
+ QTimer::singleShot(400, this, SLOT(init() ) );
return;
}
m_notify = new QSocketNotifier(m_socket, QSocketNotifier::Read, this );
connect( m_notify, SIGNAL(activated(int) ),
this, SLOT(newData() ) );
}
/**
* new data
* read the header check magic number
* and maybe read body
*/
void OCOPClient::newData() {
OCOPPacket pack = packet();
if ( pack.channel().isEmpty() )
return;
switch( pack.type() ) {
case OCOPPacket::Register:
case OCOPPacket::Unregister:
case OCOPPacket::Method:
case OCOPPacket::RegisterChannel:
case OCOPPacket::UnregisterChannel:
case OCOPPacket::Return:
case OCOPPacket::Signal:
/* is Registered should be handled sync */
case OCOPPacket::IsRegistered:
break;
/* emit the signal */
case OCOPPacket::Call:
emit called( pack.channel(), pack.header(), pack.content() );
break;
}
}
OCOPPacket OCOPClient::packet() const{
QCString chan;
QCString func;
QByteArray ar;
OCOPHead head;
memset(&head, 0, sizeof(head) );
read(m_socket, &head, sizeof(head) );
if ( head.magic == 47 ) {
read(m_socket, chan.data(), head.chlen );
read(m_socket, func.data(), head.funclen );
read(m_socket, ar.data(), head.datalen );
}
OCOPPacket pack(head.type, chan, func, ar );
return pack;
}
/*
* we've blocking IO here on these sockets
* so we send and go on read
* this will be blocked
*/
bool OCOPClient::isRegistered( const QCString& chan ) const{
/* should I disconnect the socket notfier? */
OCOPPacket packe(OCOPPacket::IsRegistered, chan );
OCOPHead head = packe.head();
write(m_socket, &head, sizeof(head) );
/* block */
OCOPPacket pack = packet();
/* connect here again */
if ( pack.channel() == chan ) {
QCString func = pack.header();
if (func[0] == 1 )
return true;
}
return false;
};
void OCOPClient::send( const QCString& chan, const QCString& fu, const QByteArray& arr ) {
OCOPPacket pack(OCOPPacket::Call, chan, fu, arr );
call( pack );
}
void OCOPClient::addChannel(const QCString& channel) {
OCOPPacket pack(OCOPPacket::RegisterChannel, channel );
call( pack );
}
void OCOPClient::delChannel(const QCString& chan ) {
OCOPPacket pack(OCOPPacket::UnregisterChannel, chan );
call( pack );
}
void OCOPClient::call( const OCOPPacket& pack ) {
OCOPHead head = pack.head();
write(m_socket, &head, sizeof(head) );
write(m_socket, pack.channel().data(), pack.channel().size() );
write(m_socket, pack.header().data(), pack.header().size() );
write(m_socket, pack.content().data(), pack.content().size() );
}
+void OCOPClient::startUP() {
+ qWarning("Start me up");
+ pid_t pi = fork();
+ if ( pi == 0 ) {
+ setsid();
+ execlp("opie-ipc", "opie-ipc", NULL );
+ _exit(1);
+ }
+}
diff --git a/x11/ipc/client/ocopclient.h b/x11/ipc/client/ocopclient.h
index e9544b9..53018a5 100644
--- a/x11/ipc/client/ocopclient.h
+++ b/x11/ipc/client/ocopclient.h
@@ -1,59 +1,61 @@
#ifndef OPIE_OCOP_CLIENT_H
#define OPIE_OCOP_CLIENT_H
#include <qobject.h>
#include <qcstring.h>
#include <qmap.h>
#include <qsignal.h>
#include <qstring.h>
#include <qsocketnotifier.h>
/**
* This is the OCOP client
* It currently only supports
* asking if a Channel is registered,
* calling and receiving calls
*/
class OCOPPacket;
class OCOPClient : public QObject{
Q_OBJECT
public:
/**
* Occasionally I decide to start a Server from here
*/
OCOPClient(const QString& pathToServer = QString::null, QObject* obj = 0l);
~OCOPClient();
bool isRegistered( const QCString& )const;
void send( const QCString& chan, const QCString&, const QByteArray& msg );
/**
* add a channel and does connect to a signal
* callback is the object
* slot is the SLOT()
*/
void addChannel( const QCString& channel );
void delChannel( const QCString& channel );
/* make it singleton? */
//static OCOPClient* self();
/* no direct signals due the design */
signals:
void called(const QCString&, const QCString&, const QByteArray& );
private slots:
+ void init();
void init(const QCString& pa);
void newData();
private:
+ void startUP();
OCOPPacket packet()const;
void call( const OCOPPacket& );
QSocketNotifier* m_notify;
int m_socket;
-private slots:
+ int m_tries;
};
#endif