Ale*_*ton 5 c linux ssh unit-testing pipe
我正在使用管道与stdin和stdout进行通信的系统.子进程使用api库来促进这种通信,我需要为库编写单元测试.我能弄清楚如何正确测试这些函数的唯一方法是用管道替换stdin/stdout,以便测试在调用函数时可以伪装成父系统.
/* replace stdin and stdout with pipes */
void setup(void) {
pipe(in_sub);
pipe(out_sub);
dup2(out_sub[1], fileno(stdout));
dup2( in_sub[0], fileno(stdin));
read_from = fdopen(out_sub[0], "rb");
write_to = fdopen( in_sub[1], "wb");
stdout_t = fopen("/dev/tty", "wb");
stdin_t = fopen("/dev/tty", "rb");
}
/* reopen stdin and stdout for future test suites */
void teardown(void) {
fclose(read_from);
fclose(write_to);
stdout = stdout_t;
stdin = stdin_t;
close(in_sub[0]);
close(in_sub[1]);
close(out_sub[0]);
close(out_sub[1]);
}
Run Code Online (Sandbox Code Playgroud)
我试过在temps中保存stdin和stdout并在它们上使用fdopen()(应该工作,因为它们是FILE*)但这不会导致正确写入管道.直接从主机shell运行时,此代码可以正常工作.在ssh上运行时会出现问题.单元测试执行完美,但是当我在这个测试套件之后向stdout写任何东西时,我收到一个破坏的管道错误.
我能做些什么来避免使用dup2以便stdin和stdout永远不会被关闭,或者我如何重新打开stdin和stdout以便它们能够正确地在shell和ssh中工作?
stdin、stdout 只是 FILE* 指向一个结构体(对象),该结构体内部的 fd 设置为 0(和 1)。因此,当您执行 dup2 时,文件 0 和 1 不再起作用。您需要做的是在执行 dup2之前从头开始创建一个新的文件对象,因此这可能就是您需要的所有修改;
void setup(void) {
int dupin, dupout;
dupin = dup(0); // Create an extra fd to stdin
dupout = dup(1); // create an extra fd to stdout
pipe(in_sub);
pipe(out_sub);
dup2(out_sub[1], fileno(stdout));
dup2( in_sub[0], fileno(stdin));
read_from = fdopen(out_sub[0], "rb");
write_to = fdopen( in_sub[1], "wb");
stdout_t = fdopen(dupout, "wb");
stdin_t = fdopen(dupin, "rb");
}
Run Code Online (Sandbox Code Playgroud)