зеркало из 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.
|
* DOMException.
|
||||||
*/
|
*/
|
||||||
Promise<sequence<DOMString>> getChildren(DOMString path);
|
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.
|
* This is only available on MacOS and Windows.
|
||||||
*/
|
*/
|
||||||
long long creationTime;
|
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()) {
|
if (aInternalFileInfo.mCreationTime.isSome()) {
|
||||||
info.mCreationTime.Construct(aInternalFileInfo.mCreationTime.ref());
|
info.mCreationTime.Construct(aInternalFileInfo.mCreationTime.ref());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info.mPermissions.Construct(aInternalFileInfo.mPermissions);
|
||||||
|
|
||||||
return ToJSValue(aCx, info, aValue);
|
return ToJSValue(aCx, info, aValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -456,6 +459,25 @@ already_AddRefed<Promise> IOUtils::GetChildren(GlobalObject& aGlobal,
|
||||||
return promise.forget();
|
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 */
|
/* static */
|
||||||
already_AddRefed<nsISerialEventTarget> IOUtils::GetBackgroundEventTarget() {
|
already_AddRefed<nsISerialEventTarget> IOUtils::GetBackgroundEventTarget() {
|
||||||
if (sShutdownStarted) {
|
if (sShutdownStarted) {
|
||||||
|
@ -1117,6 +1139,8 @@ Result<IOUtils::InternalFileInfo, IOUtils::IOError> IOUtils::StatSync(
|
||||||
return Err(IOError(rv));
|
return Err(IOError(rv));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MOZ_TRY(aFile->GetPermissions(&info.mPermissions));
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1205,6 +1229,15 @@ Result<nsTArray<nsString>, IOUtils::IOError> IOUtils::GetChildrenSync(
|
||||||
return children;
|
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 */
|
/* static */
|
||||||
Result<nsTArray<uint8_t>, IOUtils::IOError> IOUtils::MozLZ4::Compress(
|
Result<nsTArray<uint8_t>, IOUtils::IOError> IOUtils::MozLZ4::Compress(
|
||||||
Span<const uint8_t> aUncompressed) {
|
Span<const uint8_t> aUncompressed) {
|
||||||
|
|
|
@ -99,6 +99,10 @@ class IOUtils final {
|
||||||
static already_AddRefed<Promise> GetChildren(GlobalObject& aGlobal,
|
static already_AddRefed<Promise> GetChildren(GlobalObject& aGlobal,
|
||||||
const nsAString& aPath);
|
const nsAString& aPath);
|
||||||
|
|
||||||
|
static already_AddRefed<Promise> SetPermissions(GlobalObject& aGlobal,
|
||||||
|
const nsAString& aPath,
|
||||||
|
const uint32_t aPermissions);
|
||||||
|
|
||||||
static bool IsAbsolutePath(const nsAString& aPath);
|
static bool IsAbsolutePath(const nsAString& aPath);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -326,6 +330,22 @@ class IOUtils final {
|
||||||
* If there are no children, an empty array. Otherwise, an error.
|
* If there are no children, an empty array. Otherwise, an error.
|
||||||
*/
|
*/
|
||||||
static Result<nsTArray<nsString>, IOError> GetChildrenSync(nsIFile* aFile);
|
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 mSize;
|
||||||
uint64_t mLastModified;
|
uint64_t mLastModified;
|
||||||
Maybe<uint64_t> mCreationTime;
|
Maybe<uint64_t> mCreationTime;
|
||||||
|
uint32_t mPermissions;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -12,3 +12,4 @@ support-files =
|
||||||
[test_ioutils_remove.html]
|
[test_ioutils_remove.html]
|
||||||
[test_ioutils_stat_touch.html]
|
[test_ioutils_stat_touch.html]
|
||||||
[test_ioutils_worker.xhtml]
|
[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>
|
Загрузка…
Ссылка в новой задаче