2017-08-26 1 views
0

J'ai un périphérique basé sur Linux qui exécute du code C++ en utilisant QT framework. L'utilisation de QProcess n'est pas une option, puisque QT n'est pas compilé pour le supporter.commande tar dans execl en utilisant busybox. Erreur: aucun fichier ou répertoire de ce type

Je ne peux pas créer une archive tar.gz en utilisant execl().

elle renvoie -1 (échec) et l'erreur est "No such file or directory"

Exemple de code:

std::string applicationPathWithName = "/bin/busybox"; 
QString dataDirectory("/opt/appl/data/"); 
QString archiveName = QString("AswLogs.tar.gz"); 
char* applName; 
applName = new char [applicationPathWithName.size() + 1]; 
strcpy(applName, applicationPathWithName.c_str()); 

itsFlmFileManagerPtr->writeInFile(eFlmFileTypes_LogFile, data); //This creates logs.txt successfully 

pid_t pid = fork(); 

QString command = QString("tar -czvf %1%2 %3logs.txt").arg(dataDirectory).arg(archiveName).arg(dataDirectory); 

if(0 == pid) 
{ 
    INFO("Pid is 0"); 
    int execStatus = 0; 
    execStatus = execl(applName, applName, command.toStdString().c_str(), (char*)NULL); 
    INFO("Execl is done, execStatus= " << execStatus); 
    std::string errorStr = strerror(errno); 
    INFO("Error: " << errorStr); 

    _exit(EXIT_FAILURE); 
} 
else if (pid < 0) 
{ 
    INFO("Failed to fork"); 
} 
else 
{ 
    INFO("pid=" << pid); 
    int status; 
    if(wait(&status) == -1) 
    { 
     INFO("Wait child error"); 
    } 
    INFO("Resume from fork"); 
} 

sortie:

pid = 877

Pid est de 0

Execl est fait, execStatus = -1

Erreur: Aucun fichier ou répertoire

Reprise de la fourche

Autorisations:

logs.txt 666 | busybox 755

Comment puis-je obtenir plus de détails sur les erreurs ou ce qui ne va pas ici? Donc, après un certain temps, j'ai essayé de faire juste l'archive .tar et cela a fonctionné. Ensuite, j'ai essayé juste de faire la compression. Gz et cela a également fonctionné.

Solution: Donc, au moins dans mon cas, la solution était de faire la tar.gz en deux étapes (deux processus requis):

execl("/bin/busybox", "/bin/busybox", "tar", "-cvf", "/opt/appl/data/logs.tar", "/opt/appl/data/logs.txt", (char*) NULL);

execl("/bin/busybox", "/bin/busybox", "gzip", "/opt/appl/data/logs.tar", (char*) NULL);

Répondre

0

Je ne Je ne connais pas la plate-forme ou le compilateur, mais il n'est généralement pas possible de passer des lignes entières à execl(). Si je comprends bien, vous utilisez quelque chose comme ceci:

execl ("/bin/busybox", "/bin/busybox", "tar -czvf blah blah", null); 

mais en général vous avez besoin

execl ("/bin/busybox", "/bin/busybox", "tar", "-czvf", "blah", "blah", null); 

C'est, vous devez analyser la ligne de commande jusqu'à ses arguments individuels. Cela devrait être assez facile dans le cas que vous avez décrit, puisque vous savez déjà quels sont les arguments individuels.

Je pense que le problème est que/bin/busybox démarre, mais s'étouffe lorsqu'il essaie d'interpréter "tar -czvf blah blah" comme le nom d'une applet à exécuter. Incidemment - et probablement pas connexe - busybox "tar" ne gèrera pas la compression gzip en interne, sauf si vous avez activé cette fonctionnalité au moment de la construction.

+0

Vous avez bien compris. J'ai essayé votre version en séparant les arguments mais j'ai quand même eu la même erreur "No such file or directory". De plus, j'ai remplacé "-czvf" par "-cvf", respectivement "AswLogs.tar.gz" par "AswLogs.tar" mais sans succès.Avez-vous d'autres suggestions? – ionutCb

+0

Avez-vous vérifié que votre commande tar Busybox fonctionne correctement lorsqu'elle est invoquée à partir d'une invite de commande? Quelle est la valeur de errno après l'appel de execl()? –

+0

Oui, j'ai vérifié. Invoqué du terminal fonctionne bien. La valeur de errorStr est "No tel fichier ou répertoire" – ionutCb