зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1673019 - Get and set file permissions in IOUtils r=emalysz
Differential Revision: https://phabricator.services.mozilla.com/D97689
This commit is contained in:
Родитель
69d3035e96
Коммит
47793f361c
|
@ -155,6 +155,22 @@ namespace IOUtils {
|
|||
* DOMException.
|
||||
*/
|
||||
Promise<sequence<DOMString>> getChildren(DOMString path);
|
||||
/**
|
||||
* Set the permissions of the file at |path|.
|
||||
*
|
||||
* Windows does not make a distinction between user, group, and other
|
||||
* permissions like UNICES do. If a permission flag is set for any of user,
|
||||
* group, or other has a permission, then all users will have that
|
||||
* permission. Additionally, Windows does not support setting the
|
||||
* "executable" permission.
|
||||
*
|
||||
* @param path An absolute file path
|
||||
* @param permissions The UNIX file mode representing the permissions.
|
||||
*
|
||||
* @return Resolves if the permissions were set successfully, otherwise
|
||||
* rejects with a DOMException.
|
||||
*/
|
||||
Promise<void> setPermissions(DOMString path, unsigned long permissions);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -305,4 +321,12 @@ dictionary FileInfo {
|
|||
* This is only available on MacOS and Windows.
|
||||
*/
|
||||
long long creationTime;
|
||||
/**
|
||||
* The permissions of the file, expressed as a UNIX file mode.
|
||||
*
|
||||
* NB: Windows does not make a distinction between user, group, and other
|
||||
* permissions like UNICES do. The user, group, and other parts will always
|
||||
* be identical on Windows.
|
||||
*/
|
||||
unsigned long permissions;
|
||||
};
|
||||
|
|
|
@ -131,6 +131,9 @@ MOZ_MUST_USE inline bool ToJSValue(
|
|||
if (aInternalFileInfo.mCreationTime.isSome()) {
|
||||
info.mCreationTime.Construct(aInternalFileInfo.mCreationTime.ref());
|
||||
}
|
||||
|
||||
info.mPermissions.Construct(aInternalFileInfo.mPermissions);
|
||||
|
||||
return ToJSValue(aCx, info, aValue);
|
||||
}
|
||||
|
||||
|
@ -456,6 +459,25 @@ already_AddRefed<Promise> IOUtils::GetChildren(GlobalObject& aGlobal,
|
|||
return promise.forget();
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<Promise> IOUtils::SetPermissions(GlobalObject& aGlobal,
|
||||
const nsAString& aPath,
|
||||
const uint32_t aPermissions) {
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
RefPtr<Promise> promise = CreateJSPromise(aGlobal);
|
||||
NS_ENSURE_TRUE(!!promise, nullptr);
|
||||
|
||||
nsCOMPtr<nsIFile> file = new nsLocalFile();
|
||||
REJECT_IF_INIT_PATH_FAILED(file, aPath, promise);
|
||||
|
||||
RunOnBackgroundThread<Ok>(
|
||||
promise, [file = std::move(file), permissions = aPermissions]() {
|
||||
return SetPermissionsSync(file, permissions);
|
||||
});
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<nsISerialEventTarget> IOUtils::GetBackgroundEventTarget() {
|
||||
if (sShutdownStarted) {
|
||||
|
@ -1117,6 +1139,8 @@ Result<IOUtils::InternalFileInfo, IOUtils::IOError> IOUtils::StatSync(
|
|||
return Err(IOError(rv));
|
||||
}
|
||||
|
||||
MOZ_TRY(aFile->GetPermissions(&info.mPermissions));
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
|
@ -1205,6 +1229,15 @@ Result<nsTArray<nsString>, IOUtils::IOError> IOUtils::GetChildrenSync(
|
|||
return children;
|
||||
}
|
||||
|
||||
/* static */
|
||||
Result<Ok, IOUtils::IOError> IOUtils::SetPermissionsSync(
|
||||
nsIFile* aFile, const uint32_t aPermissions) {
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
MOZ_TRY(aFile->SetPermissions(aPermissions));
|
||||
return Ok{};
|
||||
}
|
||||
|
||||
/* static */
|
||||
Result<nsTArray<uint8_t>, IOUtils::IOError> IOUtils::MozLZ4::Compress(
|
||||
Span<const uint8_t> aUncompressed) {
|
||||
|
|
|
@ -99,6 +99,10 @@ class IOUtils final {
|
|||
static already_AddRefed<Promise> GetChildren(GlobalObject& aGlobal,
|
||||
const nsAString& aPath);
|
||||
|
||||
static already_AddRefed<Promise> SetPermissions(GlobalObject& aGlobal,
|
||||
const nsAString& aPath,
|
||||
const uint32_t aPermissions);
|
||||
|
||||
static bool IsAbsolutePath(const nsAString& aPath);
|
||||
|
||||
private:
|
||||
|
@ -326,6 +330,22 @@ class IOUtils final {
|
|||
* If there are no children, an empty array. Otherwise, an error.
|
||||
*/
|
||||
static Result<nsTArray<nsString>, IOError> GetChildrenSync(nsIFile* aFile);
|
||||
|
||||
/**
|
||||
* Set the permissions of the given file.
|
||||
*
|
||||
* Windows does not make a distinction between user, group, and other
|
||||
* permissions like UNICES do. If a permission flag is set for any of user,
|
||||
* group, or other has a permission, then all users will have that
|
||||
* permission.
|
||||
*
|
||||
* @param aFile The location of the file.
|
||||
* @param aPermissions The permissions to set, as a UNIX file mode.
|
||||
*
|
||||
* @return |Ok| if the permissions were successfully set, or an error.
|
||||
*/
|
||||
static Result<Ok, IOError> SetPermissionsSync(nsIFile* aFile,
|
||||
const uint32_t aPermissions);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -382,6 +402,7 @@ struct IOUtils::InternalFileInfo {
|
|||
uint64_t mSize;
|
||||
uint64_t mLastModified;
|
||||
Maybe<uint64_t> mCreationTime;
|
||||
uint32_t mPermissions;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -12,3 +12,4 @@ support-files =
|
|||
[test_ioutils_remove.html]
|
||||
[test_ioutils_stat_touch.html]
|
||||
[test_ioutils_worker.xhtml]
|
||||
[test_ioutils_set_permissions.html]
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
- http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test the IOUtils file I/O API</title>
|
||||
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
<script src="file_ioutils_test_fixtures.js"></script>
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
add_task(async function test_setPermissions() {
|
||||
const tempDir = await PathUtils.getTempDir();
|
||||
const tempFile = PathUtils.join(tempDir, "setPermissions.tmp");
|
||||
|
||||
await IOUtils.writeAtomicUTF8(tempFile, "");
|
||||
await IOUtils.setPermissions(tempFile, 0o421);
|
||||
|
||||
let stat = await IOUtils.stat(tempFile);
|
||||
|
||||
if (Services.appinfo.OS === "WINNT") {
|
||||
// setPermissions ignores the x bit on Windows.
|
||||
is(stat.permissions, 0o666, "Permissions munged on Windows");
|
||||
} else {
|
||||
is(stat.permissions, 0o421, "Permissions match");
|
||||
}
|
||||
|
||||
await IOUtils.setPermissions(tempFile, 0o400);
|
||||
stat = await IOUtils.stat(tempFile);
|
||||
|
||||
if (Services.appinfo.OS === "WINNT") {
|
||||
is(stat.permissions, 0o444, "Permissions munged on Windows");
|
||||
} else {
|
||||
is(stat.permissions, 0o400, "Permissions match");
|
||||
|
||||
await cleanup(tempFile);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче