I have a linux based device that runs c++ code using QT framework. Using QProcess is not an option, since we don't have the QT compiled to support it.
I can't create a tar.gz
archive using execl().
It returns -1(fail) and error is "No such file or directory"
Code sample:
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");
}
Output:
pid=877
Pid is 0
Execl is done, execStatus= -1
Error: No such file or directory
Resume from fork
Permissions:
logs.txt 666 | busybox 755
How can I get more error details or what is wrong here?
Edit:
So, after a while, I tried to do just the .tar archive and it worked.
Then I tried just to do the .gz compression and it also worked.
Solution: So, at least in my case, the solution was to do the tar.gz in two steps(Two processes required):
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);
I don't know what platform or compiler this is, but it generally isn't possible to pass whole command lines to execl(). If I understanding correctly, you are running something like this:
but in general you need
That is, you need to parse the command line down to its individual arguments. That should be easy enough in the case you described, since you already know what the individual arguments are.
I think the problem is that /bin/busybox starts, but chokes when it tries to interpret "tar -czvf blah blah" as the name of an applet to run.
Incidentally -- and probably not related -- busybox "tar" won't handle gzip compression internally by default, unless you have enabled this feature at build time.