1// Copyright Joyent, Inc. and other Node contributors. 2// 3// Permission is hereby granted, free of charge, to any person obtaining a 4// copy of this software and associated documentation files (the 5// "Software"), to deal in the Software without restriction, including 6// without limitation the rights to use, copy, modify, merge, publish, 7// distribute, sublicense, and/or sell copies of the Software, and to permit 8// persons to whom the Software is furnished to do so, subject to the 9// following conditions: 10// 11// The above copyright notice and this permission notice shall be included 12// in all copies or substantial portions of the Software. 13// 14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20// USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22'use strict'; 23const common = require('../common'); 24if (common.isWindows) 25 common.skip('no RLIMIT_NOFILE on Windows'); 26 27const assert = require('assert'); 28const child_process = require('child_process'); 29const fs = require('fs'); 30 31const ulimit = Number(child_process.execSync('ulimit -Hn')); 32if (ulimit > 64 || Number.isNaN(ulimit)) { 33 // Sorry about this nonsense. It can be replaced if 34 // https://github.com/nodejs/node-v0.x-archive/pull/2143#issuecomment-2847886 35 // ever happens. 36 const result = child_process.spawnSync( 37 '/bin/sh', 38 ['-c', `ulimit -n 64 && '${process.execPath}' '${__filename}'`] 39 ); 40 assert.strictEqual(result.stdout.toString(), ''); 41 assert.strictEqual(result.stderr.toString(), ''); 42 assert.strictEqual(result.status, 0); 43 assert.strictEqual(result.error, undefined); 44 return; 45} 46 47const openFds = []; 48 49for (;;) { 50 try { 51 openFds.push(fs.openSync(__filename, 'r')); 52 } catch (err) { 53 assert.strictEqual(err.code, 'EMFILE'); 54 break; 55 } 56} 57 58// Should emit an error, not throw. 59const proc = child_process.spawn(process.execPath, ['-e', '0']); 60 61// Verify that stdio is not setup on EMFILE or ENFILE. 62assert.strictEqual(proc.stdin, undefined); 63assert.strictEqual(proc.stdout, undefined); 64assert.strictEqual(proc.stderr, undefined); 65assert.strictEqual(proc.stdio, undefined); 66 67proc.on('error', common.mustCall(function(err) { 68 assert.strictEqual(err.code, 'EMFILE'); 69})); 70 71proc.on('exit', common.mustNotCall('"exit" event should not be emitted')); 72 73// Close one fd for LSan 74if (openFds.length >= 1) { 75 fs.closeSync(openFds.pop()); 76} 77