c - 通过 ssh 替换并打开 stdin/stdout

标签 c linux unit-testing ssh pipe

我正在开发一个系统,该系统使用到标准输入和标准输出的管道与子进程通信。子进程使用 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]);
}

我试过将标准输入和标准输出保存在临时文件中并在它们上使用 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");
}

关于c - 通过 ssh 替换并打开 stdin/stdout,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6961358/

相关文章:

c++ - linux 到 windows C++ 字节数组

XCode 4 单元测试 : Is it possible to ignore certain test cases?

javascript - 如何在 Jest 中进行单元测试并检查函数是否正在调用预期的 firebase 方法?

编译其他人的使用 math.h 的 C 程序

c - 为什么malloc不“用完”计算机上的内存?

检查一个目录。 readdir 返回的条目是目录、链接或文件。 dent->d_type 没有显示类型

linux - umask 对文本文件的影响

c - 警告 : assignment makes integer from pointer without a cast in shellsort algorithm

linux - 如何对 linux bash * 字母数字字符串进行排序

c# - 单元测试 : how to test methods with a lot of underlying objects and business logic