Bug 770538 - dirfd, MacOS X version. r=froydnj

This commit is contained in:
David Rajchenbach-Teller 2012-10-30 11:34:49 -04:00
parent 44ca94fcc1
commit 8bc51b6773
2 changed files with 51 additions and 17 deletions

View File

@ -380,6 +380,13 @@ static dom::ConstantSpec gLibcProperties[] =
{ "OSFILE_OFFSETOF_DIRENT_D_TYPE", INT_TO_JSVAL(offsetof (struct dirent, d_type)) },
#endif // defined(DT_UNKNOWN)
// Under MacOS X, |dirfd| is a macro rather than a function, so we
// need a little help to get it to work
#if defined(dirfd)
{ "OSFILE_SIZEOF_DIR", INT_TO_JSVAL(sizeof (DIR)) },
{ "OSFILE_OFFSETOF_DIR_DD_FD", INT_TO_JSVAL(offsetof (DIR, __dd_fd)) },
#endif
// Defining |stat|

View File

@ -108,19 +108,6 @@
Types.time_t =
Types.intn_t(OS.Constants.libc.OSFILE_SIZEOF_TIME_T).withName("time_t");
Types.DIR =
new Type("DIR",
ctypes.StructType("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;
}
return ctypes.CDataFinalizer(dir, _close_dir);
};
// Structure |dirent|
// Building this type is rather complicated, as its layout varies between
// variants of Unix. For this reason, we rely on a number of constants
@ -175,6 +162,37 @@
Types.stat = stat.getType();
}
// Structure |DIR|
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 OS.Shared.HollowStructure(
"DIR",
OS.Constants.libc.OSFILE_SIZEOF_DIR);
DIR.add_field_at(
OS.Constants.libc.OSFILE_OFFSETOF_DIR_DD_FD,
"dd_fd",
Types.fd.implementation);
Types.DIR = DIR.getType();
} else {
// On other platforms, we keep DIR as a blackbox
Types.DIR =
new Type("DIR",
ctypes.StructType("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;
}
return ctypes.CDataFinalizer(dir, _close_dir);
};
// Declare libc functions as functions of |OS.Unix.File|
// Finalizer-related functions
@ -241,10 +259,19 @@
/*return*/ Types.negativeone_or_fd,
/*fd*/ Types.fd);
UnixFile.dirfd =
declareFFI("dirfd", ctypes.default_abi,
/*return*/ Types.negativeone_or_fd,
/*dir*/ Types.null_or_DIR_ptr);
if ("OSFILE_SIZEOF_DIR" in OS.Constants.libc) {
// On platforms for which |dirfd| is a macro
UnixFile.dirfd =
function dirfd(DIRp) {
return Types.DIR.in_ptr.implementation(DIRp).contents.dd_fd;
};
} else {
// On platforms for which |dirfd| is a function
UnixFile.dirfd =
declareFFI("dirfd", ctypes.default_abi,
/*return*/ Types.negativeone_or_fd,
/*dir*/ Types.DIR.in_ptr);
}
UnixFile.chdir =
declareFFI("chdir", ctypes.default_abi,