2012-06-21 41 views
1

我使用管道讀取exec'd程序的stdout:更好的方式來讀取一個exec'd程序的stdout用C

int pipes[2]; 
pipe(pipes); 
if (fork() == 0) { 
    dup2(pipes[1], 1); 
    close(pipes[1]); 
    execlp("some_prog", ""); 
} else { 
    char* buf = auto_read(pipes[0]); 
} 

從標準輸出讀,我有一個函數auto_read自動分配更多的內存如所須。

char* auto_read(int fp) { 
    int bytes = 1000; 
    char* buf = (char*)malloc(bytes+1); 
    int bytes_read = read(fp, buf, bytes); 
    int total_reads = 1; 
    while (bytes_read != 0) { 
     realloc(buf, total_reads * bytes + 1); 
     bytes_read = read(fp, buf + total_reads * bytes, bytes); 
     total_reads++; 
    } 
    buf[(total_reads - 1) * bytes + bytes_read] = 0; 
    return buf; 
} 

我之所以做這種方式是我不知道這個程序是多少文本要提前出局噴涌,我不希望創建一個過大的緩衝區,併成爲回憶豬。我想知道是否有:

  1. 一個更清潔的方式來寫這個。
  2. 這樣做的內存或速度更快的方式。

回答

4

使用popen如果你只需要從一個進程來讀,並在* NIX平臺:

FILE *programStdout = popen("command", "r"); 

// read from programStdout (fread(), fgets(), etc.) 
char buffer[1024]; 

while (fgets(buffer, 1024, programStdout)) 
{ 
    puts(buffer); 
} 

編輯:你問了一個方法來映射一個節目輸出到文件,所以在這裏你去:

#import <stdio.h> 
#import <unistd.h> 
#import <sys/mman.h> 

void *dataWithContentsOfMappedProgram(const char *command, size_t *len) 
{ 
    // read the data 
    char template[] = "/tmp/tmpfile_XXXXXX"; 
    int fd = mkstemp(template); 

    FILE *output = fdopen(fd, "w+"); 
    FILE *input = popen(command, "r"); 

#define BUF_SIZ 1024 
    char buffer[BUF_SIZ]; 
    size_t readSize = 0; 
    while ((readSize = fread(buffer, 1, BUF_SIZ, input))) 
    { 
     fwrite(buffer, 1, readSize, output); 
    } 
    fclose(input); 

    input = NULL; 
#undef BUF_SIZ 

    // now we map the file 
    long fileLength = ftell(output); 
    fseek(output, 0, SEEK_SET); 

    void *data = mmap(NULL, fileLength, PROT_READ | PROT_WRITE, MAP_FILE | MAP_PRIVATE, fd, 0); 

    close(fd); 

    if (data == MAP_FAILED) 
     return NULL; 

    return data; 
} 


int main() 
{ 
    size_t fileLen = 0; 
    char *mapped = dataWithContentsOfMappedProgram("echo Hello World!", &fileLen); 

    puts(mapped); 

    munmap(mapped, fileLen); 
} 
+0

嗯不錯,我會用這個。那緩衝區呢?我想我應該仍然使用'auto_read',因爲我不知道這個命令會打印多少? –

+0

@VladtheImpala注意到'while'循環。它會讀取,直到程序不再輸出,並將其輸出到控制檯。如果你需要在內存中輸出的全部內容,可以考慮將輸出寫入一個文件,然後'mmapp''。如果你想要一個嘖嘖的話,就說,我會寫一個。 –

+0

是的請!那太好了! –

相關問題