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