Bug 801376 - OS.File loads symbols lazily;r=froydnj

This commit is contained in:
David Rajchenbach-Teller 2013-10-22 02:43:00 +01:00
parent b0c424efea
commit a01b1f3365
5 changed files with 194 additions and 186 deletions

View File

@ -41,6 +41,8 @@ let EXPORTED_SYMBOLS = [
"HollowStructure",
"OSError",
"declareFFI",
"declareLazy",
"declareLazyFFI",
"projectValue",
"isTypedArray",
"defineLazyGetter",
@ -890,9 +892,7 @@ exports.HollowStructure = HollowStructure;
* @return null if the function could not be defined (generally because
* it does not exist), or a JavaScript wrapper performing the call to C
* and any type conversion required.
*/// Note: Future versions will use a different implementation of this
// function on the main thread, osfile worker thread and regular worker
// thread
*/
let declareFFI = function declareFFI(lib, symbol, abi,
returnType /*, argTypes ...*/) {
LOG("Attempting to declare FFI ", symbol);
@ -941,6 +941,62 @@ let declareFFI = function declareFFI(lib, symbol, abi,
};
exports.declareFFI = declareFFI;
/**
* Define a lazy getter to a js-ctypes function using declareFFI.
*
* @param {object} The object containing the function as a field.
* @param {string} The name of the field containing the function.
* @param {ctypes.library} lib The ctypes library holding the function.
* @param {string} symbol The name of the function, as defined in the
* library.
* @param {ctypes.abi} abi The abi to use, or |null| for default.
* @param {Type} returnType The type of values returned by the function.
* @param {...Type} argTypes The type of arguments to the function.
*/
function declareLazyFFI(object, field, ...declareFFIArgs) {
Object.defineProperty(object, field, {
get: function() {
delete this[field];
let ffi = declareFFI(...declareFFIArgs);
if (ffi) {
return this[field] = ffi;
}
return undefined;
},
configurable: true
});
}
exports.declareLazyFFI = declareLazyFFI;
/**
* Define a lazy getter to a js-ctypes function using ctypes method declare.
*
* @param {object} The object containing the function as a field.
* @param {string} The name of the field containing the function.
* @param {ctypes.library} lib The ctypes library holding the function.
* @param {string} symbol The name of the function, as defined in the
* library.
* @param {ctypes.abi} abi The abi to use, or |null| for default.
* @param {ctypes.CType} returnType The type of values returned by the function.
* @param {...ctypes.CType} argTypes The type of arguments to the function.
*/
function declareLazy(object, field, lib, ...declareArgs) {
Object.defineProperty(object, field, {
get: function() {
delete this[field];
try {
let ffi = lib.declare(...declareArgs);
return this[field] = ffi;
} catch (ex) {
// The symbol doesn't exist
return undefined;
}
},
configurable: true
});
}
exports.declareLazy = declareLazy;
// A bogus array type used to perform pointer arithmetics
let gOffsetByType;

View File

@ -38,6 +38,7 @@
} else {
declareFFI = SysAll.declareFFI;
}
let declareLazyFFI = SharedAll.declareLazyFFI;
// Initialize types that require additional OS-specific
// support - either finalization or matching against
@ -50,7 +51,7 @@
*/
Type.fd = Type.int.withName("fd");
Type.fd.importFromC = function importFromC(fd_int) {
return ctypes.CDataFinalizer(fd_int, _close);
return ctypes.CDataFinalizer(fd_int, SysFile._close);
};
@ -64,7 +65,7 @@
if (fd_int == -1) {
return -1;
}
return ctypes.CDataFinalizer(fd_int, _close);
return ctypes.CDataFinalizer(fd_int, SysFile._close);
};
/**
@ -196,14 +197,14 @@
if (dir == null || dir.isNull()) {
return null;
}
return ctypes.CDataFinalizer(dir, _close_dir);
return ctypes.CDataFinalizer(dir, SysFile._close_dir);
};
// Declare libc functions as functions of |OS.Unix.File|
// Finalizer-related functions
let _close = SysFile._close =
libc.declare("close", ctypes.default_abi,
SharedAll.declareLazy(SysFile, "_close", libc,
"close", ctypes.default_abi,
/*return */ctypes.int,
/*fd*/ ctypes.int);
@ -212,8 +213,8 @@
return fd.dispose();
};
let _close_dir =
libc.declare("closedir", ctypes.default_abi,
SharedAll.declareLazy(SysFile, "_close_dir", libc,
"closedir", ctypes.default_abi,
/*return */ctypes.int,
/*dirp*/ Type.DIR.in_ptr.implementation);
@ -232,8 +233,8 @@
// correct implementation free().
default_lib = ctypes.open("a.out");
SysFile.free =
default_lib.declare("free", ctypes.default_abi,
SharedAll.declareLazy(SysFile, "free", default_lib,
"free", ctypes.default_abi,
/*return*/ ctypes.void_t,
/*ptr*/ ctypes.voidptr_t);
@ -241,8 +242,8 @@
// We don't have an a.out library or a.out doesn't contain free.
// Either way, use the ordinary libc free.
SysFile.free =
libc.declare("free", ctypes.default_abi,
SharedAll.declareLazy(SysFile, "free", libc,
"free", ctypes.default_abi,
/*return*/ ctypes.void_t,
/*ptr*/ ctypes.voidptr_t);
}
@ -250,40 +251,34 @@
// Other functions
SysFile.access =
declareFFI("access", ctypes.default_abi,
declareLazyFFI(SysFile, "access", libc, "access", ctypes.default_abi,
/*return*/ Type.negativeone_or_nothing,
/*path*/ Type.path,
/*mode*/ Type.int);
SysFile.chdir =
declareFFI("chdir", ctypes.default_abi,
declareLazyFFI(SysFile, "chdir", libc, "chdir", ctypes.default_abi,
/*return*/ Type.negativeone_or_nothing,
/*path*/ Type.path);
SysFile.chmod =
declareFFI("chmod", ctypes.default_abi,
declareLazyFFI(SysFile, "chmod", libc, "chmod", ctypes.default_abi,
/*return*/ Type.negativeone_or_nothing,
/*path*/ Type.path,
/*mode*/ Type.mode_t);
SysFile.chown =
declareFFI("chown", ctypes.default_abi,
declareLazyFFI(SysFile, "chown", libc, "chown", ctypes.default_abi,
/*return*/ Type.negativeone_or_nothing,
/*path*/ Type.path,
/*uid*/ Type.uid_t,
/*gid*/ Type.gid_t);
SysFile.copyfile =
declareFFI("copyfile", ctypes.default_abi,
declareLazyFFI(SysFile, "copyfile", libc, "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);
SysFile.dup =
declareFFI("dup", ctypes.default_abi,
declareLazyFFI(SysFile, "dup", libc, "dup", ctypes.default_abi,
/*return*/ Type.negativeone_or_fd,
/*fd*/ Type.fd);
@ -295,42 +290,35 @@
};
} else {
// On platforms for which |dirfd| is a function
SysFile.dirfd =
declareFFI("dirfd", ctypes.default_abi,
declareLazyFFI(SysFile, "dirfd", libc, "dirfd", ctypes.default_abi,
/*return*/ Type.negativeone_or_fd,
/*dir*/ Type.DIR.in_ptr);
}
SysFile.chdir =
declareFFI("chdir", ctypes.default_abi,
declareLazyFFI(SysFile, "chdir", libc, "chdir", ctypes.default_abi,
/*return*/ Type.negativeone_or_nothing,
/*path*/ Type.path);
SysFile.fchdir =
declareFFI("fchdir", ctypes.default_abi,
declareLazyFFI(SysFile, "fchdir", libc, "fchdir", ctypes.default_abi,
/*return*/ Type.negativeone_or_nothing,
/*fd*/ Type.fd);
SysFile.fchown =
declareFFI("fchown", ctypes.default_abi,
declareLazyFFI(SysFile, "fchown", libc, "fchown", ctypes.default_abi,
/*return*/ Type.negativeone_or_nothing,
/*fd*/ Type.fd,
/*uid_t*/ Type.uid_t,
/*gid_t*/ Type.gid_t);
SysFile.fsync =
declareFFI("fsync", ctypes.default_abi,
declareLazyFFI(SysFile, "fsync", libc, "fsync", ctypes.default_abi,
/*return*/ Type.negativeone_or_nothing,
/*fd*/ Type.fd);
SysFile.getcwd =
declareFFI("getcwd", ctypes.default_abi,
declareLazyFFI(SysFile, "getcwd", libc, "getcwd", ctypes.default_abi,
/*return*/ Type.out_path,
/*buf*/ Type.out_path,
/*size*/ Type.size_t);
SysFile.getwd =
declareFFI("getwd", ctypes.default_abi,
declareLazyFFI(SysFile, "getwd", libc, "getwd", ctypes.default_abi,
/*return*/ Type.out_path,
/*buf*/ Type.out_path);
@ -338,111 +326,85 @@
// dynamically.
// Linux/Android version
SysFile.get_current_dir_name =
declareFFI("get_current_dir_name", ctypes.default_abi,
/*return*/ Type.out_path.releaseWith(SysFile.free));
declareLazyFFI(SysFile, "get_current_dir_name", libc,
"get_current_dir_name", ctypes.default_abi,
/*return*/ Type.out_path.releaseWith(SysFile.free));
// MacOS/BSD version (will return NULL on Linux/Android)
SysFile.getwd_auto =
declareFFI("getwd", ctypes.default_abi,
/*return*/ Type.out_path.releaseWith(SysFile.free),
/*buf*/ Type.void_t.out_ptr);
declareLazyFFI(SysFile, "getwd_auto", libc,
"getwd", ctypes.default_abi,
/*return*/ Type.out_path.releaseWith(SysFile.free),
/*buf*/ Type.void_t.out_ptr);
SysFile.fdatasync =
declareFFI("fdatasync", ctypes.default_abi,
declareLazyFFI(SysFile, "fdatasync", libc,
"fdatasync", ctypes.default_abi,
/*return*/ Type.negativeone_or_nothing,
/*fd*/ Type.fd); // Note: MacOS/BSD-specific
SysFile.ftruncate =
declareFFI("ftruncate", ctypes.default_abi,
declareLazyFFI(SysFile, "ftruncate", libc,
"ftruncate", ctypes.default_abi,
/*return*/ Type.negativeone_or_nothing,
/*fd*/ Type.fd,
/*length*/ Type.off_t);
if (Const._DARWIN_FEATURE_64_BIT_INODE) {
SysFile.fstat =
declareFFI("fstat$INODE64", ctypes.default_abi,
/*return*/ Type.negativeone_or_nothing,
/*path*/ Type.fd,
/*buf*/ Type.stat.out_ptr
);
} else {
SysFile.fstat =
declareFFI("fstat", ctypes.default_abi,
/*return*/ Type.negativeone_or_nothing,
/*path*/ Type.fd,
/*buf*/ Type.stat.out_ptr
);
}
SysFile.lchown =
declareFFI("lchown", ctypes.default_abi,
declareLazyFFI(SysFile, "lchown", libc, "lchown", ctypes.default_abi,
/*return*/ Type.negativeone_or_nothing,
/*path*/ Type.path,
/*uid_t*/ Type.uid_t,
/*gid_t*/ Type.gid_t);
SysFile.link =
declareFFI("link", ctypes.default_abi,
declareLazyFFI(SysFile, "link", libc, "link", ctypes.default_abi,
/*return*/ Type.negativeone_or_nothing,
/*source*/ Type.path,
/*dest*/ Type.path);
SysFile.lseek =
declareFFI("lseek", ctypes.default_abi,
declareLazyFFI(SysFile, "lseek", libc, "lseek", ctypes.default_abi,
/*return*/ Type.off_t,
/*fd*/ Type.fd,
/*offset*/ Type.off_t,
/*whence*/ Type.int);
SysFile.mkdir =
declareFFI("mkdir", ctypes.default_abi,
declareLazyFFI(SysFile, "mkdir", libc, "mkdir", ctypes.default_abi,
/*return*/ Type.int,
/*path*/ Type.path,
/*mode*/ Type.int);
SysFile.mkstemp =
declareFFI("mkstemp", ctypes.default_abi,
declareLazyFFI(SysFile, "mkstemp", libc, "mkstemp", ctypes.default_abi,
/*return*/ Type.fd,
/*template*/Type.out_path);
SysFile.open =
declareFFI("open", ctypes.default_abi,
declareLazyFFI(SysFile, "open", libc, "open", ctypes.default_abi,
/*return*/Type.negativeone_or_fd,
/*path*/ Type.path,
/*oflags*/Type.int,
/*mode*/ Type.int);
SysFile.opendir =
declareFFI("opendir", ctypes.default_abi,
declareLazyFFI(SysFile, "opendir", libc, "opendir", ctypes.default_abi,
/*return*/ Type.null_or_DIR_ptr,
/*path*/ Type.path);
SysFile.pread =
declareFFI("pread", ctypes.default_abi,
declareLazyFFI(SysFile, "pread", libc, "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);
SysFile.pwrite =
declareFFI("pwrite", ctypes.default_abi,
declareLazyFFI(SysFile, "pwrite", libc, "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);
SysFile.read =
declareFFI("read", ctypes.default_abi,
declareLazyFFI(SysFile, "read", libc, "read", ctypes.default_abi,
/*return*/Type.negativeone_or_ssize_t,
/*fd*/ Type.fd,
/*buf*/ Type.void_t.out_ptr,
/*nbytes*/Type.size_t);
SysFile.posix_fadvise =
declareFFI("posix_fadvise", ctypes.default_abi,
declareLazyFFI(SysFile, "posix_fadvise", libc, "posix_fadvise", ctypes.default_abi,
/*return*/ Type.int,
/*fd*/ Type.fd,
/*offset*/ Type.off_t,
@ -454,30 +416,25 @@
// Symbol name "readdir" still exists but is used for a
// deprecated function that does not match the
// constants of |Const|.
SysFile.readdir =
declareFFI("readdir$INODE64", ctypes.default_abi,
declareLazyFFI(SysFile, "readdir", libc, "readdir$INODE64", ctypes.default_abi,
/*return*/Type.null_or_dirent_ptr,
/*dir*/ Type.DIR.in_ptr); // For MacOS X
} else {
SysFile.readdir =
declareFFI("readdir", ctypes.default_abi,
declareLazyFFI(SysFile, "readdir", libc, "readdir", ctypes.default_abi,
/*return*/Type.null_or_dirent_ptr,
/*dir*/ Type.DIR.in_ptr); // Other Unices
}
SysFile.rename =
declareFFI("rename", ctypes.default_abi,
declareLazyFFI(SysFile, "rename", libc, "rename", ctypes.default_abi,
/*return*/ Type.negativeone_or_nothing,
/*old*/ Type.path,
/*new*/ Type.path);
SysFile.rmdir =
declareFFI("rmdir", ctypes.default_abi,
declareLazyFFI(SysFile, "rmdir", libc, "rmdir", ctypes.default_abi,
/*return*/ Type.int,
/*path*/ Type.path);
SysFile.splice =
declareFFI("splice", ctypes.default_abi,
declareLazyFFI(SysFile, "splice", libc, "splice", ctypes.default_abi,
/*return*/ Type.long,
/*fd_in*/ Type.fd,
/*off_in*/ Type.off_t.in_ptr,
@ -486,25 +443,21 @@
/*len*/ Type.size_t,
/*flags*/ Type.unsigned_int); // Linux/Android-specific
SysFile.symlink =
declareFFI("symlink", ctypes.default_abi,
declareLazyFFI(SysFile, "symlink", libc, "symlink", ctypes.default_abi,
/*return*/ Type.negativeone_or_nothing,
/*source*/ Type.path,
/*dest*/ Type.path);
SysFile.truncate =
declareFFI("truncate", ctypes.default_abi,
declareLazyFFI(SysFile, "truncate", libc, "truncate", ctypes.default_abi,
/*return*/Type.negativeone_or_nothing,
/*path*/ Type.path,
/*length*/ Type.off_t);
SysFile.unlink =
declareFFI("unlink", ctypes.default_abi,
declareLazyFFI(SysFile, "unlink", libc, "unlink", ctypes.default_abi,
/*return*/ Type.negativeone_or_nothing,
/*path*/ Type.path);
SysFile.write =
declareFFI("write", ctypes.default_abi,
declareLazyFFI(SysFile, "write", libc, "write", ctypes.default_abi,
/*return*/ Type.negativeone_or_ssize_t,
/*fd*/ Type.fd,
/*buf*/ Type.void_t.in_ptr,
@ -516,20 +469,17 @@
// 32-bits and 64-bits versions of |stat|, |lstat|, |fstat|.
if (Const._DARWIN_FEATURE_64_BIT_INODE) {
// MacOS X 64-bits
SysFile.stat =
declareFFI("stat$INODE64", ctypes.default_abi,
declareLazyFFI(SysFile, "stat", libc, "stat$INODE64", ctypes.default_abi,
/*return*/ Type.negativeone_or_nothing,
/*path*/ Type.path,
/*buf*/ Type.stat.out_ptr
);
SysFile.lstat =
declareFFI("lstat$INODE64", ctypes.default_abi,
declareLazyFFI(SysFile, "lstat", libc, "lstat$INODE64", ctypes.default_abi,
/*return*/ Type.negativeone_or_nothing,
/*path*/ Type.path,
/*buf*/ Type.stat.out_ptr
);
SysFile.fstat =
declareFFI("fstat$INODE64", ctypes.default_abi,
declareLazyFFI(SysFile, "fstat", libc, "fstat$INODE64", ctypes.default_abi,
/*return*/ Type.negativeone_or_nothing,
/*path*/ Type.fd,
/*buf*/ Type.stat.out_ptr
@ -549,50 +499,49 @@
fxstat_name = "__fxstat";
}
let xstat =
declareFFI(xstat_name, ctypes.default_abi,
let Stat = {};
declareLazyFFI(Stat, "xstat", libc, xstat_name, ctypes.default_abi,
/*return*/ Type.negativeone_or_nothing,
/*_stat_ver*/ Type.int,
/*path*/ Type.path,
/*buf*/ Type.stat.out_ptr);
let lxstat =
declareFFI(lxstat_name, ctypes.default_abi,
declareLazyFFI(Stat, "lxstat", libc, lxstat_name, ctypes.default_abi,
/*return*/ Type.negativeone_or_nothing,
/*_stat_ver*/ Type.int,
/*path*/ Type.path,
/*buf*/ Type.stat.out_ptr);
let fxstat =
declareFFI(fxstat_name, ctypes.default_abi,
declareLazyFFI(Stat, "fxstat", libc,
fxstat_name, ctypes.default_abi,
/*return*/ Type.negativeone_or_nothing,
/*_stat_ver*/ Type.int,
/*fd*/ Type.fd,
/*buf*/ Type.stat.out_ptr);
SysFile.stat = function stat(path, buf) {
return xstat(ver, path, buf);
return Stat.xstat(ver, path, buf);
};
SysFile.lstat = function stat(path, buf) {
return lxstat(ver, path, buf);
SysFile.lstat = function lstat(path, buf) {
return Stat.lxstat(ver, path, buf);
};
SysFile.fstat = function stat(fd, buf) {
return fxstat(ver, fd, buf);
SysFile.fstat = function fstat(fd, buf) {
return Stat.fxstat(ver, fd, buf);
};
} else {
// Mac OS X 32-bits, other Unix
SysFile.stat =
declareFFI("stat", ctypes.default_abi,
declareLazyFFI(SysFile, "stat", libc, "stat", ctypes.default_abi,
/*return*/ Type.negativeone_or_nothing,
/*path*/ Type.path,
/*buf*/ Type.stat.out_ptr
);
SysFile.lstat =
declareFFI("lstat", ctypes.default_abi,
declareLazyFFI(SysFile, "lstat", libc, "lstat", ctypes.default_abi,
/*return*/ Type.negativeone_or_nothing,
/*path*/ Type.path,
/*buf*/ Type.stat.out_ptr
);
SysFile.fstat =
declareFFI("fstat", ctypes.default_abi,
declareLazyFFI(SysFile, "fstat", libc, "fstat", ctypes.default_abi,
/*return*/ Type.negativeone_or_nothing,
/*fd*/ Type.fd,
/*buf*/ Type.stat.out_ptr
@ -602,22 +551,23 @@
// We cannot make a C array of CDataFinalizer, so
// pipe cannot be directly defined as a C function.
let _pipe =
declareFFI("pipe", ctypes.default_abi,
/*return*/ Type.negativeone_or_nothing,
/*fds*/ new SharedAll.Type("two file descriptors",
let Pipe = {};
declareLazyFFI(Pipe, "_pipe", libc,
"pipe", ctypes.default_abi,
/*return*/ Type.negativeone_or_nothing,
/*fds*/ new SharedAll.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) {
let result = _pipe(_pipebuf);
let result = Pipe._pipe(_pipebuf);
if (result == -1) {
return result;
}
array[0] = ctypes.CDataFinalizer(_pipebuf[0], _close);
array[1] = ctypes.CDataFinalizer(_pipebuf[1], _close);
array[0] = ctypes.CDataFinalizer(_pipebuf[0], SysFile._close);
array[1] = ctypes.CDataFinalizer(_pipebuf[1], SysFile._close);
return result;
};
};

View File

@ -53,8 +53,11 @@ exports.libc = libc;
let declareFFI = SharedAll.declareFFI.bind(null, libc);
exports.declareFFI = declareFFI;
let Scope = {};
// Define Error
let FormatMessage = libc.declare("FormatMessageW", ctypes.winapi_abi,
SharedAll.declareLazy(Scope, "FormatMessage", libc,
"FormatMessageW", ctypes.winapi_abi,
/*return*/ ctypes.uint32_t,
/*flags*/ ctypes.uint32_t,
/*source*/ ctypes.voidptr_t,
@ -96,7 +99,7 @@ let OSError = function OSError(operation, lastError) {
OSError.prototype = Object.create(SharedAll.OSError.prototype);
OSError.prototype.toString = function toString() {
let buf = new (ctypes.ArrayType(ctypes.jschar, 1024))();
let result = FormatMessage(
let result = Scope.FormatMessage(
Const.FORMAT_MESSAGE_FROM_SYSTEM |
Const.FORMAT_MESSAGE_IGNORE_INSERTS,
null,

View File

@ -54,6 +54,7 @@
} else {
declareFFI = SysAll.declareFFI;
}
let declareLazyFFI = SharedAll.declareLazyFFI;
// Initialize types that require additional OS-specific
// support - either finalization or matching against
@ -87,14 +88,14 @@
SharedAll.defineLazyGetter(Type.file_HANDLE,
"finalizeHANDLE",
function() {
return _CloseHandle;
return SysFile._CloseHandle;
});
Type.find_HANDLE = Type.HANDLE.withName("find HANDLE");
SharedAll.defineLazyGetter(Type.find_HANDLE,
"finalizeHANDLE",
function() {
return _FindClose;
return SysFile._FindClose;
});
Type.DWORD = Type.int32_t.withName("DWORD");
@ -173,8 +174,8 @@
// Special case: these functions are used by the
// finalizer
let _CloseHandle = SysFile._CloseHandle =
libc.declare("CloseHandle", ctypes.winapi_abi,
SharedAll.declareLazy(SysFile, "_CloseHandle", libc,
"CloseHandle", ctypes.winapi_abi,
/*return */ctypes.bool,
/*handle*/ ctypes.voidptr_t);
@ -186,8 +187,8 @@
}
};
let _FindClose =
libc.declare("FindClose", ctypes.winapi_abi,
SharedAll.declareLazy(SysFile, "_FindClose", libc,
"FindClose", ctypes.winapi_abi,
/*return */ctypes.bool,
/*handle*/ ctypes.voidptr_t);
@ -201,21 +202,21 @@
// Declare libc functions as functions of |OS.Win.File|
SysFile.CopyFile =
declareFFI("CopyFileW", ctypes.winapi_abi,
declareLazyFFI(SysFile, "CopyFile", libc,
"CopyFileW", ctypes.winapi_abi,
/*return*/ Type.zero_or_nothing,
/*sourcePath*/ Type.path,
/*destPath*/ Type.path,
/*bailIfExist*/Type.bool);
SysFile.CreateDirectory =
declareFFI("CreateDirectoryW", ctypes.winapi_abi,
declareLazyFFI(SysFile, "CreateDirectory", libc,
"CreateDirectoryW", ctypes.winapi_abi,
/*return*/ Type.zero_or_nothing,
/*name*/ Type.jschar.in_ptr,
/*security*/Type.SECURITY_ATTRIBUTES.in_ptr);
SysFile.CreateFile =
declareFFI("CreateFileW", ctypes.winapi_abi,
declareLazyFFI(SysFile, "CreateFile", libc,
"CreateFileW", ctypes.winapi_abi,
/*return*/ Type.file_HANDLE,
/*name*/ Type.path,
/*access*/ Type.DWORD,
@ -225,31 +226,31 @@
/*flags*/ Type.DWORD,
/*template*/Type.HANDLE);
SysFile.DeleteFile =
declareFFI("DeleteFileW", ctypes.winapi_abi,
declareLazyFFI(SysFile, "DeleteFile", libc,
"DeleteFileW", ctypes.winapi_abi,
/*return*/ Type.zero_or_nothing,
/*path*/ Type.path);
SysFile.FileTimeToSystemTime =
declareFFI("FileTimeToSystemTime", ctypes.winapi_abi,
declareLazyFFI(SysFile, "FileTimeToSystemTime", libc,
"FileTimeToSystemTime", ctypes.winapi_abi,
/*return*/ Type.zero_or_nothing,
/*filetime*/Type.FILETIME.in_ptr,
/*systime*/ Type.SystemTime.out_ptr);
SysFile.FindFirstFile =
declareFFI("FindFirstFileW", ctypes.winapi_abi,
declareLazyFFI(SysFile, "FindFirstFile", libc,
"FindFirstFileW", ctypes.winapi_abi,
/*return*/ Type.find_HANDLE,
/*pattern*/Type.path,
/*data*/ Type.FindData.out_ptr);
SysFile.FindNextFile =
declareFFI("FindNextFileW", ctypes.winapi_abi,
declareLazyFFI(SysFile, "FindNextFile", libc,
"FindNextFileW", ctypes.winapi_abi,
/*return*/ Type.zero_or_nothing,
/*prev*/ Type.find_HANDLE,
/*data*/ Type.FindData.out_ptr);
SysFile.FormatMessage =
declareFFI("FormatMessageW", ctypes.winapi_abi,
declareLazyFFI(SysFile, "FormatMessage", libc,
"FormatMessageW", ctypes.winapi_abi,
/*return*/ Type.DWORD,
/*flags*/ Type.DWORD,
/*source*/ Type.void_t.in_ptr,
@ -260,29 +261,29 @@
/*Arguments*/Type.void_t.in_ptr
);
SysFile.GetCurrentDirectory =
declareFFI("GetCurrentDirectoryW", ctypes.winapi_abi,
declareLazyFFI(SysFile, "GetCurrentDirectory", libc,
"GetCurrentDirectoryW", ctypes.winapi_abi,
/*return*/ Type.zero_or_DWORD,
/*length*/ Type.DWORD,
/*buf*/ Type.out_path
);
SysFile.GetFileInformationByHandle =
declareFFI("GetFileInformationByHandle", ctypes.winapi_abi,
declareLazyFFI(SysFile, "GetFileInformationByHandle", libc,
"GetFileInformationByHandle", ctypes.winapi_abi,
/*return*/ Type.zero_or_nothing,
/*handle*/ Type.HANDLE,
/*info*/ Type.FILE_INFORMATION.out_ptr);
SysFile.MoveFileEx =
declareFFI("MoveFileExW", ctypes.winapi_abi,
declareLazyFFI(SysFile, "MoveFileEx", libc,
"MoveFileExW", ctypes.winapi_abi,
/*return*/ Type.zero_or_nothing,
/*sourcePath*/ Type.path,
/*destPath*/ Type.path,
/*flags*/ Type.DWORD
);
SysFile.ReadFile =
declareFFI("ReadFile", ctypes.winapi_abi,
declareLazyFFI(SysFile, "ReadFile", libc,
"ReadFile", ctypes.winapi_abi,
/*return*/ Type.zero_or_nothing,
/*file*/ Type.HANDLE,
/*buffer*/ Type.voidptr_t,
@ -291,32 +292,32 @@
/*overlapped*/Type.void_t.inout_ptr // FIXME: Implement?
);
SysFile.RemoveDirectory =
declareFFI("RemoveDirectoryW", ctypes.winapi_abi,
declareLazyFFI(SysFile, "RemoveDirectory", libc,
"RemoveDirectoryW", ctypes.winapi_abi,
/*return*/ Type.zero_or_nothing,
/*path*/ Type.path);
SysFile.SetCurrentDirectory =
declareFFI("SetCurrentDirectoryW", ctypes.winapi_abi,
declareLazyFFI(SysFile, "SetCurrentDirectory", libc,
"SetCurrentDirectoryW", ctypes.winapi_abi,
/*return*/ Type.zero_or_nothing,
/*path*/ Type.path
);
SysFile.SetEndOfFile =
declareFFI("SetEndOfFile", ctypes.winapi_abi,
declareLazyFFI(SysFile, "SetEndOfFile", libc,
"SetEndOfFile", ctypes.winapi_abi,
/*return*/ Type.zero_or_nothing,
/*file*/ Type.HANDLE);
SysFile.SetFilePointer =
declareFFI("SetFilePointer", ctypes.winapi_abi,
declareLazyFFI(SysFile, "SetFilePointer", libc,
"SetFilePointer", ctypes.winapi_abi,
/*return*/ Type.negative_or_DWORD,
/*file*/ Type.HANDLE,
/*distlow*/Type.long,
/*disthi*/ Type.long.in_ptr,
/*method*/ Type.DWORD);
SysFile.WriteFile =
declareFFI("WriteFile", ctypes.winapi_abi,
declareLazyFFI(SysFile, "WriteFile", libc,
"WriteFile", ctypes.winapi_abi,
/*return*/ Type.zero_or_nothing,
/*file*/ Type.HANDLE,
/*buffer*/ Type.voidptr_t,
@ -325,8 +326,8 @@
/*overlapped*/Type.void_t.inout_ptr // FIXME: Implement?
);
SysFile.FlushFileBuffers =
declareFFI("FlushFileBuffers", ctypes.winapi_abi,
declareLazyFFI(SysFile, "FlushFileBuffers", libc,
"FlushFileBuffers", ctypes.winapi_abi,
/*return*/ Type.zero_or_nothing,
/*file*/ Type.HANDLE);
};

View File

@ -4,23 +4,21 @@ Components.utils.import("resource://gre/modules/osfile.jsm");
Components.utils.import("resource://gre/modules/Task.jsm");
function run_test() {
do_get_profile();
run_next_test();
}
function testFiles(filename) {
return Task.spawn(function() {
const MAX_TRIES = 10;
let currentDir = yield OS.File.getCurrentDirectory();
let path = OS.Path.join(currentDir, filename);
let exists = yield OS.File.exists(path);
// Check a file with the same name doesn't exist already
do_check_false(exists);
let profileDir = OS.Constants.Path.profileDir;
let path = OS.Path.join(profileDir, filename);
// Ensure that openUnique() uses the file name if there is no file with that name already.
let openedFile = yield OS.File.openUnique(path);
do_print("\nCreate new file: " + openedFile.path);
yield openedFile.file.close();
exists = yield OS.File.exists(openedFile.path);
let exists = yield OS.File.exists(openedFile.path);
do_check_true(exists);
do_check_eq(path, openedFile.path);
let fileInfo = yield OS.File.stat(openedFile.path);