我正在尝试访问从控制台接收输入的文件描述符。我目前正在使用
HANDLE fd = CreateFile(
"CONIN$",
GENERIC_READ | GENERIC_WRITE,
TRUE,
0,
OPEN_EXISTING,
0,
0);
SetConsoleMode(fd, ENABLE_WINDOW_INPUT);
将fd返回到一个程序,该程序从控制台读取(基于libuv)输入。
当在控制台中执行该过程时,这可以正常工作,但是当我将输入输入到程序中时,读取fd会崩溃
echo hello | inputProgram
我怀疑没有与输入过程相关的控制台,但我不确定。如何以这种方式执行时,如何正确读取cmd窗口中的输入?
所以我在Node.js中绑定了这个C ++程序。我打电话给
var ReadStream = require("tty").ReadStream();
var TTY = process.binding("tty_wrap").TTY;
module.exports = function () {
var opentty = require("./bin/opentty.node") // program returns the fd int
var fd = opentty();
var t = new _TTY(fd, true);
return new ReadStream(t);
}
opentty在文件句柄的重定向输入模式下返回3。可以在此处找到处理此文件句柄的代码
https://github.com/joyent/node/blob/master/src/tty_wrap.cc#L185
基本上会调用此处的uv_tty_init
https://github.com/joyent/node/blob/master/deps/uv/src/win/tty.c#L99
使用Error: read EBADF
,syscall:read
答案 0 :(得分:1)
通过Node存储库可以清楚地看到new _TTY(fd, true)
期待一个C文件描述符,但是你将它传递给Win32句柄。
_open_osfhandle
函数从句柄创建文件描述符。
所以,你应该试试
var t = new _TTY(_open_osfhandle(fd), true);
(正如评论中所讨论的,只有在您与libuv共享C运行时才会有效。)
理想情况下,您会使用libuv的开放功能,但不幸的是fs__open中存在错误:
case _O_RDWR:
access = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
这是决定请求哪些访问权限的地方。顾名思义,FILE_GENERIC_WRITE和FILE_GENERIC_READ特定于文件,不能用于打开CONIN $。它应该是
case _O_RDWR:
access = GENERIC_READ | GENERIC_WRITE;
适用于文件和其他类型的对象,例如控制台输入和输出。 (我在一个简单的C程序中重现了这个;在我的系统上,使用FILE_ *权限肯定会阻止你打开CONIN $。)