Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fs.writeSync truncates long lines #1541

Closed
segrey opened this issue Apr 27, 2015 · 12 comments
Closed

fs.writeSync truncates long lines #1541

segrey opened this issue Apr 27, 2015 · 12 comments
Labels
duplicate Issues and PRs that are duplicates of other issues or PRs. fs Issues and PRs related to the fs subsystem / file system.

Comments

@segrey
Copy link

segrey commented Apr 27, 2015

iojs 1.8.1
Linux Mint 17, x64, 3.13.0-24

function formatString(n) {
  var str = '';
  while (str.length < n) {
    str = str + ' ' + str.length;
  }
  return str;
}

var fs = require('fs')
  , str = formatString(100000)
  , buffer = new Buffer(str + '\n', 'utf8');

fs.writeSync(process.stdout.fd, buffer, 0, buffer.length, null);

Running this script produces a truncated output. Here is a tail of it ... 77530 77536 77542 77548 77554 77560 7.

Replacing fs.writeSync(process.stdout.fd, buffer, 0, buffer.length, null) with console.log(str) changes output. Now the full string is output correctly. Tail is ... 9964 99970 99976 99982 99988 99994.

@mscdex mscdex added the fs Issues and PRs related to the fs subsystem / file system. label Apr 28, 2015
@monsanto
Copy link
Contributor

(I made/deleted an incorrect comment earlier -- sorry) This only happens for me when process.stdout.fd is a TTY. If you redirect the output of this script to a file it seems to work fine.

@monsanto
Copy link
Contributor

Maybe this will be useful to someone with familiarity w/ libuv. The last good commit (that can build) was b444392 @ v0.11.12-pre, right before upgrading libuv to v0.11.22

git bisect start
# bad: [fd896d5acfe0832cfb211d861f78845bcad4f301] 2014.09.24, Version 0.11.14 (Unstable)
git bisect bad fd896d5acfe0832cfb211d861f78845bcad4f301
# bad: [547213913b2e1525c15968916452995ab14e2195] test: adjust Makefile/test-ci, add to vcbuild.bat
git bisect bad 547213913b2e1525c15968916452995ab14e2195
# good: [84952da24192da98746573f1086b7f393f423a3c] Now working on 0.10.33
git bisect good 84952da24192da98746573f1086b7f393f423a3c
# bad: [e643fe4c4b79f2683914c6435f7166fc6be9f1a7] dns: fix GetAddrInfo assert
git bisect bad e643fe4c4b79f2683914c6435f7166fc6be9f1a7
# good: [2e13d0ce17d75b30db22dea058f35207ecf1ad66] fs: remove duplicate !options case
git bisect good 2e13d0ce17d75b30db22dea058f35207ecf1ad66
# good: [c0d81f90996667a658aa4403123e02161262506a] process: allow changing `exitCode` in `on('exit')`
git bisect good c0d81f90996667a658aa4403123e02161262506a
# bad: [d0fc5538d1ac769885c7e449b0d1f6759a7d4230] stream: split `objectMode` for Duplex
git bisect bad d0fc5538d1ac769885c7e449b0d1f6759a7d4230
# bad: [e496707d3971d45cd0b9f4147ce6abe00e7d6cf1] mdb_v8: update to latest version
git bisect bad e496707d3971d45cd0b9f4147ce6abe00e7d6cf1
# good: [78a854f8721693cf9a9b33136b485825bfff2142] test: move pummel/test-fs-largefile to disabled
git bisect good 78a854f8721693cf9a9b33136b485825bfff2142
# good: [f3189ace6b5e31a874df421ac2f74da0e77cb14d] http: remove the circular dependency
git bisect good f3189ace6b5e31a874df421ac2f74da0e77cb14d
# good: [78d245f5b21eede58e79138330690d63cf3d86f8] Merge remote-tracking branch 'origin/v0.10'
git bisect good 78d245f5b21eede58e79138330690d63cf3d86f8
# good: [a18c9b7dde22cce6cec5d47cfd6a16694c9992e8] test: timers-ordering should be more precise
git bisect good a18c9b7dde22cce6cec5d47cfd6a16694c9992e8
# skip: [e92d35d80be6e193cb547e94c6fbf3654542dbaa] uv: Upgrade to v0.11.22
git bisect skip e92d35d80be6e193cb547e94c6fbf3654542dbaa
# skip: [d2f2a32b897840d91cf240830ad5cf5f0e33a0c8] src: adapt to API change in uv_cwd
git bisect skip d2f2a32b897840d91cf240830ad5cf5f0e33a0c8
# good: [b444392a98e66b49dfee8c7e36c59d4e7c6ea1ac] Merge remote-tracking branch 'upstream/v0.10'
git bisect good b444392a98e66b49dfee8c7e36c59d4e7c6ea1ac
# bad: [e2fcfea46e334743aed24993eeebb2482c6ea762] src: update from uv_read2_start removal
git bisect bad e2fcfea46e334743aed24993eeebb2482c6ea762
# only skipped commits left to test
# possible first bad commit: [e2fcfea46e334743aed24993eeebb2482c6ea762] src: update from uv_read2_start removal
# possible first bad commit: [d2f2a32b897840d91cf240830ad5cf5f0e33a0c8] src: adapt to API change in uv_cwd
# possible first bad commit: [e92d35d80be6e193cb547e94c6fbf3654542dbaa] uv: Upgrade to v0.11.22

I'll add that I've experienced this one in the wild--when I encountered it, I thought it was the process.send regression so I didn't investigate further. Turns out it is something different.

@ChALkeR
Copy link
Member

ChALkeR commented Apr 28, 2015

Ok, this is an off-topic, but never do that type of string concatenation in javascript.
In real-world apps, I mean.

@segrey
Copy link
Author

segrey commented Apr 28, 2015

@ChALkeR Sorry for this kind of concatenation. It's for demonstration purposes only. Performance-friendly version would be more complicated obscuring the overall idea of formatString as it seems to me.

@bnoordhuis
Copy link
Member

I suspect it is caused by libuv/libuv@b197515 but I'm not sure it qualifies as a regression.

The tty file descriptor is non-blocking now whenever possible; I don't think the documentation made any promises about the blocking or non-blocking nature of process.stdout.fd or indeed even documented its existence.

For the record, what happens is a partial write:

write(1, " 0 2 4 6 8 10 13 16 19 22 25 28 "..., 100001) = 90112

You don't have that issue with process.stdout.write() because it keeps the event loop alive until the string is fully written.

@segrey
Copy link
Author

segrey commented Apr 28, 2015

JFYI The issue is also reproducible for me when running ~/.nvm/versions/io.js/v1.8.1/bin/iojs test.js | less, i.e. when the file descriptor is a PIPE. In that case the tail of output is ... 65512 65518 65524 65530.

@monsanto
Copy link
Contributor

@bnoordhuis If I keep the event loop alive with a timer, it still does not finish writing. It was my understanding that libuv retries writes (or at least that the fs functions retry writes), is this incorrect?

@bnoordhuis
Copy link
Member

You mean with fs.writeSync()? It does a partial write and returns the number of bytes written. It doesn't retry.

@alexlamsl
Copy link

FWIW, the example works as expected on Windows (10 x64) with io.js 1.8.1

@monsanto
Copy link
Contributor

@bnoordhuis Sorry for the confusion.

There is still a problem here though. You can reproduce this issue with process.stdout.write by simply putting a process.exit() afterwards. The docs say that that process.stdout.write is blocking for TTYs and pipes so this should not happen.

Merging #774 fixes pipes, but not TTYs.

For an example of a regression in the wild, see autoprefixer.

@Fishrock123
Copy link
Contributor

Actually a duplicate of #784

@Fishrock123 Fishrock123 added the duplicate Issues and PRs that are duplicates of other issues or PRs. label Jul 1, 2015
@rheaton
Copy link

rheaton commented Feb 12, 2018

bitmoji

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
duplicate Issues and PRs that are duplicates of other issues or PRs. fs Issues and PRs related to the fs subsystem / file system.
Projects
None yet
Development

No branches or pull requests

8 participants