在没有tty的情况下访问CONAN $

时间:2014-03-19 16:12:36

标签: windows cmd libuv

我正在尝试访问从控制台接收输入的文件描述符。我目前正在使用

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

的流错误

1 个答案:

答案 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 $。)