2015-08-17 2 views
0

Mon application est une application serveur qui accepte certaines commandes prédéfinies de l'utilisateur et affiche la sortie respective provenant des fichiers XML présents sur le serveur.xerces-c la fonction de bibliothèque renvoie NULL lorsque daemon est exécuté via inetd

Pour analyser le fichier XML, j'utilise la bibliothèque xerces-c version 3.1.2 d'apache. L'application fonctionne correctement lorsqu'elle est exécutée manuellement sur un terminal. Mais je voulais exécuter l'application via telnet sur un réseau afin que je puisse donner des entrées à l'application via telnet et recevoir la sortie sur un système distant aussi. Pour cela, j'utilisé super serveur inetd et ajouté sous la ligne dans inetd.conf:

vterm stream tcp nowait root /path/to/my/binary/vterm vterm 

ensuite ajouté ci-dessous ligne dans/etc/services pour le faire écouter sur le port 5000

vterm 5000/tcp 

Après que quand je a essayé de se connecter à ma demande j'obtenir message ci-dessous:

[email protected] ~/programming/cpp/xml $ telnet localhost 5000 
Trying ::1... 
Trying 127.0.0.1... 
Connected to localhost. 
Escape character is '^]'. 
Connection closed by foreign host. 

Lorsque le message fermé connexion ci-dessus est venu, je pensais que je ne l'ai pas correctement configuré ma demande avec inetd. Donc, j'ai remplacé mon binaire par un simple binaire qui n'utilisait pas de bibliothèques supplémentaires. Juste cin et cout simples, qui a fonctionné parfaitement bien.

Ensuite, il se avère que quelque chose ne va pas avec mon application donc pour cela, j'ai mis beaucoup de cout pour identifier ce qui se passe réellement. Avec cela, j'ai trouvé que l'une des fonctions de la bibliothèque d'analyse XML de xerces-c renvoie NULL et avec cette référence NULL j'essaie d'appeler une fonction en ligne ci-dessous qui fait que mon application se vide dès qu'elle démarre.

Mais la chose est la même fonction fonctionne bien lorsque je cours mon application manuellement sur un terminal. L'application complète est un peu grande, j'ai donc créé un code de démonstration qui reproduit le problème. Voici mon code:

#include <xercesc/util/PlatformUtils.hpp> 
    #include <xercesc/parsers/XercesDOMParser.hpp> 
    #include <xercesc/dom/DOMDocument.hpp> 
    #include <xercesc/dom/DOMElement.hpp> 
    #include <iostream> 

    using namespace std; 
    using namespace xercesc; 

int main() 
{ 
    try 
    { 
     // init xerces XML Parser library 
     XMLPlatformUtils::Initialize(); 
    } 
    catch (const XMLException& ex) 
    { 
     cerr << ex.getMessage() << endl; 
    } 

    // parse a XML file 
    XercesDOMParser* parser = new XercesDOMParser(); 
    try 
    { 
     parser->parse("sample.xml"); 
    } 
    catch (const XMLException& ex) 
    { 
     cerr << ex.getMessage() << endl; 
    } 

    // get the document reference 
    DOMDocument* doc = parser->getDocument(); 

    if (doc == NULL) 
    { 
     cout <<"Doc is NULL" << endl; 
    } 

    // else do stuff further 
    // like get root element 
    DOMElement* root = doc->getDocumentElement(); 

    // print node name 
    string name = XMLString::transcode(root->getTagName()); 
    cout << "Name: " << name << endl; 

    XMLPlatformUtils::Terminate(); 
return 0; 
} 

Le code ci-dessus lors de la compilation et couru ne manuellement vont pas dans ce si la condition qui dit « Doc est NULL » et imprime avec succès le nom de la balise d'élément racine, mais quand je lance cette application derrière inetd et quand je me suis connecté à telnet je peux voir la déclaration "Doc is NULL" et après ce même message "Connection closed by host host". comme ma demande serait probablement dumping.

Je suis un peu hors de la tête maintenant que je ne suis pas sûr où regarder exactement. Comme le même code fonctionne lorsqu'il est exécuté manuellement mais pas via inetd. Donc, je pense que nous devons prendre une attention particulière lors de l'exécution de processus via inetd qui utilise des bibliothèques partagées, comme ici j'utilise la bibliothèque partagée xerces-c pour l'analyse XML. Ou Quoi d'autre pourrait être éventuellement mal avec ma compréhension ou mon code. Pourquoi les mêmes fonctions de bibliothèque fonctionnent-elles parfaitement lorsque l'application est exécutée manuellement et ne fonctionne pas lorsqu'elle est exécutée via inetd?

J'ai essayé la même chose en utilisant xinetd au lieu de inetd mais les mêmes résultats.

+0

Le "répertoire de travail actuel" est-il identique dans les deux cas? – Sleafar

+0

Je ne suis pas au courant du répertoire de travail actuel d'inetd ... ou vous demandez le chemin vers binaire que j'ai donné inetd est le même ou pas .. – mSatyam

+1

Configurez votre inetd pour exécuter 'pwd' au lieu de votre outil. Quel est le résultat? Vous pouvez trouver le chemin complet de cet outil en utilisant 'which pwd'. – Sleafar

Répondre

1

Comme vous l'avez prouvé vous-même, le répertoire de travail est / lorsque vous démarrez votre outil via inetd. Mais votre fichier XML n'est pas dans le répertoire racine de votre système. Vous pouvez connecter le chemin complet dans votre application. Une meilleure solution serait de passer l'emplacement de votre fichier (s) en tant que paramètre.