2015-09-09 74 views
1

中編寫和讀取我正在使用英特爾Edison和SensorTag。爲了通過BLE獲得溫度數據,有一堆命令。當我將popen定義爲:如何在同一個文件中使用「popen」在C

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... 

回答

2

你不能用popen做到這一點,但可以使用forkexecpipe來構建程序。最後打開兩個文件描述符,它們是相關的:父節點與管道的連接以及子節點的連接。要與子進程建立雙向連接,必須使用兩個調用pipe

通過pipe打開的文件描述符不緩衝,因此會使用readwrite與孩子(而不是fgetsfprintf)進行通信。

對於實例和討論,請參閱

+1

什麼的printf /與fgets得到了與BUFF做E-環? – immibis

+0

你也不能在文件描述符上使用'fread/fwrite'。這些調用在一個指向'FILE'結構的指針上進行操作。在文件描述符上使用簡單的「讀/寫」調用。 –

1

不幸的是,你只能在一個方向上使用的popen()。要獲得雙向通信,您需要爲標準輸入和標準輸出創建兩個具有pipe()的匿名管道,並將它們分配給dup2()的文件控制柄0和1。

請參閱http://tldp.org/LDP/lpg/node11.html瞭解更多詳情。

相關問題