Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
michael@0 | 1 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
michael@0 | 3 | * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 4 | |
michael@0 | 5 | { |
michael@0 | 6 | if (typeof Components != "undefined") { |
michael@0 | 7 | // We do not wish osfile_unix_back.jsm to be used directly as a main thread |
michael@0 | 8 | // module yet. When time comes, it will be loaded by a combination of |
michael@0 | 9 | // a main thread front-end/worker thread implementation that makes sure |
michael@0 | 10 | // that we are not executing synchronous IO code in the main thread. |
michael@0 | 11 | |
michael@0 | 12 | throw new Error("osfile_unix_back.jsm cannot be used from the main thread yet"); |
michael@0 | 13 | } |
michael@0 | 14 | (function(exports) { |
michael@0 | 15 | "use strict"; |
michael@0 | 16 | if (exports.OS && exports.OS.Unix && exports.OS.Unix.File) { |
michael@0 | 17 | return; // Avoid double initialization |
michael@0 | 18 | } |
michael@0 | 19 | |
michael@0 | 20 | let SharedAll = |
michael@0 | 21 | require("resource://gre/modules/osfile/osfile_shared_allthreads.jsm"); |
michael@0 | 22 | let SysAll = |
michael@0 | 23 | require("resource://gre/modules/osfile/osfile_unix_allthreads.jsm"); |
michael@0 | 24 | let LOG = SharedAll.LOG.bind(SharedAll, "Unix", "back"); |
michael@0 | 25 | let libc = SysAll.libc; |
michael@0 | 26 | let Const = SharedAll.Constants.libc; |
michael@0 | 27 | |
michael@0 | 28 | /** |
michael@0 | 29 | * Initialize the Unix module. |
michael@0 | 30 | * |
michael@0 | 31 | * @param {function=} declareFFI |
michael@0 | 32 | */ |
michael@0 | 33 | // FIXME: Both |init| and |aDeclareFFI| are deprecated, we should remove them |
michael@0 | 34 | let init = function init(aDeclareFFI) { |
michael@0 | 35 | let declareFFI; |
michael@0 | 36 | if (aDeclareFFI) { |
michael@0 | 37 | declareFFI = aDeclareFFI.bind(null, libc); |
michael@0 | 38 | } else { |
michael@0 | 39 | declareFFI = SysAll.declareFFI; |
michael@0 | 40 | } |
michael@0 | 41 | let declareLazyFFI = SharedAll.declareLazyFFI; |
michael@0 | 42 | |
michael@0 | 43 | // Initialize types that require additional OS-specific |
michael@0 | 44 | // support - either finalization or matching against |
michael@0 | 45 | // OS-specific constants. |
michael@0 | 46 | let Type = Object.create(SysAll.Type); |
michael@0 | 47 | let SysFile = exports.OS.Unix.File = { Type: Type }; |
michael@0 | 48 | |
michael@0 | 49 | /** |
michael@0 | 50 | * A file descriptor. |
michael@0 | 51 | */ |
michael@0 | 52 | Type.fd = Type.int.withName("fd"); |
michael@0 | 53 | Type.fd.importFromC = function importFromC(fd_int) { |
michael@0 | 54 | return ctypes.CDataFinalizer(fd_int, SysFile._close); |
michael@0 | 55 | }; |
michael@0 | 56 | |
michael@0 | 57 | |
michael@0 | 58 | /** |
michael@0 | 59 | * A C integer holding -1 in case of error or a file descriptor |
michael@0 | 60 | * in case of success. |
michael@0 | 61 | */ |
michael@0 | 62 | Type.negativeone_or_fd = Type.fd.withName("negativeone_or_fd"); |
michael@0 | 63 | Type.negativeone_or_fd.importFromC = |
michael@0 | 64 | function importFromC(fd_int) { |
michael@0 | 65 | if (fd_int == -1) { |
michael@0 | 66 | return -1; |
michael@0 | 67 | } |
michael@0 | 68 | return ctypes.CDataFinalizer(fd_int, SysFile._close); |
michael@0 | 69 | }; |
michael@0 | 70 | |
michael@0 | 71 | /** |
michael@0 | 72 | * A C integer holding -1 in case of error or a meaningless value |
michael@0 | 73 | * in case of success. |
michael@0 | 74 | */ |
michael@0 | 75 | Type.negativeone_or_nothing = |
michael@0 | 76 | Type.int.withName("negativeone_or_nothing"); |
michael@0 | 77 | |
michael@0 | 78 | /** |
michael@0 | 79 | * A C integer holding -1 in case of error or a positive integer |
michael@0 | 80 | * in case of success. |
michael@0 | 81 | */ |
michael@0 | 82 | Type.negativeone_or_ssize_t = |
michael@0 | 83 | Type.ssize_t.withName("negativeone_or_ssize_t"); |
michael@0 | 84 | |
michael@0 | 85 | /** |
michael@0 | 86 | * Various libc integer types |
michael@0 | 87 | */ |
michael@0 | 88 | Type.mode_t = |
michael@0 | 89 | Type.intn_t(Const.OSFILE_SIZEOF_MODE_T).withName("mode_t"); |
michael@0 | 90 | Type.uid_t = |
michael@0 | 91 | Type.intn_t(Const.OSFILE_SIZEOF_UID_T).withName("uid_t"); |
michael@0 | 92 | Type.gid_t = |
michael@0 | 93 | Type.intn_t(Const.OSFILE_SIZEOF_GID_T).withName("gid_t"); |
michael@0 | 94 | |
michael@0 | 95 | /** |
michael@0 | 96 | * Type |time_t| |
michael@0 | 97 | */ |
michael@0 | 98 | Type.time_t = |
michael@0 | 99 | Type.intn_t(Const.OSFILE_SIZEOF_TIME_T).withName("time_t"); |
michael@0 | 100 | |
michael@0 | 101 | // Structure |dirent| |
michael@0 | 102 | // Building this type is rather complicated, as its layout varies between |
michael@0 | 103 | // variants of Unix. For this reason, we rely on a number of constants |
michael@0 | 104 | // (computed in C from the C data structures) that give us the layout. |
michael@0 | 105 | // The structure we compute looks like |
michael@0 | 106 | // { int8_t[...] before_d_type; // ignored content |
michael@0 | 107 | // int8_t d_type ; |
michael@0 | 108 | // int8_t[...] before_d_name; // ignored content |
michael@0 | 109 | // char[...] d_name; |
michael@0 | 110 | // }; |
michael@0 | 111 | { |
michael@0 | 112 | let d_name_extra_size = 0; |
michael@0 | 113 | if (Const.OSFILE_SIZEOF_DIRENT_D_NAME < 8) { |
michael@0 | 114 | // d_name is defined like "char d_name[1];" on some platforms |
michael@0 | 115 | // (e.g. Solaris), we need to give it more size for our structure. |
michael@0 | 116 | d_name_extra_size = 256; |
michael@0 | 117 | } |
michael@0 | 118 | |
michael@0 | 119 | let dirent = new SharedAll.HollowStructure("dirent", |
michael@0 | 120 | Const.OSFILE_SIZEOF_DIRENT + d_name_extra_size); |
michael@0 | 121 | if (Const.OSFILE_OFFSETOF_DIRENT_D_TYPE != undefined) { |
michael@0 | 122 | // |dirent| doesn't have d_type on some platforms (e.g. Solaris). |
michael@0 | 123 | dirent.add_field_at(Const.OSFILE_OFFSETOF_DIRENT_D_TYPE, |
michael@0 | 124 | "d_type", ctypes.uint8_t); |
michael@0 | 125 | } |
michael@0 | 126 | dirent.add_field_at(Const.OSFILE_OFFSETOF_DIRENT_D_NAME, |
michael@0 | 127 | "d_name", ctypes.ArrayType(ctypes.char, |
michael@0 | 128 | Const.OSFILE_SIZEOF_DIRENT_D_NAME + d_name_extra_size)); |
michael@0 | 129 | |
michael@0 | 130 | // We now have built |dirent|. |
michael@0 | 131 | Type.dirent = dirent.getType(); |
michael@0 | 132 | } |
michael@0 | 133 | Type.null_or_dirent_ptr = |
michael@0 | 134 | new SharedAll.Type("null_of_dirent", |
michael@0 | 135 | Type.dirent.out_ptr.implementation); |
michael@0 | 136 | |
michael@0 | 137 | // Structure |stat| |
michael@0 | 138 | // Same technique |
michael@0 | 139 | { |
michael@0 | 140 | let stat = new SharedAll.HollowStructure("stat", |
michael@0 | 141 | Const.OSFILE_SIZEOF_STAT); |
michael@0 | 142 | stat.add_field_at(Const.OSFILE_OFFSETOF_STAT_ST_MODE, |
michael@0 | 143 | "st_mode", Type.mode_t.implementation); |
michael@0 | 144 | stat.add_field_at(Const.OSFILE_OFFSETOF_STAT_ST_UID, |
michael@0 | 145 | "st_uid", Type.uid_t.implementation); |
michael@0 | 146 | stat.add_field_at(Const.OSFILE_OFFSETOF_STAT_ST_GID, |
michael@0 | 147 | "st_gid", Type.gid_t.implementation); |
michael@0 | 148 | |
michael@0 | 149 | // Here, things get complicated with different data structures. |
michael@0 | 150 | // Some platforms have |time_t st_atime| and some platforms have |
michael@0 | 151 | // |timespec st_atimespec|. However, since |timespec| starts with |
michael@0 | 152 | // a |time_t|, followed by nanoseconds, we just cheat and pretend |
michael@0 | 153 | // that everybody has |time_t st_atime|, possibly followed by padding |
michael@0 | 154 | stat.add_field_at(Const.OSFILE_OFFSETOF_STAT_ST_ATIME, |
michael@0 | 155 | "st_atime", Type.time_t.implementation); |
michael@0 | 156 | stat.add_field_at(Const.OSFILE_OFFSETOF_STAT_ST_MTIME, |
michael@0 | 157 | "st_mtime", Type.time_t.implementation); |
michael@0 | 158 | stat.add_field_at(Const.OSFILE_OFFSETOF_STAT_ST_CTIME, |
michael@0 | 159 | "st_ctime", Type.time_t.implementation); |
michael@0 | 160 | |
michael@0 | 161 | // To complicate further, MacOS and some BSDs have a field |birthtime| |
michael@0 | 162 | if ("OSFILE_OFFSETOF_STAT_ST_BIRTHTIME" in Const) { |
michael@0 | 163 | stat.add_field_at(Const.OSFILE_OFFSETOF_STAT_ST_BIRTHTIME, |
michael@0 | 164 | "st_birthtime", Type.time_t.implementation); |
michael@0 | 165 | } |
michael@0 | 166 | |
michael@0 | 167 | stat.add_field_at(Const.OSFILE_OFFSETOF_STAT_ST_SIZE, |
michael@0 | 168 | "st_size", Type.off_t.implementation); |
michael@0 | 169 | Type.stat = stat.getType(); |
michael@0 | 170 | } |
michael@0 | 171 | |
michael@0 | 172 | // Structure |DIR| |
michael@0 | 173 | if ("OSFILE_SIZEOF_DIR" in Const) { |
michael@0 | 174 | // On platforms for which we need to access the fields of DIR |
michael@0 | 175 | // directly (e.g. because certain functions are implemented |
michael@0 | 176 | // as macros), we need to define DIR as a hollow structure. |
michael@0 | 177 | let DIR = new SharedAll.HollowStructure( |
michael@0 | 178 | "DIR", |
michael@0 | 179 | Const.OSFILE_SIZEOF_DIR); |
michael@0 | 180 | |
michael@0 | 181 | DIR.add_field_at( |
michael@0 | 182 | Const.OSFILE_OFFSETOF_DIR_DD_FD, |
michael@0 | 183 | "dd_fd", |
michael@0 | 184 | Type.fd.implementation); |
michael@0 | 185 | |
michael@0 | 186 | Type.DIR = DIR.getType(); |
michael@0 | 187 | } else { |
michael@0 | 188 | // On other platforms, we keep DIR as a blackbox |
michael@0 | 189 | Type.DIR = |
michael@0 | 190 | new SharedAll.Type("DIR", |
michael@0 | 191 | ctypes.StructType("DIR")); |
michael@0 | 192 | } |
michael@0 | 193 | |
michael@0 | 194 | Type.null_or_DIR_ptr = |
michael@0 | 195 | Type.DIR.out_ptr.withName("null_or_DIR*"); |
michael@0 | 196 | Type.null_or_DIR_ptr.importFromC = function importFromC(dir) { |
michael@0 | 197 | if (dir == null || dir.isNull()) { |
michael@0 | 198 | return null; |
michael@0 | 199 | } |
michael@0 | 200 | return ctypes.CDataFinalizer(dir, SysFile._close_dir); |
michael@0 | 201 | }; |
michael@0 | 202 | |
michael@0 | 203 | // Structure |timeval| |
michael@0 | 204 | { |
michael@0 | 205 | let timeval = new SharedAll.HollowStructure( |
michael@0 | 206 | "timeval", |
michael@0 | 207 | Const.OSFILE_SIZEOF_TIMEVAL); |
michael@0 | 208 | timeval.add_field_at( |
michael@0 | 209 | Const.OSFILE_OFFSETOF_TIMEVAL_TV_SEC, |
michael@0 | 210 | "tv_sec", |
michael@0 | 211 | Type.long.implementation); |
michael@0 | 212 | timeval.add_field_at( |
michael@0 | 213 | Const.OSFILE_OFFSETOF_TIMEVAL_TV_USEC, |
michael@0 | 214 | "tv_usec", |
michael@0 | 215 | Type.long.implementation); |
michael@0 | 216 | Type.timeval = timeval.getType(); |
michael@0 | 217 | Type.timevals = new SharedAll.Type("two timevals", |
michael@0 | 218 | ctypes.ArrayType(Type.timeval.implementation, 2)); |
michael@0 | 219 | } |
michael@0 | 220 | |
michael@0 | 221 | // Types fsblkcnt_t and fsfilcnt_t, used by structure |statvfs| |
michael@0 | 222 | Type.fsblkcnt_t = |
michael@0 | 223 | Type.uintn_t(Const.OSFILE_SIZEOF_FSBLKCNT_T).withName("fsblkcnt_t"); |
michael@0 | 224 | |
michael@0 | 225 | // Structure |statvfs| |
michael@0 | 226 | // Use an hollow structure |
michael@0 | 227 | { |
michael@0 | 228 | let statvfs = new SharedAll.HollowStructure("statvfs", |
michael@0 | 229 | Const.OSFILE_SIZEOF_STATVFS); |
michael@0 | 230 | |
michael@0 | 231 | statvfs.add_field_at(Const.OSFILE_OFFSETOF_STATVFS_F_BSIZE, |
michael@0 | 232 | "f_bsize", Type.unsigned_long.implementation); |
michael@0 | 233 | statvfs.add_field_at(Const.OSFILE_OFFSETOF_STATVFS_F_BAVAIL, |
michael@0 | 234 | "f_bavail", Type.fsblkcnt_t.implementation); |
michael@0 | 235 | |
michael@0 | 236 | Type.statvfs = statvfs.getType(); |
michael@0 | 237 | } |
michael@0 | 238 | |
michael@0 | 239 | // Declare libc functions as functions of |OS.Unix.File| |
michael@0 | 240 | |
michael@0 | 241 | // Finalizer-related functions |
michael@0 | 242 | libc.declareLazy(SysFile, "_close", |
michael@0 | 243 | "close", ctypes.default_abi, |
michael@0 | 244 | /*return */ctypes.int, |
michael@0 | 245 | /*fd*/ ctypes.int); |
michael@0 | 246 | |
michael@0 | 247 | SysFile.close = function close(fd) { |
michael@0 | 248 | // Detach the finalizer and call |_close|. |
michael@0 | 249 | return fd.dispose(); |
michael@0 | 250 | }; |
michael@0 | 251 | |
michael@0 | 252 | libc.declareLazy(SysFile, "_close_dir", |
michael@0 | 253 | "closedir", ctypes.default_abi, |
michael@0 | 254 | /*return */ctypes.int, |
michael@0 | 255 | /*dirp*/ Type.DIR.in_ptr.implementation); |
michael@0 | 256 | |
michael@0 | 257 | SysFile.closedir = function closedir(fd) { |
michael@0 | 258 | // Detach the finalizer and call |_close_dir|. |
michael@0 | 259 | return fd.dispose(); |
michael@0 | 260 | }; |
michael@0 | 261 | |
michael@0 | 262 | { |
michael@0 | 263 | // Symbol free() is special. |
michael@0 | 264 | // We override the definition of free() on several platforms. |
michael@0 | 265 | let default_lib = new SharedAll.Library("default_lib", |
michael@0 | 266 | "a.out"); |
michael@0 | 267 | try { |
michael@0 | 268 | // On platforms for which we override free(), nspr defines |
michael@0 | 269 | // a special library name "a.out" that will resolve to the |
michael@0 | 270 | // correct implementation free(). |
michael@0 | 271 | |
michael@0 | 272 | default_lib.declareLazy(SysFile, "free", |
michael@0 | 273 | "free", ctypes.default_abi, |
michael@0 | 274 | /*return*/ ctypes.void_t, |
michael@0 | 275 | /*ptr*/ ctypes.voidptr_t); |
michael@0 | 276 | |
michael@0 | 277 | } catch (ex) { |
michael@0 | 278 | // We don't have an a.out library or a.out doesn't contain free. |
michael@0 | 279 | // Either way, use the ordinary libc free. |
michael@0 | 280 | |
michael@0 | 281 | libc.declareLazy(SysFile, "free", |
michael@0 | 282 | "free", ctypes.default_abi, |
michael@0 | 283 | /*return*/ ctypes.void_t, |
michael@0 | 284 | /*ptr*/ ctypes.voidptr_t); |
michael@0 | 285 | } |
michael@0 | 286 | } |
michael@0 | 287 | |
michael@0 | 288 | |
michael@0 | 289 | // Other functions |
michael@0 | 290 | libc.declareLazyFFI(SysFile, "access", |
michael@0 | 291 | "access", ctypes.default_abi, |
michael@0 | 292 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 293 | /*path*/ Type.path, |
michael@0 | 294 | /*mode*/ Type.int); |
michael@0 | 295 | |
michael@0 | 296 | libc.declareLazyFFI(SysFile, "chdir", |
michael@0 | 297 | "chdir", ctypes.default_abi, |
michael@0 | 298 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 299 | /*path*/ Type.path); |
michael@0 | 300 | |
michael@0 | 301 | libc.declareLazyFFI(SysFile, "chmod", |
michael@0 | 302 | "chmod", ctypes.default_abi, |
michael@0 | 303 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 304 | /*path*/ Type.path, |
michael@0 | 305 | /*mode*/ Type.mode_t); |
michael@0 | 306 | |
michael@0 | 307 | libc.declareLazyFFI(SysFile, "chown", |
michael@0 | 308 | "chown", ctypes.default_abi, |
michael@0 | 309 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 310 | /*path*/ Type.path, |
michael@0 | 311 | /*uid*/ Type.uid_t, |
michael@0 | 312 | /*gid*/ Type.gid_t); |
michael@0 | 313 | |
michael@0 | 314 | libc.declareLazyFFI(SysFile, "copyfile", |
michael@0 | 315 | "copyfile", ctypes.default_abi, |
michael@0 | 316 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 317 | /*source*/ Type.path, |
michael@0 | 318 | /*dest*/ Type.path, |
michael@0 | 319 | /*state*/ Type.void_t.in_ptr, // Ignored atm |
michael@0 | 320 | /*flags*/ Type.uint32_t); |
michael@0 | 321 | |
michael@0 | 322 | libc.declareLazyFFI(SysFile, "dup", |
michael@0 | 323 | "dup", ctypes.default_abi, |
michael@0 | 324 | /*return*/ Type.negativeone_or_fd, |
michael@0 | 325 | /*fd*/ Type.fd); |
michael@0 | 326 | |
michael@0 | 327 | if ("OSFILE_SIZEOF_DIR" in Const) { |
michael@0 | 328 | // On platforms for which |dirfd| is a macro |
michael@0 | 329 | SysFile.dirfd = |
michael@0 | 330 | function dirfd(DIRp) { |
michael@0 | 331 | return Type.DIR.in_ptr.implementation(DIRp).contents.dd_fd; |
michael@0 | 332 | }; |
michael@0 | 333 | } else { |
michael@0 | 334 | // On platforms for which |dirfd| is a function |
michael@0 | 335 | libc.declareLazyFFI(SysFile, "dirfd", |
michael@0 | 336 | "dirfd", ctypes.default_abi, |
michael@0 | 337 | /*return*/ Type.negativeone_or_fd, |
michael@0 | 338 | /*dir*/ Type.DIR.in_ptr); |
michael@0 | 339 | } |
michael@0 | 340 | |
michael@0 | 341 | libc.declareLazyFFI(SysFile, "chdir", |
michael@0 | 342 | "chdir", ctypes.default_abi, |
michael@0 | 343 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 344 | /*path*/ Type.path); |
michael@0 | 345 | |
michael@0 | 346 | libc.declareLazyFFI(SysFile, "fchdir", |
michael@0 | 347 | "fchdir", ctypes.default_abi, |
michael@0 | 348 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 349 | /*fd*/ Type.fd); |
michael@0 | 350 | |
michael@0 | 351 | libc.declareLazyFFI(SysFile, "fchmod", |
michael@0 | 352 | "fchmod", ctypes.default_abi, |
michael@0 | 353 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 354 | /*fd*/ Type.fd, |
michael@0 | 355 | /*mode*/ Type.mode_t); |
michael@0 | 356 | |
michael@0 | 357 | libc.declareLazyFFI(SysFile, "fchown", |
michael@0 | 358 | "fchown", ctypes.default_abi, |
michael@0 | 359 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 360 | /*fd*/ Type.fd, |
michael@0 | 361 | /*uid_t*/ Type.uid_t, |
michael@0 | 362 | /*gid_t*/ Type.gid_t); |
michael@0 | 363 | |
michael@0 | 364 | libc.declareLazyFFI(SysFile, "fsync", |
michael@0 | 365 | "fsync", ctypes.default_abi, |
michael@0 | 366 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 367 | /*fd*/ Type.fd); |
michael@0 | 368 | |
michael@0 | 369 | libc.declareLazyFFI(SysFile, "getcwd", |
michael@0 | 370 | "getcwd", ctypes.default_abi, |
michael@0 | 371 | /*return*/ Type.out_path, |
michael@0 | 372 | /*buf*/ Type.out_path, |
michael@0 | 373 | /*size*/ Type.size_t); |
michael@0 | 374 | |
michael@0 | 375 | libc.declareLazyFFI(SysFile, "getwd", |
michael@0 | 376 | "getwd", ctypes.default_abi, |
michael@0 | 377 | /*return*/ Type.out_path, |
michael@0 | 378 | /*buf*/ Type.out_path); |
michael@0 | 379 | |
michael@0 | 380 | // Two variants of |getwd| which allocate the memory |
michael@0 | 381 | // dynamically. |
michael@0 | 382 | |
michael@0 | 383 | // Linux/Android version |
michael@0 | 384 | libc.declareLazyFFI(SysFile, "get_current_dir_name", |
michael@0 | 385 | "get_current_dir_name", ctypes.default_abi, |
michael@0 | 386 | /*return*/ Type.out_path.releaseWithLazy(() => |
michael@0 | 387 | SysFile.free |
michael@0 | 388 | )); |
michael@0 | 389 | |
michael@0 | 390 | // MacOS/BSD version (will return NULL on Linux/Android) |
michael@0 | 391 | libc.declareLazyFFI(SysFile, "getwd_auto", |
michael@0 | 392 | "getwd", ctypes.default_abi, |
michael@0 | 393 | /*return*/ Type.out_path.releaseWithLazy(() => |
michael@0 | 394 | SysFile.free |
michael@0 | 395 | ), |
michael@0 | 396 | /*buf*/ Type.void_t.out_ptr); |
michael@0 | 397 | |
michael@0 | 398 | libc.declareLazyFFI(SysFile, "fdatasync", |
michael@0 | 399 | "fdatasync", ctypes.default_abi, |
michael@0 | 400 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 401 | /*fd*/ Type.fd); // Note: MacOS/BSD-specific |
michael@0 | 402 | |
michael@0 | 403 | libc.declareLazyFFI(SysFile, "ftruncate", |
michael@0 | 404 | "ftruncate", ctypes.default_abi, |
michael@0 | 405 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 406 | /*fd*/ Type.fd, |
michael@0 | 407 | /*length*/ Type.off_t); |
michael@0 | 408 | |
michael@0 | 409 | |
michael@0 | 410 | libc.declareLazyFFI(SysFile, "lchown", |
michael@0 | 411 | "lchown", ctypes.default_abi, |
michael@0 | 412 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 413 | /*path*/ Type.path, |
michael@0 | 414 | /*uid_t*/ Type.uid_t, |
michael@0 | 415 | /*gid_t*/ Type.gid_t); |
michael@0 | 416 | |
michael@0 | 417 | libc.declareLazyFFI(SysFile, "link", |
michael@0 | 418 | "link", ctypes.default_abi, |
michael@0 | 419 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 420 | /*source*/ Type.path, |
michael@0 | 421 | /*dest*/ Type.path); |
michael@0 | 422 | |
michael@0 | 423 | libc.declareLazyFFI(SysFile, "lseek", |
michael@0 | 424 | "lseek", ctypes.default_abi, |
michael@0 | 425 | /*return*/ Type.off_t, |
michael@0 | 426 | /*fd*/ Type.fd, |
michael@0 | 427 | /*offset*/ Type.off_t, |
michael@0 | 428 | /*whence*/ Type.int); |
michael@0 | 429 | |
michael@0 | 430 | libc.declareLazyFFI(SysFile, "mkdir", |
michael@0 | 431 | "mkdir", ctypes.default_abi, |
michael@0 | 432 | /*return*/ Type.int, |
michael@0 | 433 | /*path*/ Type.path, |
michael@0 | 434 | /*mode*/ Type.int); |
michael@0 | 435 | |
michael@0 | 436 | libc.declareLazyFFI(SysFile, "mkstemp", |
michael@0 | 437 | "mkstemp", ctypes.default_abi, |
michael@0 | 438 | /*return*/ Type.fd, |
michael@0 | 439 | /*template*/ Type.out_path); |
michael@0 | 440 | |
michael@0 | 441 | libc.declareLazyFFI(SysFile, "open", |
michael@0 | 442 | "open", ctypes.default_abi, |
michael@0 | 443 | /*return*/ Type.negativeone_or_fd, |
michael@0 | 444 | /*path*/ Type.path, |
michael@0 | 445 | /*oflags*/ Type.int, |
michael@0 | 446 | /*mode*/ Type.int); |
michael@0 | 447 | |
michael@0 | 448 | if (OS.Constants.Sys.Name == "NetBSD") { |
michael@0 | 449 | libc.declareLazyFFI(SysFile, "opendir", |
michael@0 | 450 | "__opendir30", ctypes.default_abi, |
michael@0 | 451 | /*return*/ Type.null_or_DIR_ptr, |
michael@0 | 452 | /*path*/ Type.path); |
michael@0 | 453 | } else { |
michael@0 | 454 | libc.declareLazyFFI(SysFile, "opendir", |
michael@0 | 455 | "opendir", ctypes.default_abi, |
michael@0 | 456 | /*return*/ Type.null_or_DIR_ptr, |
michael@0 | 457 | /*path*/ Type.path); |
michael@0 | 458 | } |
michael@0 | 459 | |
michael@0 | 460 | libc.declareLazyFFI(SysFile, "pread", |
michael@0 | 461 | "pread", ctypes.default_abi, |
michael@0 | 462 | /*return*/ Type.negativeone_or_ssize_t, |
michael@0 | 463 | /*fd*/ Type.fd, |
michael@0 | 464 | /*buf*/ Type.void_t.out_ptr, |
michael@0 | 465 | /*nbytes*/ Type.size_t, |
michael@0 | 466 | /*offset*/ Type.off_t); |
michael@0 | 467 | |
michael@0 | 468 | libc.declareLazyFFI(SysFile, "pwrite", |
michael@0 | 469 | "pwrite", ctypes.default_abi, |
michael@0 | 470 | /*return*/ Type.negativeone_or_ssize_t, |
michael@0 | 471 | /*fd*/ Type.fd, |
michael@0 | 472 | /*buf*/ Type.void_t.in_ptr, |
michael@0 | 473 | /*nbytes*/ Type.size_t, |
michael@0 | 474 | /*offset*/ Type.off_t); |
michael@0 | 475 | |
michael@0 | 476 | libc.declareLazyFFI(SysFile, "read", |
michael@0 | 477 | "read", ctypes.default_abi, |
michael@0 | 478 | /*return*/Type.negativeone_or_ssize_t, |
michael@0 | 479 | /*fd*/ Type.fd, |
michael@0 | 480 | /*buf*/ Type.void_t.out_ptr, |
michael@0 | 481 | /*nbytes*/Type.size_t); |
michael@0 | 482 | |
michael@0 | 483 | libc.declareLazyFFI(SysFile, "posix_fadvise", |
michael@0 | 484 | "posix_fadvise", ctypes.default_abi, |
michael@0 | 485 | /*return*/ Type.int, |
michael@0 | 486 | /*fd*/ Type.fd, |
michael@0 | 487 | /*offset*/ Type.off_t, |
michael@0 | 488 | /*len*/ Type.off_t, |
michael@0 | 489 | /*advise*/ Type.int); |
michael@0 | 490 | |
michael@0 | 491 | if (Const._DARWIN_FEATURE_64_BIT_INODE) { |
michael@0 | 492 | // Special case for MacOS X 10.5+ |
michael@0 | 493 | // Symbol name "readdir" still exists but is used for a |
michael@0 | 494 | // deprecated function that does not match the |
michael@0 | 495 | // constants of |Const|. |
michael@0 | 496 | libc.declareLazyFFI(SysFile, "readdir", |
michael@0 | 497 | "readdir$INODE64", ctypes.default_abi, |
michael@0 | 498 | /*return*/ Type.null_or_dirent_ptr, |
michael@0 | 499 | /*dir*/ Type.DIR.in_ptr); // For MacOS X |
michael@0 | 500 | } else if (OS.Constants.Sys.Name == "NetBSD") { |
michael@0 | 501 | libc.declareLazyFFI(SysFile, "readdir", |
michael@0 | 502 | "__readdir30", ctypes.default_abi, |
michael@0 | 503 | /*return*/Type.null_or_dirent_ptr, |
michael@0 | 504 | /*dir*/ Type.DIR.in_ptr); // Other Unices |
michael@0 | 505 | } else { |
michael@0 | 506 | libc.declareLazyFFI(SysFile, "readdir", |
michael@0 | 507 | "readdir", ctypes.default_abi, |
michael@0 | 508 | /*return*/Type.null_or_dirent_ptr, |
michael@0 | 509 | /*dir*/ Type.DIR.in_ptr); // Other Unices |
michael@0 | 510 | } |
michael@0 | 511 | |
michael@0 | 512 | libc.declareLazyFFI(SysFile, "rename", |
michael@0 | 513 | "rename", ctypes.default_abi, |
michael@0 | 514 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 515 | /*old*/ Type.path, |
michael@0 | 516 | /*new*/ Type.path); |
michael@0 | 517 | |
michael@0 | 518 | libc.declareLazyFFI(SysFile, "rmdir", |
michael@0 | 519 | "rmdir", ctypes.default_abi, |
michael@0 | 520 | /*return*/ Type.int, |
michael@0 | 521 | /*path*/ Type.path); |
michael@0 | 522 | |
michael@0 | 523 | libc.declareLazyFFI(SysFile, "splice", |
michael@0 | 524 | "splice", ctypes.default_abi, |
michael@0 | 525 | /*return*/ Type.long, |
michael@0 | 526 | /*fd_in*/ Type.fd, |
michael@0 | 527 | /*off_in*/ Type.off_t.in_ptr, |
michael@0 | 528 | /*fd_out*/ Type.fd, |
michael@0 | 529 | /*off_out*/Type.off_t.in_ptr, |
michael@0 | 530 | /*len*/ Type.size_t, |
michael@0 | 531 | /*flags*/ Type.unsigned_int); // Linux/Android-specific |
michael@0 | 532 | |
michael@0 | 533 | libc.declareLazyFFI(SysFile, "statvfs", |
michael@0 | 534 | "statvfs", ctypes.default_abi, |
michael@0 | 535 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 536 | /*path*/ Type.path, |
michael@0 | 537 | /*buf*/ Type.statvfs.out_ptr); |
michael@0 | 538 | |
michael@0 | 539 | libc.declareLazyFFI(SysFile, "symlink", |
michael@0 | 540 | "symlink", ctypes.default_abi, |
michael@0 | 541 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 542 | /*source*/ Type.path, |
michael@0 | 543 | /*dest*/ Type.path); |
michael@0 | 544 | |
michael@0 | 545 | libc.declareLazyFFI(SysFile, "truncate", |
michael@0 | 546 | "truncate", ctypes.default_abi, |
michael@0 | 547 | /*return*/Type.negativeone_or_nothing, |
michael@0 | 548 | /*path*/ Type.path, |
michael@0 | 549 | /*length*/ Type.off_t); |
michael@0 | 550 | |
michael@0 | 551 | libc.declareLazyFFI(SysFile, "unlink", |
michael@0 | 552 | "unlink", ctypes.default_abi, |
michael@0 | 553 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 554 | /*path*/ Type.path); |
michael@0 | 555 | |
michael@0 | 556 | libc.declareLazyFFI(SysFile, "write", |
michael@0 | 557 | "write", ctypes.default_abi, |
michael@0 | 558 | /*return*/ Type.negativeone_or_ssize_t, |
michael@0 | 559 | /*fd*/ Type.fd, |
michael@0 | 560 | /*buf*/ Type.void_t.in_ptr, |
michael@0 | 561 | /*nbytes*/ Type.size_t); |
michael@0 | 562 | |
michael@0 | 563 | // Weird cases that require special treatment |
michael@0 | 564 | |
michael@0 | 565 | // OSes use a variety of hacks to differentiate between |
michael@0 | 566 | // 32-bits and 64-bits versions of |stat|, |lstat|, |fstat|. |
michael@0 | 567 | if (Const._DARWIN_FEATURE_64_BIT_INODE) { |
michael@0 | 568 | // MacOS X 64-bits |
michael@0 | 569 | libc.declareLazyFFI(SysFile, "stat", |
michael@0 | 570 | "stat$INODE64", ctypes.default_abi, |
michael@0 | 571 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 572 | /*path*/ Type.path, |
michael@0 | 573 | /*buf*/ Type.stat.out_ptr |
michael@0 | 574 | ); |
michael@0 | 575 | libc.declareLazyFFI(SysFile, "lstat", |
michael@0 | 576 | "lstat$INODE64", ctypes.default_abi, |
michael@0 | 577 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 578 | /*path*/ Type.path, |
michael@0 | 579 | /*buf*/ Type.stat.out_ptr |
michael@0 | 580 | ); |
michael@0 | 581 | libc.declareLazyFFI(SysFile, "fstat", |
michael@0 | 582 | "fstat$INODE64", ctypes.default_abi, |
michael@0 | 583 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 584 | /*path*/ Type.fd, |
michael@0 | 585 | /*buf*/ Type.stat.out_ptr |
michael@0 | 586 | ); |
michael@0 | 587 | } else if (Const._STAT_VER != undefined) { |
michael@0 | 588 | const ver = Const._STAT_VER; |
michael@0 | 589 | let xstat_name, lxstat_name, fxstat_name; |
michael@0 | 590 | if (OS.Constants.Sys.Name == "SunOS") { |
michael@0 | 591 | // Solaris |
michael@0 | 592 | xstat_name = "_xstat"; |
michael@0 | 593 | lxstat_name = "_lxstat"; |
michael@0 | 594 | fxstat_name = "_fxstat"; |
michael@0 | 595 | } else { |
michael@0 | 596 | // Linux, all widths |
michael@0 | 597 | xstat_name = "__xstat"; |
michael@0 | 598 | lxstat_name = "__lxstat"; |
michael@0 | 599 | fxstat_name = "__fxstat"; |
michael@0 | 600 | } |
michael@0 | 601 | |
michael@0 | 602 | let Stat = {}; |
michael@0 | 603 | libc.declareLazyFFI(Stat, "xstat", |
michael@0 | 604 | xstat_name, ctypes.default_abi, |
michael@0 | 605 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 606 | /*_stat_ver*/ Type.int, |
michael@0 | 607 | /*path*/ Type.path, |
michael@0 | 608 | /*buf*/ Type.stat.out_ptr); |
michael@0 | 609 | libc.declareLazyFFI(Stat, "lxstat", |
michael@0 | 610 | lxstat_name, ctypes.default_abi, |
michael@0 | 611 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 612 | /*_stat_ver*/ Type.int, |
michael@0 | 613 | /*path*/ Type.path, |
michael@0 | 614 | /*buf*/ Type.stat.out_ptr); |
michael@0 | 615 | libc.declareLazyFFI(Stat, "fxstat", |
michael@0 | 616 | fxstat_name, ctypes.default_abi, |
michael@0 | 617 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 618 | /*_stat_ver*/ Type.int, |
michael@0 | 619 | /*fd*/ Type.fd, |
michael@0 | 620 | /*buf*/ Type.stat.out_ptr); |
michael@0 | 621 | |
michael@0 | 622 | |
michael@0 | 623 | SysFile.stat = function stat(path, buf) { |
michael@0 | 624 | return Stat.xstat(ver, path, buf); |
michael@0 | 625 | }; |
michael@0 | 626 | |
michael@0 | 627 | SysFile.lstat = function lstat(path, buf) { |
michael@0 | 628 | return Stat.lxstat(ver, path, buf); |
michael@0 | 629 | }; |
michael@0 | 630 | |
michael@0 | 631 | SysFile.fstat = function fstat(fd, buf) { |
michael@0 | 632 | return Stat.fxstat(ver, fd, buf); |
michael@0 | 633 | }; |
michael@0 | 634 | } else if (OS.Constants.Sys.Name == "NetBSD") { |
michael@0 | 635 | // NetBSD 5.0 and newer |
michael@0 | 636 | libc.declareLazyFFI(SysFile, "stat", |
michael@0 | 637 | "__stat50", ctypes.default_abi, |
michael@0 | 638 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 639 | /*path*/ Type.path, |
michael@0 | 640 | /*buf*/ Type.stat.out_ptr |
michael@0 | 641 | ); |
michael@0 | 642 | libc.declareLazyFFI(SysFile, "lstat", |
michael@0 | 643 | "__lstat50", ctypes.default_abi, |
michael@0 | 644 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 645 | /*path*/ Type.path, |
michael@0 | 646 | /*buf*/ Type.stat.out_ptr |
michael@0 | 647 | ); |
michael@0 | 648 | libc.declareLazyFFI(SysFile, "fstat", |
michael@0 | 649 | "__fstat50", ctypes.default_abi, |
michael@0 | 650 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 651 | /*fd*/ Type.fd, |
michael@0 | 652 | /*buf*/ Type.stat.out_ptr |
michael@0 | 653 | ); |
michael@0 | 654 | } else { |
michael@0 | 655 | // Mac OS X 32-bits, other Unix |
michael@0 | 656 | libc.declareLazyFFI(SysFile, "stat", |
michael@0 | 657 | "stat", ctypes.default_abi, |
michael@0 | 658 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 659 | /*path*/ Type.path, |
michael@0 | 660 | /*buf*/ Type.stat.out_ptr |
michael@0 | 661 | ); |
michael@0 | 662 | libc.declareLazyFFI(SysFile, "lstat", |
michael@0 | 663 | "lstat", ctypes.default_abi, |
michael@0 | 664 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 665 | /*path*/ Type.path, |
michael@0 | 666 | /*buf*/ Type.stat.out_ptr |
michael@0 | 667 | ); |
michael@0 | 668 | libc.declareLazyFFI(SysFile, "fstat", |
michael@0 | 669 | "fstat", ctypes.default_abi, |
michael@0 | 670 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 671 | /*fd*/ Type.fd, |
michael@0 | 672 | /*buf*/ Type.stat.out_ptr |
michael@0 | 673 | ); |
michael@0 | 674 | } |
michael@0 | 675 | |
michael@0 | 676 | // We cannot make a C array of CDataFinalizer, so |
michael@0 | 677 | // pipe cannot be directly defined as a C function. |
michael@0 | 678 | |
michael@0 | 679 | let Pipe = {}; |
michael@0 | 680 | libc.declareLazyFFI(Pipe, "_pipe", |
michael@0 | 681 | "pipe", ctypes.default_abi, |
michael@0 | 682 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 683 | /*fds*/ new SharedAll.Type("two file descriptors", |
michael@0 | 684 | ctypes.ArrayType(ctypes.int, 2))); |
michael@0 | 685 | |
michael@0 | 686 | // A shared per-thread buffer used to communicate with |pipe| |
michael@0 | 687 | let _pipebuf = new (ctypes.ArrayType(ctypes.int, 2))(); |
michael@0 | 688 | |
michael@0 | 689 | SysFile.pipe = function pipe(array) { |
michael@0 | 690 | let result = Pipe._pipe(_pipebuf); |
michael@0 | 691 | if (result == -1) { |
michael@0 | 692 | return result; |
michael@0 | 693 | } |
michael@0 | 694 | array[0] = ctypes.CDataFinalizer(_pipebuf[0], SysFile._close); |
michael@0 | 695 | array[1] = ctypes.CDataFinalizer(_pipebuf[1], SysFile._close); |
michael@0 | 696 | return result; |
michael@0 | 697 | }; |
michael@0 | 698 | |
michael@0 | 699 | if (OS.Constants.Sys.Name == "NetBSD") { |
michael@0 | 700 | libc.declareLazyFFI(SysFile, "utimes", |
michael@0 | 701 | "__utimes50", ctypes.default_abi, |
michael@0 | 702 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 703 | /*path*/ Type.path, |
michael@0 | 704 | /*timeval[2]*/ Type.timevals.out_ptr |
michael@0 | 705 | ); |
michael@0 | 706 | } else { |
michael@0 | 707 | libc.declareLazyFFI(SysFile, "utimes", |
michael@0 | 708 | "utimes", ctypes.default_abi, |
michael@0 | 709 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 710 | /*path*/ Type.path, |
michael@0 | 711 | /*timeval[2]*/ Type.timevals.out_ptr |
michael@0 | 712 | ); |
michael@0 | 713 | } |
michael@0 | 714 | if (OS.Constants.Sys.Name == "NetBSD") { |
michael@0 | 715 | libc.declareLazyFFI(SysFile, "futimes", |
michael@0 | 716 | "__futimes50", ctypes.default_abi, |
michael@0 | 717 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 718 | /*fd*/ Type.fd, |
michael@0 | 719 | /*timeval[2]*/ Type.timevals.out_ptr |
michael@0 | 720 | ); |
michael@0 | 721 | } else { |
michael@0 | 722 | libc.declareLazyFFI(SysFile, "futimes", |
michael@0 | 723 | "futimes", ctypes.default_abi, |
michael@0 | 724 | /*return*/ Type.negativeone_or_nothing, |
michael@0 | 725 | /*fd*/ Type.fd, |
michael@0 | 726 | /*timeval[2]*/ Type.timevals.out_ptr |
michael@0 | 727 | ); |
michael@0 | 728 | } |
michael@0 | 729 | }; |
michael@0 | 730 | |
michael@0 | 731 | exports.OS.Unix = { |
michael@0 | 732 | File: { |
michael@0 | 733 | _init: init |
michael@0 | 734 | } |
michael@0 | 735 | }; |
michael@0 | 736 | })(this); |
michael@0 | 737 | } |