mirror of
https://github.com/denoland/deno.git
synced 2025-01-12 00:54:02 -05:00
fix(runtime/fs): preserve permissions in copyFileSync for macOS (#17412)
Fixes https://github.com/denoland/deno/issues/16921
This commit is contained in:
parent
68782346d0
commit
ae2981d7ac
2 changed files with 46 additions and 2 deletions
|
@ -209,3 +209,30 @@ Deno.test(
|
||||||
}, Deno.errors.PermissionDenied);
|
}, Deno.errors.PermissionDenied);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
function copyFileSyncMode(content: string): void {
|
||||||
|
const tempDir = Deno.makeTempDirSync();
|
||||||
|
const fromFilename = tempDir + "/from.txt";
|
||||||
|
const toFilename = tempDir + "/to.txt";
|
||||||
|
Deno.writeTextFileSync(fromFilename, content);
|
||||||
|
Deno.chmodSync(fromFilename, 0o100755);
|
||||||
|
|
||||||
|
Deno.copyFileSync(fromFilename, toFilename);
|
||||||
|
const toStat = Deno.statSync(toFilename);
|
||||||
|
assertEquals(toStat.mode!, 0o100755);
|
||||||
|
}
|
||||||
|
|
||||||
|
Deno.test(
|
||||||
|
{
|
||||||
|
ignore: Deno.build.os === "windows",
|
||||||
|
permissions: { read: true, write: true },
|
||||||
|
},
|
||||||
|
function copyFileSyncChmod() {
|
||||||
|
// this Tests different optimization paths on MacOS:
|
||||||
|
//
|
||||||
|
// < 128 KB clonefile() w/ fallback to copyfile()
|
||||||
|
// > 128 KB
|
||||||
|
copyFileSyncMode("Hello world!");
|
||||||
|
copyFileSyncMode("Hello world!".repeat(128 * 1024));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
|
@ -881,6 +881,8 @@ fn op_copy_file_sync(
|
||||||
use libc::unlink;
|
use libc::unlink;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
use std::os::unix::fs::OpenOptionsExt;
|
||||||
|
use std::os::unix::fs::PermissionsExt;
|
||||||
|
|
||||||
let from = CString::new(from).unwrap();
|
let from = CString::new(from).unwrap();
|
||||||
let to = CString::new(to).unwrap();
|
let to = CString::new(to).unwrap();
|
||||||
|
@ -909,8 +911,23 @@ fn op_copy_file_sync(
|
||||||
let mut buf = [0u8; 128 * 1024];
|
let mut buf = [0u8; 128 * 1024];
|
||||||
let mut from_file =
|
let mut from_file =
|
||||||
std::fs::File::open(&from_path).map_err(err_mapper)?;
|
std::fs::File::open(&from_path).map_err(err_mapper)?;
|
||||||
let mut to_file =
|
let perm = from_file.metadata().map_err(err_mapper)?.permissions();
|
||||||
std::fs::File::create(&to_path).map_err(err_mapper)?;
|
|
||||||
|
let mut to_file = std::fs::OpenOptions::new()
|
||||||
|
// create the file with the correct mode right away
|
||||||
|
.mode(perm.mode())
|
||||||
|
.write(true)
|
||||||
|
.create(true)
|
||||||
|
.truncate(true)
|
||||||
|
.open(&to_path)
|
||||||
|
.map_err(err_mapper)?;
|
||||||
|
let writer_metadata = to_file.metadata()?;
|
||||||
|
if writer_metadata.is_file() {
|
||||||
|
// Set the correct file permissions, in case the file already existed.
|
||||||
|
// Don't set the permissions on already existing non-files like
|
||||||
|
// pipes/FIFOs or device nodes.
|
||||||
|
to_file.set_permissions(perm)?;
|
||||||
|
}
|
||||||
loop {
|
loop {
|
||||||
let nread = from_file.read(&mut buf).map_err(err_mapper)?;
|
let nread = from_file.read(&mut buf).map_err(err_mapper)?;
|
||||||
if nread == 0 {
|
if nread == 0 {
|
||||||
|
|
Loading…
Reference in a new issue