如何在 C 中使用 "popen" 写入和读取同一个文件
How to write and read at the same file using "popen" in C
我正在使用 Intel Edison 和 SensorTag。为了通过 BLE 获取温度数据,有一堆命令。当我将 popen 定义为:
popen(command,"w");
大多数情况下,代码都能正常工作。 (其他时候由于我无法控制响应而导致的延迟问题会崩溃。)
但是,当我想控制 command/console 响应时(例如建立蓝牙连接时进入下一行,如果不尝试再次连接等),我无法读取响应。我的 "data" 变量没有改变。
我也尝试了 "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...
很遗憾,您只能在一个方向上使用 popen()
。要获得双向通信,您需要为 stdin 和 stdout 创建两个带有 pipe()
的匿名管道,并将它们分配给带有 dup2()
.
的文件句柄 0 和 1
有关详细信息,请参阅 http://tldp.org/LDP/lpg/node11.html。
您无法使用 popen
执行此操作,但可以使用 fork
、exec
和 pipe
构建程序。最后打开两个相关的文件描述符:parent 与管道的连接,以及 child 的连接。要与 child 进程建立 two-way 连接,您必须使用 两次 调用 pipe
.
pipe
打开的file-descriptors没有缓冲,所以你会用read
和write
来通信child(而不是 fgets
和 fprintf
)。
有关示例和讨论,请参阅
- Does one end of a pipe have both read and write fd?
- Read / Write through a pipe in C
- UNIX pipe() : Example Programs
- pipe(7) - Linux man page
- 6.2.2 Creating Pipes in C
我正在使用 Intel Edison 和 SensorTag。为了通过 BLE 获取温度数据,有一堆命令。当我将 popen 定义为:
popen(command,"w");
大多数情况下,代码都能正常工作。 (其他时候由于我无法控制响应而导致的延迟问题会崩溃。)
但是,当我想控制 command/console 响应时(例如建立蓝牙连接时进入下一行,如果不尝试再次连接等),我无法读取响应。我的 "data" 变量没有改变。
我也尝试了 "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...
很遗憾,您只能在一个方向上使用 popen()
。要获得双向通信,您需要为 stdin 和 stdout 创建两个带有 pipe()
的匿名管道,并将它们分配给带有 dup2()
.
有关详细信息,请参阅 http://tldp.org/LDP/lpg/node11.html。
您无法使用 popen
执行此操作,但可以使用 fork
、exec
和 pipe
构建程序。最后打开两个相关的文件描述符:parent 与管道的连接,以及 child 的连接。要与 child 进程建立 two-way 连接,您必须使用 两次 调用 pipe
.
pipe
打开的file-descriptors没有缓冲,所以你会用read
和write
来通信child(而不是 fgets
和 fprintf
)。
有关示例和讨论,请参阅
- Does one end of a pipe have both read and write fd?
- Read / Write through a pipe in C
- UNIX pipe() : Example Programs
- pipe(7) - Linux man page
- 6.2.2 Creating Pipes in C