mirror of
https://github.com/denoland/deno.git
synced 2024-12-24 08:09:08 -05:00
Add Deno.umask (#4290)
This commit is contained in:
parent
6443e4aed1
commit
8078d976d2
7 changed files with 80 additions and 0 deletions
|
@ -113,6 +113,7 @@ export { symlinkSync, symlink } from "./ops/fs/symlink.ts";
|
||||||
export { connectTLS, listenTLS } from "./tls.ts";
|
export { connectTLS, listenTLS } from "./tls.ts";
|
||||||
export { truncateSync, truncate } from "./ops/fs/truncate.ts";
|
export { truncateSync, truncate } from "./ops/fs/truncate.ts";
|
||||||
export { isatty, setRaw } from "./ops/tty.ts";
|
export { isatty, setRaw } from "./ops/tty.ts";
|
||||||
|
export { umask } from "./ops/fs/umask.ts";
|
||||||
export { utimeSync, utime } from "./ops/fs/utime.ts";
|
export { utimeSync, utime } from "./ops/fs/utime.ts";
|
||||||
export { version } from "./version.ts";
|
export { version } from "./version.ts";
|
||||||
export { writeFileSync, writeFile, WriteFileOptions } from "./write_file.ts";
|
export { writeFileSync, writeFile, WriteFileOptions } from "./write_file.ts";
|
||||||
|
|
8
cli/js/lib.deno.ns.d.ts
vendored
8
cli/js/lib.deno.ns.d.ts
vendored
|
@ -287,6 +287,14 @@ declare namespace Deno {
|
||||||
*/
|
*/
|
||||||
export function chdir(directory: string): void;
|
export function chdir(directory: string): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* **UNSTABLE**: New API. Maybe needs permissions.
|
||||||
|
*
|
||||||
|
* If `mask` is provided, sets the process umask. Always returns what the umask
|
||||||
|
* was before the call.
|
||||||
|
*/
|
||||||
|
export function umask(mask?: number): number;
|
||||||
|
|
||||||
/** **UNSTABLE**: might move to `Deno.symbols`. */
|
/** **UNSTABLE**: might move to `Deno.symbols`. */
|
||||||
export const EOF: unique symbol;
|
export const EOF: unique symbol;
|
||||||
export type EOF = typeof EOF;
|
export type EOF = typeof EOF;
|
||||||
|
|
12
cli/js/ops/fs/umask.ts
Normal file
12
cli/js/ops/fs/umask.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||||
|
import { sendSync } from "../dispatch_json.ts";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* **UNSTABLE**: maybe needs `allow-env` permissions.
|
||||||
|
*
|
||||||
|
* If `mask` is provided, sets the process umask. Always returns what the umask
|
||||||
|
* was before the call.
|
||||||
|
*/
|
||||||
|
export function umask(mask?: number): number {
|
||||||
|
return sendSync("op_umask", { mask });
|
||||||
|
}
|
16
cli/js/tests/umask_test.ts
Normal file
16
cli/js/tests/umask_test.ts
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||||
|
import { unitTest, assertEquals } from "./test_util.ts";
|
||||||
|
|
||||||
|
unitTest(
|
||||||
|
{
|
||||||
|
skip: Deno.build.os === "win"
|
||||||
|
},
|
||||||
|
function umaskSuccess(): void {
|
||||||
|
const prevMask = Deno.umask(0o020);
|
||||||
|
const newMask = Deno.umask(prevMask);
|
||||||
|
const finalMask = Deno.umask();
|
||||||
|
assertEquals(newMask, 0o020);
|
||||||
|
assertEquals(finalMask, prevMask);
|
||||||
|
assertEquals(prevMask, 0o022);
|
||||||
|
}
|
||||||
|
);
|
|
@ -57,6 +57,7 @@ import "./timers_test.ts";
|
||||||
import "./tls_test.ts";
|
import "./tls_test.ts";
|
||||||
import "./truncate_test.ts";
|
import "./truncate_test.ts";
|
||||||
import "./tty_test.ts";
|
import "./tty_test.ts";
|
||||||
|
import "./umask_test.ts";
|
||||||
import "./url_test.ts";
|
import "./url_test.ts";
|
||||||
import "./url_search_params_test.ts";
|
import "./url_search_params_test.ts";
|
||||||
import "./utime_test.ts";
|
import "./utime_test.ts";
|
||||||
|
|
|
@ -71,6 +71,10 @@ impl OpError {
|
||||||
Self::new(ErrorKind::NotFound, msg)
|
Self::new(ErrorKind::NotFound, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn not_implemented() -> Self {
|
||||||
|
Self::other("not implemented".to_string())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn other(msg: String) -> Self {
|
pub fn other(msg: String) -> Self {
|
||||||
Self::new(ErrorKind::Other, msg)
|
Self::new(ErrorKind::Other, msg)
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ use std::os::unix::fs::{MetadataExt, PermissionsExt};
|
||||||
pub fn init(i: &mut Isolate, s: &State) {
|
pub fn init(i: &mut Isolate, s: &State) {
|
||||||
i.register_op("op_open", s.stateful_json_op(op_open));
|
i.register_op("op_open", s.stateful_json_op(op_open));
|
||||||
i.register_op("op_seek", s.stateful_json_op(op_seek));
|
i.register_op("op_seek", s.stateful_json_op(op_seek));
|
||||||
|
i.register_op("op_umask", s.stateful_json_op(op_umask));
|
||||||
i.register_op("op_chdir", s.stateful_json_op(op_chdir));
|
i.register_op("op_chdir", s.stateful_json_op(op_chdir));
|
||||||
i.register_op("op_mkdir", s.stateful_json_op(op_mkdir));
|
i.register_op("op_mkdir", s.stateful_json_op(op_mkdir));
|
||||||
i.register_op("op_chmod", s.stateful_json_op(op_chmod));
|
i.register_op("op_chmod", s.stateful_json_op(op_chmod));
|
||||||
|
@ -221,6 +222,43 @@ fn op_seek(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct UmaskArgs {
|
||||||
|
mask: Option<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn op_umask(
|
||||||
|
_state: &State,
|
||||||
|
args: Value,
|
||||||
|
_zero_copy: Option<ZeroCopyBuf>,
|
||||||
|
) -> Result<JsonOp, OpError> {
|
||||||
|
let args: UmaskArgs = serde_json::from_value(args)?;
|
||||||
|
// TODO implement umask for Windows
|
||||||
|
// see https://github.com/nodejs/node/blob/master/src/node_process_methods.cc
|
||||||
|
// and https://docs.microsoft.com/fr-fr/cpp/c-runtime-library/reference/umask?view=vs-2019
|
||||||
|
#[cfg(not(unix))]
|
||||||
|
{
|
||||||
|
let _ = args.mask; // avoid unused warning.
|
||||||
|
return Err(OpError::not_implemented());
|
||||||
|
}
|
||||||
|
#[cfg(unix)]
|
||||||
|
{
|
||||||
|
use nix::sys::stat::mode_t;
|
||||||
|
use nix::sys::stat::umask;
|
||||||
|
use nix::sys::stat::Mode;
|
||||||
|
let r = if let Some(mask) = args.mask {
|
||||||
|
// If mask provided, return previous.
|
||||||
|
umask(Mode::from_bits_truncate(mask as mode_t))
|
||||||
|
} else {
|
||||||
|
// If no mask provided, we query the current. Requires two syscalls.
|
||||||
|
let prev = umask(Mode::from_bits_truncate(0o777));
|
||||||
|
let _ = umask(prev);
|
||||||
|
prev
|
||||||
|
};
|
||||||
|
Ok(JsonOp::Sync(json!(r.bits() as u32)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct ChdirArgs {
|
struct ChdirArgs {
|
||||||
directory: String,
|
directory: String,
|
||||||
|
|
Loading…
Reference in a new issue