mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Backed out changeset 03d629375717 (bug 904652) for suspicion of causing mass test bustage.
CLOSED TREE
This commit is contained in:
parent
19d5c5ce8c
commit
718a8e2cf9
@ -98,7 +98,7 @@ PromiseWorker.prototype = {
|
||||
* @param {Error} error Some JS error.
|
||||
*/
|
||||
worker.onerror = function onerror(error) {
|
||||
self._log("Received uncaught error from worker", error.message, error.filename, error.lineno);
|
||||
self._log("Received uncaught error from worker", error.message);
|
||||
error.preventDefault();
|
||||
let {deferred} = self._queue.pop();
|
||||
deferred.reject(error);
|
||||
|
@ -29,21 +29,24 @@ Cu.import("resource://gre/modules/osfile/osfile_shared_allthreads.jsm", SharedAl
|
||||
Cu.import("resource://gre/modules/Deprecated.jsm", this);
|
||||
|
||||
// Boilerplate, to simplify the transition to require()
|
||||
let LOG = SharedAll.LOG.bind(SharedAll, "Controller");
|
||||
let isTypedArray = SharedAll.isTypedArray;
|
||||
let OS = SharedAll.OS;
|
||||
|
||||
let LOG = OS.Shared.LOG.bind(OS.Shared, "Controller");
|
||||
|
||||
let isTypedArray = OS.Shared.isTypedArray;
|
||||
|
||||
// The constructor for file errors.
|
||||
let SysAll = {};
|
||||
if (SharedAll.Constants.Win) {
|
||||
Cu.import("resource://gre/modules/osfile/osfile_win_allthreads.jsm", SysAll);
|
||||
} else if (SharedAll.Constants.libc) {
|
||||
Cu.import("resource://gre/modules/osfile/osfile_unix_allthreads.jsm", SysAll);
|
||||
let OSError;
|
||||
if (OS.Constants.Win) {
|
||||
Cu.import("resource://gre/modules/osfile/osfile_win_allthreads.jsm", this);
|
||||
OSError = OS.Shared.Win.Error;
|
||||
} else if (OS.Constants.libc) {
|
||||
Cu.import("resource://gre/modules/osfile/osfile_unix_allthreads.jsm", this);
|
||||
OSError = OS.Shared.Unix.Error;
|
||||
} else {
|
||||
throw new Error("I am neither under Windows nor under a Posix system");
|
||||
}
|
||||
let OSError = SysAll.Error;
|
||||
let Type = SysAll.Type;
|
||||
|
||||
let Type = OS.Shared.Type;
|
||||
let Path = {};
|
||||
Cu.import("resource://gre/modules/osfile/ospath.jsm", Path);
|
||||
|
||||
@ -57,16 +60,18 @@ Cu.import("resource://gre/modules/Services.jsm", this);
|
||||
|
||||
Cu.import("resource://gre/modules/AsyncShutdown.jsm", this);
|
||||
|
||||
LOG("Checking profileDir", OS.Constants.Path);
|
||||
|
||||
// If profileDir is not available, osfile.jsm has been imported before the
|
||||
// profile is setup. In this case, make this a lazy getter.
|
||||
if (!("profileDir" in SharedAll.Constants.Path)) {
|
||||
Object.defineProperty(SharedAll.Constants.Path, "profileDir", {
|
||||
if (!("profileDir" in OS.Constants.Path)) {
|
||||
Object.defineProperty(OS.Constants.Path, "profileDir", {
|
||||
get: function() {
|
||||
let path = undefined;
|
||||
try {
|
||||
path = Services.dirsvc.get("ProfD", Ci.nsIFile).path;
|
||||
delete SharedAll.Constants.Path.profileDir;
|
||||
SharedAll.Constants.Path.profileDir = path;
|
||||
delete OS.Constants.Path.profileDir;
|
||||
OS.Constants.Path.profileDir = path;
|
||||
} catch (ex) {
|
||||
// Ignore errors: profileDir is still not available
|
||||
}
|
||||
@ -77,14 +82,14 @@ if (!("profileDir" in SharedAll.Constants.Path)) {
|
||||
|
||||
LOG("Checking localProfileDir");
|
||||
|
||||
if (!("localProfileDir" in SharedAll.Constants.Path)) {
|
||||
Object.defineProperty(SharedAll.Constants.Path, "localProfileDir", {
|
||||
if (!("localProfileDir" in OS.Constants.Path)) {
|
||||
Object.defineProperty(OS.Constants.Path, "localProfileDir", {
|
||||
get: function() {
|
||||
let path = undefined;
|
||||
try {
|
||||
path = Services.dirsvc.get("ProfLD", Ci.nsIFile).path;
|
||||
delete SharedAll.Constants.Path.localProfileDir;
|
||||
SharedAll.Constants.Path.localProfileDir = path;
|
||||
delete OS.Constants.Path.localProfileDir;
|
||||
OS.Constants.Path.localProfileDir = path;
|
||||
} catch (ex) {
|
||||
// Ignore errors: localProfileDir is still not available
|
||||
}
|
||||
@ -118,7 +123,7 @@ let Scheduler = {
|
||||
latestPromise: Promise.resolve("OS.File scheduler hasn't been launched yet"),
|
||||
|
||||
post: function post(...args) {
|
||||
if (!this.launched && SharedAll.Config.DEBUG) {
|
||||
if (!this.launched && OS.Shared.DEBUG) {
|
||||
// If we have delayed sending SET_DEBUG, do it now.
|
||||
worker.post("SET_DEBUG", [true]);
|
||||
}
|
||||
@ -207,23 +212,23 @@ let readDebugPref = function readDebugPref(prefName, oldPref = false) {
|
||||
*/
|
||||
Services.prefs.addObserver(PREF_OSFILE_LOG,
|
||||
function prefObserver(aSubject, aTopic, aData) {
|
||||
SharedAll.Config.DEBUG = readDebugPref(PREF_OSFILE_LOG, SharedAll.Config.DEBUG);
|
||||
OS.Shared.DEBUG = readDebugPref(PREF_OSFILE_LOG, OS.Shared.DEBUG);
|
||||
if (Scheduler.launched) {
|
||||
// Don't start the worker just to set this preference.
|
||||
Scheduler.post("SET_DEBUG", [SharedAll.Config.DEBUG]);
|
||||
Scheduler.post("SET_DEBUG", [OS.Shared.DEBUG]);
|
||||
}
|
||||
}, false);
|
||||
SharedAll.Config.DEBUG = readDebugPref(PREF_OSFILE_LOG, false);
|
||||
OS.Shared.DEBUG = readDebugPref(PREF_OSFILE_LOG, false);
|
||||
|
||||
Services.prefs.addObserver(PREF_OSFILE_LOG_REDIRECT,
|
||||
function prefObserver(aSubject, aTopic, aData) {
|
||||
SharedAll.Config.TEST = readDebugPref(PREF_OSFILE_LOG_REDIRECT, OS.Shared.TEST);
|
||||
OS.Shared.TEST = readDebugPref(PREF_OSFILE_LOG_REDIRECT, OS.Shared.TEST);
|
||||
}, false);
|
||||
SharedAll.Config.TEST = readDebugPref(PREF_OSFILE_LOG_REDIRECT, false);
|
||||
OS.Shared.TEST = readDebugPref(PREF_OSFILE_LOG_REDIRECT, false);
|
||||
|
||||
// Update worker's DEBUG flag if it's true.
|
||||
// Don't start the worker just for this, though.
|
||||
if (SharedAll.Config.DEBUG && Scheduler.launched) {
|
||||
if (OS.Shared.DEBUG && Scheduler.launched) {
|
||||
Scheduler.post("SET_DEBUG", [true]);
|
||||
}
|
||||
|
||||
@ -764,7 +769,13 @@ File.Info = function Info(value) {
|
||||
}
|
||||
Object.defineProperty(this, "_deprecatedCreationDate", {value: value["creationDate"]});
|
||||
};
|
||||
File.Info.prototype = SysAll.AbstractInfo.prototype;
|
||||
if (OS.Constants.Win) {
|
||||
File.Info.prototype = Object.create(OS.Shared.Win.AbstractInfo.prototype);
|
||||
} else if (OS.Constants.libc) {
|
||||
File.Info.prototype = Object.create(OS.Shared.Unix.AbstractInfo.prototype);
|
||||
} else {
|
||||
throw new Error("I am neither under Windows nor under a Posix system");
|
||||
}
|
||||
|
||||
// Deprecated
|
||||
Object.defineProperty(File.Info.prototype, "creationDate", {
|
||||
@ -960,35 +971,26 @@ DirectoryIterator.prototype = {
|
||||
DirectoryIterator.Entry = function Entry(value) {
|
||||
return value;
|
||||
};
|
||||
DirectoryIterator.Entry.prototype = Object.create(SysAll.AbstractEntry.prototype);
|
||||
if (OS.Constants.Win) {
|
||||
DirectoryIterator.Entry.prototype = Object.create(OS.Shared.Win.AbstractEntry.prototype);
|
||||
} else if (OS.Constants.libc) {
|
||||
DirectoryIterator.Entry.prototype = Object.create(OS.Shared.Unix.AbstractEntry.prototype);
|
||||
} else {
|
||||
throw new Error("I am neither under Windows nor under a Posix system");
|
||||
}
|
||||
|
||||
DirectoryIterator.Entry.fromMsg = function fromMsg(value) {
|
||||
return new DirectoryIterator.Entry(value);
|
||||
};
|
||||
|
||||
// Constants
|
||||
File.POS_START = SysAll.POS_START;
|
||||
File.POS_CURRENT = SysAll.POS_CURRENT;
|
||||
File.POS_END = SysAll.POS_END;
|
||||
Object.defineProperty(File, "POS_START", {value: OS.Shared.POS_START});
|
||||
Object.defineProperty(File, "POS_CURRENT", {value: OS.Shared.POS_CURRENT});
|
||||
Object.defineProperty(File, "POS_END", {value: OS.Shared.POS_END});
|
||||
|
||||
// Exports
|
||||
File.Error = OSError;
|
||||
File.DirectoryIterator = DirectoryIterator;
|
||||
|
||||
this.OS = {};
|
||||
OS.File = File;
|
||||
OS.Constants = SharedAll.Constants;
|
||||
OS.Shared = {
|
||||
LOG: SharedAll.LOG,
|
||||
Type: SysAll.Type,
|
||||
get DEBUG() {
|
||||
return SharedAll.Config.DEBUG;
|
||||
},
|
||||
set DEBUG(x) {
|
||||
return SharedAll.Config.DEBUG = x;
|
||||
}
|
||||
};
|
||||
Object.freeze(OS.Shared);
|
||||
OS.File.Error = OSError;
|
||||
OS.File.DirectoryIterator = DirectoryIterator;
|
||||
OS.Path = Path;
|
||||
|
||||
|
||||
|
@ -14,8 +14,7 @@ if (this.Components) {
|
||||
|
||||
importScripts("resource://gre/modules/osfile.jsm");
|
||||
|
||||
let SharedAll = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm");
|
||||
let LOG = SharedAll.LOG.bind(SharedAll, "Agent");
|
||||
let LOG = exports.OS.Shared.LOG.bind(exports.OS.Shared.LOG, "Agent");
|
||||
|
||||
/**
|
||||
* Communications with the controller.
|
||||
@ -217,12 +216,12 @@ if (this.Components) {
|
||||
let Agent = {
|
||||
// Update worker's OS.Shared.DEBUG flag message from controller.
|
||||
SET_DEBUG: function SET_DEBUG (aDEBUG) {
|
||||
SharedAll.Config.DEBUG = aDEBUG;
|
||||
exports.OS.Shared.DEBUG = aDEBUG;
|
||||
},
|
||||
// Return worker's current OS.Shared.DEBUG value to controller.
|
||||
// Note: This is used for testing purposes.
|
||||
GET_DEBUG: function GET_DEBUG () {
|
||||
return SharedAll.Config.DEBUG;
|
||||
return exports.OS.Shared.DEBUG;
|
||||
},
|
||||
// Report file descriptors leaks.
|
||||
System_shutdown: function System_shutdown () {
|
||||
|
@ -1026,6 +1026,11 @@ exports.OS = {
|
||||
offsetBy: offsetBy
|
||||
}
|
||||
};
|
||||
if (exports.Constants.Win) {
|
||||
exports.OS.Win = {};
|
||||
} else {
|
||||
exports.OS.Unix = {};
|
||||
}
|
||||
|
||||
Object.defineProperty(exports.OS.Shared, "DEBUG", {
|
||||
get: function() {
|
||||
|
@ -14,11 +14,10 @@ if (typeof Components != "undefined") {
|
||||
}
|
||||
(function(exports) {
|
||||
|
||||
let SharedAll =
|
||||
require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm");
|
||||
exports.OS = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm").OS;
|
||||
|
||||
let LOG = SharedAll.LOG.bind(SharedAll, "Shared front-end");
|
||||
let clone = SharedAll.clone;
|
||||
let LOG = exports.OS.Shared.LOG.bind(OS.Shared, "Shared front-end");
|
||||
let clone = exports.OS.Shared.clone;
|
||||
|
||||
/**
|
||||
* Code shared by implementations of File.
|
||||
@ -90,7 +89,7 @@ AbstractFile.prototype = {
|
||||
break;
|
||||
}
|
||||
pos += chunkSize;
|
||||
ptr = SharedAll.offsetBy(ptr, chunkSize);
|
||||
ptr = exports.OS.Shared.offsetBy(ptr, chunkSize);
|
||||
}
|
||||
|
||||
return pos;
|
||||
@ -122,7 +121,7 @@ AbstractFile.prototype = {
|
||||
while (pos < bytes) {
|
||||
let chunkSize = this._write(ptr, bytes - pos, options);
|
||||
pos += chunkSize;
|
||||
ptr = SharedAll.offsetBy(ptr, chunkSize);
|
||||
ptr = exports.OS.Shared.offsetBy(ptr, chunkSize);
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
@ -151,13 +150,13 @@ AbstractFile.normalizeToPointer = function normalizeToPointer(candidate, bytes)
|
||||
if (candidate.isNull()) {
|
||||
throw new TypeError("Expecting a non-null pointer");
|
||||
}
|
||||
ptr = SharedAll.Type.uint8_t.out_ptr.cast(candidate);
|
||||
ptr = exports.OS.Shared.Type.uint8_t.out_ptr.cast(candidate);
|
||||
if (bytes == null) {
|
||||
throw new TypeError("C pointer missing bytes indication.");
|
||||
}
|
||||
} else if (SharedAll.isTypedArray(candidate)) {
|
||||
} else if (exports.OS.Shared.isTypedArray(candidate)) {
|
||||
// Typed Array
|
||||
ptr = SharedAll.Type.uint8_t.out_ptr.implementation(candidate.buffer);
|
||||
ptr = exports.OS.Shared.Type.uint8_t.out_ptr.implementation(candidate.buffer);
|
||||
if (bytes == null) {
|
||||
bytes = candidate.byteLength;
|
||||
} else if (candidate.byteLength < bytes) {
|
||||
@ -431,8 +430,5 @@ AbstractFile.removeDir = function(path, options = {}) {
|
||||
OS.File.removeEmptyDir(path);
|
||||
};
|
||||
|
||||
if (!exports.OS.Shared) {
|
||||
exports.OS.Shared = {};
|
||||
}
|
||||
exports.OS.Shared.AbstractFile = AbstractFile;
|
||||
exports.OS.Shared.AbstractFile = AbstractFile;
|
||||
})(this);
|
||||
|
@ -14,339 +14,323 @@
|
||||
*
|
||||
* This module can be:
|
||||
* - opened from the main thread as a jsm module;
|
||||
* - opened from a chrome worker through require().
|
||||
* - opened from a chrome worker through importScripts.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
let SharedAll;
|
||||
if (typeof Components != "undefined") {
|
||||
let Cu = Components.utils;
|
||||
// Module is opened as a jsm module
|
||||
Cu.import("resource://gre/modules/ctypes.jsm", this);
|
||||
this.EXPORTED_SYMBOLS = ["OS"];
|
||||
Components.utils.import("resource://gre/modules/ctypes.jsm");
|
||||
|
||||
SharedAll = {};
|
||||
Cu.import("resource://gre/modules/osfile/osfile_shared_allthreads.jsm", SharedAll);
|
||||
this.exports = {};
|
||||
} else if (typeof "module" != "undefined" && typeof "require" != "undefined") {
|
||||
// Module is loaded with require()
|
||||
SharedAll = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm");
|
||||
Components.utils.import("resource://gre/modules/osfile/osfile_shared_allthreads.jsm", SharedAll);
|
||||
} else {
|
||||
throw new Error("Please open this module with Component.utils.import or with require()");
|
||||
SharedAll = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm");
|
||||
}
|
||||
|
||||
let LOG = SharedAll.LOG.bind(SharedAll, "Unix", "allthreads");
|
||||
let Const = SharedAll.Constants.libc;
|
||||
|
||||
// Open libc
|
||||
let libc;
|
||||
let libc_candidates = [ "libSystem.B.dylib",
|
||||
"libc.so.6",
|
||||
"libc.so" ];
|
||||
for (let i = 0; i < libc_candidates.length; ++i) {
|
||||
try {
|
||||
libc = ctypes.open(libc_candidates[i]);
|
||||
break;
|
||||
} catch (x) {
|
||||
LOG("Could not open libc ", libc_candidates[i]);
|
||||
(function(exports) {
|
||||
"use strict";
|
||||
if ("OS" in exports && "Shared" in exports.OS && "Unix" in exports.OS.Shared) {
|
||||
// Avoid double inclusion
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!libc) {
|
||||
// Note: If you change the string here, please adapt tests accordingly
|
||||
throw new Error("Could not open system library: no libc");
|
||||
}
|
||||
exports.libc = libc;
|
||||
exports.OS = SharedAll.OS;
|
||||
|
||||
// Define declareFFI
|
||||
let declareFFI = SharedAll.declareFFI.bind(null, libc);
|
||||
exports.declareFFI = declareFFI;
|
||||
exports.OS.Shared.Unix = {};
|
||||
|
||||
// Define Error
|
||||
let strerror = libc.declare("strerror",
|
||||
ctypes.default_abi,
|
||||
/*return*/ ctypes.char.ptr,
|
||||
/*errnum*/ ctypes.int);
|
||||
let LOG = OS.Shared.LOG.bind(OS.Shared, "Unix", "allthreads");
|
||||
|
||||
/**
|
||||
* A File-related error.
|
||||
*
|
||||
* To obtain a human-readable error message, use method |toString|.
|
||||
* To determine the cause of the error, use the various |becauseX|
|
||||
* getters. To determine the operation that failed, use field
|
||||
* |operation|.
|
||||
*
|
||||
* Additionally, this implementation offers a field
|
||||
* |unixErrno|, which holds the OS-specific error
|
||||
* constant. If you need this level of detail, you may match the value
|
||||
* of this field against the error constants of |OS.Constants.libc|.
|
||||
*
|
||||
* @param {string=} operation The operation that failed. If unspecified,
|
||||
* the name of the calling function is taken to be the operation that
|
||||
* failed.
|
||||
* @param {number=} lastError The OS-specific constant detailing the
|
||||
* reason of the error. If unspecified, this is fetched from the system
|
||||
* status.
|
||||
*
|
||||
* @constructor
|
||||
* @extends {OS.Shared.Error}
|
||||
*/
|
||||
let OSError = function OSError(operation, errno) {
|
||||
operation = operation || "unknown operation";
|
||||
SharedAll.OSError.call(this, operation);
|
||||
this.unixErrno = errno || ctypes.errno;
|
||||
};
|
||||
OSError.prototype = Object.create(SharedAll.OSError.prototype);
|
||||
OSError.prototype.toString = function toString() {
|
||||
return "Unix error " + this.unixErrno +
|
||||
" during operation " + this.operation +
|
||||
" (" + strerror(this.unixErrno).readString() + ")";
|
||||
};
|
||||
|
||||
/**
|
||||
* |true| if the error was raised because a file or directory
|
||||
* already exists, |false| otherwise.
|
||||
*/
|
||||
Object.defineProperty(OSError.prototype, "becauseExists", {
|
||||
get: function becauseExists() {
|
||||
return this.unixErrno == Const.EEXIST;
|
||||
// Open libc
|
||||
let libc;
|
||||
let libc_candidates = [ "libSystem.B.dylib",
|
||||
"libc.so.6",
|
||||
"libc.so" ];
|
||||
for (let i = 0; i < libc_candidates.length; ++i) {
|
||||
try {
|
||||
libc = ctypes.open(libc_candidates[i]);
|
||||
break;
|
||||
} catch (x) {
|
||||
LOG("Could not open libc ", libc_candidates[i]);
|
||||
}
|
||||
}
|
||||
});
|
||||
/**
|
||||
* |true| if the error was raised because a file or directory
|
||||
* does not exist, |false| otherwise.
|
||||
*/
|
||||
Object.defineProperty(OSError.prototype, "becauseNoSuchFile", {
|
||||
get: function becauseNoSuchFile() {
|
||||
return this.unixErrno == Const.ENOENT;
|
||||
if (!libc) {
|
||||
// Note: If you change the string here, please adapt tests accordingly
|
||||
throw new Error("Could not open system library: no libc");
|
||||
}
|
||||
});
|
||||
exports.OS.Shared.Unix.libc = libc;
|
||||
|
||||
/**
|
||||
* |true| if the error was raised because a directory is not empty
|
||||
* does not exist, |false| otherwise.
|
||||
*/
|
||||
Object.defineProperty(OSError.prototype, "becauseNotEmpty", {
|
||||
get: function becauseNotEmpty() {
|
||||
return this.unixErrno == Const.ENOTEMPTY;
|
||||
}
|
||||
});
|
||||
/**
|
||||
* |true| if the error was raised because a file or directory
|
||||
* is closed, |false| otherwise.
|
||||
*/
|
||||
Object.defineProperty(OSError.prototype, "becauseClosed", {
|
||||
get: function becauseClosed() {
|
||||
return this.unixErrno == Const.EBADF;
|
||||
}
|
||||
});
|
||||
/**
|
||||
* |true| if the error was raised because permission is denied to
|
||||
* access a file or directory, |false| otherwise.
|
||||
*/
|
||||
Object.defineProperty(OSError.prototype, "becauseAccessDenied", {
|
||||
get: function becauseAccessDenied() {
|
||||
return this.unixErrno == Const.EACCES;
|
||||
}
|
||||
});
|
||||
// Define declareFFI
|
||||
let declareFFI = OS.Shared.declareFFI.bind(null, libc);
|
||||
exports.OS.Shared.Unix.declareFFI = declareFFI;
|
||||
|
||||
/**
|
||||
* Serialize an instance of OSError to something that can be
|
||||
* transmitted across threads (not necessarily a string).
|
||||
*/
|
||||
OSError.toMsg = function toMsg(error) {
|
||||
return {
|
||||
operation: error.operation,
|
||||
unixErrno: error.unixErrno
|
||||
// Define Error
|
||||
let strerror = libc.declare("strerror",
|
||||
ctypes.default_abi,
|
||||
/*return*/ ctypes.char.ptr,
|
||||
/*errnum*/ ctypes.int);
|
||||
|
||||
/**
|
||||
* A File-related error.
|
||||
*
|
||||
* To obtain a human-readable error message, use method |toString|.
|
||||
* To determine the cause of the error, use the various |becauseX|
|
||||
* getters. To determine the operation that failed, use field
|
||||
* |operation|.
|
||||
*
|
||||
* Additionally, this implementation offers a field
|
||||
* |unixErrno|, which holds the OS-specific error
|
||||
* constant. If you need this level of detail, you may match the value
|
||||
* of this field against the error constants of |OS.Constants.libc|.
|
||||
*
|
||||
* @param {string=} operation The operation that failed. If unspecified,
|
||||
* the name of the calling function is taken to be the operation that
|
||||
* failed.
|
||||
* @param {number=} lastError The OS-specific constant detailing the
|
||||
* reason of the error. If unspecified, this is fetched from the system
|
||||
* status.
|
||||
*
|
||||
* @constructor
|
||||
* @extends {OS.Shared.Error}
|
||||
*/
|
||||
let OSError = function OSError(operation, errno) {
|
||||
operation = operation || "unknown operation";
|
||||
exports.OS.Shared.Error.call(this, operation);
|
||||
this.unixErrno = errno || ctypes.errno;
|
||||
};
|
||||
OSError.prototype = new exports.OS.Shared.Error();
|
||||
OSError.prototype.toString = function toString() {
|
||||
return "Unix error " + this.unixErrno +
|
||||
" during operation " + this.operation +
|
||||
" (" + strerror(this.unixErrno).readString() + ")";
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Deserialize a message back to an instance of OSError
|
||||
*/
|
||||
OSError.fromMsg = function fromMsg(msg) {
|
||||
return new OSError(msg.operation, msg.unixErrno);
|
||||
};
|
||||
exports.Error = OSError;
|
||||
|
||||
/**
|
||||
* Code shared by implementations of File.Info on Unix
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
let AbstractInfo = function AbstractInfo(isDir, isSymLink, size, lastAccessDate,
|
||||
lastModificationDate, unixLastStatusChangeDate,
|
||||
unixOwner, unixGroup, unixMode) {
|
||||
this._isDir = isDir;
|
||||
this._isSymlLink = isSymLink;
|
||||
this._size = size;
|
||||
this._lastAccessDate = lastAccessDate;
|
||||
this._lastModificationDate = lastModificationDate;
|
||||
this._unixLastStatusChangeDate = unixLastStatusChangeDate;
|
||||
this._unixOwner = unixOwner;
|
||||
this._unixGroup = unixGroup;
|
||||
this._unixMode = unixMode;
|
||||
};
|
||||
|
||||
AbstractInfo.prototype = {
|
||||
/**
|
||||
* |true| if this file is a directory, |false| otherwise
|
||||
* |true| if the error was raised because a file or directory
|
||||
* already exists, |false| otherwise.
|
||||
*/
|
||||
get isDir() {
|
||||
return this._isDir;
|
||||
},
|
||||
Object.defineProperty(OSError.prototype, "becauseExists", {
|
||||
get: function becauseExists() {
|
||||
return this.unixErrno == OS.Constants.libc.EEXIST;
|
||||
}
|
||||
});
|
||||
/**
|
||||
* |true| if this file is a symbolink link, |false| otherwise
|
||||
* |true| if the error was raised because a file or directory
|
||||
* does not exist, |false| otherwise.
|
||||
*/
|
||||
get isSymLink() {
|
||||
return this._isSymlLink;
|
||||
},
|
||||
Object.defineProperty(OSError.prototype, "becauseNoSuchFile", {
|
||||
get: function becauseNoSuchFile() {
|
||||
return this.unixErrno == OS.Constants.libc.ENOENT;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* The size of the file, in bytes.
|
||||
* |true| if the error was raised because a directory is not empty
|
||||
* does not exist, |false| otherwise.
|
||||
*/
|
||||
Object.defineProperty(OSError.prototype, "becauseNotEmpty", {
|
||||
get: function becauseNotEmpty() {
|
||||
return this.unixErrno == OS.Constants.libc.ENOTEMPTY;
|
||||
}
|
||||
});
|
||||
/**
|
||||
* |true| if the error was raised because a file or directory
|
||||
* is closed, |false| otherwise.
|
||||
*/
|
||||
Object.defineProperty(OSError.prototype, "becauseClosed", {
|
||||
get: function becauseClosed() {
|
||||
return this.unixErrno == OS.Constants.libc.EBADF;
|
||||
}
|
||||
});
|
||||
/**
|
||||
* |true| if the error was raised because permission is denied to
|
||||
* access a file or directory, |false| otherwise.
|
||||
*/
|
||||
Object.defineProperty(OSError.prototype, "becauseAccessDenied", {
|
||||
get: function becauseAccessDenied() {
|
||||
return this.unixErrno == OS.Constants.libc.EACCES;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Serialize an instance of OSError to something that can be
|
||||
* transmitted across threads (not necessarily a string).
|
||||
*/
|
||||
OSError.toMsg = function toMsg(error) {
|
||||
return {
|
||||
operation: error.operation,
|
||||
unixErrno: error.unixErrno
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Deserialize a message back to an instance of OSError
|
||||
*/
|
||||
OSError.fromMsg = function fromMsg(msg) {
|
||||
return new OSError(msg.operation, msg.unixErrno);
|
||||
};
|
||||
|
||||
exports.OS.Shared.Unix.Error = OSError;
|
||||
|
||||
/**
|
||||
* Code shared by implementations of File.Info on Unix
|
||||
*
|
||||
* Note that the result may be |NaN| if the size of the file cannot be
|
||||
* represented in JavaScript.
|
||||
* @constructor
|
||||
*/
|
||||
let AbstractInfo = function AbstractInfo(isDir, isSymLink, size, lastAccessDate,
|
||||
lastModificationDate, unixLastStatusChangeDate,
|
||||
unixOwner, unixGroup, unixMode) {
|
||||
this._isDir = isDir;
|
||||
this._isSymlLink = isSymLink;
|
||||
this._size = size;
|
||||
this._lastAccessDate = lastAccessDate;
|
||||
this._lastModificationDate = lastModificationDate;
|
||||
this._unixLastStatusChangeDate = unixLastStatusChangeDate;
|
||||
this._unixOwner = unixOwner;
|
||||
this._unixGroup = unixGroup;
|
||||
this._unixMode = unixMode;
|
||||
};
|
||||
|
||||
AbstractInfo.prototype = {
|
||||
/**
|
||||
* |true| if this file is a directory, |false| otherwise
|
||||
*/
|
||||
get isDir() {
|
||||
return this._isDir;
|
||||
},
|
||||
/**
|
||||
* |true| if this file is a symbolink link, |false| otherwise
|
||||
*/
|
||||
get isSymLink() {
|
||||
return this._isSymlLink;
|
||||
},
|
||||
/**
|
||||
* The size of the file, in bytes.
|
||||
*
|
||||
* Note that the result may be |NaN| if the size of the file cannot be
|
||||
* represented in JavaScript.
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
get size() {
|
||||
return this._size;
|
||||
},
|
||||
/**
|
||||
* The date of last access to this file.
|
||||
*
|
||||
* Note that the definition of last access may depend on the
|
||||
* underlying operating system and file system.
|
||||
*
|
||||
* @type {Date}
|
||||
*/
|
||||
get lastAccessDate() {
|
||||
return this._lastAccessDate;
|
||||
},
|
||||
/**
|
||||
* Return the date of last modification of this file.
|
||||
*/
|
||||
get lastModificationDate() {
|
||||
return this._lastModificationDate;
|
||||
},
|
||||
/**
|
||||
* Return the date at which the status of this file was last modified
|
||||
* (this is the date of the latest write/renaming/mode change/...
|
||||
* of the file)
|
||||
*/
|
||||
get unixLastStatusChangeDate() {
|
||||
return this._unixLastStatusChangeDate;
|
||||
},
|
||||
/*
|
||||
* Return the Unix owner of this file
|
||||
*/
|
||||
get unixOwner() {
|
||||
return this._unixOwner;
|
||||
},
|
||||
/*
|
||||
* Return the Unix group of this file
|
||||
*/
|
||||
get unixGroup() {
|
||||
return this._unixGroup;
|
||||
},
|
||||
/*
|
||||
* Return the Unix group of this file
|
||||
*/
|
||||
get unixMode() {
|
||||
return this._unixMode;
|
||||
}
|
||||
};
|
||||
exports.OS.Shared.Unix.AbstractInfo = AbstractInfo;
|
||||
|
||||
/**
|
||||
* Code shared by implementations of File.DirectoryIterator.Entry on Unix
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
get size() {
|
||||
return this._size;
|
||||
},
|
||||
/**
|
||||
* The date of last access to this file.
|
||||
*
|
||||
* Note that the definition of last access may depend on the
|
||||
* underlying operating system and file system.
|
||||
*
|
||||
* @type {Date}
|
||||
*/
|
||||
get lastAccessDate() {
|
||||
return this._lastAccessDate;
|
||||
},
|
||||
/**
|
||||
* Return the date of last modification of this file.
|
||||
*/
|
||||
get lastModificationDate() {
|
||||
return this._lastModificationDate;
|
||||
},
|
||||
/**
|
||||
* Return the date at which the status of this file was last modified
|
||||
* (this is the date of the latest write/renaming/mode change/...
|
||||
* of the file)
|
||||
*/
|
||||
get unixLastStatusChangeDate() {
|
||||
return this._unixLastStatusChangeDate;
|
||||
},
|
||||
/*
|
||||
* Return the Unix owner of this file
|
||||
*/
|
||||
get unixOwner() {
|
||||
return this._unixOwner;
|
||||
},
|
||||
/*
|
||||
* Return the Unix group of this file
|
||||
*/
|
||||
get unixGroup() {
|
||||
return this._unixGroup;
|
||||
},
|
||||
/*
|
||||
* Return the Unix group of this file
|
||||
*/
|
||||
get unixMode() {
|
||||
return this._unixMode;
|
||||
}
|
||||
};
|
||||
exports.AbstractInfo = AbstractInfo;
|
||||
* @constructor
|
||||
*/
|
||||
let AbstractEntry = function AbstractEntry(isDir, isSymLink, name, path) {
|
||||
this._isDir = isDir;
|
||||
this._isSymlLink = isSymLink;
|
||||
this._name = name;
|
||||
this._path = path;
|
||||
};
|
||||
|
||||
/**
|
||||
* Code shared by implementations of File.DirectoryIterator.Entry on Unix
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
let AbstractEntry = function AbstractEntry(isDir, isSymLink, name, path) {
|
||||
this._isDir = isDir;
|
||||
this._isSymlLink = isSymLink;
|
||||
this._name = name;
|
||||
this._path = path;
|
||||
};
|
||||
AbstractEntry.prototype = {
|
||||
/**
|
||||
* |true| if the entry is a directory, |false| otherwise
|
||||
*/
|
||||
get isDir() {
|
||||
return this._isDir;
|
||||
},
|
||||
/**
|
||||
* |true| if the entry is a directory, |false| otherwise
|
||||
*/
|
||||
get isSymLink() {
|
||||
return this._isSymlLink;
|
||||
},
|
||||
/**
|
||||
* The name of the entry
|
||||
* @type {string}
|
||||
*/
|
||||
get name() {
|
||||
return this._name;
|
||||
},
|
||||
/**
|
||||
* The full path to the entry
|
||||
*/
|
||||
get path() {
|
||||
return this._path;
|
||||
}
|
||||
};
|
||||
exports.OS.Shared.Unix.AbstractEntry = AbstractEntry;
|
||||
|
||||
AbstractEntry.prototype = {
|
||||
/**
|
||||
* |true| if the entry is a directory, |false| otherwise
|
||||
*/
|
||||
get isDir() {
|
||||
return this._isDir;
|
||||
},
|
||||
/**
|
||||
* |true| if the entry is a directory, |false| otherwise
|
||||
*/
|
||||
get isSymLink() {
|
||||
return this._isSymlLink;
|
||||
},
|
||||
/**
|
||||
* The name of the entry
|
||||
* @type {string}
|
||||
*/
|
||||
get name() {
|
||||
return this._name;
|
||||
},
|
||||
/**
|
||||
* The full path to the entry
|
||||
*/
|
||||
get path() {
|
||||
return this._path;
|
||||
}
|
||||
};
|
||||
exports.AbstractEntry = AbstractEntry;
|
||||
// Special constants that need to be defined on all platforms
|
||||
|
||||
// Special constants that need to be defined on all platforms
|
||||
Object.defineProperty(exports.OS.Shared, "POS_START", { value: exports.OS.Constants.libc.SEEK_SET });
|
||||
Object.defineProperty(exports.OS.Shared, "POS_CURRENT", { value: exports.OS.Constants.libc.SEEK_CUR });
|
||||
Object.defineProperty(exports.OS.Shared, "POS_END", { value: exports.OS.Constants.libc.SEEK_END });
|
||||
|
||||
exports.POS_START = Const.SEEK_SET;
|
||||
exports.POS_CURRENT = Const.SEEK_CUR;
|
||||
exports.POS_END = Const.SEEK_END;
|
||||
// Special types that need to be defined for communication
|
||||
// between threads
|
||||
let Types = exports.OS.Shared.Type;
|
||||
|
||||
// Special types that need to be defined for communication
|
||||
// between threads
|
||||
let Type = Object.create(SharedAll.Type);
|
||||
exports.Type = Type;
|
||||
/**
|
||||
* Native paths
|
||||
*
|
||||
* Under Unix, expressed as C strings
|
||||
*/
|
||||
Types.path = Types.cstring.withName("[in] path");
|
||||
Types.out_path = Types.out_cstring.withName("[out] path");
|
||||
|
||||
/**
|
||||
* Native paths
|
||||
*
|
||||
* Under Unix, expressed as C strings
|
||||
*/
|
||||
Type.path = Type.cstring.withName("[in] path");
|
||||
Type.out_path = Type.out_cstring.withName("[out] path");
|
||||
// Special constructors that need to be defined on all threads
|
||||
OSError.closed = function closed(operation) {
|
||||
return new OSError(operation, OS.Constants.libc.EBADF);
|
||||
};
|
||||
|
||||
// Special constructors that need to be defined on all threads
|
||||
OSError.closed = function closed(operation) {
|
||||
return new OSError(operation, Const.EBADF);
|
||||
};
|
||||
OSError.exists = function exists(operation) {
|
||||
return new OSError(operation, OS.Constants.libc.EEXIST);
|
||||
};
|
||||
|
||||
OSError.exists = function exists(operation) {
|
||||
return new OSError(operation, Const.EEXIST);
|
||||
};
|
||||
|
||||
OSError.noSuchFile = function noSuchFile(operation) {
|
||||
return new OSError(operation, Const.ENOENT);
|
||||
};
|
||||
|
||||
let EXPORTED_SYMBOLS = [
|
||||
"declareFFI",
|
||||
"libc",
|
||||
"Error",
|
||||
"AbstractInfo",
|
||||
"AbstractEntry",
|
||||
"Type",
|
||||
"POS_START",
|
||||
"POS_CURRENT",
|
||||
"POS_END"
|
||||
];
|
||||
|
||||
//////////// Boilerplate
|
||||
if (typeof Components != "undefined") {
|
||||
this.EXPORTED_SYMBOLS = EXPORTED_SYMBOLS;
|
||||
for (let symbol of EXPORTED_SYMBOLS) {
|
||||
this[symbol] = exports[symbol];
|
||||
}
|
||||
}
|
||||
OSError.noSuchFile = function noSuchFile(operation) {
|
||||
return new OSError(operation, OS.Constants.libc.ENOENT);
|
||||
};
|
||||
})(this);
|
||||
|
@ -17,13 +17,12 @@
|
||||
return; // Avoid double initialization
|
||||
}
|
||||
|
||||
let SharedAll =
|
||||
require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm");
|
||||
let SysAll =
|
||||
require("resource://gre/modules/osfile/osfile_unix_allthreads.jsm");
|
||||
let LOG = SharedAll.LOG.bind(SharedAll, "Unix", "back");
|
||||
let libc = SysAll.libc;
|
||||
let Const = SharedAll.Constants.libc;
|
||||
exports.OS = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm").OS;
|
||||
|
||||
exports.OS.Unix.File = {};
|
||||
|
||||
let LOG = exports.OS.Shared.LOG.bind(OS.Shared, "Unix", "back");
|
||||
let libc = exports.OS.Shared.Unix.libc;
|
||||
|
||||
/**
|
||||
* Initialize the Unix module.
|
||||
@ -36,20 +35,27 @@
|
||||
if (aDeclareFFI) {
|
||||
declareFFI = aDeclareFFI.bind(null, libc);
|
||||
} else {
|
||||
declareFFI = SysAll.declareFFI;
|
||||
declareFFI = exports.OS.Shared.Unix.declareFFI;
|
||||
}
|
||||
|
||||
// Shorthands
|
||||
let OSUnix = exports.OS.Unix;
|
||||
let UnixFile = exports.OS.Unix.File;
|
||||
if (!exports.OS.Types) {
|
||||
exports.OS.Types = {};
|
||||
}
|
||||
let Type = exports.OS.Shared.Type;
|
||||
let Types = Type;
|
||||
|
||||
// Initialize types that require additional OS-specific
|
||||
// support - either finalization or matching against
|
||||
// OS-specific constants.
|
||||
let Type = Object.create(SysAll.Type);
|
||||
let SysFile = exports.OS.Unix.File = { Type: Type };
|
||||
|
||||
/**
|
||||
* A file descriptor.
|
||||
*/
|
||||
Type.fd = Type.int.withName("fd");
|
||||
Type.fd.importFromC = function importFromC(fd_int) {
|
||||
Types.fd = Type.int.withName("fd");
|
||||
Types.fd.importFromC = function importFromC(fd_int) {
|
||||
return ctypes.CDataFinalizer(fd_int, _close);
|
||||
};
|
||||
|
||||
@ -58,8 +64,8 @@
|
||||
* A C integer holding -1 in case of error or a file descriptor
|
||||
* in case of success.
|
||||
*/
|
||||
Type.negativeone_or_fd = Type.fd.withName("negativeone_or_fd");
|
||||
Type.negativeone_or_fd.importFromC =
|
||||
Types.negativeone_or_fd = Types.fd.withName("negativeone_or_fd");
|
||||
Types.negativeone_or_fd.importFromC =
|
||||
function importFromC(fd_int) {
|
||||
if (fd_int == -1) {
|
||||
return -1;
|
||||
@ -71,31 +77,31 @@
|
||||
* A C integer holding -1 in case of error or a meaningless value
|
||||
* in case of success.
|
||||
*/
|
||||
Type.negativeone_or_nothing =
|
||||
Type.int.withName("negativeone_or_nothing");
|
||||
Types.negativeone_or_nothing =
|
||||
Types.int.withName("negativeone_or_nothing");
|
||||
|
||||
/**
|
||||
* A C integer holding -1 in case of error or a positive integer
|
||||
* in case of success.
|
||||
*/
|
||||
Type.negativeone_or_ssize_t =
|
||||
Type.ssize_t.withName("negativeone_or_ssize_t");
|
||||
Types.negativeone_or_ssize_t =
|
||||
Types.ssize_t.withName("negativeone_or_ssize_t");
|
||||
|
||||
/**
|
||||
* Various libc integer types
|
||||
*/
|
||||
Type.mode_t =
|
||||
Type.intn_t(Const.OSFILE_SIZEOF_MODE_T).withName("mode_t");
|
||||
Type.uid_t =
|
||||
Type.intn_t(Const.OSFILE_SIZEOF_UID_T).withName("uid_t");
|
||||
Type.gid_t =
|
||||
Type.intn_t(Const.OSFILE_SIZEOF_GID_T).withName("gid_t");
|
||||
Types.mode_t =
|
||||
Types.intn_t(OS.Constants.libc.OSFILE_SIZEOF_MODE_T).withName("mode_t");
|
||||
Types.uid_t =
|
||||
Types.intn_t(OS.Constants.libc.OSFILE_SIZEOF_UID_T).withName("uid_t");
|
||||
Types.gid_t =
|
||||
Types.intn_t(OS.Constants.libc.OSFILE_SIZEOF_GID_T).withName("gid_t");
|
||||
|
||||
/**
|
||||
* Type |time_t|
|
||||
*/
|
||||
Type.time_t =
|
||||
Type.intn_t(Const.OSFILE_SIZEOF_TIME_T).withName("time_t");
|
||||
Types.time_t =
|
||||
Types.intn_t(OS.Constants.libc.OSFILE_SIZEOF_TIME_T).withName("time_t");
|
||||
|
||||
// Structure |dirent|
|
||||
// Building this type is rather complicated, as its layout varies between
|
||||
@ -109,90 +115,90 @@
|
||||
// };
|
||||
{
|
||||
let d_name_extra_size = 0;
|
||||
if (Const.OSFILE_SIZEOF_DIRENT_D_NAME < 8) {
|
||||
if (OS.Constants.libc.OSFILE_SIZEOF_DIRENT_D_NAME < 8) {
|
||||
// d_name is defined like "char d_name[1];" on some platforms
|
||||
// (e.g. Solaris), we need to give it more size for our structure.
|
||||
d_name_extra_size = 256;
|
||||
}
|
||||
|
||||
let dirent = new SharedAll.HollowStructure("dirent",
|
||||
Const.OSFILE_SIZEOF_DIRENT + d_name_extra_size);
|
||||
if (Const.OSFILE_OFFSETOF_DIRENT_D_TYPE != undefined) {
|
||||
let dirent = new OS.Shared.HollowStructure("dirent",
|
||||
OS.Constants.libc.OSFILE_SIZEOF_DIRENT + d_name_extra_size);
|
||||
if (OS.Constants.libc.OSFILE_OFFSETOF_DIRENT_D_TYPE != undefined) {
|
||||
// |dirent| doesn't have d_type on some platforms (e.g. Solaris).
|
||||
dirent.add_field_at(Const.OSFILE_OFFSETOF_DIRENT_D_TYPE,
|
||||
dirent.add_field_at(OS.Constants.libc.OSFILE_OFFSETOF_DIRENT_D_TYPE,
|
||||
"d_type", ctypes.uint8_t);
|
||||
}
|
||||
dirent.add_field_at(Const.OSFILE_OFFSETOF_DIRENT_D_NAME,
|
||||
dirent.add_field_at(OS.Constants.libc.OSFILE_OFFSETOF_DIRENT_D_NAME,
|
||||
"d_name", ctypes.ArrayType(ctypes.char,
|
||||
Const.OSFILE_SIZEOF_DIRENT_D_NAME + d_name_extra_size));
|
||||
OS.Constants.libc.OSFILE_SIZEOF_DIRENT_D_NAME + d_name_extra_size));
|
||||
|
||||
// We now have built |dirent|.
|
||||
Type.dirent = dirent.getType();
|
||||
Types.dirent = dirent.getType();
|
||||
}
|
||||
Type.null_or_dirent_ptr =
|
||||
new SharedAll.Type("null_of_dirent",
|
||||
Type.dirent.out_ptr.implementation);
|
||||
Types.null_or_dirent_ptr =
|
||||
new Type("null_of_dirent",
|
||||
Types.dirent.out_ptr.implementation);
|
||||
|
||||
// Structure |stat|
|
||||
// Same technique
|
||||
{
|
||||
let stat = new SharedAll.HollowStructure("stat",
|
||||
Const.OSFILE_SIZEOF_STAT);
|
||||
stat.add_field_at(Const.OSFILE_OFFSETOF_STAT_ST_MODE,
|
||||
"st_mode", Type.mode_t.implementation);
|
||||
stat.add_field_at(Const.OSFILE_OFFSETOF_STAT_ST_UID,
|
||||
"st_uid", Type.uid_t.implementation);
|
||||
stat.add_field_at(Const.OSFILE_OFFSETOF_STAT_ST_GID,
|
||||
"st_gid", Type.gid_t.implementation);
|
||||
let stat = new OS.Shared.HollowStructure("stat",
|
||||
OS.Constants.libc.OSFILE_SIZEOF_STAT);
|
||||
stat.add_field_at(OS.Constants.libc.OSFILE_OFFSETOF_STAT_ST_MODE,
|
||||
"st_mode", Types.mode_t.implementation);
|
||||
stat.add_field_at(OS.Constants.libc.OSFILE_OFFSETOF_STAT_ST_UID,
|
||||
"st_uid", Types.uid_t.implementation);
|
||||
stat.add_field_at(OS.Constants.libc.OSFILE_OFFSETOF_STAT_ST_GID,
|
||||
"st_gid", Types.gid_t.implementation);
|
||||
|
||||
// Here, things get complicated with different data structures.
|
||||
// Some platforms have |time_t st_atime| and some platforms have
|
||||
// |timespec st_atimespec|. However, since |timespec| starts with
|
||||
// a |time_t|, followed by nanoseconds, we just cheat and pretend
|
||||
// that everybody has |time_t st_atime|, possibly followed by padding
|
||||
stat.add_field_at(Const.OSFILE_OFFSETOF_STAT_ST_ATIME,
|
||||
"st_atime", Type.time_t.implementation);
|
||||
stat.add_field_at(Const.OSFILE_OFFSETOF_STAT_ST_MTIME,
|
||||
"st_mtime", Type.time_t.implementation);
|
||||
stat.add_field_at(Const.OSFILE_OFFSETOF_STAT_ST_CTIME,
|
||||
"st_ctime", Type.time_t.implementation);
|
||||
stat.add_field_at(OS.Constants.libc.OSFILE_OFFSETOF_STAT_ST_ATIME,
|
||||
"st_atime", Types.time_t.implementation);
|
||||
stat.add_field_at(OS.Constants.libc.OSFILE_OFFSETOF_STAT_ST_MTIME,
|
||||
"st_mtime", Types.time_t.implementation);
|
||||
stat.add_field_at(OS.Constants.libc.OSFILE_OFFSETOF_STAT_ST_CTIME,
|
||||
"st_ctime", Types.time_t.implementation);
|
||||
|
||||
// To complicate further, MacOS and some BSDs have a field |birthtime|
|
||||
if ("OSFILE_OFFSETOF_STAT_ST_BIRTHTIME" in Const) {
|
||||
stat.add_field_at(Const.OSFILE_OFFSETOF_STAT_ST_BIRTHTIME,
|
||||
"st_birthtime", Type.time_t.implementation);
|
||||
if ("OSFILE_OFFSETOF_STAT_ST_BIRTHTIME" in OS.Constants.libc) {
|
||||
stat.add_field_at(OS.Constants.libc.OSFILE_OFFSETOF_STAT_ST_BIRTHTIME,
|
||||
"st_birthtime", Types.time_t.implementation);
|
||||
}
|
||||
|
||||
stat.add_field_at(Const.OSFILE_OFFSETOF_STAT_ST_SIZE,
|
||||
"st_size", Type.size_t.implementation);
|
||||
Type.stat = stat.getType();
|
||||
stat.add_field_at(OS.Constants.libc.OSFILE_OFFSETOF_STAT_ST_SIZE,
|
||||
"st_size", Types.size_t.implementation);
|
||||
Types.stat = stat.getType();
|
||||
}
|
||||
|
||||
// Structure |DIR|
|
||||
if ("OSFILE_SIZEOF_DIR" in Const) {
|
||||
if ("OSFILE_SIZEOF_DIR" in OS.Constants.libc) {
|
||||
// On platforms for which we need to access the fields of DIR
|
||||
// directly (e.g. because certain functions are implemented
|
||||
// as macros), we need to define DIR as a hollow structure.
|
||||
let DIR = new SharedAll.HollowStructure(
|
||||
let DIR = new OS.Shared.HollowStructure(
|
||||
"DIR",
|
||||
Const.OSFILE_SIZEOF_DIR);
|
||||
OS.Constants.libc.OSFILE_SIZEOF_DIR);
|
||||
|
||||
DIR.add_field_at(
|
||||
Const.OSFILE_OFFSETOF_DIR_DD_FD,
|
||||
OS.Constants.libc.OSFILE_OFFSETOF_DIR_DD_FD,
|
||||
"dd_fd",
|
||||
Type.fd.implementation);
|
||||
Types.fd.implementation);
|
||||
|
||||
Type.DIR = DIR.getType();
|
||||
Types.DIR = DIR.getType();
|
||||
} else {
|
||||
// On other platforms, we keep DIR as a blackbox
|
||||
Type.DIR =
|
||||
new SharedAll.Type("DIR",
|
||||
Types.DIR =
|
||||
new Type("DIR",
|
||||
ctypes.StructType("DIR"));
|
||||
}
|
||||
|
||||
Type.null_or_DIR_ptr =
|
||||
Type.DIR.out_ptr.withName("null_or_DIR*");
|
||||
Type.null_or_DIR_ptr.importFromC = function importFromC(dir) {
|
||||
Types.null_or_DIR_ptr =
|
||||
Types.DIR.out_ptr.withName("null_or_DIR*");
|
||||
Types.null_or_DIR_ptr.importFromC = function importFromC(dir) {
|
||||
if (dir == null || dir.isNull()) {
|
||||
return null;
|
||||
}
|
||||
@ -202,12 +208,12 @@
|
||||
// Declare libc functions as functions of |OS.Unix.File|
|
||||
|
||||
// Finalizer-related functions
|
||||
let _close = SysFile._close =
|
||||
let _close = UnixFile._close =
|
||||
libc.declare("close", ctypes.default_abi,
|
||||
/*return */ctypes.int,
|
||||
/*fd*/ ctypes.int);
|
||||
|
||||
SysFile.close = function close(fd) {
|
||||
UnixFile.close = function close(fd) {
|
||||
// Detach the finalizer and call |_close|.
|
||||
return fd.dispose();
|
||||
};
|
||||
@ -215,9 +221,9 @@
|
||||
let _close_dir =
|
||||
libc.declare("closedir", ctypes.default_abi,
|
||||
/*return */ctypes.int,
|
||||
/*dirp*/ Type.DIR.in_ptr.implementation);
|
||||
/*dirp*/ Types.DIR.in_ptr.implementation);
|
||||
|
||||
SysFile.closedir = function closedir(fd) {
|
||||
UnixFile.closedir = function closedir(fd) {
|
||||
// Detach the finalizer and call |_close_dir|.
|
||||
return fd.dispose();
|
||||
};
|
||||
@ -232,7 +238,7 @@
|
||||
// correct implementation free().
|
||||
default_lib = ctypes.open("a.out");
|
||||
|
||||
SysFile.free =
|
||||
UnixFile.free =
|
||||
default_lib.declare("free", ctypes.default_abi,
|
||||
/*return*/ ctypes.void_t,
|
||||
/*ptr*/ ctypes.voidptr_t);
|
||||
@ -241,7 +247,7 @@
|
||||
// We don't have an a.out library or a.out doesn't contain free.
|
||||
// Either way, use the ordinary libc free.
|
||||
|
||||
SysFile.free =
|
||||
UnixFile.free =
|
||||
libc.declare("free", ctypes.default_abi,
|
||||
/*return*/ ctypes.void_t,
|
||||
/*ptr*/ ctypes.voidptr_t);
|
||||
@ -250,293 +256,293 @@
|
||||
|
||||
|
||||
// Other functions
|
||||
SysFile.access =
|
||||
UnixFile.access =
|
||||
declareFFI("access", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*path*/ Type.path,
|
||||
/*mode*/ Type.int);
|
||||
/*return*/ Types.negativeone_or_nothing,
|
||||
/*path*/ Types.path,
|
||||
/*mode*/ Types.int);
|
||||
|
||||
SysFile.chdir =
|
||||
UnixFile.chdir =
|
||||
declareFFI("chdir", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*path*/ Type.path);
|
||||
/*return*/ Types.negativeone_or_nothing,
|
||||
/*path*/ Types.path);
|
||||
|
||||
SysFile.chmod =
|
||||
UnixFile.chmod =
|
||||
declareFFI("chmod", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*path*/ Type.path,
|
||||
/*mode*/ Type.mode_t);
|
||||
/*return*/ Types.negativeone_or_nothing,
|
||||
/*path*/ Types.path,
|
||||
/*mode*/ Types.mode_t);
|
||||
|
||||
SysFile.chown =
|
||||
UnixFile.chown =
|
||||
declareFFI("chown", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*path*/ Type.path,
|
||||
/*uid*/ Type.uid_t,
|
||||
/*gid*/ Type.gid_t);
|
||||
/*return*/ Types.negativeone_or_nothing,
|
||||
/*path*/ Types.path,
|
||||
/*uid*/ Types.uid_t,
|
||||
/*gid*/ Types.gid_t);
|
||||
|
||||
SysFile.copyfile =
|
||||
UnixFile.copyfile =
|
||||
declareFFI("copyfile", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*source*/ Type.path,
|
||||
/*dest*/ Type.path,
|
||||
/*state*/ Type.void_t.in_ptr, // Ignored atm
|
||||
/*flags*/ Type.uint32_t);
|
||||
/*return*/ Types.negativeone_or_nothing,
|
||||
/*source*/ Types.path,
|
||||
/*dest*/ Types.path,
|
||||
/*state*/ Types.void_t.in_ptr, // Ignored atm
|
||||
/*flags*/ Types.uint32_t);
|
||||
|
||||
SysFile.dup =
|
||||
UnixFile.dup =
|
||||
declareFFI("dup", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_fd,
|
||||
/*fd*/ Type.fd);
|
||||
/*return*/ Types.negativeone_or_fd,
|
||||
/*fd*/ Types.fd);
|
||||
|
||||
if ("OSFILE_SIZEOF_DIR" in Const) {
|
||||
if ("OSFILE_SIZEOF_DIR" in OS.Constants.libc) {
|
||||
// On platforms for which |dirfd| is a macro
|
||||
SysFile.dirfd =
|
||||
UnixFile.dirfd =
|
||||
function dirfd(DIRp) {
|
||||
return Type.DIR.in_ptr.implementation(DIRp).contents.dd_fd;
|
||||
return Types.DIR.in_ptr.implementation(DIRp).contents.dd_fd;
|
||||
};
|
||||
} else {
|
||||
// On platforms for which |dirfd| is a function
|
||||
SysFile.dirfd =
|
||||
UnixFile.dirfd =
|
||||
declareFFI("dirfd", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_fd,
|
||||
/*dir*/ Type.DIR.in_ptr);
|
||||
/*return*/ Types.negativeone_or_fd,
|
||||
/*dir*/ Types.DIR.in_ptr);
|
||||
}
|
||||
|
||||
SysFile.chdir =
|
||||
UnixFile.chdir =
|
||||
declareFFI("chdir", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*path*/ Type.path);
|
||||
/*return*/ Types.negativeone_or_nothing,
|
||||
/*path*/ Types.path);
|
||||
|
||||
SysFile.fchdir =
|
||||
UnixFile.fchdir =
|
||||
declareFFI("fchdir", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*fd*/ Type.fd);
|
||||
/*return*/ Types.negativeone_or_nothing,
|
||||
/*fd*/ Types.fd);
|
||||
|
||||
SysFile.fchown =
|
||||
UnixFile.fchown =
|
||||
declareFFI("fchown", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*fd*/ Type.fd,
|
||||
/*uid_t*/ Type.uid_t,
|
||||
/*gid_t*/ Type.gid_t);
|
||||
/*return*/ Types.negativeone_or_nothing,
|
||||
/*fd*/ Types.fd,
|
||||
/*uid_t*/ Types.uid_t,
|
||||
/*gid_t*/ Types.gid_t);
|
||||
|
||||
SysFile.fsync =
|
||||
UnixFile.fsync =
|
||||
declareFFI("fsync", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*fd*/ Type.fd);
|
||||
/*return*/ Types.negativeone_or_nothing,
|
||||
/*fd*/ Types.fd);
|
||||
|
||||
SysFile.getcwd =
|
||||
UnixFile.getcwd =
|
||||
declareFFI("getcwd", ctypes.default_abi,
|
||||
/*return*/ Type.out_path,
|
||||
/*buf*/ Type.out_path,
|
||||
/*size*/ Type.size_t);
|
||||
/*return*/ Types.out_path,
|
||||
/*buf*/ Types.out_path,
|
||||
/*size*/ Types.size_t);
|
||||
|
||||
SysFile.getwd =
|
||||
UnixFile.getwd =
|
||||
declareFFI("getwd", ctypes.default_abi,
|
||||
/*return*/ Type.out_path,
|
||||
/*buf*/ Type.out_path);
|
||||
/*return*/ Types.out_path,
|
||||
/*buf*/ Types.out_path);
|
||||
|
||||
// Two variants of |getwd| which allocate the memory
|
||||
// dynamically.
|
||||
|
||||
// Linux/Android version
|
||||
SysFile.get_current_dir_name =
|
||||
UnixFile.get_current_dir_name =
|
||||
declareFFI("get_current_dir_name", ctypes.default_abi,
|
||||
/*return*/ Type.out_path.releaseWith(SysFile.free));
|
||||
/*return*/ Types.out_path.releaseWith(UnixFile.free));
|
||||
|
||||
// MacOS/BSD version (will return NULL on Linux/Android)
|
||||
SysFile.getwd_auto =
|
||||
UnixFile.getwd_auto =
|
||||
declareFFI("getwd", ctypes.default_abi,
|
||||
/*return*/ Type.out_path.releaseWith(SysFile.free),
|
||||
/*buf*/ Type.void_t.out_ptr);
|
||||
/*return*/ Types.out_path.releaseWith(UnixFile.free),
|
||||
/*buf*/ Types.void_t.out_ptr);
|
||||
|
||||
SysFile.fdatasync =
|
||||
UnixFile.fdatasync =
|
||||
declareFFI("fdatasync", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*fd*/ Type.fd); // Note: MacOS/BSD-specific
|
||||
/*return*/ Types.negativeone_or_nothing,
|
||||
/*fd*/ Types.fd); // Note: MacOS/BSD-specific
|
||||
|
||||
SysFile.ftruncate =
|
||||
UnixFile.ftruncate =
|
||||
declareFFI("ftruncate", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*fd*/ Type.fd,
|
||||
/*length*/ Type.off_t);
|
||||
/*return*/ Types.negativeone_or_nothing,
|
||||
/*fd*/ Types.fd,
|
||||
/*length*/ Types.off_t);
|
||||
|
||||
if (Const._DARWIN_FEATURE_64_BIT_INODE) {
|
||||
SysFile.fstat =
|
||||
if (OS.Constants.libc._DARWIN_FEATURE_64_BIT_INODE) {
|
||||
UnixFile.fstat =
|
||||
declareFFI("fstat$INODE64", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*path*/ Type.fd,
|
||||
/*buf*/ Type.stat.out_ptr
|
||||
/*return*/ Types.negativeone_or_nothing,
|
||||
/*path*/ Types.fd,
|
||||
/*buf*/ Types.stat.out_ptr
|
||||
);
|
||||
} else {
|
||||
SysFile.fstat =
|
||||
UnixFile.fstat =
|
||||
declareFFI("fstat", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*path*/ Type.fd,
|
||||
/*buf*/ Type.stat.out_ptr
|
||||
/*return*/ Types.negativeone_or_nothing,
|
||||
/*path*/ Types.fd,
|
||||
/*buf*/ Types.stat.out_ptr
|
||||
);
|
||||
}
|
||||
|
||||
SysFile.lchown =
|
||||
UnixFile.lchown =
|
||||
declareFFI("lchown", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*path*/ Type.path,
|
||||
/*uid_t*/ Type.uid_t,
|
||||
/*gid_t*/ Type.gid_t);
|
||||
/*return*/ Types.negativeone_or_nothing,
|
||||
/*path*/ Types.path,
|
||||
/*uid_t*/ Types.uid_t,
|
||||
/*gid_t*/ Types.gid_t);
|
||||
|
||||
SysFile.link =
|
||||
UnixFile.link =
|
||||
declareFFI("link", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*source*/ Type.path,
|
||||
/*dest*/ Type.path);
|
||||
/*return*/ Types.negativeone_or_nothing,
|
||||
/*source*/ Types.path,
|
||||
/*dest*/ Types.path);
|
||||
|
||||
SysFile.lseek =
|
||||
UnixFile.lseek =
|
||||
declareFFI("lseek", ctypes.default_abi,
|
||||
/*return*/ Type.off_t,
|
||||
/*fd*/ Type.fd,
|
||||
/*offset*/ Type.off_t,
|
||||
/*whence*/ Type.int);
|
||||
/*return*/ Types.off_t,
|
||||
/*fd*/ Types.fd,
|
||||
/*offset*/ Types.off_t,
|
||||
/*whence*/ Types.int);
|
||||
|
||||
SysFile.mkdir =
|
||||
UnixFile.mkdir =
|
||||
declareFFI("mkdir", ctypes.default_abi,
|
||||
/*return*/ Type.int,
|
||||
/*path*/ Type.path,
|
||||
/*mode*/ Type.int);
|
||||
/*return*/ Types.int,
|
||||
/*path*/ Types.path,
|
||||
/*mode*/ Types.int);
|
||||
|
||||
SysFile.mkstemp =
|
||||
UnixFile.mkstemp =
|
||||
declareFFI("mkstemp", ctypes.default_abi,
|
||||
/*return*/ Type.fd,
|
||||
/*template*/Type.out_path);
|
||||
/*return*/ Types.fd,
|
||||
/*template*/Types.out_path);
|
||||
|
||||
SysFile.open =
|
||||
UnixFile.open =
|
||||
declareFFI("open", ctypes.default_abi,
|
||||
/*return*/Type.negativeone_or_fd,
|
||||
/*path*/ Type.path,
|
||||
/*oflags*/Type.int,
|
||||
/*mode*/ Type.int);
|
||||
/*return*/Types.negativeone_or_fd,
|
||||
/*path*/ Types.path,
|
||||
/*oflags*/Types.int,
|
||||
/*mode*/ Types.int);
|
||||
|
||||
SysFile.opendir =
|
||||
UnixFile.opendir =
|
||||
declareFFI("opendir", ctypes.default_abi,
|
||||
/*return*/ Type.null_or_DIR_ptr,
|
||||
/*path*/ Type.path);
|
||||
/*return*/ Types.null_or_DIR_ptr,
|
||||
/*path*/ Types.path);
|
||||
|
||||
SysFile.pread =
|
||||
UnixFile.pread =
|
||||
declareFFI("pread", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_ssize_t,
|
||||
/*fd*/ Type.fd,
|
||||
/*buf*/ Type.void_t.out_ptr,
|
||||
/*nbytes*/ Type.size_t,
|
||||
/*offset*/ Type.off_t);
|
||||
/*return*/ Types.negativeone_or_ssize_t,
|
||||
/*fd*/ Types.fd,
|
||||
/*buf*/ Types.void_t.out_ptr,
|
||||
/*nbytes*/ Types.size_t,
|
||||
/*offset*/ Types.off_t);
|
||||
|
||||
SysFile.pwrite =
|
||||
UnixFile.pwrite =
|
||||
declareFFI("pwrite", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_ssize_t,
|
||||
/*fd*/ Type.fd,
|
||||
/*buf*/ Type.void_t.in_ptr,
|
||||
/*nbytes*/ Type.size_t,
|
||||
/*offset*/ Type.off_t);
|
||||
/*return*/ Types.negativeone_or_ssize_t,
|
||||
/*fd*/ Types.fd,
|
||||
/*buf*/ Types.void_t.in_ptr,
|
||||
/*nbytes*/ Types.size_t,
|
||||
/*offset*/ Types.off_t);
|
||||
|
||||
SysFile.read =
|
||||
UnixFile.read =
|
||||
declareFFI("read", ctypes.default_abi,
|
||||
/*return*/Type.negativeone_or_ssize_t,
|
||||
/*fd*/ Type.fd,
|
||||
/*buf*/ Type.void_t.out_ptr,
|
||||
/*nbytes*/Type.size_t);
|
||||
/*return*/Types.negativeone_or_ssize_t,
|
||||
/*fd*/ Types.fd,
|
||||
/*buf*/ Types.void_t.out_ptr,
|
||||
/*nbytes*/Types.size_t);
|
||||
|
||||
SysFile.posix_fadvise =
|
||||
UnixFile.posix_fadvise =
|
||||
declareFFI("posix_fadvise", ctypes.default_abi,
|
||||
/*return*/ Type.int,
|
||||
/*fd*/ Type.fd,
|
||||
/*offset*/ Type.off_t,
|
||||
/*len*/ Type.off_t,
|
||||
/*advise*/ Type.int);
|
||||
/*return*/ Types.int,
|
||||
/*fd*/ Types.fd,
|
||||
/*offset*/ Types.off_t,
|
||||
/*len*/ Types.off_t,
|
||||
/*advise*/ Types.int);
|
||||
|
||||
if (Const._DARWIN_FEATURE_64_BIT_INODE) {
|
||||
if (OS.Constants.libc._DARWIN_FEATURE_64_BIT_INODE) {
|
||||
// Special case for MacOS X 10.5+
|
||||
// Symbol name "readdir" still exists but is used for a
|
||||
// deprecated function that does not match the
|
||||
// constants of |Const|.
|
||||
SysFile.readdir =
|
||||
// constants of |OS.Constants.libc|.
|
||||
UnixFile.readdir =
|
||||
declareFFI("readdir$INODE64", ctypes.default_abi,
|
||||
/*return*/Type.null_or_dirent_ptr,
|
||||
/*dir*/ Type.DIR.in_ptr); // For MacOS X
|
||||
/*return*/Types.null_or_dirent_ptr,
|
||||
/*dir*/ Types.DIR.in_ptr); // For MacOS X
|
||||
} else {
|
||||
SysFile.readdir =
|
||||
UnixFile.readdir =
|
||||
declareFFI("readdir", ctypes.default_abi,
|
||||
/*return*/Type.null_or_dirent_ptr,
|
||||
/*dir*/ Type.DIR.in_ptr); // Other Unices
|
||||
/*return*/Types.null_or_dirent_ptr,
|
||||
/*dir*/ Types.DIR.in_ptr); // Other Unices
|
||||
}
|
||||
|
||||
SysFile.rename =
|
||||
UnixFile.rename =
|
||||
declareFFI("rename", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*old*/ Type.path,
|
||||
/*new*/ Type.path);
|
||||
/*return*/ Types.negativeone_or_nothing,
|
||||
/*old*/ Types.path,
|
||||
/*new*/ Types.path);
|
||||
|
||||
SysFile.rmdir =
|
||||
UnixFile.rmdir =
|
||||
declareFFI("rmdir", ctypes.default_abi,
|
||||
/*return*/ Type.int,
|
||||
/*path*/ Type.path);
|
||||
/*return*/ Types.int,
|
||||
/*path*/ Types.path);
|
||||
|
||||
SysFile.splice =
|
||||
UnixFile.splice =
|
||||
declareFFI("splice", ctypes.default_abi,
|
||||
/*return*/ Type.long,
|
||||
/*fd_in*/ Type.fd,
|
||||
/*off_in*/ Type.off_t.in_ptr,
|
||||
/*fd_out*/ Type.fd,
|
||||
/*off_out*/Type.off_t.in_ptr,
|
||||
/*len*/ Type.size_t,
|
||||
/*flags*/ Type.unsigned_int); // Linux/Android-specific
|
||||
/*return*/ Types.long,
|
||||
/*fd_in*/ Types.fd,
|
||||
/*off_in*/ Types.off_t.in_ptr,
|
||||
/*fd_out*/ Types.fd,
|
||||
/*off_out*/Types.off_t.in_ptr,
|
||||
/*len*/ Types.size_t,
|
||||
/*flags*/ Types.unsigned_int); // Linux/Android-specific
|
||||
|
||||
SysFile.symlink =
|
||||
UnixFile.symlink =
|
||||
declareFFI("symlink", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*source*/ Type.path,
|
||||
/*dest*/ Type.path);
|
||||
/*return*/ Types.negativeone_or_nothing,
|
||||
/*source*/ Types.path,
|
||||
/*dest*/ Types.path);
|
||||
|
||||
SysFile.truncate =
|
||||
UnixFile.truncate =
|
||||
declareFFI("truncate", ctypes.default_abi,
|
||||
/*return*/Type.negativeone_or_nothing,
|
||||
/*path*/ Type.path,
|
||||
/*length*/ Type.off_t);
|
||||
/*return*/Types.negativeone_or_nothing,
|
||||
/*path*/ Types.path,
|
||||
/*length*/ Types.off_t);
|
||||
|
||||
SysFile.unlink =
|
||||
UnixFile.unlink =
|
||||
declareFFI("unlink", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*path*/ Type.path);
|
||||
/*return*/ Types.negativeone_or_nothing,
|
||||
/*path*/ Types.path);
|
||||
|
||||
SysFile.write =
|
||||
UnixFile.write =
|
||||
declareFFI("write", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_ssize_t,
|
||||
/*fd*/ Type.fd,
|
||||
/*buf*/ Type.void_t.in_ptr,
|
||||
/*nbytes*/ Type.size_t);
|
||||
/*return*/ Types.negativeone_or_ssize_t,
|
||||
/*fd*/ Types.fd,
|
||||
/*buf*/ Types.void_t.in_ptr,
|
||||
/*nbytes*/ Types.size_t);
|
||||
|
||||
// Weird cases that require special treatment
|
||||
|
||||
// OSes use a variety of hacks to differentiate between
|
||||
// 32-bits and 64-bits versions of |stat|, |lstat|, |fstat|.
|
||||
if (Const._DARWIN_FEATURE_64_BIT_INODE) {
|
||||
if (OS.Constants.libc._DARWIN_FEATURE_64_BIT_INODE) {
|
||||
// MacOS X 64-bits
|
||||
SysFile.stat =
|
||||
UnixFile.stat =
|
||||
declareFFI("stat$INODE64", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*path*/ Type.path,
|
||||
/*buf*/ Type.stat.out_ptr
|
||||
/*return*/ Types.negativeone_or_nothing,
|
||||
/*path*/ Types.path,
|
||||
/*buf*/ Types.stat.out_ptr
|
||||
);
|
||||
SysFile.lstat =
|
||||
UnixFile.lstat =
|
||||
declareFFI("lstat$INODE64", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*path*/ Type.path,
|
||||
/*buf*/ Type.stat.out_ptr
|
||||
/*return*/ Types.negativeone_or_nothing,
|
||||
/*path*/ Types.path,
|
||||
/*buf*/ Types.stat.out_ptr
|
||||
);
|
||||
SysFile.fstat =
|
||||
UnixFile.fstat =
|
||||
declareFFI("fstat$INODE64", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*path*/ Type.fd,
|
||||
/*buf*/ Type.stat.out_ptr
|
||||
/*return*/ Types.negativeone_or_nothing,
|
||||
/*path*/ Types.fd,
|
||||
/*buf*/ Types.stat.out_ptr
|
||||
);
|
||||
} else if (Const._STAT_VER != undefined) {
|
||||
const ver = Const._STAT_VER;
|
||||
let xstat_name, lxstat_name, fxstat_name;
|
||||
} else if (OS.Constants.libc._STAT_VER != undefined) {
|
||||
const ver = OS.Constants.libc._STAT_VER;
|
||||
let xstat_name, lxstat_name, fxstat_name
|
||||
if (OS.Constants.Sys.Name == "SunOS") {
|
||||
// Solaris
|
||||
xstat_name = "_xstat";
|
||||
@ -551,51 +557,51 @@
|
||||
|
||||
let xstat =
|
||||
declareFFI(xstat_name, ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*_stat_ver*/ Type.int,
|
||||
/*path*/ Type.path,
|
||||
/*buf*/ Type.stat.out_ptr);
|
||||
/*return*/ Types.negativeone_or_nothing,
|
||||
/*_stat_ver*/ Types.int,
|
||||
/*path*/ Types.path,
|
||||
/*buf*/ Types.stat.out_ptr);
|
||||
let lxstat =
|
||||
declareFFI(lxstat_name, ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*_stat_ver*/ Type.int,
|
||||
/*path*/ Type.path,
|
||||
/*buf*/ Type.stat.out_ptr);
|
||||
/*return*/ Types.negativeone_or_nothing,
|
||||
/*_stat_ver*/ Types.int,
|
||||
/*path*/ Types.path,
|
||||
/*buf*/ Types.stat.out_ptr);
|
||||
let fxstat =
|
||||
declareFFI(fxstat_name, ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*_stat_ver*/ Type.int,
|
||||
/*fd*/ Type.fd,
|
||||
/*buf*/ Type.stat.out_ptr);
|
||||
/*return*/ Types.negativeone_or_nothing,
|
||||
/*_stat_ver*/ Types.int,
|
||||
/*fd*/ Types.fd,
|
||||
/*buf*/ Types.stat.out_ptr);
|
||||
|
||||
SysFile.stat = function stat(path, buf) {
|
||||
UnixFile.stat = function stat(path, buf) {
|
||||
return xstat(ver, path, buf);
|
||||
};
|
||||
SysFile.lstat = function stat(path, buf) {
|
||||
UnixFile.lstat = function stat(path, buf) {
|
||||
return lxstat(ver, path, buf);
|
||||
};
|
||||
SysFile.fstat = function stat(fd, buf) {
|
||||
UnixFile.fstat = function stat(fd, buf) {
|
||||
return fxstat(ver, fd, buf);
|
||||
};
|
||||
} else {
|
||||
// Mac OS X 32-bits, other Unix
|
||||
SysFile.stat =
|
||||
UnixFile.stat =
|
||||
declareFFI("stat", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*path*/ Type.path,
|
||||
/*buf*/ Type.stat.out_ptr
|
||||
/*return*/ Types.negativeone_or_nothing,
|
||||
/*path*/ Types.path,
|
||||
/*buf*/ Types.stat.out_ptr
|
||||
);
|
||||
SysFile.lstat =
|
||||
UnixFile.lstat =
|
||||
declareFFI("lstat", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*path*/ Type.path,
|
||||
/*buf*/ Type.stat.out_ptr
|
||||
/*return*/ Types.negativeone_or_nothing,
|
||||
/*path*/ Types.path,
|
||||
/*buf*/ Types.stat.out_ptr
|
||||
);
|
||||
SysFile.fstat =
|
||||
UnixFile.fstat =
|
||||
declareFFI("fstat", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*fd*/ Type.fd,
|
||||
/*buf*/ Type.stat.out_ptr
|
||||
/*return*/ Types.negativeone_or_nothing,
|
||||
/*fd*/ Types.fd,
|
||||
/*buf*/ Types.stat.out_ptr
|
||||
);
|
||||
}
|
||||
|
||||
@ -604,14 +610,14 @@
|
||||
|
||||
let _pipe =
|
||||
declareFFI("pipe", ctypes.default_abi,
|
||||
/*return*/ Type.negativeone_or_nothing,
|
||||
/*fds*/ new SharedAll.Type("two file descriptors",
|
||||
/*return*/ Types.negativeone_or_nothing,
|
||||
/*fds*/ new Type("two file descriptors",
|
||||
ctypes.ArrayType(ctypes.int, 2)));
|
||||
|
||||
// A shared per-thread buffer used to communicate with |pipe|
|
||||
let _pipebuf = new (ctypes.ArrayType(ctypes.int, 2))();
|
||||
|
||||
SysFile.pipe = function pipe(array) {
|
||||
UnixFile.pipe = function pipe(array) {
|
||||
let result = _pipe(_pipebuf);
|
||||
if (result == -1) {
|
||||
return result;
|
||||
@ -621,11 +627,6 @@
|
||||
return result;
|
||||
};
|
||||
};
|
||||
|
||||
exports.OS.Unix = {
|
||||
File: {
|
||||
_init: init
|
||||
}
|
||||
};
|
||||
exports.OS.Unix.File._init = init;
|
||||
})(this);
|
||||
}
|
||||
|
@ -19,19 +19,18 @@
|
||||
(function(exports) {
|
||||
"use strict";
|
||||
|
||||
exports.OS = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm").OS;
|
||||
let Path = require("resource://gre/modules/osfile/ospath.jsm");
|
||||
|
||||
// exports.OS.Unix is created by osfile_unix_back.jsm
|
||||
if (exports.OS && exports.OS.File) {
|
||||
return; // Avoid double-initialization
|
||||
}
|
||||
|
||||
let SharedAll = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm");
|
||||
let Path = require("resource://gre/modules/osfile/ospath.jsm");
|
||||
let SysAll = require("resource://gre/modules/osfile/osfile_unix_allthreads.jsm");
|
||||
exports.OS.Unix.File._init();
|
||||
let LOG = SharedAll.LOG.bind(SharedAll, "Unix front-end");
|
||||
let Const = SharedAll.Constants.libc;
|
||||
let Const = exports.OS.Constants.libc;
|
||||
let UnixFile = exports.OS.Unix.File;
|
||||
let Type = UnixFile.Type;
|
||||
let LOG = OS.Shared.LOG.bind(OS.Shared, "Unix front-end");
|
||||
|
||||
/**
|
||||
* Representation of a file.
|
||||
@ -270,7 +269,7 @@
|
||||
* @return {bool} true if the file exists, false otherwise.
|
||||
*/
|
||||
File.exists = function Unix_exists(path) {
|
||||
if (UnixFile.access(path, Const.F_OK) == -1) {
|
||||
if (UnixFile.access(path, OS.Constants.libc.F_OK) == -1) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
@ -339,7 +338,7 @@
|
||||
let omode = options.unixMode !== undefined ? options.unixMode : DEFAULT_UNIX_MODE_DIR;
|
||||
let result = UnixFile.mkdir(path, omode);
|
||||
if (result != -1 ||
|
||||
options.ignoreExisting && ctypes.errno == Const.EEXIST) {
|
||||
options.ignoreExisting && ctypes.errno == OS.Constants.libc.EEXIST) {
|
||||
return;
|
||||
}
|
||||
throw new File.Error("makeDir");
|
||||
@ -519,10 +518,10 @@
|
||||
// We *might* be on a file system that does not support splice.
|
||||
// Try again with a fallback pump.
|
||||
if (total_read) {
|
||||
source.setPosition(-total_read, File.POS_CURRENT);
|
||||
source.setPosition(-total_read, OS.File.POS_CURRENT);
|
||||
}
|
||||
if (total_written) {
|
||||
dest.setPosition(-total_written, File.POS_CURRENT);
|
||||
dest.setPosition(-total_written, OS.File.POS_CURRENT);
|
||||
}
|
||||
return pump_userland(source, dest, options);
|
||||
}
|
||||
@ -621,7 +620,7 @@
|
||||
this._dir = UnixFile.opendir(this._path);
|
||||
if (this._dir == null) {
|
||||
let error = ctypes.errno;
|
||||
if (error != Const.ENOENT) {
|
||||
if (error != OS.Constants.libc.ENOENT) {
|
||||
throw new File.Error("DirectoryIterator", error);
|
||||
}
|
||||
this._exists = false;
|
||||
@ -664,11 +663,11 @@
|
||||
// |dirent| doesn't have d_type on some platforms (e.g. Solaris).
|
||||
let path = Path.join(this._path, name);
|
||||
throw_on_negative("lstat", UnixFile.lstat(path, gStatDataPtr));
|
||||
isDir = (gStatData.st_mode & Const.S_IFMT) == Const.S_IFDIR;
|
||||
isSymLink = (gStatData.st_mode & Const.S_IFMT) == Const.S_IFLNK;
|
||||
isDir = (gStatData.st_mode & OS.Constants.libc.S_IFMT) == OS.Constants.libc.S_IFDIR;
|
||||
isSymLink = (gStatData.st_mode & OS.Constants.libc.S_IFMT) == OS.Constants.libc.S_IFLNK;
|
||||
} else {
|
||||
isDir = contents.d_type == Const.DT_DIR;
|
||||
isSymLink = contents.d_type == Const.DT_LNK;
|
||||
isDir = contents.d_type == OS.Constants.libc.DT_DIR;
|
||||
isSymLink = contents.d_type == OS.Constants.libc.DT_LNK;
|
||||
}
|
||||
|
||||
return new File.DirectoryIterator.Entry(isDir, isSymLink, name, this._path);
|
||||
@ -714,9 +713,9 @@
|
||||
this._parent = parent;
|
||||
let path = Path.join(this._parent, name);
|
||||
|
||||
SysAll.AbstractEntry.call(this, isDir, isSymLink, name, path);
|
||||
exports.OS.Shared.Unix.AbstractEntry.call(this, isDir, isSymLink, name, path);
|
||||
};
|
||||
File.DirectoryIterator.Entry.prototype = Object.create(SysAll.AbstractEntry.prototype);
|
||||
File.DirectoryIterator.Entry.prototype = Object.create(exports.OS.Shared.Unix.AbstractEntry.prototype);
|
||||
|
||||
/**
|
||||
* Return a version of an instance of
|
||||
@ -738,28 +737,28 @@
|
||||
return serialized;
|
||||
};
|
||||
|
||||
let gStatData = new Type.stat.implementation();
|
||||
let gStatData = new OS.Shared.Type.stat.implementation();
|
||||
let gStatDataPtr = gStatData.address();
|
||||
let MODE_MASK = 4095 /*= 07777*/;
|
||||
File.Info = function Info(stat) {
|
||||
let isDir = (stat.st_mode & Const.S_IFMT) == Const.S_IFDIR;
|
||||
let isSymLink = (stat.st_mode & Const.S_IFMT) == Const.S_IFLNK;
|
||||
let size = Type.size_t.importFromC(stat.st_size);
|
||||
let isDir = (stat.st_mode & OS.Constants.libc.S_IFMT) == OS.Constants.libc.S_IFDIR;
|
||||
let isSymLink = (stat.st_mode & OS.Constants.libc.S_IFMT) == OS.Constants.libc.S_IFLNK;
|
||||
let size = exports.OS.Shared.Type.size_t.importFromC(stat.st_size);
|
||||
|
||||
let lastAccessDate = new Date(stat.st_atime * 1000);
|
||||
let lastModificationDate = new Date(stat.st_mtime * 1000);
|
||||
let unixLastStatusChangeDate = new Date(stat.st_ctime * 1000);
|
||||
|
||||
let unixOwner = Type.uid_t.importFromC(stat.st_uid);
|
||||
let unixGroup = Type.gid_t.importFromC(stat.st_gid);
|
||||
let unixMode = Type.mode_t.importFromC(stat.st_mode & MODE_MASK);
|
||||
let unixOwner = exports.OS.Shared.Type.uid_t.importFromC(stat.st_uid);
|
||||
let unixGroup = exports.OS.Shared.Type.gid_t.importFromC(stat.st_gid);
|
||||
let unixMode = exports.OS.Shared.Type.mode_t.importFromC(stat.st_mode & MODE_MASK);
|
||||
|
||||
SysAll.AbstractInfo.call(this, isDir, isSymLink, size, lastAccessDate,
|
||||
lastModificationDate, unixLastStatusChangeDate,
|
||||
unixOwner, unixGroup, unixMode);
|
||||
exports.OS.Shared.Unix.AbstractInfo.call(this, isDir, isSymLink, size, lastAccessDate,
|
||||
lastModificationDate, unixLastStatusChangeDate,
|
||||
unixOwner, unixGroup, unixMode);
|
||||
|
||||
// Some platforms (e.g. MacOS X, some BSDs) store a file creation date
|
||||
if ("OSFILE_OFFSETOF_STAT_ST_BIRTHTIME" in Const) {
|
||||
if ("OSFILE_OFFSETOF_STAT_ST_BIRTHTIME" in OS.Constants.libc) {
|
||||
let date = new Date(stat.st_birthtime * 1000);
|
||||
|
||||
/**
|
||||
@ -774,7 +773,7 @@
|
||||
this.macBirthDate = date;
|
||||
}
|
||||
};
|
||||
File.Info.prototype = Object.create(SysAll.AbstractInfo.prototype);
|
||||
File.Info.prototype = Object.create(exports.OS.Shared.Unix.AbstractInfo.prototype);
|
||||
|
||||
// Deprecated, use macBirthDate/winBirthDate instead
|
||||
Object.defineProperty(File.Info.prototype, "creationDate", {
|
||||
@ -895,12 +894,11 @@
|
||||
}
|
||||
|
||||
File.Unix = exports.OS.Unix.File;
|
||||
File.Error = SysAll.Error;
|
||||
File.Error = exports.OS.Shared.Unix.Error;
|
||||
exports.OS.File = File;
|
||||
exports.OS.Shared.Type = Type;
|
||||
|
||||
Object.defineProperty(File, "POS_START", { value: SysAll.POS_START });
|
||||
Object.defineProperty(File, "POS_CURRENT", { value: SysAll.POS_CURRENT });
|
||||
Object.defineProperty(File, "POS_END", { value: SysAll.POS_END });
|
||||
Object.defineProperty(File, "POS_START", { value: OS.Shared.POS_START });
|
||||
Object.defineProperty(File, "POS_CURRENT", { value: OS.Shared.POS_CURRENT });
|
||||
Object.defineProperty(File, "POS_END", { value: OS.Shared.POS_END });
|
||||
})(this);
|
||||
}
|
||||
|
@ -8,371 +8,354 @@
|
||||
* of OS.File.
|
||||
*
|
||||
* It serves the following purposes:
|
||||
* - open kernel32;
|
||||
* - open libc;
|
||||
* - define OS.Shared.Win.Error;
|
||||
* - define a few constants and types that need to be defined on all platforms.
|
||||
*
|
||||
* This module can be:
|
||||
* - opened from the main thread as a jsm module;
|
||||
* - opened from a chrome worker through require().
|
||||
* - opened from a chrome worker through importScripts.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
let SharedAll;
|
||||
if (typeof Components != "undefined") {
|
||||
let Cu = Components.utils;
|
||||
// Module is opened as a jsm module
|
||||
Cu.import("resource://gre/modules/ctypes.jsm", this);
|
||||
this.EXPORTED_SYMBOLS = ["OS"];
|
||||
Components.utils.import("resource://gre/modules/ctypes.jsm");
|
||||
|
||||
SharedAll = {};
|
||||
Cu.import("resource://gre/modules/osfile/osfile_shared_allthreads.jsm", SharedAll);
|
||||
this.exports = {};
|
||||
} else if (typeof "module" != "undefined" && typeof "require" != "undefined") {
|
||||
// Module is loaded with require()
|
||||
SharedAll = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm");
|
||||
Components.utils.import("resource://gre/modules/osfile/osfile_shared_allthreads.jsm", SharedAll);
|
||||
} else {
|
||||
throw new Error("Please open this module with Component.utils.import or with require()");
|
||||
SharedAll = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm");
|
||||
}
|
||||
|
||||
let LOG = SharedAll.LOG.bind(SharedAll, "Win", "allthreads");
|
||||
let Const = SharedAll.Constants.Win;
|
||||
(function(exports) {
|
||||
"use strict";
|
||||
if (exports.OS && exports.OS.Shared && exports.OS.Shared.Win) {
|
||||
// Avoid double inclusion
|
||||
return;
|
||||
}
|
||||
exports.OS = SharedAll.OS;
|
||||
exports.OS.Shared.Win = {};
|
||||
|
||||
// Open libc
|
||||
let libc;
|
||||
try {
|
||||
libc = ctypes.open("kernel32.dll");
|
||||
} catch (ex) {
|
||||
// Note: If you change the string here, please adapt consumers and
|
||||
// tests accordingly
|
||||
throw new Error("Could not open system library: " + ex.message);
|
||||
}
|
||||
exports.libc = libc;
|
||||
let LOG = OS.Shared.LOG.bind(OS.Shared, "Win", "allthreads");
|
||||
|
||||
// Define declareFFI
|
||||
let declareFFI = SharedAll.declareFFI.bind(null, libc);
|
||||
exports.declareFFI = declareFFI;
|
||||
// Open libc
|
||||
let libc;
|
||||
try {
|
||||
libc = ctypes.open("kernel32.dll");
|
||||
} catch (ex) {
|
||||
// Note: If you change the string here, please adapt consumers and
|
||||
// tests accordingly
|
||||
throw new Error("Could not open system library: " + ex.message);
|
||||
}
|
||||
exports.OS.Shared.Win.libc = libc;
|
||||
|
||||
// Define Error
|
||||
let FormatMessage = libc.declare("FormatMessageW", ctypes.winapi_abi,
|
||||
/*return*/ ctypes.uint32_t,
|
||||
/*flags*/ ctypes.uint32_t,
|
||||
/*source*/ ctypes.voidptr_t,
|
||||
/*msgid*/ ctypes.uint32_t,
|
||||
/*langid*/ ctypes.uint32_t,
|
||||
/*buf*/ ctypes.jschar.ptr,
|
||||
/*size*/ ctypes.uint32_t,
|
||||
/*Arguments*/ctypes.voidptr_t
|
||||
);
|
||||
// Define declareFFI
|
||||
let declareFFI = OS.Shared.declareFFI.bind(null, libc);
|
||||
exports.OS.Shared.Win.declareFFI = declareFFI;
|
||||
|
||||
/**
|
||||
* A File-related error.
|
||||
*
|
||||
* To obtain a human-readable error message, use method |toString|.
|
||||
* To determine the cause of the error, use the various |becauseX|
|
||||
* getters. To determine the operation that failed, use field
|
||||
* |operation|.
|
||||
*
|
||||
* Additionally, this implementation offers a field
|
||||
* |winLastError|, which holds the OS-specific error
|
||||
* constant. If you need this level of detail, you may match the value
|
||||
* of this field against the error constants of |OS.Constants.Win|.
|
||||
*
|
||||
* @param {string=} operation The operation that failed. If unspecified,
|
||||
* the name of the calling function is taken to be the operation that
|
||||
* failed.
|
||||
* @param {number=} lastError The OS-specific constant detailing the
|
||||
* reason of the error. If unspecified, this is fetched from the system
|
||||
* status.
|
||||
*
|
||||
* @constructor
|
||||
* @extends {OS.Shared.Error}
|
||||
*/
|
||||
let OSError = function OSError(operation, lastError) {
|
||||
operation = operation || "unknown operation";
|
||||
SharedAll.OSError.call(this, operation);
|
||||
this.winLastError = lastError || ctypes.winLastError;
|
||||
};
|
||||
OSError.prototype = Object.create(SharedAll.OSError.prototype);
|
||||
OSError.prototype.toString = function toString() {
|
||||
let buf = new (ctypes.ArrayType(ctypes.jschar, 1024))();
|
||||
let result = FormatMessage(
|
||||
Const.FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
Const.FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
null,
|
||||
/* The error number */ this.winLastError,
|
||||
/* Default language */ 0,
|
||||
/* Output buffer*/ buf,
|
||||
/* Minimum size of buffer */ 1024,
|
||||
/* Format args*/ null
|
||||
// Define Error
|
||||
let FormatMessage = libc.declare("FormatMessageW", ctypes.winapi_abi,
|
||||
/*return*/ ctypes.uint32_t,
|
||||
/*flags*/ ctypes.uint32_t,
|
||||
/*source*/ ctypes.voidptr_t,
|
||||
/*msgid*/ ctypes.uint32_t,
|
||||
/*langid*/ ctypes.uint32_t,
|
||||
/*buf*/ ctypes.jschar.ptr,
|
||||
/*size*/ ctypes.uint32_t,
|
||||
/*Arguments*/ctypes.voidptr_t
|
||||
);
|
||||
if (!result) {
|
||||
buf = "additional error " +
|
||||
ctypes.winLastError +
|
||||
" while fetching system error message";
|
||||
}
|
||||
return "Win error " + this.winLastError + " during operation "
|
||||
+ this.operation + " (" + buf.readString() + ")";
|
||||
};
|
||||
|
||||
/**
|
||||
* |true| if the error was raised because a file or directory
|
||||
* already exists, |false| otherwise.
|
||||
*/
|
||||
Object.defineProperty(OSError.prototype, "becauseExists", {
|
||||
get: function becauseExists() {
|
||||
return this.winLastError == Const.ERROR_FILE_EXISTS ||
|
||||
this.winLastError == Const.ERROR_ALREADY_EXISTS;
|
||||
}
|
||||
});
|
||||
/**
|
||||
* |true| if the error was raised because a file or directory
|
||||
* does not exist, |false| otherwise.
|
||||
*/
|
||||
Object.defineProperty(OSError.prototype, "becauseNoSuchFile", {
|
||||
get: function becauseNoSuchFile() {
|
||||
return this.winLastError == Const.ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
});
|
||||
/**
|
||||
* |true| if the error was raised because a directory is not empty
|
||||
* does not exist, |false| otherwise.
|
||||
*/
|
||||
Object.defineProperty(OSError.prototype, "becauseNotEmpty", {
|
||||
get: function becauseNotEmpty() {
|
||||
return this.winLastError == Const.ERROR_DIR_NOT_EMPTY;
|
||||
}
|
||||
});
|
||||
/**
|
||||
* |true| if the error was raised because a file or directory
|
||||
* is closed, |false| otherwise.
|
||||
*/
|
||||
Object.defineProperty(OSError.prototype, "becauseClosed", {
|
||||
get: function becauseClosed() {
|
||||
return this.winLastError == Const.ERROR_INVALID_HANDLE;
|
||||
}
|
||||
});
|
||||
/**
|
||||
* |true| if the error was raised because permission is denied to
|
||||
* access a file or directory, |false| otherwise.
|
||||
*/
|
||||
Object.defineProperty(OSError.prototype, "becauseAccessDenied", {
|
||||
get: function becauseAccessDenied() {
|
||||
return this.winLastError == Const.ERROR_ACCESS_DENIED;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Serialize an instance of OSError to something that can be
|
||||
* transmitted across threads (not necessarily a string).
|
||||
*/
|
||||
OSError.toMsg = function toMsg(error) {
|
||||
return {
|
||||
operation: error.operation,
|
||||
winLastError: error.winLastError
|
||||
/**
|
||||
* A File-related error.
|
||||
*
|
||||
* To obtain a human-readable error message, use method |toString|.
|
||||
* To determine the cause of the error, use the various |becauseX|
|
||||
* getters. To determine the operation that failed, use field
|
||||
* |operation|.
|
||||
*
|
||||
* Additionally, this implementation offers a field
|
||||
* |winLastError|, which holds the OS-specific error
|
||||
* constant. If you need this level of detail, you may match the value
|
||||
* of this field against the error constants of |OS.Constants.Win|.
|
||||
*
|
||||
* @param {string=} operation The operation that failed. If unspecified,
|
||||
* the name of the calling function is taken to be the operation that
|
||||
* failed.
|
||||
* @param {number=} lastError The OS-specific constant detailing the
|
||||
* reason of the error. If unspecified, this is fetched from the system
|
||||
* status.
|
||||
*
|
||||
* @constructor
|
||||
* @extends {OS.Shared.Error}
|
||||
*/
|
||||
let OSError = function OSError(operation, lastError) {
|
||||
operation = operation || "unknown operation";
|
||||
exports.OS.Shared.Error.call(this, operation);
|
||||
this.winLastError = lastError || ctypes.winLastError;
|
||||
};
|
||||
OSError.prototype = new exports.OS.Shared.Error();
|
||||
OSError.prototype.toString = function toString() {
|
||||
let buf = new (ctypes.ArrayType(ctypes.jschar, 1024))();
|
||||
let result = FormatMessage(
|
||||
exports.OS.Constants.Win.FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
exports.OS.Constants.Win.FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
null,
|
||||
/* The error number */ this.winLastError,
|
||||
/* Default language */ 0,
|
||||
/* Output buffer*/ buf,
|
||||
/* Minimum size of buffer */ 1024,
|
||||
/* Format args*/ null
|
||||
);
|
||||
if (!result) {
|
||||
buf = "additional error " +
|
||||
ctypes.winLastError +
|
||||
" while fetching system error message";
|
||||
}
|
||||
return "Win error " + this.winLastError + " during operation "
|
||||
+ this.operation + " (" + buf.readString() + ")";
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Deserialize a message back to an instance of OSError
|
||||
*/
|
||||
OSError.fromMsg = function fromMsg(msg) {
|
||||
return new OSError(msg.operation, msg.winLastError);
|
||||
};
|
||||
exports.Error = OSError;
|
||||
|
||||
/**
|
||||
* Code shared by implementation of File.Info on Windows
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
let AbstractInfo = function AbstractInfo(isDir, isSymLink, size, winBirthDate,
|
||||
lastAccessDate, lastWriteDate) {
|
||||
this._isDir = isDir;
|
||||
this._isSymLink = isSymLink;
|
||||
this._size = size;
|
||||
this._winBirthDate = winBirthDate;
|
||||
this._lastAccessDate = lastAccessDate;
|
||||
this._lastModificationDate = lastWriteDate;
|
||||
};
|
||||
|
||||
AbstractInfo.prototype = {
|
||||
/**
|
||||
* |true| if this file is a directory, |false| otherwise
|
||||
* |true| if the error was raised because a file or directory
|
||||
* already exists, |false| otherwise.
|
||||
*/
|
||||
get isDir() {
|
||||
return this._isDir;
|
||||
},
|
||||
Object.defineProperty(OSError.prototype, "becauseExists", {
|
||||
get: function becauseExists() {
|
||||
return this.winLastError == exports.OS.Constants.Win.ERROR_FILE_EXISTS ||
|
||||
this.winLastError == exports.OS.Constants.Win.ERROR_ALREADY_EXISTS;
|
||||
}
|
||||
});
|
||||
/**
|
||||
* |true| if this file is a symbolic link, |false| otherwise
|
||||
* |true| if the error was raised because a file or directory
|
||||
* does not exist, |false| otherwise.
|
||||
*/
|
||||
get isSymLink() {
|
||||
return this._isSymLink;
|
||||
},
|
||||
Object.defineProperty(OSError.prototype, "becauseNoSuchFile", {
|
||||
get: function becauseNoSuchFile() {
|
||||
return this.winLastError == exports.OS.Constants.Win.ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
});
|
||||
/**
|
||||
* The size of the file, in bytes.
|
||||
* |true| if the error was raised because a directory is not empty
|
||||
* does not exist, |false| otherwise.
|
||||
*/
|
||||
Object.defineProperty(OSError.prototype, "becauseNotEmpty", {
|
||||
get: function becauseNotEmpty() {
|
||||
return this.winLastError == OS.Constants.Win.ERROR_DIR_NOT_EMPTY;
|
||||
}
|
||||
});
|
||||
/**
|
||||
* |true| if the error was raised because a file or directory
|
||||
* is closed, |false| otherwise.
|
||||
*/
|
||||
Object.defineProperty(OSError.prototype, "becauseClosed", {
|
||||
get: function becauseClosed() {
|
||||
return this.winLastError == exports.OS.Constants.Win.ERROR_INVALID_HANDLE;
|
||||
}
|
||||
});
|
||||
/**
|
||||
* |true| if the error was raised because permission is denied to
|
||||
* access a file or directory, |false| otherwise.
|
||||
*/
|
||||
Object.defineProperty(OSError.prototype, "becauseAccessDenied", {
|
||||
get: function becauseAccessDenied() {
|
||||
return this.winLastError == exports.OS.Constants.Win.ERROR_ACCESS_DENIED;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Serialize an instance of OSError to something that can be
|
||||
* transmitted across threads (not necessarily a string).
|
||||
*/
|
||||
OSError.toMsg = function toMsg(error) {
|
||||
return {
|
||||
operation: error.operation,
|
||||
winLastError: error.winLastError
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Deserialize a message back to an instance of OSError
|
||||
*/
|
||||
OSError.fromMsg = function fromMsg(msg) {
|
||||
return new OSError(msg.operation, msg.winLastError);
|
||||
};
|
||||
|
||||
exports.OS.Shared.Win.Error = OSError;
|
||||
|
||||
/**
|
||||
* Code shared by implementation of File.Info on Windows
|
||||
*
|
||||
* Note that the result may be |NaN| if the size of the file cannot be
|
||||
* represented in JavaScript.
|
||||
* @constructor
|
||||
*/
|
||||
let AbstractInfo = function AbstractInfo(isDir, isSymLink, size, winBirthDate,
|
||||
lastAccessDate, lastWriteDate) {
|
||||
this._isDir = isDir;
|
||||
this._isSymLink = isSymLink;
|
||||
this._size = size;
|
||||
this._winBirthDate = winBirthDate;
|
||||
this._lastAccessDate = lastAccessDate;
|
||||
this._lastModificationDate = lastWriteDate;
|
||||
};
|
||||
|
||||
AbstractInfo.prototype = {
|
||||
/**
|
||||
* |true| if this file is a directory, |false| otherwise
|
||||
*/
|
||||
get isDir() {
|
||||
return this._isDir;
|
||||
},
|
||||
/**
|
||||
* |true| if this file is a symbolic link, |false| otherwise
|
||||
*/
|
||||
get isSymLink() {
|
||||
return this._isSymLink;
|
||||
},
|
||||
/**
|
||||
* The size of the file, in bytes.
|
||||
*
|
||||
* Note that the result may be |NaN| if the size of the file cannot be
|
||||
* represented in JavaScript.
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
get size() {
|
||||
return this._size;
|
||||
},
|
||||
// Deprecated
|
||||
get creationDate() {
|
||||
return this._winBirthDate;
|
||||
},
|
||||
/**
|
||||
* The date of creation of this file.
|
||||
*
|
||||
* @type {Date}
|
||||
*/
|
||||
get winBirthDate() {
|
||||
return this._winBirthDate;
|
||||
},
|
||||
/**
|
||||
* The date of last access to this file.
|
||||
*
|
||||
* Note that the definition of last access may depend on the underlying
|
||||
* operating system and file system.
|
||||
*
|
||||
* @type {Date}
|
||||
*/
|
||||
get lastAccessDate() {
|
||||
return this._lastAccessDate;
|
||||
},
|
||||
/**
|
||||
* The date of last modification of this file.
|
||||
*
|
||||
* Note that the definition of last access may depend on the underlying
|
||||
* operating system and file system.
|
||||
*
|
||||
* @type {Date}
|
||||
*/
|
||||
get lastModificationDate() {
|
||||
return this._lastModificationDate;
|
||||
}
|
||||
};
|
||||
exports.OS.Shared.Win.AbstractInfo = AbstractInfo;
|
||||
|
||||
/**
|
||||
* Code shared by implementation of File.DirectoryIterator.Entry on Windows
|
||||
*
|
||||
* @type {number}
|
||||
* @constructor
|
||||
*/
|
||||
get size() {
|
||||
return this._size;
|
||||
},
|
||||
// Deprecated
|
||||
get creationDate() {
|
||||
return this._winBirthDate;
|
||||
},
|
||||
let AbstractEntry = function AbstractEntry(isDir, isSymLink, name,
|
||||
winCreationDate, winLastWriteDate,
|
||||
winLastAccessDate, path) {
|
||||
this._isDir = isDir;
|
||||
this._isSymLink = isSymLink;
|
||||
this._name = name;
|
||||
this._winCreationDate = winCreationDate;
|
||||
this._winLastWriteDate = winLastWriteDate;
|
||||
this._winLastAccessDate = winLastAccessDate;
|
||||
this._path = path;
|
||||
};
|
||||
|
||||
AbstractEntry.prototype = {
|
||||
/**
|
||||
* |true| if the entry is a directory, |false| otherwise
|
||||
*/
|
||||
get isDir() {
|
||||
return this._isDir;
|
||||
},
|
||||
/**
|
||||
* |true| if the entry is a symbolic link, |false| otherwise
|
||||
*/
|
||||
get isSymLink() {
|
||||
return this._isSymLink;
|
||||
},
|
||||
/**
|
||||
* The name of the entry.
|
||||
* @type {string}
|
||||
*/
|
||||
get name() {
|
||||
return this._name;
|
||||
},
|
||||
/**
|
||||
* The creation time of this file.
|
||||
* @type {Date}
|
||||
*/
|
||||
get winCreationDate() {
|
||||
return this._winCreationDate;
|
||||
},
|
||||
/**
|
||||
* The last modification time of this file.
|
||||
* @type {Date}
|
||||
*/
|
||||
get winLastWriteDate() {
|
||||
return this._winLastWriteDate;
|
||||
},
|
||||
/**
|
||||
* The last access time of this file.
|
||||
* @type {Date}
|
||||
*/
|
||||
get winLastAccessDate() {
|
||||
return this._winLastAccessDate;
|
||||
},
|
||||
/**
|
||||
* The full path of the entry
|
||||
* @type {string}
|
||||
*/
|
||||
get path() {
|
||||
return this._path;
|
||||
}
|
||||
};
|
||||
exports.OS.Shared.Win.AbstractEntry = AbstractEntry;
|
||||
|
||||
// Special constants that need to be defined on all platforms
|
||||
|
||||
Object.defineProperty(exports.OS.Shared, "POS_START", { value: exports.OS.Constants.Win.FILE_BEGIN });
|
||||
Object.defineProperty(exports.OS.Shared, "POS_CURRENT", { value: exports.OS.Constants.Win.FILE_CURRENT });
|
||||
Object.defineProperty(exports.OS.Shared, "POS_END", { value: exports.OS.Constants.Win.FILE_END });
|
||||
|
||||
// Special types that need to be defined for communication
|
||||
// between threads
|
||||
let Types = exports.OS.Shared.Type;
|
||||
|
||||
/**
|
||||
* The date of creation of this file.
|
||||
* Native paths
|
||||
*
|
||||
* @type {Date}
|
||||
* Under Windows, expressed as wide strings
|
||||
*/
|
||||
get winBirthDate() {
|
||||
return this._winBirthDate;
|
||||
},
|
||||
/**
|
||||
* The date of last access to this file.
|
||||
*
|
||||
* Note that the definition of last access may depend on the underlying
|
||||
* operating system and file system.
|
||||
*
|
||||
* @type {Date}
|
||||
*/
|
||||
get lastAccessDate() {
|
||||
return this._lastAccessDate;
|
||||
},
|
||||
/**
|
||||
* The date of last modification of this file.
|
||||
*
|
||||
* Note that the definition of last access may depend on the underlying
|
||||
* operating system and file system.
|
||||
*
|
||||
* @type {Date}
|
||||
*/
|
||||
get lastModificationDate() {
|
||||
return this._lastModificationDate;
|
||||
}
|
||||
};
|
||||
exports.AbstractInfo = AbstractInfo;
|
||||
Types.path = Types.wstring.withName("[in] path");
|
||||
Types.out_path = Types.out_wstring.withName("[out] path");
|
||||
|
||||
/**
|
||||
* Code shared by implementation of File.DirectoryIterator.Entry on Windows
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
let AbstractEntry = function AbstractEntry(isDir, isSymLink, name,
|
||||
winCreationDate, winLastWriteDate,
|
||||
winLastAccessDate, path) {
|
||||
this._isDir = isDir;
|
||||
this._isSymLink = isSymLink;
|
||||
this._name = name;
|
||||
this._winCreationDate = winCreationDate;
|
||||
this._winLastWriteDate = winLastWriteDate;
|
||||
this._winLastAccessDate = winLastAccessDate;
|
||||
this._path = path;
|
||||
};
|
||||
// Special constructors that need to be defined on all threads
|
||||
OSError.closed = function closed(operation) {
|
||||
return new OSError(operation, exports.OS.Constants.Win.ERROR_INVALID_HANDLE);
|
||||
};
|
||||
|
||||
AbstractEntry.prototype = {
|
||||
/**
|
||||
* |true| if the entry is a directory, |false| otherwise
|
||||
*/
|
||||
get isDir() {
|
||||
return this._isDir;
|
||||
},
|
||||
/**
|
||||
* |true| if the entry is a symbolic link, |false| otherwise
|
||||
*/
|
||||
get isSymLink() {
|
||||
return this._isSymLink;
|
||||
},
|
||||
/**
|
||||
* The name of the entry.
|
||||
* @type {string}
|
||||
*/
|
||||
get name() {
|
||||
return this._name;
|
||||
},
|
||||
/**
|
||||
* The creation time of this file.
|
||||
* @type {Date}
|
||||
*/
|
||||
get winCreationDate() {
|
||||
return this._winCreationDate;
|
||||
},
|
||||
/**
|
||||
* The last modification time of this file.
|
||||
* @type {Date}
|
||||
*/
|
||||
get winLastWriteDate() {
|
||||
return this._winLastWriteDate;
|
||||
},
|
||||
/**
|
||||
* The last access time of this file.
|
||||
* @type {Date}
|
||||
*/
|
||||
get winLastAccessDate() {
|
||||
return this._winLastAccessDate;
|
||||
},
|
||||
/**
|
||||
* The full path of the entry
|
||||
* @type {string}
|
||||
*/
|
||||
get path() {
|
||||
return this._path;
|
||||
}
|
||||
};
|
||||
exports.AbstractEntry = AbstractEntry;
|
||||
OSError.exists = function exists(operation) {
|
||||
return new OSError(operation, exports.OS.Constants.Win.ERROR_FILE_EXISTS);
|
||||
};
|
||||
|
||||
// Special constants that need to be defined on all platforms
|
||||
|
||||
exports.POS_START = Const.FILE_BEGIN;
|
||||
exports.POS_CURRENT = Const.FILE_CURRENT;
|
||||
exports.POS_END = Const.FILE_END;
|
||||
|
||||
// Special types that need to be defined for communication
|
||||
// between threads
|
||||
let Type = Object.create(SharedAll.Type);
|
||||
exports.Type = Type;
|
||||
|
||||
/**
|
||||
* Native paths
|
||||
*
|
||||
* Under Windows, expressed as wide strings
|
||||
*/
|
||||
Type.path = Type.wstring.withName("[in] path");
|
||||
Type.out_path = Type.out_wstring.withName("[out] path");
|
||||
|
||||
// Special constructors that need to be defined on all threads
|
||||
OSError.closed = function closed(operation) {
|
||||
return new OSError(operation, Const.ERROR_INVALID_HANDLE);
|
||||
};
|
||||
|
||||
OSError.exists = function exists(operation) {
|
||||
return new OSError(operation, Const.ERROR_FILE_EXISTS);
|
||||
};
|
||||
|
||||
OSError.noSuchFile = function noSuchFile(operation) {
|
||||
return new OSError(operation, Const.ERROR_FILE_NOT_FOUND);
|
||||
};
|
||||
|
||||
let EXPORTED_SYMBOLS = [
|
||||
"declareFFI",
|
||||
"libc",
|
||||
"Error",
|
||||
"AbstractInfo",
|
||||
"AbstractEntry",
|
||||
"Type",
|
||||
"POS_START",
|
||||
"POS_CURRENT",
|
||||
"POS_END"
|
||||
];
|
||||
|
||||
//////////// Boilerplate
|
||||
if (typeof Components != "undefined") {
|
||||
this.EXPORTED_SYMBOLS = EXPORTED_SYMBOLS;
|
||||
for (let symbol of EXPORTED_SYMBOLS) {
|
||||
this[symbol] = exports[symbol];
|
||||
}
|
||||
}
|
||||
OSError.noSuchFile = function noSuchFile(operation) {
|
||||
return new OSError(operation, exports.OS.Constants.Win.ERROR_FILE_NOT_FOUND);
|
||||
};
|
||||
})(this);
|
||||
|
@ -34,12 +34,11 @@
|
||||
if (exports.OS && exports.OS.Win && exports.OS.Win.File) {
|
||||
return; // Avoid double initialization
|
||||
}
|
||||
exports.OS = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm").OS;
|
||||
exports.OS.Win.File = {};
|
||||
|
||||
let SharedAll = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm");
|
||||
let SysAll = require("resource://gre/modules/osfile/osfile_win_allthreads.jsm");
|
||||
let LOG = SharedAll.LOG.bind(SharedAll, "Unix", "back");
|
||||
let libc = SysAll.libc;
|
||||
let Const = SharedAll.Constants.Win;
|
||||
let LOG = OS.Shared.LOG.bind(OS.Shared, "Win", "back");
|
||||
let libc = exports.OS.Shared.Win.libc;
|
||||
|
||||
/**
|
||||
* Initialize the Windows module.
|
||||
@ -52,14 +51,17 @@
|
||||
if (aDeclareFFI) {
|
||||
declareFFI = aDeclareFFI.bind(null, libc);
|
||||
} else {
|
||||
declareFFI = SysAll.declareFFI;
|
||||
declareFFI = exports.OS.Shared.Win.declareFFI;
|
||||
}
|
||||
|
||||
// Initialize types that require additional OS-specific
|
||||
// support - either finalization or matching against
|
||||
// OS-specific constants.
|
||||
let Type = Object.create(SysAll.Type);
|
||||
let SysFile = exports.OS.Win.File = { Type: Type };
|
||||
// Shorthands
|
||||
let OSWin = exports.OS.Win;
|
||||
let WinFile = exports.OS.Win.File;
|
||||
if (!exports.OS.Types) {
|
||||
exports.OS.Types = {};
|
||||
}
|
||||
let Type = exports.OS.Shared.Type;
|
||||
let Types = Type;
|
||||
|
||||
// Initialize types
|
||||
|
||||
@ -67,10 +69,10 @@
|
||||
* A C integer holding INVALID_HANDLE_VALUE in case of error or
|
||||
* a file descriptor in case of success.
|
||||
*/
|
||||
Type.HANDLE =
|
||||
Type.voidptr_t.withName("HANDLE");
|
||||
Type.HANDLE.importFromC = function importFromC(maybe) {
|
||||
if (Type.int.cast(maybe).value == INVALID_HANDLE) {
|
||||
Types.HANDLE =
|
||||
Types.voidptr_t.withName("HANDLE");
|
||||
Types.HANDLE.importFromC = function importFromC(maybe) {
|
||||
if (Types.int.cast(maybe).value == INVALID_HANDLE) {
|
||||
// Ensure that API clients can effectively compare against
|
||||
// Const.INVALID_HANDLE_VALUE. Without this cast,
|
||||
// == would always return |false|.
|
||||
@ -78,88 +80,88 @@
|
||||
}
|
||||
return ctypes.CDataFinalizer(maybe, this.finalizeHANDLE);
|
||||
};
|
||||
Type.HANDLE.finalizeHANDLE = function placeholder() {
|
||||
Types.HANDLE.finalizeHANDLE = function placeholder() {
|
||||
throw new Error("finalizeHANDLE should be implemented");
|
||||
};
|
||||
let INVALID_HANDLE = Const.INVALID_HANDLE_VALUE;
|
||||
let INVALID_HANDLE = exports.OS.Constants.Win.INVALID_HANDLE_VALUE;
|
||||
|
||||
Type.file_HANDLE = Type.HANDLE.withName("file HANDLE");
|
||||
SharedAll.defineLazyGetter(Type.file_HANDLE,
|
||||
Types.file_HANDLE = Types.HANDLE.withName("file HANDLE");
|
||||
exports.OS.Shared.defineLazyGetter(Types.file_HANDLE,
|
||||
"finalizeHANDLE",
|
||||
function() {
|
||||
return _CloseHandle;
|
||||
});
|
||||
|
||||
Type.find_HANDLE = Type.HANDLE.withName("find HANDLE");
|
||||
SharedAll.defineLazyGetter(Type.find_HANDLE,
|
||||
Types.find_HANDLE = Types.HANDLE.withName("find HANDLE");
|
||||
exports.OS.Shared.defineLazyGetter(Types.find_HANDLE,
|
||||
"finalizeHANDLE",
|
||||
function() {
|
||||
return _FindClose;
|
||||
});
|
||||
|
||||
Type.DWORD = Type.int32_t.withName("DWORD");
|
||||
Types.DWORD = Types.int32_t.withName("DWORD");
|
||||
|
||||
/**
|
||||
* A C integer holding -1 in case of error or a positive integer
|
||||
* in case of success.
|
||||
*/
|
||||
Type.negative_or_DWORD =
|
||||
Type.DWORD.withName("negative_or_DWORD");
|
||||
Types.negative_or_DWORD =
|
||||
Types.DWORD.withName("negative_or_DWORD");
|
||||
|
||||
/**
|
||||
* A C integer holding 0 in case of error or a positive integer
|
||||
* in case of success.
|
||||
*/
|
||||
Type.zero_or_DWORD =
|
||||
Type.DWORD.withName("zero_or_DWORD");
|
||||
Types.zero_or_DWORD =
|
||||
Types.DWORD.withName("zero_or_DWORD");
|
||||
|
||||
/**
|
||||
* A C integer holding 0 in case of error, any other value in
|
||||
* case of success.
|
||||
*/
|
||||
Type.zero_or_nothing =
|
||||
Type.int.withName("zero_or_nothing");
|
||||
Types.zero_or_nothing =
|
||||
Types.int.withName("zero_or_nothing");
|
||||
|
||||
Type.SECURITY_ATTRIBUTES =
|
||||
Type.void_t.withName("SECURITY_ATTRIBUTES");
|
||||
Types.SECURITY_ATTRIBUTES =
|
||||
Types.void_t.withName("SECURITY_ATTRIBUTES");
|
||||
|
||||
Type.FILETIME =
|
||||
new SharedAll.Type("FILETIME",
|
||||
Types.FILETIME =
|
||||
new Type("FILETIME",
|
||||
ctypes.StructType("FILETIME", [
|
||||
{ lo: Type.DWORD.implementation },
|
||||
{ hi: Type.DWORD.implementation }]));
|
||||
{ lo: Types.DWORD.implementation },
|
||||
{ hi: Types.DWORD.implementation }]));
|
||||
|
||||
Type.FindData =
|
||||
new SharedAll.Type("FIND_DATA",
|
||||
Types.FindData =
|
||||
new Type("FIND_DATA",
|
||||
ctypes.StructType("FIND_DATA", [
|
||||
{ dwFileAttributes: ctypes.uint32_t },
|
||||
{ ftCreationTime: Type.FILETIME.implementation },
|
||||
{ ftLastAccessTime: Type.FILETIME.implementation },
|
||||
{ ftLastWriteTime: Type.FILETIME.implementation },
|
||||
{ nFileSizeHigh: Type.DWORD.implementation },
|
||||
{ nFileSizeLow: Type.DWORD.implementation },
|
||||
{ dwReserved0: Type.DWORD.implementation },
|
||||
{ dwReserved1: Type.DWORD.implementation },
|
||||
{ cFileName: ctypes.ArrayType(ctypes.jschar, Const.MAX_PATH) },
|
||||
{ ftCreationTime: Types.FILETIME.implementation },
|
||||
{ ftLastAccessTime: Types.FILETIME.implementation },
|
||||
{ ftLastWriteTime: Types.FILETIME.implementation },
|
||||
{ nFileSizeHigh: Types.DWORD.implementation },
|
||||
{ nFileSizeLow: Types.DWORD.implementation },
|
||||
{ dwReserved0: Types.DWORD.implementation },
|
||||
{ dwReserved1: Types.DWORD.implementation },
|
||||
{ cFileName: ctypes.ArrayType(ctypes.jschar, exports.OS.Constants.Win.MAX_PATH) },
|
||||
{ cAlternateFileName: ctypes.ArrayType(ctypes.jschar, 14) }
|
||||
]));
|
||||
|
||||
Type.FILE_INFORMATION =
|
||||
new SharedAll.Type("FILE_INFORMATION",
|
||||
Types.FILE_INFORMATION =
|
||||
new Type("FILE_INFORMATION",
|
||||
ctypes.StructType("FILE_INFORMATION", [
|
||||
{ dwFileAttributes: ctypes.uint32_t },
|
||||
{ ftCreationTime: Type.FILETIME.implementation },
|
||||
{ ftLastAccessTime: Type.FILETIME.implementation },
|
||||
{ ftLastWriteTime: Type.FILETIME.implementation },
|
||||
{ ftCreationTime: Types.FILETIME.implementation },
|
||||
{ ftLastAccessTime: Types.FILETIME.implementation },
|
||||
{ ftLastWriteTime: Types.FILETIME.implementation },
|
||||
{ dwVolumeSerialNumber: ctypes.uint32_t },
|
||||
{ nFileSizeHigh: Type.DWORD.implementation },
|
||||
{ nFileSizeLow: Type.DWORD.implementation },
|
||||
{ nFileSizeHigh: Types.DWORD.implementation },
|
||||
{ nFileSizeLow: Types.DWORD.implementation },
|
||||
{ nNumberOfLinks: ctypes.uint32_t },
|
||||
{ nFileIndex: ctypes.uint64_t }
|
||||
]));
|
||||
|
||||
Type.SystemTime =
|
||||
new SharedAll.Type("SystemTime",
|
||||
Types.SystemTime =
|
||||
new Type("SystemTime",
|
||||
ctypes.StructType("SystemTime", [
|
||||
{ wYear: ctypes.int16_t },
|
||||
{ wMonth: ctypes.int16_t },
|
||||
@ -173,12 +175,12 @@
|
||||
|
||||
// Special case: these functions are used by the
|
||||
// finalizer
|
||||
let _CloseHandle = SysFile._CloseHandle =
|
||||
let _CloseHandle = WinFile._CloseHandle =
|
||||
libc.declare("CloseHandle", ctypes.winapi_abi,
|
||||
/*return */ctypes.bool,
|
||||
/*handle*/ ctypes.voidptr_t);
|
||||
|
||||
SysFile.CloseHandle = function(fd) {
|
||||
WinFile.CloseHandle = function(fd) {
|
||||
if (fd == INVALID_HANDLE) {
|
||||
return true;
|
||||
} else {
|
||||
@ -191,7 +193,7 @@
|
||||
/*return */ctypes.bool,
|
||||
/*handle*/ ctypes.voidptr_t);
|
||||
|
||||
SysFile.FindClose = function(handle) {
|
||||
WinFile.FindClose = function(handle) {
|
||||
if (handle == INVALID_HANDLE) {
|
||||
return true;
|
||||
} else {
|
||||
@ -201,140 +203,135 @@
|
||||
|
||||
// Declare libc functions as functions of |OS.Win.File|
|
||||
|
||||
SysFile.CopyFile =
|
||||
WinFile.CopyFile =
|
||||
declareFFI("CopyFileW", ctypes.winapi_abi,
|
||||
/*return*/ Type.zero_or_nothing,
|
||||
/*sourcePath*/ Type.path,
|
||||
/*destPath*/ Type.path,
|
||||
/*bailIfExist*/Type.bool);
|
||||
/*return*/ Types.zero_or_nothing,
|
||||
/*sourcePath*/ Types.path,
|
||||
/*destPath*/ Types.path,
|
||||
/*bailIfExist*/Types.bool);
|
||||
|
||||
SysFile.CreateDirectory =
|
||||
WinFile.CreateDirectory =
|
||||
declareFFI("CreateDirectoryW", ctypes.winapi_abi,
|
||||
/*return*/ Type.zero_or_nothing,
|
||||
/*name*/ Type.jschar.in_ptr,
|
||||
/*security*/Type.SECURITY_ATTRIBUTES.in_ptr);
|
||||
/*return*/ Types.zero_or_nothing,
|
||||
/*name*/ Types.jschar.in_ptr,
|
||||
/*security*/Types.SECURITY_ATTRIBUTES.in_ptr);
|
||||
|
||||
SysFile.CreateFile =
|
||||
WinFile.CreateFile =
|
||||
declareFFI("CreateFileW", ctypes.winapi_abi,
|
||||
/*return*/ Type.file_HANDLE,
|
||||
/*name*/ Type.path,
|
||||
/*access*/ Type.DWORD,
|
||||
/*share*/ Type.DWORD,
|
||||
/*security*/Type.SECURITY_ATTRIBUTES.in_ptr,
|
||||
/*creation*/Type.DWORD,
|
||||
/*flags*/ Type.DWORD,
|
||||
/*template*/Type.HANDLE);
|
||||
/*return*/ Types.file_HANDLE,
|
||||
/*name*/ Types.path,
|
||||
/*access*/ Types.DWORD,
|
||||
/*share*/ Types.DWORD,
|
||||
/*security*/Types.SECURITY_ATTRIBUTES.in_ptr,
|
||||
/*creation*/Types.DWORD,
|
||||
/*flags*/ Types.DWORD,
|
||||
/*template*/Types.HANDLE);
|
||||
|
||||
SysFile.DeleteFile =
|
||||
WinFile.DeleteFile =
|
||||
declareFFI("DeleteFileW", ctypes.winapi_abi,
|
||||
/*return*/ Type.zero_or_nothing,
|
||||
/*path*/ Type.path);
|
||||
/*return*/ Types.zero_or_nothing,
|
||||
/*path*/ Types.path);
|
||||
|
||||
SysFile.FileTimeToSystemTime =
|
||||
WinFile.FileTimeToSystemTime =
|
||||
declareFFI("FileTimeToSystemTime", ctypes.winapi_abi,
|
||||
/*return*/ Type.zero_or_nothing,
|
||||
/*filetime*/Type.FILETIME.in_ptr,
|
||||
/*systime*/ Type.SystemTime.out_ptr);
|
||||
/*return*/ Types.zero_or_nothing,
|
||||
/*filetime*/Types.FILETIME.in_ptr,
|
||||
/*systime*/ Types.SystemTime.out_ptr);
|
||||
|
||||
SysFile.FindFirstFile =
|
||||
WinFile.FindFirstFile =
|
||||
declareFFI("FindFirstFileW", ctypes.winapi_abi,
|
||||
/*return*/ Type.find_HANDLE,
|
||||
/*pattern*/Type.path,
|
||||
/*data*/ Type.FindData.out_ptr);
|
||||
/*return*/ Types.find_HANDLE,
|
||||
/*pattern*/Types.path,
|
||||
/*data*/ Types.FindData.out_ptr);
|
||||
|
||||
SysFile.FindNextFile =
|
||||
WinFile.FindNextFile =
|
||||
declareFFI("FindNextFileW", ctypes.winapi_abi,
|
||||
/*return*/ Type.zero_or_nothing,
|
||||
/*prev*/ Type.find_HANDLE,
|
||||
/*data*/ Type.FindData.out_ptr);
|
||||
/*return*/ Types.zero_or_nothing,
|
||||
/*prev*/ Types.find_HANDLE,
|
||||
/*data*/ Types.FindData.out_ptr);
|
||||
|
||||
SysFile.FormatMessage =
|
||||
WinFile.FormatMessage =
|
||||
declareFFI("FormatMessageW", ctypes.winapi_abi,
|
||||
/*return*/ Type.DWORD,
|
||||
/*flags*/ Type.DWORD,
|
||||
/*source*/ Type.void_t.in_ptr,
|
||||
/*msgid*/ Type.DWORD,
|
||||
/*langid*/ Type.DWORD,
|
||||
/*buf*/ Type.out_wstring,
|
||||
/*size*/ Type.DWORD,
|
||||
/*Arguments*/Type.void_t.in_ptr
|
||||
/*return*/ Types.DWORD,
|
||||
/*flags*/ Types.DWORD,
|
||||
/*source*/ Types.void_t.in_ptr,
|
||||
/*msgid*/ Types.DWORD,
|
||||
/*langid*/ Types.DWORD,
|
||||
/*buf*/ Types.out_wstring,
|
||||
/*size*/ Types.DWORD,
|
||||
/*Arguments*/Types.void_t.in_ptr
|
||||
);
|
||||
|
||||
SysFile.GetCurrentDirectory =
|
||||
WinFile.GetCurrentDirectory =
|
||||
declareFFI("GetCurrentDirectoryW", ctypes.winapi_abi,
|
||||
/*return*/ Type.zero_or_DWORD,
|
||||
/*length*/ Type.DWORD,
|
||||
/*buf*/ Type.out_path
|
||||
/*return*/ Types.zero_or_DWORD,
|
||||
/*length*/ Types.DWORD,
|
||||
/*buf*/ Types.out_path
|
||||
);
|
||||
|
||||
SysFile.GetFileInformationByHandle =
|
||||
WinFile.GetFileInformationByHandle =
|
||||
declareFFI("GetFileInformationByHandle", ctypes.winapi_abi,
|
||||
/*return*/ Type.zero_or_nothing,
|
||||
/*handle*/ Type.HANDLE,
|
||||
/*info*/ Type.FILE_INFORMATION.out_ptr);
|
||||
/*return*/ Types.zero_or_nothing,
|
||||
/*handle*/ Types.HANDLE,
|
||||
/*info*/ Types.FILE_INFORMATION.out_ptr);
|
||||
|
||||
SysFile.MoveFileEx =
|
||||
WinFile.MoveFileEx =
|
||||
declareFFI("MoveFileExW", ctypes.winapi_abi,
|
||||
/*return*/ Type.zero_or_nothing,
|
||||
/*sourcePath*/ Type.path,
|
||||
/*destPath*/ Type.path,
|
||||
/*flags*/ Type.DWORD
|
||||
/*return*/ Types.zero_or_nothing,
|
||||
/*sourcePath*/ Types.path,
|
||||
/*destPath*/ Types.path,
|
||||
/*flags*/ Types.DWORD
|
||||
);
|
||||
|
||||
SysFile.ReadFile =
|
||||
WinFile.ReadFile =
|
||||
declareFFI("ReadFile", ctypes.winapi_abi,
|
||||
/*return*/ Type.zero_or_nothing,
|
||||
/*file*/ Type.HANDLE,
|
||||
/*buffer*/ Type.voidptr_t,
|
||||
/*nbytes*/ Type.DWORD,
|
||||
/*nbytes_read*/Type.DWORD.out_ptr,
|
||||
/*overlapped*/Type.void_t.inout_ptr // FIXME: Implement?
|
||||
/*return*/ Types.zero_or_nothing,
|
||||
/*file*/ Types.HANDLE,
|
||||
/*buffer*/ Types.voidptr_t,
|
||||
/*nbytes*/ Types.DWORD,
|
||||
/*nbytes_read*/Types.DWORD.out_ptr,
|
||||
/*overlapped*/Types.void_t.inout_ptr // FIXME: Implement?
|
||||
);
|
||||
|
||||
SysFile.RemoveDirectory =
|
||||
WinFile.RemoveDirectory =
|
||||
declareFFI("RemoveDirectoryW", ctypes.winapi_abi,
|
||||
/*return*/ Type.zero_or_nothing,
|
||||
/*path*/ Type.path);
|
||||
/*return*/ Types.zero_or_nothing,
|
||||
/*path*/ Types.path);
|
||||
|
||||
SysFile.SetCurrentDirectory =
|
||||
WinFile.SetCurrentDirectory =
|
||||
declareFFI("SetCurrentDirectoryW", ctypes.winapi_abi,
|
||||
/*return*/ Type.zero_or_nothing,
|
||||
/*path*/ Type.path
|
||||
/*return*/ Types.zero_or_nothing,
|
||||
/*path*/ Types.path
|
||||
);
|
||||
|
||||
SysFile.SetEndOfFile =
|
||||
WinFile.SetEndOfFile =
|
||||
declareFFI("SetEndOfFile", ctypes.winapi_abi,
|
||||
/*return*/ Type.zero_or_nothing,
|
||||
/*file*/ Type.HANDLE);
|
||||
/*return*/ Types.zero_or_nothing,
|
||||
/*file*/ Types.HANDLE);
|
||||
|
||||
SysFile.SetFilePointer =
|
||||
WinFile.SetFilePointer =
|
||||
declareFFI("SetFilePointer", ctypes.winapi_abi,
|
||||
/*return*/ Type.negative_or_DWORD,
|
||||
/*file*/ Type.HANDLE,
|
||||
/*distlow*/Type.long,
|
||||
/*disthi*/ Type.long.in_ptr,
|
||||
/*method*/ Type.DWORD);
|
||||
/*return*/ Types.negative_or_DWORD,
|
||||
/*file*/ Types.HANDLE,
|
||||
/*distlow*/Types.long,
|
||||
/*disthi*/ Types.long.in_ptr,
|
||||
/*method*/ Types.DWORD);
|
||||
|
||||
SysFile.WriteFile =
|
||||
WinFile.WriteFile =
|
||||
declareFFI("WriteFile", ctypes.winapi_abi,
|
||||
/*return*/ Type.zero_or_nothing,
|
||||
/*file*/ Type.HANDLE,
|
||||
/*buffer*/ Type.voidptr_t,
|
||||
/*nbytes*/ Type.DWORD,
|
||||
/*nbytes_wr*/Type.DWORD.out_ptr,
|
||||
/*overlapped*/Type.void_t.inout_ptr // FIXME: Implement?
|
||||
/*return*/ Types.zero_or_nothing,
|
||||
/*file*/ Types.HANDLE,
|
||||
/*buffer*/ Types.voidptr_t,
|
||||
/*nbytes*/ Types.DWORD,
|
||||
/*nbytes_wr*/Types.DWORD.out_ptr,
|
||||
/*overlapped*/Types.void_t.inout_ptr // FIXME: Implement?
|
||||
);
|
||||
|
||||
SysFile.FlushFileBuffers =
|
||||
WinFile.FlushFileBuffers =
|
||||
declareFFI("FlushFileBuffers", ctypes.winapi_abi,
|
||||
/*return*/ Type.zero_or_nothing,
|
||||
/*file*/ Type.HANDLE);
|
||||
};
|
||||
|
||||
exports.OS.Win = {
|
||||
File: {
|
||||
_init: init
|
||||
}
|
||||
/*return*/ Types.zero_or_nothing,
|
||||
/*file*/ Types.HANDLE);
|
||||
};
|
||||
exports.OS.Win.File._init = init;
|
||||
})(this);
|
||||
}
|
||||
|
@ -19,19 +19,18 @@
|
||||
(function(exports) {
|
||||
"use strict";
|
||||
|
||||
exports.OS = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm").OS;
|
||||
let Path = require("resource://gre/modules/osfile/ospath.jsm");
|
||||
|
||||
// exports.OS.Win is created by osfile_win_back.jsm
|
||||
if (exports.OS && exports.OS.File) {
|
||||
return; // Avoid double-initialization
|
||||
}
|
||||
|
||||
let SharedAll = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm");
|
||||
let Path = require("resource://gre/modules/osfile/ospath.jsm");
|
||||
let SysAll = require("resource://gre/modules/osfile/osfile_win_allthreads.jsm");
|
||||
exports.OS.Win.File._init();
|
||||
let Const = exports.OS.Constants.Win;
|
||||
let WinFile = exports.OS.Win.File;
|
||||
let Type = WinFile.Type;
|
||||
let LOG = OS.Shared.LOG.bind(OS.Shared, "Win front-end");
|
||||
|
||||
// Mutable thread-global data
|
||||
// In the Windows implementation, methods |read| and |write|
|
||||
@ -48,7 +47,7 @@
|
||||
let gBytesWrittenPtr = gBytesWritten.address();
|
||||
|
||||
// Same story for GetFileInformationByHandle
|
||||
let gFileInfo = new Type.FILE_INFORMATION.implementation();
|
||||
let gFileInfo = new OS.Shared.Type.FILE_INFORMATION.implementation();
|
||||
let gFileInfoPtr = gFileInfo.address();
|
||||
|
||||
/**
|
||||
@ -389,7 +388,7 @@
|
||||
let result = WinFile.CreateDirectory(path, security);
|
||||
if (result ||
|
||||
options.ignoreExisting &&
|
||||
ctypes.winLastError == Const.ERROR_ALREADY_EXISTS) {
|
||||
ctypes.winLastError == OS.Constants.Win.ERROR_ALREADY_EXISTS) {
|
||||
return;
|
||||
}
|
||||
throw new File.Error("makeDir");
|
||||
@ -466,7 +465,7 @@
|
||||
/**
|
||||
* A global value used to receive data during time conversions.
|
||||
*/
|
||||
let gSystemTime = new Type.SystemTime.implementation();
|
||||
let gSystemTime = new OS.Shared.Type.SystemTime.implementation();
|
||||
let gSystemTimePtr = gSystemTime.address();
|
||||
|
||||
/**
|
||||
@ -515,7 +514,7 @@
|
||||
|
||||
// Pre-open the first item.
|
||||
this._first = true;
|
||||
this._findData = new Type.FindData.implementation();
|
||||
this._findData = new OS.Shared.Type.FindData.implementation();
|
||||
this._findDataPtr = this._findData.address();
|
||||
this._handle = WinFile.FindFirstFile(this._pattern, this._findDataPtr);
|
||||
if (this._handle == Const.INVALID_HANDLE_VALUE) {
|
||||
@ -524,12 +523,12 @@
|
||||
this._findDataPtr = null;
|
||||
if (error == Const.ERROR_FILE_NOT_FOUND) {
|
||||
// Directory is empty, let's behave as if it were closed
|
||||
SharedAll.LOG("Directory is empty");
|
||||
LOG("Directory is empty");
|
||||
this._closed = true;
|
||||
this._exists = true;
|
||||
} else if (error == Const.ERROR_PATH_NOT_FOUND) {
|
||||
// Directory does not exist, let's throw if we attempt to walk it
|
||||
SharedAll.LOG("Directory does not exist");
|
||||
LOG("Directory does not exist");
|
||||
this._closed = true;
|
||||
this._exists = false;
|
||||
} else {
|
||||
@ -651,11 +650,11 @@
|
||||
|
||||
let path = Path.join(this._parent, name);
|
||||
|
||||
SysAll.AbstractEntry.call(this, isDir, isSymLink, name,
|
||||
winCreationDate, winLastWriteDate,
|
||||
winLastAccessDate, path);
|
||||
exports.OS.Shared.Win.AbstractEntry.call(this, isDir, isSymLink, name,
|
||||
winCreationDate, winLastWriteDate,
|
||||
winLastAccessDate, path);
|
||||
};
|
||||
File.DirectoryIterator.Entry.prototype = Object.create(SysAll.AbstractEntry.prototype);
|
||||
File.DirectoryIterator.Entry.prototype = Object.create(exports.OS.Shared.Win.AbstractEntry.prototype);
|
||||
|
||||
/**
|
||||
* Return a version of an instance of
|
||||
@ -696,13 +695,13 @@
|
||||
let lastWriteDate = FILETIME_to_Date(stat.ftLastWriteTime);
|
||||
|
||||
let value = ctypes.UInt64.join(stat.nFileSizeHigh, stat.nFileSizeLow);
|
||||
let size = Type.uint64_t.importFromC(value);
|
||||
let size = exports.OS.Shared.Type.uint64_t.importFromC(value);
|
||||
|
||||
SysAll.AbstractInfo.call(this, isDir, isSymLink, size,
|
||||
winBirthDate, lastAccessDate,
|
||||
lastWriteDate);
|
||||
exports.OS.Shared.Win.AbstractInfo.call(this, isDir, isSymLink, size,
|
||||
winBirthDate, lastAccessDate,
|
||||
lastWriteDate);
|
||||
};
|
||||
File.Info.prototype = Object.create(SysAll.AbstractInfo.prototype);
|
||||
File.Info.prototype = Object.create(exports.OS.Shared.Win.AbstractInfo.prototype);
|
||||
|
||||
/**
|
||||
* Return a version of an instance of File.Info that can be sent
|
||||
@ -745,14 +744,14 @@
|
||||
// All of the following is required to ensure that File.stat
|
||||
// also works on directories.
|
||||
const FILE_STAT_MODE = {
|
||||
read: true
|
||||
read:true
|
||||
};
|
||||
const FILE_STAT_OPTIONS = {
|
||||
// Directories can be opened neither for reading(!) nor for writing
|
||||
winAccess: 0,
|
||||
// Directories can only be opened with backup semantics(!)
|
||||
winFlags: Const.FILE_FLAG_BACKUP_SEMANTICS,
|
||||
winDisposition: Const.OPEN_EXISTING
|
||||
winFlags: OS.Constants.Win.FILE_FLAG_BACKUP_SEMANTICS,
|
||||
winDisposition: OS.Constants.Win.OPEN_EXISTING
|
||||
};
|
||||
|
||||
File.read = exports.OS.Shared.AbstractFile.read;
|
||||
@ -763,34 +762,35 @@
|
||||
* Get the current directory by getCurrentDirectory.
|
||||
*/
|
||||
File.getCurrentDirectory = function getCurrentDirectory() {
|
||||
// This function is more complicated than one could hope.
|
||||
//
|
||||
// This is due to two facts:
|
||||
// - the maximal length of a path under Windows is not completely
|
||||
// specified (there is a constant MAX_PATH, but it is quite possible
|
||||
// to create paths that are much larger, see bug 744413);
|
||||
// - if we attempt to call |GetCurrentDirectory| with a buffer that
|
||||
// is too short, it returns the length of the current directory, but
|
||||
// this length might be insufficient by the time we can call again
|
||||
// the function with a larger buffer, in the (unlikely but possible)
|
||||
// case in which the process changes directory to a directory with
|
||||
// a longer name between both calls.
|
||||
//
|
||||
let buffer_size = 4096;
|
||||
while (true) {
|
||||
let array = new (ctypes.ArrayType(ctypes.jschar, buffer_size))();
|
||||
// This function is more complicated than one could hope.
|
||||
//
|
||||
// This is due to two facts:
|
||||
// - the maximal length of a path under Windows is not completely
|
||||
// specified (there is a constant MAX_PATH, but it is quite possible
|
||||
// to create paths that are much larger, see bug 744413);
|
||||
// - if we attempt to call |GetCurrentDirectory| with a buffer that
|
||||
// is too short, it returns the length of the current directory, but
|
||||
// this length might be insufficient by the time we can call again
|
||||
// the function with a larger buffer, in the (unlikely byt possible)
|
||||
// case in which the process changes directory to a directory with
|
||||
// a longer name between both calls.
|
||||
let buffer_size = 4096;
|
||||
while (true) {
|
||||
let array = new (ctypes.ArrayType(ctypes.jschar, buffer_size))();
|
||||
let expected_size = throw_on_zero("getCurrentDirectory",
|
||||
WinFile.GetCurrentDirectory(buffer_size, array)
|
||||
);
|
||||
if (expected_size <= buffer_size) {
|
||||
return array.readString();
|
||||
}
|
||||
// At this point, we are in a case in which our buffer was not
|
||||
// large enough to hold the name of the current directory.
|
||||
// Consequently, we need to increase the size of the buffer.
|
||||
// Note that, even in crazy scenarios, the loop will eventually
|
||||
// converge, as the length of the paths cannot increase infinitely.
|
||||
buffer_size = expected_size + 1 /* to store \0 */;
|
||||
WinFile.GetCurrentDirectory(buffer_size, array)
|
||||
);
|
||||
if (expected_size <= buffer_size) {
|
||||
return array.readString();
|
||||
}
|
||||
// At this point, we are in a case in which our buffer was not
|
||||
// large enough to hold the name of the current directory.
|
||||
// Consequently
|
||||
|
||||
// Note that, even in crazy scenarios, the loop will eventually
|
||||
// converge, as the length of the paths cannot increase infinitely.
|
||||
buffer_size = expected_size;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@ -816,7 +816,7 @@
|
||||
|
||||
// Utility functions, used for error-handling
|
||||
function error_or_file(maybe) {
|
||||
if (maybe == Const.INVALID_HANDLE_VALUE) {
|
||||
if (maybe == exports.OS.Constants.Win.INVALID_HANDLE_VALUE) {
|
||||
throw new File.Error("open");
|
||||
}
|
||||
return new File(maybe);
|
||||
@ -841,12 +841,13 @@
|
||||
}
|
||||
|
||||
File.Win = exports.OS.Win.File;
|
||||
File.Error = SysAll.Error;
|
||||
File.Error = exports.OS.Shared.Win.Error;
|
||||
exports.OS.File = File;
|
||||
exports.OS.Shared.Type = Type;
|
||||
|
||||
Object.defineProperty(File, "POS_START", { value: SysAll.POS_START });
|
||||
Object.defineProperty(File, "POS_CURRENT", { value: SysAll.POS_CURRENT });
|
||||
Object.defineProperty(File, "POS_END", { value: SysAll.POS_END });
|
||||
exports.OS.Path = exports.Path;
|
||||
|
||||
Object.defineProperty(File, "POS_START", { value: OS.Shared.POS_START });
|
||||
Object.defineProperty(File, "POS_CURRENT", { value: OS.Shared.POS_CURRENT });
|
||||
Object.defineProperty(File, "POS_END", { value: OS.Shared.POS_END });
|
||||
})(this);
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ if (typeof Components != "undefined") {
|
||||
#ifdef XP_WIN
|
||||
importScripts(
|
||||
"resource://gre/modules/workers/require.js",
|
||||
"resource://gre/modules/osfile/osfile_win_allthreads.jsm",
|
||||
"resource://gre/modules/osfile/osfile_win_back.jsm",
|
||||
"resource://gre/modules/osfile/osfile_shared_front.jsm",
|
||||
"resource://gre/modules/osfile/osfile_win_front.jsm"
|
||||
@ -23,6 +24,7 @@ if (typeof Components != "undefined") {
|
||||
#else
|
||||
importScripts(
|
||||
"resource://gre/modules/workers/require.js",
|
||||
"resource://gre/modules/osfile/osfile_unix_allthreads.jsm",
|
||||
"resource://gre/modules/osfile/osfile_unix_back.jsm",
|
||||
"resource://gre/modules/osfile/osfile_shared_front.jsm",
|
||||
"resource://gre/modules/osfile/osfile_unix_front.jsm"
|
||||
|
@ -61,9 +61,6 @@ let maketest = function(prefix, test) {
|
||||
utils.info("Complete");
|
||||
}, function catch_uncaught_errors(err) {
|
||||
utils.fail("Uncaught error " + err);
|
||||
if (err && typeof err == "object" && "message" in err) {
|
||||
utils.fail("(" + err.message + ")");
|
||||
}
|
||||
if (err && typeof err == "object" && "stack" in err) {
|
||||
utils.fail("at " + err.stack);
|
||||
}
|
||||
@ -927,9 +924,12 @@ let test_duration = maketest("duration", function duration(test) {
|
||||
test.ok(copyOptions.outExecutionDuration >= backupDuration, "duration has increased 3");
|
||||
OS.File.remove(pathDest);
|
||||
|
||||
OS.Shared.TEST = true;
|
||||
|
||||
// Testing an operation that doesn't take arguments at all
|
||||
let file = yield OS.File.open(pathSource);
|
||||
yield file.stat();
|
||||
yield file.close();
|
||||
Services.prefs.setBoolPref("toolkit.osfile.log", false);
|
||||
});
|
||||
});
|
||||
|
@ -4,7 +4,7 @@
|
||||
function worker_handler(worker) {
|
||||
worker.onerror = function(error) {
|
||||
error.preventDefault();
|
||||
ok(false, "Worker error " + error.message);
|
||||
ok(false, "error "+error);
|
||||
}
|
||||
worker.onmessage = function(msg) {
|
||||
ok(true, "MAIN: onmessage " + JSON.stringify(msg.data));
|
||||
|
@ -2,10 +2,6 @@
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
importScripts('worker_test_osfile_shared.js');
|
||||
importScripts("resource://gre/modules/workers/require.js");
|
||||
|
||||
let SharedAll = require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm");
|
||||
SharedAll.Config.DEBUG = true;
|
||||
|
||||
function should_throw(f) {
|
||||
try {
|
||||
@ -63,9 +59,9 @@ function test_offsetby() {
|
||||
}
|
||||
|
||||
// Walk through the array with offsetBy by 8 bits
|
||||
let uint8 = SharedAll.Type.uint8_t.in_ptr.implementation(buf);
|
||||
let uint8 = OS.Shared.Type.uint8_t.in_ptr.implementation(buf);
|
||||
for (i = 0; i < LENGTH; ++i) {
|
||||
let value = SharedAll.offsetBy(uint8, i).contents;
|
||||
let value = OS.Shared.offsetBy(uint8, i).contents;
|
||||
if (value != i%256) {
|
||||
is(value, i % 256, "test_offsetby: Walking through array with offsetBy (8 bits)");
|
||||
break;
|
||||
@ -73,10 +69,10 @@ function test_offsetby() {
|
||||
}
|
||||
|
||||
// Walk again by 16 bits
|
||||
let uint16 = SharedAll.Type.uint16_t.in_ptr.implementation(buf);
|
||||
let uint16 = OS.Shared.Type.uint16_t.in_ptr.implementation(buf);
|
||||
let view2 = new Uint16Array(buf);
|
||||
for (i = 0; i < LENGTH/2; ++i) {
|
||||
let value = SharedAll.offsetBy(uint16, i).contents;
|
||||
let value = OS.Shared.offsetBy(uint16, i).contents;
|
||||
if (value != view2[i]) {
|
||||
is(value, view2[i], "test_offsetby: Walking through array with offsetBy (16 bits)");
|
||||
break;
|
||||
@ -84,15 +80,15 @@ function test_offsetby() {
|
||||
}
|
||||
|
||||
// Ensure that offsetBy(..., 0) is idempotent
|
||||
let startptr = SharedAll.offsetBy(uint8, 0);
|
||||
let startptr2 = SharedAll.offsetBy(startptr, 0);
|
||||
let startptr = OS.Shared.offsetBy(uint8, 0);
|
||||
let startptr2 = OS.Shared.offsetBy(startptr, 0);
|
||||
is(startptr.toString(), startptr2.toString(), "test_offsetby: offsetBy(..., 0) is idmpotent");
|
||||
|
||||
// Ensure that offsetBy(ptr, ...) does not work if ptr is a void*
|
||||
let ptr = ctypes.voidptr_t(0);
|
||||
let exn;
|
||||
try {
|
||||
SharedAll.offsetBy(ptr, 1);
|
||||
OS.Shared.Utils.offsetBy(ptr, 1);
|
||||
} catch (x) {
|
||||
exn = x;
|
||||
}
|
||||
|
@ -145,10 +145,6 @@ function run_test()
|
||||
|
||||
do_print("Testing the presence of ospath.jsm");
|
||||
let Scope = {};
|
||||
try {
|
||||
Components.utils.import("resource://gre/modules/osfile/ospath.jsm", Scope);
|
||||
} catch (ex) {
|
||||
// Can't load ospath
|
||||
}
|
||||
Components.utils.import("resource://gre/modules/osfile/ospath.jsm", Scope);
|
||||
do_check_true(!!Scope.basename);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user