2010-05-06 4 views
1

J'utilise popen pour exécuter une commande sous Linux, puis 4 process wile utilise la même sortie. Je suis en train de dupliquer le descripteur de fichier pour le passer à chaque processus. voici mon code:Descripteur de fichier en double après

FILE* file_source = (FILE*) popen(source_command, "r"); 
int fd = fileno(file_source); 
fdatasync(fd); 

int dest_fd[4], y, total = 4; 
    for (y = 0; y < total; y++) { 
     dest_fd[y] = dup(fd); 
    } 

en fait, si ensemble total à 1 il fin de travail, après avoir changé total = 4, il ne fonctionne plus. cette réponse est trop proche de ce que je dois: link

+0

Est-ce que dup() renvoie -1? Avez-vous essayé de vérifier l'errno? – Vereb

+0

Que voulez-vous dire par «ça ne marche plus»? Je suppose que vos lectures échouent, plutôt que "dup" échouer – Hasturkun

Répondre

1

Votre approche actuelle ne fera probablement pas ce que vous voulez. Lorsque vous venez de dupliquer les descripteurs de fichiers, ils se réfèrent tous au même canal - aucune donnée ne sera dupliquée. Pour chaque bloc de données envoyé par la commande source, exactement un processus va le lire.

Si vous souhaitez dupliquer les données (comme l'utilitaire tee ne), vous devez faire explicitement:

#define TOTAL 4 

int dest_fd[TOTAL]; 
int dest_fd_wr[TOTAL]; 
int y; 

/* Build pipes for reading the data from the child process */ 
for (y = 0; y < TOTAL; y++) 
{ 
    int p[2]; 

    pipe(p); 
    dest_fd[y] = p[0]; 
    dest_fd_wr[y] = p[1]; 
} 

/* Create a child process to handle the "tee"-style duplication */ 
if (fork() == 0) 
{ 
    /* Child process */ 
    FILE *file_source = popen(source_command, "r"); 
    FILE *file_sink[TOTAL]; 
    char buffer[2048]; 
    size_t nbytes; 

    for (y = 0; y < TOTAL; y++) 
    { 
     close(dest_fd[y]); 
     file_sink[y] = fdopen(dest_fd_wr[y], "w"); 
    } 

    while ((nbytes = fread(buffer, 1, sizeof buffer, file_source)) > 0) 
    { 
     for (y = 0; y < TOTAL; y++) 
     { 
      fwrite(buffer, 1, nbytes, file_sink[y]); 
     } 
    } 

    _exit(0); 
} 

for (y = 0; y < TOTAL; y++) 
{ 
    close(dest_fd_wr[y]); 
} 

/* Now have a set of file descriptors in dest_fd[0..TOTAL-1] that each have 
* a copy of the data from the source_command process. */ 

-gestion des erreurs est laissé comme un exercice pour le lecteur;)

+0

excellent, merci – alaamh

0

À la lecture de la question que vous avez lié à, il semble parler de dup() et la création d'un nouveau descripteur de fichier qui est complètement séparé de eachother (ils ne partagent pas fichier offset entre autres choses). Si c'est ce que vous voulez, vous devrez faire ce qu'ils suggèrent dans la question.

Vous devrez ouvrir/rouvrir la sortie autant de fois que vous souhaitez avoir des doublons. Il semble qu'ils travaillent autour de la limitation en ouvrant un nouveau fichier vers lequel la sortie est dirigée. Ma conjecture est que vous avez simplement besoin de rediriger la sortie de la commande_source vers un fichier, puis d'ouvrir le fichier de sortie plusieurs fois plutôt que d'utiliser dup().

Questions connexes