簡體   English   中英

更好的方式從C中的exec'd程序的stdout讀取

[英]Better Way To Read From An exec'd Program's stdout in C

我用管道讀了一個exec'd程序的stdout:

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]);
}

要從stdout讀取,我有一個函數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. 更多內存或速度有效的方法。

如果您只需要從進程讀取並且在* NIX平台上,請使用popen

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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM