Skip to content

Commit d99b7bc

Browse files
ebraminiojasnell
authored andcommitted
fs: fix realpath{Sync} on resolving pipes/sockets
PR-URL: #13028 Reviewed-By: Refael Ackermann <[email protected]>
1 parent f077e51 commit d99b7bc

File tree

3 files changed

+59
-5
lines changed

3 files changed

+59
-5
lines changed

doc/api/fs.md

+12
Original file line numberDiff line numberDiff line change
@@ -1840,6 +1840,9 @@ Synchronous version of [`fs.read()`][]. Returns the number of `bytesRead`.
18401840
<!-- YAML
18411841
added: v0.1.31
18421842
changes:
1843+
- version: REPLACEME
1844+
pr-url: https://github.com/nodejs/node/pull/13028
1845+
description: Pipe/Socket resolve support was added.
18431846
- version: v7.6.0
18441847
pr-url: https://github.com/nodejs/node/pull/10739
18451848
description: The `path` parameter can be a WHATWG `URL` object using
@@ -1872,10 +1875,16 @@ object with an `encoding` property specifying the character encoding to use for
18721875
the path passed to the callback. If the `encoding` is set to `'buffer'`,
18731876
the path returned will be passed as a `Buffer` object.
18741877

1878+
*Note*: If `path` resolves to a socket or a pipe, the function will return a
1879+
system dependent name for that object.
1880+
18751881
## fs.realpathSync(path[, options])
18761882
<!-- YAML
18771883
added: v0.1.31
18781884
changes:
1885+
- version: REPLACEME
1886+
pr-url: https://github.com/nodejs/node/pull/13028
1887+
description: Pipe/Socket resolve support was added.
18791888
- version: v7.6.0
18801889
pr-url: https://github.com/nodejs/node/pull/10739
18811890
description: The `path` parameter can be a WHATWG `URL` object using
@@ -1902,6 +1911,9 @@ object with an `encoding` property specifying the character encoding to use for
19021911
the returned value. If the `encoding` is set to `'buffer'`, the path returned
19031912
will be passed as a `Buffer` object.
19041913

1914+
*Note*: If `path` resolves to a socket or a pipe, the function will return a
1915+
system dependent name for that object.
1916+
19051917
## fs.rename(oldPath, newPath, callback)
19061918
<!-- YAML
19071919
added: v0.0.2

lib/fs.js

+13-5
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
'use strict';
2626

2727
const constants = process.binding('constants').fs;
28-
const { S_IFMT, S_IFREG, S_IFLNK } = constants;
28+
const { S_IFIFO, S_IFLNK, S_IFMT, S_IFREG, S_IFSOCK } = constants;
2929
const util = require('util');
3030
const pathModule = require('path');
3131
const { isUint8Array } = process.binding('util');
@@ -228,11 +228,11 @@ Stats.prototype.isSymbolicLink = function() {
228228
};
229229

230230
Stats.prototype.isFIFO = function() {
231-
return this._checkModeProperty(constants.S_IFIFO);
231+
return this._checkModeProperty(S_IFIFO);
232232
};
233233

234234
Stats.prototype.isSocket = function() {
235-
return this._checkModeProperty(constants.S_IFSOCK);
235+
return this._checkModeProperty(S_IFSOCK);
236236
};
237237

238238
const statValues = binding.getStatValues();
@@ -1625,8 +1625,12 @@ fs.realpathSync = function realpathSync(p, options) {
16251625
pos = result + 1;
16261626
}
16271627

1628-
// continue if not a symlink
1628+
// continue if not a symlink, break if a pipe/socket
16291629
if (knownHard[base] || (cache && cache.get(base) === base)) {
1630+
if ((statValues[1/*mode*/] & S_IFMT) === S_IFIFO ||
1631+
(statValues[1/*mode*/] & S_IFMT) === S_IFSOCK) {
1632+
break;
1633+
}
16301634
continue;
16311635
}
16321636

@@ -1752,8 +1756,12 @@ fs.realpath = function realpath(p, options, callback) {
17521756
pos = result + 1;
17531757
}
17541758

1755-
// continue if not a symlink
1759+
// continue if not a symlink, break if a pipe/socket
17561760
if (knownHard[base]) {
1761+
if ((statValues[1/*mode*/] & S_IFMT) === S_IFIFO ||
1762+
(statValues[1/*mode*/] & S_IFMT) === S_IFSOCK) {
1763+
return callback(null, encodeRealpathResult(p, options));
1764+
}
17571765
return process.nextTick(LOOP);
17581766
}
17591767

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
5+
if (common.isWindows || common.isAix) {
6+
common.skip(`No /dev/stdin on ${process.platform}.`);
7+
return;
8+
}
9+
10+
const assert = require('assert');
11+
12+
const { spawnSync } = require('child_process');
13+
14+
for (const code of [
15+
`require('fs').realpath('/dev/stdin', (err, resolvedPath) => {
16+
if (err) {
17+
process.exit(1);
18+
}
19+
if (resolvedPath) {
20+
process.exit(2);
21+
}
22+
});`,
23+
`try {
24+
if (require('fs').realpathSync('/dev/stdin')) {
25+
process.exit(2);
26+
}
27+
} catch (e) {
28+
process.exit(1);
29+
}`
30+
]) {
31+
assert.strictEqual(spawnSync(process.execPath, ['-e', code], {
32+
stdio: 'pipe'
33+
}).status, 2);
34+
}

0 commit comments

Comments
 (0)