首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >fgetc不会返回到进程

fgetc不会返回到进程
EN

Stack Overflow用户
提问于 2022-08-09 05:01:40
回答 1查看 65关注 0票数 0

我正在尝试执行类似echo {a:1} | prettier --stdin-filepath index.js的操作,并返回stdout中返回的值。但我也想让这个程序平台独立。

引用,我成功地编写了如下代码:

代码语言:javascript
复制
#include <Windows.h>
#include <fcntl.h>
#include <io.h>
#include <iostream>
#include <stdexcept>

HANDLE hChildStd_IN_Rd = NULL;
HANDLE hChildStd_IN_Wr = NULL;
HANDLE hChildStd_OUT_Rd = NULL;
HANDLE hChildStd_OUT_Wr = NULL;

int main() {
  const char source_code[] = "{a:1}";

  FILE *fd_OUT = nullptr, *fd_IN = nullptr;
#ifdef _WIN32
  try {
    SECURITY_ATTRIBUTES saAttr{};
    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
    saAttr.bInheritHandle = TRUE;
    saAttr.lpSecurityDescriptor = NULL;

    if (!CreatePipe(&hChildStd_OUT_Rd, &hChildStd_OUT_Wr, &saAttr, 0))
      throw std::runtime_error("StdoutRd CreatePipe");
    if (!SetHandleInformation(hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0))
      throw std::runtime_error("Stdout SetHandleInformation");
    if (!CreatePipe(&hChildStd_IN_Rd, &hChildStd_IN_Wr, &saAttr, 0))
      throw std::runtime_error("Stdin CreatePipe");
    if (!SetHandleInformation(hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0))
      throw std::runtime_error("Stdin SetHandleInformation");

    TCHAR szCmdline[] = TEXT(
        "C:\\Users\\yuto0214w\\AppData\\Roaming\\npm\\prettier.cmd "
        "--stdin-filepath index.js");

    PROCESS_INFORMATION piProcInfo;
    STARTUPINFO siStartInfo;
    ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));
    ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));

    siStartInfo.cb = sizeof(STARTUPINFO);
    siStartInfo.hStdError = hChildStd_OUT_Wr;
    siStartInfo.hStdOutput = hChildStd_OUT_Wr;
    siStartInfo.hStdInput = hChildStd_IN_Rd;
    siStartInfo.dwFlags |= STARTF_USESTDHANDLES;

    if (!CreateProcess(NULL, szCmdline, NULL, NULL, TRUE, 0, NULL, NULL,
                       &siStartInfo, &piProcInfo))
      throw std::runtime_error("CreateProcess");

    CloseHandle(piProcInfo.hProcess);
    CloseHandle(piProcInfo.hThread);
    CloseHandle(hChildStd_OUT_Wr);
    CloseHandle(hChildStd_IN_Rd);

    fd_OUT = _fdopen(_open_osfhandle((intptr_t)hChildStd_OUT_Rd, _O_RDONLY), "r");
    fd_IN = _fdopen(_open_osfhandle((intptr_t)hChildStd_IN_Wr, _O_WRONLY), "w");
  } catch (std::exception& e) {
    std::cout << std::string("Encountered an error when running: ") + e.what()
              << std::endl;
    return 1;
  }
#else
  // pipe fork dup2 execlp fdopen
#endif
  fputs(source_code, fd_IN);

  std::string formatted_code;
  int c;
  while ((c = fgetc(fd_OUT)) != EOF) {
    formatted_code += c;
    std::cout << "ch: " << c << std::endl; // For testing
  }

  fclose(fd_OUT);
  fclose(fd_IN);

  std::cout << formatted_code << std::endl;

  return 0;
}

这将编译,但在fgetc上完全停止。我的意思是完全停止它没有显示任何ch:

我用MSVC v143编写了程序。

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-11 02:37:16

问题是,在阅读fd_IN之前,我并没有关闭fd_OUT

这会导致死锁,因为更漂亮的程序正在等待程序的输入,而程序正在等待更漂亮的程序的输出。

为了解决这个问题,

代码语言:javascript
复制
  fputs(source_code, fd_IN);
  fclose(fd_IN);

  std::string formatted_code;
  int c;
  while ((c = fgetc(fd_OUT)) != EOF) {
    formatted_code += c;
    std::cout << "ch: " << c << std::endl; // For testing
  }

  fclose(fd_OUT);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73286731

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档