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

process: allow reading umask in workers #25526

Merged
merged 1 commit into from
Jan 17, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions doc/api/errors.md
Original file line number Diff line number Diff line change
@@ -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

3 changes: 2 additions & 1 deletion doc/api/process.md
Original file line number Diff line number Diff line change
@@ -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
4 changes: 4 additions & 0 deletions lib/internal/bootstrap/node.js
Original file line number Diff line number Diff line change
@@ -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
2 changes: 2 additions & 0 deletions lib/internal/errors.js
Original file line number Diff line number Diff line change
@@ -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);
21 changes: 20 additions & 1 deletion lib/internal/process/worker_thread_only.js
Original file line number Diff line number Diff line change
@@ -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
};
7 changes: 6 additions & 1 deletion src/node_process_methods.cc
Original file line number Diff line number Diff line change
@@ -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);
9 changes: 4 additions & 5 deletions test/common/index.js
Original file line number Diff line number Diff line change
@@ -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 &&
2 changes: 1 addition & 1 deletion test/parallel/test-fs-write-file-sync.js
Original file line number Diff line number Diff line change
@@ -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');
2 changes: 1 addition & 1 deletion test/parallel/test-process-umask-mask.js
Original file line number Diff line number Diff line change
@@ -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;

11 changes: 9 additions & 2 deletions test/parallel/test-process-umask.js
Original file line number Diff line number Diff line change
@@ -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;