Question

open() fails with ENOENT (no such file or directory) on first attempt but works fine in subsequent attempts.
My program forks a child process and and waits for the child to finish using waitpid(). The child process creates a copy of a file path received from user in specific directory using execl().
Once the child exits, the parent process opens this newly created copy using open(). However it fails with ENOENT (no such file or directory) on the first attempt. I can see that child process creates a file in the specified directory.
If I run this program again by supplying the same file name, then it works fine. My question is: Why isn't it opening the file on the first attempt? Do I need to refresh directory or what is it?

I am on redhat

HERE IS A QUICK N DIRTY CODE SNIPPETS

my_function()
{
char *src = "TEST.txt";  
char *dest = "./Output/";  
char *fp = "/Output/TEST.txt";  
int fd;  
struct fstat file_stat;  

pid_t PID = fork();  

if(PID == -1)  
      exit(1);   


if(PID == 0)  
{
       execl("/bin/cp", "/bin/cp", src, dest);   
       exit(1);   
}   


if(PID > 0)  
{  
       int chldstat;
       pid_t ws = waitpid(PID,&chldstat,WNOHANG);  
}  


if(stat(fp,&file_stat) == -1)  
{  
       perror("stat");  
       exit(1);  
}  


if((fd = open(dest,O_RDWR)) == -1)  
{  
       perror("open");
       exit(1);
}  


if((fp=mmap(0,file_stat.st_size,PROT_READ | PROT_WRITE,fd,0)) == -1)  
{  
       perror("mmap");
       exit(1);
}  


//OTHER ROUTINES      
.............  
............    
............  


}  
Was it helpful?

Solution

As other noted, it's hard to answer such a question without the source code. But:

You seem to suffer from a race condition. The file is created, but a bit later than your first open attempt. On your second attempt you're luckier, and the file was already created.
The fact that running again works fine supports this theory - the file existed even before the program started, so opening it succeeds at any time.

How come you have the race condition? If the child creates it, and the father tries to open it only after it has verified that the child ended, then there should be no problem.
It's hard to speculate what went wrong. Maybe you wait for the wrong process. Maybe the child creates another process, which creates the file, and the parent waits only for the first child. And a million other maybes.

OTHER TIPS

You are calling waitpid() with the WNOHANG flag, which means that it will not actually block waiting for the child if it is still running. This flag is used to test whether the child process state has changed, without actually waiting for it if not; the return value will indicate whether the child was ready. If you want it to block waiting for it, remove the WNOHANG flag. However, note that it could still return before the child state changes if the call is interrupted by a signal handler. If you don't care about whether the child exited successfully then you could write:

while (waitpid(PID, &chldstat, 0) == -1 && errno == EINTR)
    ;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top