2010-03-06 4 views
4

Je veux que le processus parent prenne les arguments de main() et envoie les caractères un à la fois au processus fils via un canal commençant par argv [1] et continuez à travers le reste des arguments (un appel à écrire pour chaque caractère).passer les arguments de la ligne de commande à un processus enfant et les compter

Je souhaite que le processus enfant compte les caractères envoyés par le processus parent et imprime le nombre de caractères reçus du parent. Le processus fils ne doit pas utiliser les arguments de main() de quelque façon que ce soit.

Qu'est-ce que je fais de mal? dois-je utiliser exec()?

sortie qui nest pas correct:

~ $ gc a03 
gcc -Wall -g a03.c -o a03 
~ $ ./a03 abcd ef ghi 

child: counted 12 characters 
~ $ 

est le programme ici ..

#include <sys/wait.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 

int main(int argc, char *argv[]) 
{ 

    int length = 0; 
    int i, count; 

    int  fdest[2];   // for pipe 
    pid_t pid;    //process IDs 
    char buffer[BUFSIZ]; 



    if (pipe(fdest) < 0)   /* attempt to create pipe */ 
     printf("pipe error"); 

    if ((pid = fork()) < 0) /* attempt to create child/parent process */ 

    { 
     printf("fork error"); 
    } 


    /* parent process */ 
    else if (pid > 0) {  
     close(fdest[0]); 

     for(i = 1; i < argc; i++) /* write to pipe */ 
     { 
      write(fdest[1], argv[i], strlen(argv[1])); 
     } 

     wait(0); 

    } else { 

     /* child Process */ 
     close(fdest[1]); 

     for(i = 0; i < argc; i++) 
     { 
      length +=(strlen(argv[i])); /* get length of arguments */ 
     } 

     count = read(fdest[0], buffer, length); 
     printf("\nchild: counted %d characters\n", count); 

    } 

    exit(0); 

} 

Répondre

3

Vous avez dit que "le processus fils ne doit pas utiliser les arguments de main() de quelque manière que ce soit". Cependant, je vois que votre processus enfant utilise argc. Cela ne va-t-il pas à l'encontre de votre restriction?

Vous dites également que vous voulez "un appel à écrire pour chaque caractère". Votre implémentation actuelle utilise un appel à écrire pour chaque argument, pas chaque caractère. Était-ce une faute de frappe? Dans le cas contraire, vous voulez utiliser quelque chose comme ceci:

char nul='\0', endl='\n'; 
for (a=1; a < argc; ++a) { 
    for (c=0; c < strlen(argv[a]); ++c) { 
     write(fdest[1], &argv[a][c], 1); 
    } 
    write(fdest[1], &nul, 1); 
} 
write(fdest[1], &endl, 1); 

Ce écrirez un caractère à la fois, avec chaque argument comme une chaîne terminée par NULL et un caractère de nouvelle ligne à la fin. La nouvelle ligne est seulement là pour servir de marqueur pour indiquer qu'il n'y a plus de données à envoyer (et est sûr à utiliser puisque vous ne passerez pas dans un saut de ligne dans un argument CLI).

Le processus enfant devra simplement être une boucle qui lit les octets entrants un par un et incrémente un compteur si l'octet n'est pas '\0' ou '\n'.Quand il lit le caractère de nouvelle ligne, il sort de la boucle de traitement d'entrée et signale la valeur du compteur.

+0

pour le processus fils - while (read (fdest [0], buffer, length)! = '\ N'; quelque chose liek cela? –

+0

Oui, mais vous pourriez faire 'fdest' un simple caractère et le simplifier à' while (read (& fdest, buffer, 1)! = '\ n') '. – bta

0

Ici:

for(i = 1; i < argc; i++) /* write to pipe */ 
{ 
    write(fdest[1], argv[i], strlen(argv[1])); 
} 

strlen(argv[1]) devrait être en fait strlen(argv[i])

+0

la façon dont je compte les arguments est-ce la meilleure façon? –

+0

Le problème que vous avez présenté est artificiel, donc c'est difficile à dire. Je veux dire, vous pouvez simplement compter les caractères dans le processus parent et le passer au processus enfant. Donc, pour améliorer quelque chose, vous devez nous en dire plus sur les contraintes d'implémentation que vous avez. – pajton

0

Le problème ici est

write(fdest[1], argv[i], strlen(argv[1])); 

Notez que ceci est strlen de argv[1], il devrait être argv[i]. Vous référencez effectivement passé la fin de argv[2] et argv[3] dans cette boucle

Vous écrivez efficacement strlen (« ABCD ») * 3 caractères qui est 12 caractères

1

Vous avez une erreur ici:

write(fdest[1], argv[i], strlen(argv[1])); 

Vous devriez prendre strlen(argv[i]) plutôt, ou vous dites à write() de lire après l'espace de argv [i] et invoquer un comportement indéfini.

Notez que vous appelez seulement read() une fois. Au moment où vous appelez read(), peut-être qu'un seul argv [] a été écrit par le parent. Ou 2. Ou n'importe quel nombre d'entre eux.

+0

la façon dont je compte les arguments est-ce la meilleure façon? –

Questions connexes