mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1001849: expose general chmod, and chmod-to-umask, support in OS.File. r=yoric
This commit is contained in:
parent
00cd340bac
commit
cf0cc1e3c0
@ -823,6 +823,27 @@ File.prototype = {
|
||||
flush: function flush() {
|
||||
return Scheduler.post("File_prototype_flush",
|
||||
[this._fdmsg]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the file's access permissions. Without any options, the
|
||||
* permissions are set to an approximation of what they would have
|
||||
* been if the file had been created in its current directory in the
|
||||
* "most typical" fashion for the operating system. In the current
|
||||
* implementation, this means that on Unix-like systems (including
|
||||
* Android, B2G, etc) we set the POSIX file mode to (0666 & ~umask),
|
||||
* and on Windows, we do nothing.
|
||||
*
|
||||
* @param {*=} options
|
||||
* - {number} unixMode If present, the POSIX file mode is set to exactly
|
||||
* this value, unless |unixHonorUmask| is also
|
||||
* present.
|
||||
* - {bool} unixHonorUmask If true, any |unixMode| value is modified by the
|
||||
* process umask, as open() would have done.
|
||||
*/
|
||||
setPermissions: function setPermissions(options = {}) {
|
||||
return Scheduler.post("File_prototype_setPermissions",
|
||||
[this._fdmsg, options]);
|
||||
}
|
||||
};
|
||||
|
||||
@ -923,6 +944,29 @@ File.setDates = function setDates(path, accessDate, modificationDate) {
|
||||
this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the file's access permissions. Without any options, the
|
||||
* permissions are set to an approximation of what they would have
|
||||
* been if the file had been created in its current directory in the
|
||||
* "most typical" fashion for the operating system. In the current
|
||||
* implementation, this means that on Unix-like systems (including
|
||||
* Android, B2G, etc) we set the POSIX file mode to (0666 & ~umask),
|
||||
* and on Windows, we do nothing.
|
||||
*
|
||||
* @param {string} path The path to the file.
|
||||
*
|
||||
* @param {*=} options
|
||||
* - {number} unixMode If present, the POSIX file mode is set to exactly
|
||||
* this value, unless |unixHonorUmask| is also
|
||||
* present.
|
||||
* - {bool} unixHonorUmask If true, any |unixMode| value is modified by the
|
||||
* process umask, as open() would have done.
|
||||
*/
|
||||
File.setPermissions = function setPermissions(path, options = {}) {
|
||||
return Scheduler.post("setPermissions",
|
||||
[Type.path.toMsg(path), options]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Fetch the current directory
|
||||
*
|
||||
|
@ -297,6 +297,9 @@ const EXCEPTION_NAMES = {
|
||||
return exports.OS.File.Info.toMsg(
|
||||
exports.OS.File.stat(Type.path.fromMsg(path), options));
|
||||
},
|
||||
setPermissions: function setPermissions(path, options = {}) {
|
||||
return exports.OS.File.setPermissions(Type.path.fromMsg(path), options);
|
||||
},
|
||||
setDates: function setDates(path, accessDate, modificationDate) {
|
||||
return exports.OS.File.setDates(Type.path.fromMsg(path), accessDate,
|
||||
modificationDate);
|
||||
@ -405,6 +408,12 @@ const EXCEPTION_NAMES = {
|
||||
return exports.OS.File.Info.toMsg(this.stat());
|
||||
});
|
||||
},
|
||||
File_prototype_setPermissions: function setPermissions(fd, options = {}) {
|
||||
return withFile(fd,
|
||||
function do_setPermissions() {
|
||||
return this.setPermissions(options);
|
||||
});
|
||||
},
|
||||
File_prototype_setDates: function setDates(fd, accessTime, modificationTime) {
|
||||
return withFile(fd,
|
||||
function do_setDates() {
|
||||
|
@ -348,6 +348,12 @@
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*fd*/ Type.fd);
|
||||
|
||||
libc.declareLazyFFI(SysFile, "fchmod",
|
||||
"fchmod", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*fd*/ Type.fd,
|
||||
/*mode*/ Type.mode_t);
|
||||
|
||||
libc.declareLazyFFI(SysFile, "fchown",
|
||||
"fchown", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
|
@ -173,6 +173,27 @@
|
||||
return new File.Info(gStatData, this._path);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the file's access permissions. Without any options, the
|
||||
* permissions are set to an approximation of what they would
|
||||
* have been if the file had been created in its current
|
||||
* directory in the "most typical" fashion for the operating
|
||||
* system. In the current implementation, this means we set
|
||||
* the POSIX file mode to (0666 & ~umask).
|
||||
*
|
||||
* @param {*=} options
|
||||
* - {number} unixMode If present, the POSIX file mode is set to
|
||||
* exactly this value, unless |unixHonorUmask| is
|
||||
* also present.
|
||||
* - {bool} unixHonorUmask If true, any |unixMode| value is modified by
|
||||
* the process umask, as open() would have done.
|
||||
*/
|
||||
File.prototype.setPermissions = function setPermissions(options = {}) {
|
||||
throw_on_negative("setPermissions",
|
||||
UnixFile.fchmod(this.fd, unixMode(options)),
|
||||
this._path);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the last access and modification date of the file.
|
||||
* The time stamp resolution is 1 second at best, but might be worse
|
||||
@ -909,6 +930,28 @@
|
||||
return new File.Info(gStatData, path);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the file's access permissions. Without any options, the
|
||||
* permissions are set to an approximation of what they would
|
||||
* have been if the file had been created in its current
|
||||
* directory in the "most typical" fashion for the operating
|
||||
* system. In the current implementation, this means we set
|
||||
* the POSIX file mode to (0666 & ~umask).
|
||||
*
|
||||
* @param {string} path The name of the file to reset the permissions of.
|
||||
* @param {*=} options
|
||||
* - {number} unixMode If present, the POSIX file mode is set to
|
||||
* exactly this value, unless |unixHonorUmask| is
|
||||
* also present.
|
||||
* - {bool} unixHonorUmask If true, any |unixMode| value is modified by
|
||||
* the process umask, as open() would have done.
|
||||
*/
|
||||
File.setPermissions = function setPermissions(path, options = {}) {
|
||||
throw_on_negative("setPermissions",
|
||||
UnixFile.chmod(path, unixMode(options)),
|
||||
path);
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert an access date and a modification date to an array
|
||||
* of two |timeval|.
|
||||
@ -1111,6 +1154,25 @@
|
||||
return date;
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper used by both versions of setPermissions.
|
||||
*/
|
||||
function unixMode(options) {
|
||||
let mode = 438; /* 0666 */
|
||||
let unixHonorUmask = true;
|
||||
if ("unixMode" in options) {
|
||||
unixHonorUmask = false;
|
||||
mode = options.unixMode;
|
||||
}
|
||||
if ("unixHonorUmask" in options) {
|
||||
unixHonorUmask = options.unixHonorUmask;
|
||||
}
|
||||
if (unixHonorUmask) {
|
||||
mode &= ~SharedAll.Constants.Sys.umask;
|
||||
}
|
||||
return mode;
|
||||
}
|
||||
|
||||
File.Unix = exports.OS.Unix.File;
|
||||
File.Error = SysAll.Error;
|
||||
exports.OS.File = File;
|
||||
|
@ -234,6 +234,14 @@
|
||||
this._path);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the file's access permission bits.
|
||||
* Not implemented for Windows (bug 1022816).
|
||||
*/
|
||||
File.prototype.setPermissions = function setPermissions(options = {}) {
|
||||
// do nothing
|
||||
};
|
||||
|
||||
/**
|
||||
* Flushes the file's buffers and causes all buffered data
|
||||
* to be written.
|
||||
@ -953,6 +961,14 @@
|
||||
winDisposition: Const.OPEN_EXISTING
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the file's access permission bits.
|
||||
* Not implemented for Windows (bug 1022816).
|
||||
*/
|
||||
File.setPermissions = function setPermissions(path, options = {}) {
|
||||
// do nothing
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the last access and modification date of the file.
|
||||
* The time stamp resolution is 1 second at best, but might be worse
|
||||
|
@ -0,0 +1,123 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* A test to ensure that OS.File.setPermissions and
|
||||
* OS.File.prototype.setPermissions are all working correctly.
|
||||
* (see bug 1001849)
|
||||
* These functions are currently Unix-specific. The manifest skips
|
||||
* the test on Windows.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Helper function for test logging: prints a POSIX file permission mode as an
|
||||
* octal number, with a leading '0' per C (not JS) convention. When the
|
||||
* numeric value is 0777 or lower, it is padded on the left with zeroes to
|
||||
* four digits wide.
|
||||
* Sample outputs: 0022, 0644, 04755.
|
||||
*/
|
||||
function format_mode(mode) {
|
||||
if (mode <= 0o777) {
|
||||
return ("0000" + mode.toString(8)).slice(-4);
|
||||
} else {
|
||||
return "0" + mode.toString(8);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this function to compare two mode values; it prints both values as
|
||||
* octal numbers in the log.
|
||||
*/
|
||||
function do_check_modes_eq(left, right, text) {
|
||||
text = text + ": " + format_mode(left) + " === " + format_mode(right);
|
||||
do_report_result(left === right, text, Components.stack.caller, false);
|
||||
}
|
||||
|
||||
const _umask = OS.Constants.Sys.umask;
|
||||
do_print("umask: " + format_mode(_umask));
|
||||
|
||||
/**
|
||||
* Compute the mode that a file should have after applying the umask,
|
||||
* whatever it happens to be.
|
||||
*/
|
||||
function apply_umask(mode) {
|
||||
return mode & ~_umask;
|
||||
}
|
||||
|
||||
// Test application to paths.
|
||||
add_task(function*() {
|
||||
let path = OS.Path.join(OS.Constants.Path.tmpDir,
|
||||
"test_osfile_async_setPerms_nonproto.tmp");
|
||||
yield OS.File.writeAtomic(path, new Uint8Array(1));
|
||||
|
||||
try {
|
||||
let stat;
|
||||
|
||||
yield OS.File.setPermissions(path, {unixMode: 0o4777});
|
||||
stat = yield OS.File.stat(path);
|
||||
do_check_modes_eq(stat.unixMode, 0o4777,
|
||||
"setPermissions(path, 04777)");
|
||||
|
||||
yield OS.File.setPermissions(path, {unixMode: 0o4777,
|
||||
unixHonorUmask: true});
|
||||
stat = yield OS.File.stat(path);
|
||||
do_check_modes_eq(stat.unixMode, apply_umask(0o4777),
|
||||
"setPermissions(path, 04777&~umask)");
|
||||
|
||||
yield OS.File.setPermissions(path);
|
||||
stat = yield OS.File.stat(path);
|
||||
do_check_modes_eq(stat.unixMode, apply_umask(0o666),
|
||||
"setPermissions(path, {})");
|
||||
|
||||
yield OS.File.setPermissions(path, {unixMode: 0});
|
||||
stat = yield OS.File.stat(path);
|
||||
do_check_modes_eq(stat.unixMode, 0,
|
||||
"setPermissions(path, 0000)");
|
||||
|
||||
} finally {
|
||||
yield OS.File.remove(path);
|
||||
}
|
||||
});
|
||||
|
||||
// Test application to open files.
|
||||
add_task(function*() {
|
||||
// First, create a file we can mess with.
|
||||
let path = OS.Path.join(OS.Constants.Path.tmpDir,
|
||||
"test_osfile_async_setDates_proto.tmp");
|
||||
yield OS.File.writeAtomic(path, new Uint8Array(1));
|
||||
|
||||
try {
|
||||
let fd = yield OS.File.open(path, {write: true});
|
||||
let stat;
|
||||
|
||||
yield fd.setPermissions({unixMode: 0o4777});
|
||||
stat = yield fd.stat();
|
||||
do_check_modes_eq(stat.unixMode, 0o4777,
|
||||
"fd.setPermissions(04777)");
|
||||
|
||||
yield fd.setPermissions({unixMode: 0o4777, unixHonorUmask: true});
|
||||
stat = yield fd.stat();
|
||||
do_check_modes_eq(stat.unixMode, apply_umask(0o4777),
|
||||
"fd.setPermissions(04777&~umask)");
|
||||
|
||||
yield fd.setPermissions();
|
||||
stat = yield fd.stat();
|
||||
do_check_modes_eq(stat.unixMode, apply_umask(0o666),
|
||||
"fd.setPermissions({})");
|
||||
|
||||
yield fd.setPermissions({unixMode: 0});
|
||||
stat = yield fd.stat();
|
||||
do_check_modes_eq(stat.unixMode, 0,
|
||||
"fd.setPermissions(0000)");
|
||||
|
||||
yield fd.close();
|
||||
} finally {
|
||||
yield OS.File.remove(path);
|
||||
}
|
||||
});
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
@ -36,3 +36,6 @@ support-files =
|
||||
[test_queue.js]
|
||||
[test_loader.js]
|
||||
[test_constants.js]
|
||||
|
||||
[test_osfile_async_setPerms.js]
|
||||
skip-if = os == 'win'
|
||||
|
Loading…
Reference in New Issue
Block a user