Skip to content

Commit

Permalink
UVStream, bugfix: make fd of stdio work in blocking mode. (#623)
Browse files Browse the repository at this point in the history
  • Loading branch information
richardo2016 committed Nov 26, 2020
1 parent 1c1930f commit b0c58bb
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 2 deletions.
15 changes: 13 additions & 2 deletions fibjs/include/UVStream.h
Expand Up @@ -14,6 +14,11 @@

namespace fibjs {

inline bool is_stdio_fd(int32_t fd)
{
return fd >= 0 && fd <= 2;
}

class UVStream : public Stream_base {
FIBER_FREE();

Expand All @@ -26,7 +31,13 @@ class UVStream : public Stream_base {
memset(&m_pipe, 0, sizeof(uv_pipe_t));
uv_call([&] {
uv_pipe_init(s_uv_loop, &m_pipe, 0);
return uv_pipe_open(&m_pipe, fd);

int ret = uv_pipe_open(&m_pipe, fd);

if (ret == 0 && is_stdio_fd(fd))
ret = uv_stream_set_blocking((uv_stream_t*)&m_pipe, 1);

return ret;
});
}

Expand Down Expand Up @@ -130,7 +141,7 @@ class UVStream : public Stream_base {
virtual result_t get_fd(int32_t& retVal)
{
#ifdef _WIN32
if (m_fd >= 0 && m_fd <= 2) {
if (is_stdio_fd(m_fd)) {
retVal = m_fd;

return 0;
Expand Down
8 changes: 8 additions & 0 deletions test/process/exec.blocking_stdin.js
@@ -0,0 +1,8 @@
/**
* @see https://github.com/fibjs/fibjs/issues/620
*
* you can access process.std, and `console.readLine()` normally.
*/
process.stdin
process.exitCode = 1;
console.log(console.readLine());
10 changes: 10 additions & 0 deletions test/process/exec.blocking_stdout.js
@@ -0,0 +1,10 @@
/**
* @see https://github.com/fibjs/fibjs/issues/622
*
* you can use stdio as you thought based on libuv
*/
process.stdout
const len = parseInt(process.env.COUNT_LEN);
Array.apply(null, { length: len }).fill(undefined).forEach((_, idx) => {
console.log(`${idx + 1}`)
})
47 changes: 47 additions & 0 deletions test/process_test.js
Expand Up @@ -57,6 +57,53 @@ describe('process', () => {
});
});

/**
* @why issues: #620, #622
*/
describe("access process.std[xx]", () => {
const child_process = require('child_process');
const io = require('io');
const os = require('os');

process.env.CI && it("test process.stdout in this proc", () => {
// access it
process.stdout;

const LEN = 100
console.log(`you could see ${LEN} lines to ouput 1~${LEN}`)
const str = Array.apply(null, { length: LEN }).fill(undefined).map((_, idx) => {
return `${idx + 1}`
})

console.log(str)
});

it("test process.stdin in child process", () => {
var bs = child_process.spawn(cmd, [path.join(__dirname, 'process', 'exec.blocking_stdin.js')]);
var stdin = new io.BufferedStream(bs.stdin);
var stdout = new io.BufferedStream(bs.stdout);

stdin.write("hello, blocking_std" + os.EOL);
assert.equal(stdout.readLine(), "hello, blocking_std");
});

it("test process.stdout in child process", () => {
const COUNT_LEN = 500;
var bs = child_process.spawn(cmd, [path.join(__dirname, 'process', 'exec.blocking_stdout.js')], {
env: {
COUNT_LEN
}
});
var stdout = new io.BufferedStream(bs.stdout);

var strs = Array.apply(null, { length: COUNT_LEN }).fill(undefined).map((_, idx) => {
return `${idx + 1}`
})

assert.deepEqual(stdout.readLines(), strs);
});
});

xdescribe("ppid", () => {
it("basic", () => {
assert.property(process, 'ppid');
Expand Down

0 comments on commit b0c58bb

Please sign in to comment.