So, I've got a Linux process where I'm trying to manage some files on a tape. I have the following code that attempts to extract a file, catalog.xml, from the current archive on the tape and copy it to a fixed location (eventually, I'll parse the file and do some work with the results). But, my code is intermittently failing to work correctly. The tar command always succeeds, (and if I check the file system, I see the catalog.xml file), but sometimes my followup check to see if the file exists returns false. Am I doing something obviously wrong? It seems like I'm probably encountering a race condition between the fork()ed process returning and the results of that process being visible on the file system - is there some call I need to make?
pid_t tPid = vfork();
if (0 == tPid)
{
int tChildRet;
tChildRet = execlp("tar", "tar", "-xvf", "/dev/nst0", "-C", "/tmp", "catalog.xml", (char *) 0);
_exit(-1 == tChildRet ? EXIT_FAILURE : EXIT_SUCCESS);
}
else
{
wait(&ret);
}
std::ifstream tCatalogFile("/tmp/catalog.xml");
if (tCatalogFile)
{
cout << "File exists!" << endl;
} else {
cout << "File does not exist!" << endl;
}
And I'm getting either "file exists!" or "file does not exist!", seemingly at random.
Other notes: On the failure cases:
- if I do a
stat ("/tmp/catalog.xml")
, I get a return of -1 with errno set to ENOENT. - the tar command (run with the -v flag) produces the expected one line of output ("catalog.xml")
/tmp is a local tmpfs filesystem; the tape drive is a local device. I'm using 2.6.30.9 Linux kernel with g++ 4.1.2 on a x86_64 box.
Thanks in advance!
If
execlp
succeeds, it will never get to the line where you call_exit
. You aren't checking the return value (ret
) fromwait
. It's not clear why you should be usingvfork
. Etc.Since the parent is not doing anything else besides waiting for the child to complete, why not make your life easier and just use
system()
?