help icon indicating copy to clipboard operation
help copied to clipboard

cause error in uv_pipe_open(stdin/stdout)

Open jc-lab opened this issue 5 years ago • 6 comments

  • Version: Many versions (Maybe all)...
  • Platform: Windows 10 1903

Same error : https://groups.google.com/forum/#!msg/libuv/iYmwxzRyemU/BBDeikdBBAAJ

int main(int argc, char **argv) {
    loop = uv_default_loop();

    uv_pipe_init(loop, &stdin_pipe, 0);
    uv_pipe_open(&stdin_pipe, 0); // <---------- return UV_EINVAL

    uv_pipe_init(loop, &stdout_pipe, 0);
    uv_pipe_open(&stdout_pipe, 1);
    
    uv_fs_t file_req;
    int fd = uv_fs_open(loop, &file_req, argv[1], O_CREAT | O_RDWR, 0644, NULL);
    uv_pipe_init(loop, &file_pipe, 0);
    uv_pipe_open(&file_pipe, fd);

    uv_read_start((uv_stream_t*)&stdin_pipe, alloc_buffer, read_stdin);

    uv_run(loop, UV_RUN_DEFAULT);
    return 0;
}

Seems like a long time ago. Still not fixed?

jc-lab avatar Dec 27 '19 02:12 jc-lab

You're trying to open file descriptor 0 but that isn't a name pipe, it's the console. What exactly is unexpected?

bnoordhuis avatar Dec 27 '19 09:12 bnoordhuis

@bnoordhuis

Hello, bnoordhuis. The opening file descriptor 0 is intentional. I want to use stdin and stdout via libuv. I attach the actual test code. The funny thing is that when I run it in CLion(JetBrains) it runs fine. But on Windows console I get the error as below.

test code:

#include <string>
#include <iostream>
#include <stdio.h>
#include <uv.h>

static void my_alloc_cb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
	buf->base = (char*)malloc(suggested_size);
	buf->len = suggested_size;
}

static void read_stdin_cb(uv_stream_t* stream,
	ssize_t nread,
	const uv_buf_t* buf) {
	std::string temp(buf->base, buf->len);
	std::cerr << "STDIN: " << temp << std::endl;
}

int main(int argc, char **argv)
{
	uv_loop_t *loop = uv_default_loop();
	uv_pipe_t stdin_pipe = { 0 };
	uv_pipe_t stdout_pipe = { 0 };

	int res;

	uv_pipe_init(loop, &stdin_pipe, 0);
	res = uv_pipe_open(&stdin_pipe, 0); // <---------- return UV_EINVAL
	std::cerr << "open stdin : " << res << std::endl;

	uv_pipe_init(loop, &stdout_pipe, 0);
	uv_pipe_open(&stdout_pipe, 1);
	std::cerr << "open stdout : " << res << std::endl;

	uv_read_start((uv_stream_t*)&stdin_pipe, my_alloc_cb, read_stdin_cb);

	uv_run(loop, UV_RUN_DEFAULT);

	return 0;
}

console out:

open stdin : -4071 open stdout : -4071

jc-lab avatar Dec 27 '19 12:12 jc-lab

I want to use stdin and stdout via libuv.

Then why don't you use uv_tty_init() with a uv_tty_t handle?

The funny thing is that when I run it in CLion(JetBrains) it runs fine.

That's because clion's terminal emulator uses a named pipe to capture the output.

bnoordhuis avatar Dec 27 '19 13:12 bnoordhuis

@bnoordhuis

I also tried tty but it didn't work in all cases.

If run with CreateProcess in windows or child_process in node.js, the tty will not work.

jc-lab avatar Dec 27 '19 13:12 jc-lab

https://github.com/libuv/libuv/blob/af45b6ba2f2c506ae18dd24481e24db17b8269e7/src/win/pipe.c#L271

In the code above, I get an ERROR_INVALID_FUNCTION error. But if ignore the above error, the read to stdin will work fine.

jc-lab avatar Dec 27 '19 13:12 jc-lab

Right, you're looking for a one-stop solution but there isn't one - libuv doesn't paper over such details. You need to switch between uv_pipe_t, uv_tty_t, etc. depending on the return value of uv_guess_handle().

I'm moving this to libuv/help because everything is working as expected as far as libuv is concerned.

bnoordhuis avatar Dec 27 '19 13:12 bnoordhuis