Skip to content

Commit

Permalink
process: allow reading umask in workers
Browse files Browse the repository at this point in the history
Refs: #25448
PR-URL: #25526
Reviewed-By: Ruben Bridgewater <[email protected]>
Reviewed-By: Michaël Zasso <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Joyee Cheung <[email protected]>
  • Loading branch information
cjihrig authored and addaleax committed Jan 23, 2019
1 parent ab86143 commit 07f1bb0
Show file tree
Hide file tree
Showing 10 changed files with 54 additions and 12 deletions.
5 changes: 5 additions & 0 deletions doc/api/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -1880,6 +1880,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

Expand Down
3 changes: 2 additions & 1 deletion doc/api/process.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions lib/internal/bootstrap/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions lib/internal/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -976,4 +976,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
Expand Up @@ -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) {
Expand Down Expand Up @@ -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
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
9 changes: 4 additions & 5 deletions test/common/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 &&
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-fs-write-file-sync.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-process-umask-mask.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;

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

0 comments on commit 07f1bb0

Please sign in to comment.