【问题标题】:How to write and read at the same file using "popen" in C如何使用 C 中的“popen”在同一个文件中写入和读取
【发布时间】:2015-09-09 08:03:35
【问题描述】:

我正在使用英特尔 Edison 和 SensorTag。为了通过 BLE 获取温度数据,有一堆命令。当我将 popen 定义为:

popen(command,"w"); 

代码在大多数情况下都能正常工作。 (由于我无法控制响应,我假设延迟问题会导致其他时间崩溃。)

但是,当我想控制命令/控制台响应时(例如在建立蓝牙连接时进入下一行,如果不尝试再次连接等),我无法读取响应。我的“数据”变量没有改变。

我也尝试了其他“popen”模式,但它们会出现运行时错误。

这是我正在使用的代码:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

int endsWith (char* base, char* str) {
    int blen = strlen(base);
    int slen = strlen(str);
    return (blen >= slen) && (0 == strcmp(base + blen - slen, str));
}

FILE* get_popen(char* command, int close, int block) {
    FILE *pf;
    char data[512];

    // Setup our pipe for reading and execute our command.
    pf = popen(command,"w");

    // Error handling

    if (block == 1) {

        // Get the data from the process execution
        char* result;
        do {
            result=fgets(data, 512 , stderr);
            if (result != NULL) {
                  printf("Data is [%s]\n", data);
            }
        } while (result != NULL);

        // the data is now in 'data'
    }
    if (close != 0) {
        if (pclose(pf) != 0)
            fprintf(stderr," Error: Failed to close command stream \n");
    }

    return pf;
}

FILE* command_cont_exe(FILE* pf, char* command, int close, int block) {
    char data[512];

    // Error handling
    if (pf == NULL) {
        // print error
        return NULL;
    }

    fwrite(command, 1, strlen(command), pf);
    fwrite("\r\n", 1, 2, pf);

    if (block == 1) {

        // Get the data from the process execution
        char* result;
        do {
            result=fgets(data, 512 , stderr);
            if (result != NULL) {
                  printf("Data is [%s]\n", data);
            }
        } while (result != NULL);//
    }
    // the data is now in 'data'

    if (close != 0) {
            if (pclose(pf) != 0)
                fprintf(stderr," Error: Failed to close command stream \n");
    }

    return pf;
}


int main()
{
    char command[50];

    sprintf(command, "rfkill unblock bluetooth");
    get_popen(command, 1, 0);
    printf("Working...(rfkill)\n");
    sleep(2);

    sprintf(command, "bluetoothctl 2>&1");
    FILE* pf = get_popen(command, 0, 1);
    printf("Working...(BT CTRL)\n");
    sleep(3);

    sprintf(command, "agent KeyboardDisplay");
    command_cont_exe(pf, command, 0, 1);
    printf("Working...(Agent)\n");
    sleep(3);
    //Main continues...

【问题讨论】:

    标签: c pipe popen intel-edison


    【解决方案1】:

    您不能使用popen 来执行此操作,但可以使用forkexecpipe 构建程序。最后打开两个文件描述符,它们是相关的:父级到管道的连接,以及子级的连接。要与子进程建立双向连接,您必须使用 两次 调用 pipe

    pipe 打开的文件描述符没有缓冲,因此您可以使用readwrite 与孩子进行通信(而不是fgetsfprintf) .

    有关示例和讨论,请参阅

    【讨论】:

    • printf/fgets 与缓冲有什么关系?
    • 你也不能在文件描述符上使用fread/fwrite。这些调用对指向FILE 结构的指针进行操作。对文件描述符使用简单的read/write 调用。
    【解决方案2】:

    很遗憾,您只能在一个方向使用popen()。要获得双向通信,您需要为 stdin 和 stdout 创建两个带有 pipe() 的匿名管道,并将它们分配给带有 dup2() 的文件句柄 0 和 1。

    更多详情请见http://tldp.org/LDP/lpg/node11.html

    【讨论】:

      猜你喜欢
      • 2012-08-31
      • 1970-01-01
      • 1970-01-01
      • 2010-10-10
      • 1970-01-01
      • 2015-12-02
      • 1970-01-01
      • 2015-12-24
      • 1970-01-01
      相关资源
      最近更新 更多