зеркало из https://github.com/mozilla/gecko-dev.git
Bug 924916: Part 1 - Implement OS.File.setDates() for Unix. r=yoric
This commit is contained in:
Родитель
5bfe05a87c
Коммит
500ac6e588
|
@ -514,6 +514,11 @@ static const dom::ConstantSpec gLibcProperties[] =
|
|||
// (may not be exact, depending on padding).
|
||||
{ "OSFILE_SIZEOF_DIRENT_D_NAME", INT_TO_JSVAL(sizeof (struct dirent) - offsetof (struct dirent, d_name)) },
|
||||
|
||||
// Defining |timeval|.
|
||||
{ "OSFILE_SIZEOF_TIMEVAL", INT_TO_JSVAL(sizeof (struct timeval)) },
|
||||
{ "OSFILE_OFFSETOF_TIMEVAL_TV_SEC", INT_TO_JSVAL(offsetof (struct timeval, tv_sec)) },
|
||||
{ "OSFILE_OFFSETOF_TIMEVAL_TV_USEC", INT_TO_JSVAL(offsetof (struct timeval, tv_usec)) },
|
||||
|
||||
#if defined(DT_UNKNOWN)
|
||||
// Position of field |d_type| in |dirent|
|
||||
// Not strictly posix, but seems defined on all platforms
|
||||
|
|
|
@ -200,6 +200,24 @@
|
|||
return ctypes.CDataFinalizer(dir, SysFile._close_dir);
|
||||
};
|
||||
|
||||
// Structure |timeval|
|
||||
{
|
||||
let timeval = new SharedAll.HollowStructure(
|
||||
"timeval",
|
||||
Const.OSFILE_SIZEOF_TIMEVAL);
|
||||
timeval.add_field_at(
|
||||
Const.OSFILE_OFFSETOF_TIMEVAL_TV_SEC,
|
||||
"tv_sec",
|
||||
Type.long.implementation);
|
||||
timeval.add_field_at(
|
||||
Const.OSFILE_OFFSETOF_TIMEVAL_TV_USEC,
|
||||
"tv_usec",
|
||||
Type.long.implementation);
|
||||
Type.timeval = timeval.getType();
|
||||
Type.timevals = new SharedAll.Type("two timevals",
|
||||
ctypes.ArrayType(Type.timeval.implementation, 2));
|
||||
}
|
||||
|
||||
// Declare libc functions as functions of |OS.Unix.File|
|
||||
|
||||
// Finalizer-related functions
|
||||
|
@ -570,6 +588,17 @@
|
|||
array[1] = ctypes.CDataFinalizer(_pipebuf[1], SysFile._close);
|
||||
return result;
|
||||
};
|
||||
|
||||
declareLazyFFI(SysFile, "utimes", libc, "utimes", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*path*/ Type.path,
|
||||
/*timeval[2]*/ Type.timevals.out_ptr
|
||||
);
|
||||
declareLazyFFI(SysFile, "futimes", libc, "futimes", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*fd*/ Type.fd,
|
||||
/*timeval[2]*/ Type.timevals.out_ptr
|
||||
);
|
||||
};
|
||||
|
||||
exports.OS.Unix = {
|
||||
|
|
|
@ -168,6 +168,33 @@
|
|||
return new File.Info(gStatData);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the last access and modification date of the file.
|
||||
* The time stamp resolution is 1 second at best, but might be worse
|
||||
* depending on the platform.
|
||||
*
|
||||
* @param {Date,number=} accessDate The last access date. If numeric,
|
||||
* milliseconds since epoch. If omitted or null, then the current date
|
||||
* will be used.
|
||||
* @param {Date,number=} modificationDate The last modification date. If
|
||||
* numeric, milliseconds since epoch. If omitted or null, then the current
|
||||
* date will be used.
|
||||
*
|
||||
* @throws {TypeError} In case of invalid parameters.
|
||||
* @throws {OS.File.Error} In case of I/O error.
|
||||
*/
|
||||
File.prototype.setDates = function setDates(accessDate, modificationDate) {
|
||||
accessDate = normalizeDate("File.prototype.setDates", accessDate);
|
||||
modificationDate = normalizeDate("File.prototype.setDates",
|
||||
modificationDate);
|
||||
gTimevals[0].tv_sec = (accessDate / 1000) | 0;
|
||||
gTimevals[0].tv_usec = 0;
|
||||
gTimevals[1].tv_sec = (modificationDate / 1000) | 0;
|
||||
gTimevals[1].tv_usec = 0;
|
||||
throw_on_negative("setDates",
|
||||
UnixFile.futimes(this.fd, gTimevalsPtr));
|
||||
};
|
||||
|
||||
/**
|
||||
* Flushes the file's buffers and causes all buffered data
|
||||
* to be written.
|
||||
|
@ -756,6 +783,8 @@
|
|||
|
||||
let gStatData = new Type.stat.implementation();
|
||||
let gStatDataPtr = gStatData.address();
|
||||
let gTimevals = new Type.timevals.implementation();
|
||||
let gTimevalsPtr = gTimevals.address();
|
||||
let MODE_MASK = 4095 /*= 07777*/;
|
||||
File.Info = function Info(stat) {
|
||||
let isDir = (stat.st_mode & Const.S_IFMT) == Const.S_IFDIR;
|
||||
|
@ -839,6 +868,33 @@
|
|||
return new File.Info(gStatData);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the last access and modification date of the file.
|
||||
* The time stamp resolution is 1 second at best, but might be worse
|
||||
* depending on the platform.
|
||||
*
|
||||
* @param {string} path The full name of the file to set the dates for.
|
||||
* @param {Date,number=} accessDate The last access date. If numeric,
|
||||
* milliseconds since epoch. If omitted or null, then the current date
|
||||
* will be used.
|
||||
* @param {Date,number=} modificationDate The last modification date. If
|
||||
* numeric, milliseconds since epoch. If omitted or null, then the current
|
||||
* date will be used.
|
||||
*
|
||||
* @throws {TypeError} In case of invalid paramters.
|
||||
* @throws {OS.File.Error} In case of I/O error.
|
||||
*/
|
||||
File.setDates = function setDates(path, accessDate, modificationDate) {
|
||||
accessDate = normalizeDate("File.setDates", accessDate);
|
||||
modificationDate = normalizeDate("File.setDates", modificationDate);
|
||||
gTimevals[0].tv_sec = (accessDate / 1000) | 0;
|
||||
gTimevals[0].tv_usec = 0;
|
||||
gTimevals[1].tv_sec = (modificationDate / 1000) | 0;
|
||||
gTimevals[1].tv_usec = 0;
|
||||
throw_on_negative("setDates",
|
||||
UnixFile.utimes(path, gTimevalsPtr));
|
||||
};
|
||||
|
||||
File.read = exports.OS.Shared.AbstractFile.read;
|
||||
File.writeAtomic = exports.OS.Shared.AbstractFile.writeAtomic;
|
||||
File.openUnique = exports.OS.Shared.AbstractFile.openUnique;
|
||||
|
@ -911,6 +967,33 @@
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize and verify a Date or numeric date value.
|
||||
*
|
||||
* @param {string} fn Function name of the calling function.
|
||||
* @param {Date,number} date The date to normalize. If omitted or null,
|
||||
* then the current date will be used.
|
||||
*
|
||||
* @throws {TypeError} Invalid date provided.
|
||||
*
|
||||
* @return {number} Sanitized, numeric date in milliseconds since epoch.
|
||||
*/
|
||||
function normalizeDate(fn, date) {
|
||||
if (typeof date !== "number" && !date) {
|
||||
// |date| was Omitted or null.
|
||||
date = Date.now();
|
||||
} else if (typeof date.getTime === "function") {
|
||||
// Input might be a date or date-like object.
|
||||
date = date.getTime();
|
||||
}
|
||||
|
||||
if (isNaN(date)) {
|
||||
throw new TypeError("|date| parameter of " + fn + " must be a " +
|
||||
"|Date| instance or number");
|
||||
}
|
||||
return date;
|
||||
};
|
||||
|
||||
File.Unix = exports.OS.Unix.File;
|
||||
File.Error = SysAll.Error;
|
||||
exports.OS.File = File;
|
||||
|
|
Загрузка…
Ссылка в новой задаче