3 votes

open() échoue à la première tentative

open() échoue avec ENOENT (no such file or directory) lors de la première tentative mais fonctionne correctement lors des tentatives suivantes.
Mon programme crée un processus fils et attend que le processus fils se termine à l'aide de la fonction waitpid() . Le processus enfant crée une copie d'un chemin d'accès à un fichier reçu de l'utilisateur dans un répertoire spécifique en utilisant la fonction execl() .
Une fois que l'enfant sort, le processus parent ouvre cette copie nouvellement créée en utilisant open() . Cependant, il échoue avec ENOENT (no such file or directory) à la première tentative. Je peux voir que le processus enfant crée un fichier dans le répertoire spécifié.
Si je relance ce programme en fournissant le même nom de fichier, il fonctionne bien. Ma question est la suivante : pourquoi le fichier ne s'ouvre-t-il pas du premier coup ? Dois-je rafraîchir le répertoire ou que se passe-t-il ?

Je suis sur redhat

VOICI UN EXTRAIT DE CODE RAPIDE ET SALE

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      
.............  
............    
............  

}

3voto

ugoren Points 9835

Comme d'autres l'ont noté, il est difficile de répondre à une telle question sans le code source. Mais :

Vous semblez souffrir d'un trouble de la course. Le fichier est créé, mais un peu plus tard que lors de votre première tentative d'ouverture. Lors de votre deuxième tentative, vous avez plus de chance, et le fichier était déjà créé.
Le fait qu'une nouvelle exécution fonctionne bien conforte cette théorie : le fichier existait déjà avant le démarrage du programme, donc son ouverture réussit à tout moment.

Comment se fait-il que vous ayez la condition de course ? Si l'enfant le crée, et que le père essaie de l'ouvrir seulement après avoir vérifié que l'enfant a terminé, alors il ne devrait pas y avoir de problème.
Il est difficile de spéculer sur ce qui a mal tourné. Peut-être que vous attendez le mauvais processus. Peut-être que l'enfant crée un autre processus, qui crée le fichier, et que le parent n'attend que le premier enfant. Et un million d'autres hypothèses.

1voto

mark4o Points 20472

Vous appelez waitpid() avec le WNOHANG ce qui signifie qu'il ne bloquera pas l'attente de l'enfant s'il est toujours en cours d'exécution. Ce drapeau est utilisé pour tester si l'état du processus enfant a changé, sans réellement l'attendre si ce n'est pas le cas ; la valeur de retour indiquera si l'enfant était prêt. Si vous voulez qu'il bloque l'attente, supprimez l'indicateur WNOHANG drapeau. Cependant, notez qu'il pourrait toujours retourner avant que l'état de l'enfant ne change si l'appel est interrompu par un gestionnaire de signal. Si vous ne vous souciez pas de savoir si l'enfant est sorti avec succès, vous pouvez écrire :

while (waitpid(PID, &chldstat, 0) == -1 && errno == EINTR)
    ;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X