2016-02-02 2 views
2

Я принимаю команду как ls как ввод и выполнение команды, используя popen и сохраняя результат в буфере. Однако он не печатает все содержимое команды. Пожалуйста, помогите мне. PS Он смог работать, когда весь код был в основном. Я пробовал gdb, но я не могу выполнить отладку.Использование popen в трубах в c

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



void process_command(char * command, char * buffer) 
{ 
    int  fd[2], nbytes; 
    pid_t childpid; 
    char readbuffer[1025]; 
    FILE *fp = NULL; 
    pipe(fd); 


    if((childpid = fork()) == -1) 
    { 
      perror("fork"); 
      exit(1); 
    } 

    int b = 0; 
    int status = 0; 

    if(childpid == 0) 
    { 
      /* Child process closes up input side of pipe */ 
      close(fd[0]); 
      fp = popen(command,"r"); 

      /* Send "string" through the output side of pipe */ 
      while((b = fread(readbuffer,1,1024,fp)) > 0) 
       write(fd[1], readbuffer, b); 

      status = pclose(fp); 

    } 

    else 
    { 
      /* Parent process closes up output side of pipe */ 
      close(fd[1]); 
      waitpid(childpid,&status,0); 
      /* Read in a string from the pipe */ 
      do 
      { 
      nbytes = read(fd[0], buffer, sizeof(buffer)); 
      }while(nbytes == -1); 
      buffer[nbytes] = '\0'; 
    printf("Received string: %s", buffer); 
    } 


} 


#define MAX 1024 

int main(void) 
{ 
    char command[MAX] ; 
    char buffer[MAX]; 
    scanf("%s",command); 
    process_command(command,buffer); 

    return(0); 
} 
+0

Почему ребенок и родители? почему бы не написать прямо в 'buffer'? – Haris

+0

есть проблема неполной записи в буфер. – Tejas

ответ

2

Проблема в том, как вы читаете выходные данные дочернего процесса. В частности, это утверждение:

 nbytes = read(fd[0], buffer, sizeof(buffer)); 

Массив buffer был принят из main() и преобразуется в указатель на функцию process_command(). Таким образом, sizeof(buffer) подходит к размеру указателя, а не массиву, который аналогичен sizeof(char*). Предположим, вы находитесь в 64-битной системе с 8 байтами для размера указателя. Таким образом, вы будете читать только 8 байтов.

Либо передать размер массива в качестве дополнительного аргумента или использовать MAX:

 nbytes = read(fd[0], buffer, MAX); 

Дополнительные примечания:

  • Вы читаете команду, используя %s, которые не могут читать пространство отделенные ввода. Поэтому, если вы хотите запустить ls /tmp, тогда это не сработает. Рассмотрим использование fgets().

  • Даже с правильным размером буфера вы будете читать только 1024 байта. Поэтому, если выход дочернего процесса дольше, он будет усечен. Лучше было бы read(), пока есть выход и распечатайте его внутри петля.

Смежные вопросы