我正在尝试执行类似echo {a:1} | prettier --stdin-filepath index.js的操作,并返回stdout中返回的值。但我也想让这个程序平台独立。
#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编写了程序。
谢谢
发布于 2022-08-11 02:37:16
问题是,在阅读fd_IN之前,我并没有关闭fd_OUT。
这会导致死锁,因为更漂亮的程序正在等待程序的输入,而程序正在等待更漂亮的程序的输出。
为了解决这个问题,
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);https://stackoverflow.com/questions/73286731
复制相似问题