2010-05-05 3 views
3

J'ai donc un flux de fichier d'un processus parent vers un enfant - et la plupart du temps cela fonctionne très bien. Cependant, lorsque vous en lisez plusieurs fois rapidement, l'utilisation de fgets() renvoie NULL et l'erreur est définie sur «ressource temporairement indisponible». Le problème est intermittent - et exécuter le script qui fait les reads aura parfois des fuels retournent NULL et parfois non.C enfant lu donnant "ressource temporairement indisponible"

Quelqu'un pourrait-il m'aider à arrêter cette erreur? Merci! Edit: voici un peu de code .. Je ne sais pas quel autre code serait utile? il y a un peu

// this is the bit that gets a line from the child 
if(fgets(line, MAX_LINE_LENGTH, fpin) == NULL) { 
    if(ferror(fpin)) { 
     perror("error on stream fpin"); 
    } 
    free(line); 
    return FAIL; 
} 

Comme demandé, le code qui ouvre pipe et traite processus enfant ..

// set up pipes 
int readPipe[2]; // child -> parent communication 
int writePipe[2]; // parent -> child communication 
int errorPipe[2]; // child -> parent, to check for errors in exec 

/* create pipe */ 
pipe(readPipe); // error if return val < 1 for any 
pipe(writePipe); 
pipe(errorPipe); 
pid_t pid; /* process id when we fork */ 
pid = fork(); /* create new child */ 

if(pid == 0) { /* pid == 0 indicates child process */ 

    // close unused fds 
    close(PARENT_READ); 
    close(PARENT_WRITE); 
    close(errorPipe[0]); 

    dup2(CHILD_READ, 0); // replace stdin with pipe in 
    dup2(CHILD_WRITE, 1); // replace stdout with pipe out 

    /* replace child process with program to run */ 
    execvp(args[0], args); 

    // if we get here, exec failed so inform the parent 
    char *error_message = "exec failed"; 
    write(errorPipe[1], error_message, strlen(error_message)+1); 
    exit(-1); 

} 
+0

Pouvez-vous écrire du code? –

+0

Le code qui ouvre le canal et crée le processus enfant est plus susceptible d'être utile. – caf

+0

Comment 'fpin' est-il ouvert? Y compris les définitions de ceux '(PARENT | CHILD) _ (READ | WRITE)' pourrait également aider. – caf

Répondre

8

Cela signifie que quelqu'un a mis le descripteur de fichier d'entrée standard non-blocage.

(ressources temporairement indisponible est le message d'erreur correspondant à EAGAIN/EWOULDBLOCK, qui est renvoyé par read() uniquement lorsque IO non-blocage a été sélectionné et il n'y a pas de données à lire).

Notez qu'il est possible que le processus parent définisse le descripteur de fichier nonbloquant avant d'exécuter votre processus enfant.

Quelques idées pour une enquête plus approfondie:

  • Si vous strace() le processus enfant qui appel système est de retour EAGAIN? Sur quel numéro de descripteur de fichier?

  • Quelle est la sortie de printf("%d\n", fcntl(fileno(fpin), F_GETFL)); juste avant l'échec fgets()?

+0

Non, stdin n'a pas été défini sur non-bloquant. Si cela aide du tout, il semble attendre le même laps de temps que le délai d'attente sur une déclaration de sélection que j'ai plus bas avant de donner l'erreur. Je vais poster un peu de code maintenant .. – Gary

+0

Eh bien, ce message d'erreur est seulement retourné par 'read()' pour les descripteurs de fichiers non bloquants - J'ai mis à jour ma réponse avec d'autres idées pour l'enquête ... – caf

+0

Je pense que je peux utiliser strace, comme je suis sur un mac. Si je peux, pourriez-vous expliquer comment? En outre, la deuxième instruction renvoie toujours 2 (mais le flux de fichier n'est pas stdin dans ce cas). En outre, qu'est-ce qui pourrait amener fgets() à retourner NULL mais feof (stream) retournerait false? C'est ce qui arrive quand je n'obtiens pas le problème "ressource temporairement indisponible" – Gary

Questions connexes