-
-
Notifications
You must be signed in to change notification settings - Fork 33.5k
Description
- Version: v10.15.0
- Platform: OS400 wernstrom 2 7 0010000ACBAA Os
- Subsystem: fs
Since upgrade of libuv to 1.23.2 in #23336, fs.readFile on a directory on the IBM i platform returns "Unknown system error -64" instead of EISDIR
. (64 is EOPNOTSUPP
on IBM i/PASE). Reproducing the problem is really easy:
node -e "try { require('fs').readFileSync('.') } catch(err) { console.log(err.code) }"
On Linux and macOS, this returns EISDIR
, while on IBM i this now returns "Unknown system error -64".
This was changed in libuv/libuv#2025 to allow AIX to read a directory, since it's supported there (as in many BSDs and other OSes) and remove the performance penalty of doing a stat call for each read. Since the PASE environment where Node.js runs on IBM i is an AIX-like environment, this affected our platform as well, but unlike AIX, PASE does not support reading from directories.
The net result of this, is that global npm install are broken, due to gentle-fs assuming that reading from a directory will return EISDIR
or ENOTASHIM
: https://github.com/npm/gentle-fs/blob/latest/lib/rm.js#L245-L248
So the question is what should happen here? I think at a minimum, err.code should be "EOPNOTSUPP" instead of "Unknown system error -64", but that still wouldn't actually fix the gentle-fs issue. libuv was deliberately changed due to the performance of the stat on each read, while gentle-fs has already done a stat and didn't bother to check if it was a directory first. gentle-fs could add a stat.isDirectory()
check prior to calling readCmdShim
, but I don't know enough about Windows to know if a cmd shim can be a directory. The other option is to standardize on the EISDIR
behavior and convert the EOPNOTSUPP
on IBM i to EISDIR
, but is then the question is whether that should happen in libuv or in Node.