process: allow reading umask in workers

Refs: https://github.com/nodejs/node/issues/25448
PR-URL: https://github.com/nodejs/node/pull/25526
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
This commit is contained in:
cjihrig 2019-01-15 15:39:43 -05:00
parent 1375af204a
commit f6cd4e3e59
No known key found for this signature in database
GPG Key ID: 7434390BDBE9B9C5
10 changed files with 54 additions and 12 deletions

View File

@ -1926,6 +1926,11 @@ All attempts at serializing an uncaught exception from a worker thread failed.
The pathname used for the main script of a worker has an
unknown file extension.
<a id="ERR_WORKER_UNSUPPORTED_OPERATION"></a>
### ERR_WORKER_UNSUPPORTED_OPERATION
The requested functionality is not supported in worker threads.
<a id="ERR_ZLIB_INITIALIZATION_FAILED"></a>
### ERR_ZLIB_INITIALIZATION_FAILED

View File

@ -2007,7 +2007,8 @@ console.log(
);
```
This feature is not available in [`Worker`][] threads.
[`Worker`][] threads are able to read the umask, however attempting to set the
umask will result in a thrown exception.
## process.uptime()
<!-- YAML

View File

@ -82,6 +82,10 @@ function startup() {
process._startProfilerIdleNotifier =
rawMethods._startProfilerIdleNotifier;
process._stopProfilerIdleNotifier = rawMethods._stopProfilerIdleNotifier;
} else {
const wrapped = workerThreadSetup.wrapProcessMethods(rawMethods);
process.umask = wrapped.umask;
}
// Set up methods on the process object for all threads

View File

@ -1001,4 +1001,6 @@ E('ERR_WORKER_UNSERIALIZABLE_ERROR',
E('ERR_WORKER_UNSUPPORTED_EXTENSION',
'The worker script extension must be ".js" or ".mjs". Received "%s"',
TypeError);
E('ERR_WORKER_UNSUPPORTED_OPERATION',
'%s is not supported in workers', TypeError);
E('ERR_ZLIB_INITIALIZATION_FAILED', 'Initialization failed', Error);

View File

@ -15,6 +15,10 @@ const {
WritableWorkerStdio
} = require('internal/worker/io');
const {
codes: { ERR_WORKER_UNSUPPORTED_OPERATION }
} = require('internal/errors');
let debuglog;
function debug(...args) {
if (!debuglog) {
@ -118,8 +122,23 @@ function createWorkerFatalExeception(port) {
};
}
// The execution of this function itself should not cause any side effects.
function wrapProcessMethods(binding) {
function umask(mask) {
// process.umask() is a read-only operation in workers.
if (mask !== undefined) {
throw new ERR_WORKER_UNSUPPORTED_OPERATION('Setting process.umask()');
}
return binding.umask(mask);
}
return { umask };
}
module.exports = {
initializeWorkerStdio,
createMessageHandler,
createWorkerFatalExeception
createWorkerFatalExeception,
wrapProcessMethods
};

View File

@ -50,6 +50,10 @@ using v8::Uint32;
using v8::Uint32Array;
using v8::Value;
namespace per_process {
Mutex umask_mutex;
} // namespace per_process
// Microseconds in a second, as a float, used in CPUUsage() below
#define MICROS_PER_SEC 1e6
// used in Hrtime() below
@ -220,6 +224,7 @@ static void Umask(const FunctionCallbackInfo<Value>& args) {
CHECK_EQ(args.Length(), 1);
CHECK(args[0]->IsUndefined() || args[0]->IsUint32());
Mutex::ScopedLock scoped_lock(per_process::umask_mutex);
if (args[0]->IsUndefined()) {
old = umask(0);
@ -396,9 +401,9 @@ static void InitializeProcessMethods(Local<Object> target,
target, "_stopProfilerIdleNotifier", StopProfilerIdleNotifier);
env->SetMethod(target, "abort", Abort);
env->SetMethod(target, "chdir", Chdir);
env->SetMethod(target, "umask", Umask);
}
env->SetMethod(target, "umask", Umask);
env->SetMethod(target, "_rawDebug", RawDebug);
env->SetMethod(target, "memoryUsage", MemoryUsage);
env->SetMethod(target, "cpuUsage", CPUUsage);

View File

@ -33,21 +33,20 @@ const {
bits,
hasIntl
} = process.binding('config');
const { isMainThread } = require('worker_threads');
// Some tests assume a umask of 0o022 so set that up front. Tests that need a
// different umask will set it themselves.
//
// process.umask() is not available in workers so we need to check for its
// existence.
if (process.umask)
// Workers can read, but not set the umask, so check that this is the main
// thread.
if (isMainThread)
process.umask(0o022);
const noop = () => {};
const hasCrypto = Boolean(process.versions.openssl);
const { isMainThread } = require('worker_threads');
// Check for flags. Skip this for workers (both, the `cluster` module and
// `worker_threads`) and child processes.
if (process.argv.length === 2 &&

View File

@ -23,7 +23,7 @@
const common = require('../common');
if (!common.isMainThread)
common.skip('process.umask is not available in Workers');
common.skip('Setting process.umask is not supported in Workers');
const assert = require('assert');
const path = require('path');

View File

@ -7,7 +7,7 @@ const common = require('../common');
const assert = require('assert');
if (!common.isMainThread)
common.skip('process.umask is not available in Workers');
common.skip('Setting process.umask is not supported in Workers');
let mask;

View File

@ -22,8 +22,15 @@
'use strict';
const common = require('../common');
const assert = require('assert');
if (!common.isMainThread)
common.skip('process.umask is not available in Workers');
if (!common.isMainThread) {
assert.strictEqual(typeof process.umask(), 'number');
assert.throws(() => {
process.umask('0664');
}, { code: 'ERR_WORKER_UNSUPPORTED_OPERATION' });
common.skip('Setting process.umask is not supported in Workers');
}
// Note in Windows one can only set the "user" bits.
let mask;