c - 在 C 中读取执行程序标准输出的更好方法

标签 c memory-management

我使用管道读取执行程序的标准输出:

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. 执行此操作的内存更多或速度更高效的方法。

最佳答案

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

关于c - 在 C 中读取执行程序标准输出的更好方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11130029/

相关文章:

c++ - HPUX 上的套接字未收到完整数据

c - 为什么结构必须单词对齐?

ios - 将数据从磁盘发送到服务器而不加载到 iOS 上的 ram

java - 通过本地网络传输实时数据

c - 是否可以将指针从结构类型转换为扩展 C 中第一个结构类型的另一种结构类型?

Makefile 中的 C : Unix SDL2 library : undefined reference, 问题?

objective-c - ARC 适用于所有对象?

java - 对象内对象的内存分配

c内存泄漏问题

c - 为什么 char[] 在堆栈上,而 char * 在堆上?