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() {
|
flush: function flush() {
|
||||||
return Scheduler.post("File_prototype_flush",
|
return Scheduler.post("File_prototype_flush",
|
||||||
[this._fdmsg]);
|
[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);
|
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
|
* Fetch the current directory
|
||||||
*
|
*
|
||||||
|
@ -297,6 +297,9 @@ const EXCEPTION_NAMES = {
|
|||||||
return exports.OS.File.Info.toMsg(
|
return exports.OS.File.Info.toMsg(
|
||||||
exports.OS.File.stat(Type.path.fromMsg(path), options));
|
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) {
|
setDates: function setDates(path, accessDate, modificationDate) {
|
||||||
return exports.OS.File.setDates(Type.path.fromMsg(path), accessDate,
|
return exports.OS.File.setDates(Type.path.fromMsg(path), accessDate,
|
||||||
modificationDate);
|
modificationDate);
|
||||||
@ -405,6 +408,12 @@ const EXCEPTION_NAMES = {
|
|||||||
return exports.OS.File.Info.toMsg(this.stat());
|
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) {
|
File_prototype_setDates: function setDates(fd, accessTime, modificationTime) {
|
||||||
return withFile(fd,
|
return withFile(fd,
|
||||||
function do_setDates() {
|
function do_setDates() {
|
||||||
|
@ -348,6 +348,12 @@
|
|||||||
/*return*/ Type.negativeone_or_nothing,
|
/*return*/ Type.negativeone_or_nothing,
|
||||||
/*fd*/ Type.fd);
|
/*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",
|
libc.declareLazyFFI(SysFile, "fchown",
|
||||||
"fchown", ctypes.default_abi,
|
"fchown", ctypes.default_abi,
|
||||||
/*return*/ Type.negativeone_or_nothing,
|
/*return*/ Type.negativeone_or_nothing,
|
||||||
|
@ -173,6 +173,27 @@
|
|||||||
return new File.Info(gStatData, this._path);
|
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.
|
* Set the last access and modification date of the file.
|
||||||
* The time stamp resolution is 1 second at best, but might be worse
|
* The time stamp resolution is 1 second at best, but might be worse
|
||||||
@ -909,6 +930,28 @@
|
|||||||
return new File.Info(gStatData, path);
|
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
|
* Convert an access date and a modification date to an array
|
||||||
* of two |timeval|.
|
* of two |timeval|.
|
||||||
@ -1111,6 +1154,25 @@
|
|||||||
return date;
|
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.Unix = exports.OS.Unix.File;
|
||||||
File.Error = SysAll.Error;
|
File.Error = SysAll.Error;
|
||||||
exports.OS.File = File;
|
exports.OS.File = File;
|
||||||
|
@ -234,6 +234,14 @@
|
|||||||
this._path);
|
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
|
* Flushes the file's buffers and causes all buffered data
|
||||||
* to be written.
|
* to be written.
|
||||||
@ -953,6 +961,14 @@
|
|||||||
winDisposition: Const.OPEN_EXISTING
|
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.
|
* Set the last access and modification date of the file.
|
||||||
* The time stamp resolution is 1 second at best, but might be worse
|
* 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_queue.js]
|
||||||
[test_loader.js]
|
[test_loader.js]
|
||||||
[test_constants.js]
|
[test_constants.js]
|
||||||
|
|
||||||
|
[test_osfile_async_setPerms.js]
|
||||||
|
skip-if = os == 'win'
|
||||||
|
Loading…
Reference in New Issue
Block a user