How to exec only cat in C

846 views Asked by At

I'd like to know how can I exec only cat like this:


execvp("cat", "cat", NULL);

and ask to a client to fill the rest of the command.

For example: my client ask cat to the daemon. The daemon then ask to the client to fill cat by mkfifo, then the daemon read the pipe and send the result of the cat until the client stop to fill cat.

Thanks for helping

EDIT: this may not only work for cat. This should work for every commands that require any entry from the client. As required, I post my code :

void *run(void *dat)
{
   struct shared_memory *d = (struct shared_memory *)dat;
   int fd[2];
   int end = d->hasEnd;
   if(pipe(fd) <0){
      perror("pipe failed");
      exit(EXIT_FAILURE);
   }
   if(strcmp(d->command[0], "cat") == 0 && (strcmp(d->command[1],",")== 0 || strcmp(d->command[1],"fin") == 0)){
        printf("dans la condition\n");
        d->needClient = 1;
   }
   char pipe1[256];
   char tube2[256];
   strcpy(pipe1, d->pipe1);
   strcpy(tube2, d->tube2);
   switch(fork()){
        case -1:
            perror("fork");
            break;
        case 0:
            // redirection de l'entré standard
            close(fd[0]);
            dup2(fd[1], 1);
            dup2(fd[1], 2);
            close(fd[1]);
            // éxécution de la commande courrante.
            execvp(d->command[0], d->command);
            perror("execvp");
            break;
        default:
          // gère les processus zombies.
          if(wait(NULL) == -1){
                perror("wait");
          }
          if(d->needClient == 1){
                int sortieTube;
                char chaineALire[5000];
                do /* Pas de for car l'objectif d'optimisation est que le client recoive l'intégralité des réponses du démon au sujet de sa commande*/
                {
                    /****************  Lecture de la réponse du démon ******************/
                    while((sortieTube = open (pipe1, O_RDONLY)) == -1)
                    {
                        sleep(1); // on attend qu'il y ai une quelconque réponse du démon.
                    }
                    if(read(sortieTube, chaineALire, sizeof(chaineALire)) == -1){
                        perror("read");
                    }
                    printf("%s\n", chaineALire);
                    memset(chaineALire, 0, 5000);
                }
                while(d->needClient == 1);
            }
          unlink(d->pipe1);
          unlink(d->tube2);
          unlink(tube2);
          //création du tube nommé pour le client.
          if(mkfifo(tube2, 0644) != 0)
          {
              perror("mkfifo");
              fprintf(stderr, "Impossible de créer le tube nommé.\n");
              exit(EXIT_FAILURE);
          }
          // ouverture de ce même tube
          if((d->entree_tube = open(tube2, O_WRONLY)) == -1)
          {
              perror("open");
              fprintf(stderr, "Impossible d'ouvrir l'entrée du tube nommé.\n");
              exit(EXIT_FAILURE);
          }
          char buffer[550000] = {0};
          close(fd[1]);
          // lecture du résultat de la commande stocké dans fd[0]
          while (read(fd[0], buffer, sizeof(buffer)) >0)
          {
              //écriture du résultat dans l'entré du tube.
             if(write(d->entree_tube, buffer, strlen(buffer)) == -1){
                perror("write");
             }
             //réinitialisation du buffer stockant une partie du résultat de la commande.
             memset (buffer, 0, sizeof(buffer));
          }
          close(fd[0]);
          // on regarde si il y a eu le mot clé "fin" pour alerter la client que la commande est terminé
          // et on redonne la main à un autre client tentant de se connecter au démon.
          if(end == 1){
            strcpy(d->fin, "fin");
            d->hasEnd = 0;
          }
          unlink(d->pipe1);
          unlink(tube2);
          unlink(d->tube2);
          break;
   }
   return NULL;

}
1

There are 1 answers

0
Armali On

I already use pipe/fork to do it and when I type cat, it blocks me and it is here that I request words from my client.

The foremost reason why your code blocks is that it calls wait(NULL) immediately after it has forked the child - thus it waits for the child to terminate before any attempt is made to send data through the pipe. You have to move the wait() call behind the close(fd[0]), where the communication is finished.