1 /**
2 * D header file for POSIX.
3 *
4 * Copyright: Copyright Sean Kelly 2005 - 2009.
5 * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 * Authors: Sean Kelly, Alex Rønne Petersen
7 * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
8 */
9
10 /* Copyright Sean Kelly 2005 - 2009.
11 * Distributed under the Boost Software License, Version 1.0.
12 * (See accompanying file LICENSE or copy at
13 * http://www.boost.org/LICENSE_1_0.txt)
14 */
15 module core.sys.posix.sys.stat;
16
17 import core.sys.posix.config;
18 import core.stdc.stdint;
19 import core.sys.posix.time; // for timespec
20 public import core.sys.posix.sys.types; // for off_t, mode_t
21
22 version (OSX)
23 version = Darwin;
24 else version (iOS)
25 version = Darwin;
26 else version (TVOS)
27 version = Darwin;
28 else version (WatchOS)
29 version = Darwin;
30
31 version (RISCV32) version = RISCV_Any;
32 version (RISCV64) version = RISCV_Any;
33 version (SPARC) version = SPARC_Any;
34 version (SPARC64) version = SPARC_Any;
35
version(Posix)36 version (Posix):
37 extern (C) nothrow @nogc:
38 @system:
39
40 //
41 // Required
42 //
43 /*
44 struct stat
45 {
46 dev_t st_dev;
47 ino_t st_ino;
48 mode_t st_mode;
49 nlink_t st_nlink;
50 uid_t st_uid;
51 gid_t st_gid;
52 off_t st_size;
53 time_t st_atime;
54 time_t st_mtime;
55 time_t st_ctime;
56 }
57
58 S_ISUID
59 S_ISGID
60 S_ISVTX
61
62 S_TYPEISMQ(buf)
63 S_TYPEISSEM(buf)
64 S_TYPEISSHM(buf)
65 */
66
67 version (linux)
68 {
69 version (X86)
70 {
71 struct stat_t
72 {
73 dev_t st_dev;
74 ushort __pad1;
75 static if (!__USE_FILE_OFFSET64)
76 {
77 ino_t st_ino;
78 }
79 else
80 {
81 uint __st_ino;
82 }
83 mode_t st_mode;
84 nlink_t st_nlink;
85 uid_t st_uid;
86 gid_t st_gid;
87 dev_t st_rdev;
88 ushort __pad2;
89 off_t st_size;
90 blksize_t st_blksize;
91 blkcnt_t st_blocks;
92 static if (_DEFAULT_SOURCE || _XOPEN_SOURCE >= 700)
93 {
94 timespec st_atim;
95 timespec st_mtim;
96 timespec st_ctim;
97 extern(D) @safe @property inout pure nothrow
98 {
99 ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
100 ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
101 ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
102 }
103 }
104 else
105 {
106 time_t st_atime;
107 ulong_t st_atimensec;
108 time_t st_mtime;
109 ulong_t st_mtimensec;
110 time_t st_ctime;
111 ulong_t st_ctimensec;
112 }
113 static if (__USE_FILE_OFFSET64)
114 {
115 ino_t st_ino;
116 }
117 else
118 {
119 c_ulong __unused4;
120 c_ulong __unused5;
121 }
122 }
123 }
124 else version (X86_64)
125 {
126 struct stat_t
127 {
128 dev_t st_dev;
129 ino_t st_ino;
130 nlink_t st_nlink;
131 mode_t st_mode;
132 uid_t st_uid;
133 gid_t st_gid;
134 uint __pad0;
135 dev_t st_rdev;
136 off_t st_size;
137 blksize_t st_blksize;
138 blkcnt_t st_blocks;
139 static if (_DEFAULT_SOURCE || _XOPEN_SOURCE >= 700)
140 {
141 timespec st_atim;
142 timespec st_mtim;
143 timespec st_ctim;
144 extern(D) @safe @property inout pure nothrow
145 {
146 ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
147 ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
148 ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
149 }
150 }
151 else
152 {
153 time_t st_atime;
154 ulong_t st_atimensec;
155 time_t st_mtime;
156 ulong_t st_mtimensec;
157 time_t st_ctime;
158 ulong_t st_ctimensec;
159 }
160 slong_t[3] __unused;
161 }
162 }
163 else version (HPPA)
164 {
165 private
166 {
167 alias __dev_t = ulong;
168 alias __ino_t = c_ulong;
169 alias __ino64_t = ulong;
170 alias __mode_t = uint;
171 alias __nlink_t = size_t;
172 alias __uid_t = uint;
173 alias __gid_t = uint;
174 alias __off_t = c_long;
175 alias __off64_t = long;
176 alias __blksize_t = c_long;
177 alias __blkcnt_t = c_long;
178 alias __blkcnt64_t = long;
179 alias __timespec = timespec;
180 alias __time_t = time_t;
181 }
182 struct stat_t
183 {
184 __dev_t st_dev;
185 ushort __pad1;
186
187 static if (!__USE_FILE_OFFSET64)
188 {
189 __ino_t st_ino;
190 }
191 else
192 {
193 __ino_t __st_ino;
194 }
195 __mode_t st_mode;
196 __nlink_t st_nlink;
197 __uid_t st_uid;
198 __gid_t st_gid;
199 __dev_t st_rdev;
200 ushort __pad2;
201
202 static if (!__USE_FILE_OFFSET64)
203 {
204 __off_t st_size;
205 }
206 else
207 {
208 __off64_t st_size;
209 }
210 __blksize_t st_blksize;
211
212 static if (!__USE_FILE_OFFSET64)
213 {
214 __blkcnt_t st_blocks;
215 }
216 else
217 {
218 __blkcnt64_t st_blocks;
219 }
220
221 static if ( _DEFAULT_SOURCE || _XOPEN_SOURCE >= 700)
222 {
223 __timespec st_atim;
224 __timespec st_mtim;
225 __timespec st_ctim;
226 extern(D) @safe @property inout pure nothrow
227 {
228 ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
229 ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
230 ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
231 }
232 }
233 else
234 {
235 __time_t st_atime;
236 c_ulong st_atimensec;
237 __time_t st_mtime;
238 c_ulong st_mtimensec;
239 __time_t st_ctime;
240 c_ulong st_ctimensec;
241 }
242
243 static if (!__USE_FILE_OFFSET64)
244 {
245 c_ulong __unused4;
246 c_ulong __unused5;
247 }
248 else
249 {
250 __ino64_t st_ino;
251 }
252 }
253 static if (__USE_FILE_OFFSET64)
254 static assert(stat_t.sizeof == 104);
255 else
256 static assert(stat_t.sizeof == 88);
257 }
258 else version (MIPS_O32)
259 {
260 struct stat_t
261 {
262 c_ulong st_dev;
263 c_long[3] st_pad1;
264 ino_t st_ino;
265 mode_t st_mode;
266 nlink_t st_nlink;
267 uid_t st_uid;
268 gid_t st_gid;
269 c_ulong st_rdev;
270 static if (!__USE_FILE_OFFSET64)
271 {
272 c_long[2] st_pad2;
273 off_t st_size;
274 c_long st_pad3;
275 }
276 else
277 {
278 c_long[3] st_pad2;
279 off_t st_size;
280 }
281 static if (_DEFAULT_SOURCE || _XOPEN_SOURCE >= 700)
282 {
283 timespec st_atim;
284 timespec st_mtim;
285 timespec st_ctim;
286 extern(D) @safe @property inout pure nothrow
287 {
288 ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
289 ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
290 ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
291 }
292 }
293 else
294 {
295 time_t st_atime;
296 c_ulong st_atimensec;
297 time_t st_mtime;
298 c_ulong st_mtimensec;
299 time_t st_ctime;
300 c_ulong st_ctimensec;
301 }
302 blksize_t st_blksize;
303 static if (!__USE_FILE_OFFSET64)
304 {
305 blkcnt_t st_blocks;
306 }
307 else
308 {
309 c_long st_pad4;
310 blkcnt_t st_blocks;
311 }
312 c_long[14] st_pad5;
313 }
314 static if (!__USE_FILE_OFFSET64)
315 static assert(stat_t.sizeof == 144);
316 else
317 static assert(stat_t.sizeof == 160);
318 }
319 else version (MIPS64)
320 {
321 struct stat_t
322 {
323 dev_t st_dev;
324 int[3] st_pad1;
325 ino_t st_ino;
326 mode_t st_mode;
327 nlink_t st_nlink;
328 uid_t st_uid;
329 gid_t st_gid;
330 dev_t st_rdev;
331 static if (!__USE_FILE_OFFSET64)
332 {
333 uint[2] st_pad2;
334 off_t st_size;
335 int st_pad3;
336 }
337 else
338 {
339 uint[3] st_pad2;
340 off_t st_size;
341 }
342 static if (_DEFAULT_SOURCE || _XOPEN_SOURCE >= 700)
343 {
344 timespec st_atim;
345 timespec st_mtim;
346 timespec st_ctim;
347 extern(D) @safe @property inout pure nothrow
348 {
349 ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
350 ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
351 ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
352 }
353 }
354 else
355 {
356 time_t st_atime;
357 c_ulong st_atimensec;
358 time_t st_mtime;
359 c_ulong st_mtimensec;
360 time_t st_ctime;
361 c_ulong st_ctimensec;
362 }
363 blksize_t st_blksize;
364 uint st_pad4;
365 blkcnt_t st_blocks;
366 int[14] st_pad5;
367 }
368 version (MIPS_N32)
369 {
370 static if (!__USE_FILE_OFFSET64)
371 static assert(stat_t.sizeof == 160);
372 else
373 static assert(stat_t.sizeof == 176);
374 }
375 else version (MIPS_O64)
376 {
377 static if (!__USE_FILE_OFFSET64)
378 static assert(stat_t.sizeof == 160);
379 else
380 static assert(stat_t.sizeof == 176);
381 }
382 else
383 {
384 static assert(stat_t.sizeof == 216);
385 }
386 }
387 else version (PPC)
388 {
389 struct stat_t
390 {
391 dev_t st_dev;
392 static if (!__USE_FILE_OFFSET64)
393 {
394 ushort __pad1;
395 ino_t st_ino;
396 }
397 else
398 ino_t st_ino;
399 mode_t st_mode;
400 nlink_t st_nlink;
401 uid_t st_uid;
402 gid_t st_gid;
403 dev_t st_rdev;
404 ushort __pad2;
405 off_t st_size;
406 blksize_t st_blksize;
407 blkcnt_t st_blocks;
408 static if (_DEFAULT_SOURCE || _XOPEN_SOURCE >= 700)
409 {
410 timespec st_atim;
411 timespec st_mtim;
412 timespec st_ctim;
413 extern(D) @safe @property inout pure nothrow
414 {
415 ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
416 ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
417 ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
418 }
419 }
420 else
421 {
422 time_t st_atime;
423 c_ulong st_atimensec;
424 time_t st_mtime;
425 c_ulong st_mtimensec;
426 time_t st_ctime;
427 c_ulong st_ctimensec;
428 }
429 c_ulong __unused4;
430 c_ulong __unused5;
431 }
432 static if (__USE_FILE_OFFSET64)
433 static assert(stat_t.sizeof == 104);
434 else
435 static assert(stat_t.sizeof == 88);
436 }
437 else version (PPC64)
438 {
439 struct stat_t
440 {
441 dev_t st_dev;
442 ino_t st_ino;
443 nlink_t st_nlink;
444 mode_t st_mode;
445 uid_t st_uid;
446 gid_t st_gid;
447 int __pad2;
448 dev_t st_rdev;
449 off_t st_size;
450 blksize_t st_blksize;
451 blkcnt_t st_blocks;
452 static if (_DEFAULT_SOURCE || _XOPEN_SOURCE >= 700)
453 {
454 timespec st_atim;
455 timespec st_mtim;
456 timespec st_ctim;
457 extern(D) @safe @property inout pure nothrow
458 {
459 ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
460 ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
461 ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
462 }
463 }
464 else
465 {
466 time_t st_atime;
467 c_ulong st_atimensec;
468 time_t st_mtime;
469 c_ulong st_mtimensec;
470 time_t st_ctime;
471 c_ulong st_ctimensec;
472 }
473 c_ulong __unused4;
474 c_ulong __unused5;
475 c_ulong __unused6;
476 }
477 static assert(stat_t.sizeof == 144);
478 }
479 else version (RISCV_Any)
480 {
481 private
482 {
483 alias __dev_t = ulong;
484 alias __ino_t = c_ulong;
485 alias __ino64_t = ulong;
486 alias __mode_t = uint;
487 alias __nlink_t = uint;
488 alias __uid_t = uint;
489 alias __gid_t = uint;
490 alias __off_t = c_long;
491 alias __off64_t = long;
492 alias __blksize_t = int;
493 alias __blkcnt_t = c_long;
494 alias __blkcnt64_t = long;
495 alias __timespec = timespec;
496 alias __time_t = time_t;
497 }
498 struct stat_t
499 {
500 __dev_t st_dev;
501
502 static if (__USE_FILE_OFFSET64)
503 {
504 __ino64_t st_ino;
505 }
506 else
507 {
508 __ino_t st_ino;
509 }
510 __mode_t st_mode;
511 __nlink_t st_nlink;
512 __uid_t st_uid;
513 __gid_t st_gid;
514 __dev_t st_rdev;
515 __dev_t __pad1;
516
517 static if (__USE_FILE_OFFSET64)
518 {
519 __off64_t st_size;
520 }
521 else
522 {
523 __off_t st_size;
524 }
525 __blksize_t st_blksize;
526 int __pad2;
527
528 static if (__USE_FILE_OFFSET64)
529 {
530 __blkcnt64_t st_blocks;
531 }
532 else
533 {
534 __blkcnt_t st_blocks;
535 }
536
537 static if (_DEFAULT_SOURCE)
538 {
539 __timespec st_atim;
540 __timespec st_mtim;
541 __timespec st_ctim;
542 extern(D) @safe @property inout pure nothrow
543 {
544 ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
545 ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
546 ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
547 }
548 }
549 else
550 {
551 __time_t st_atime;
552 c_ulong st_atimensec;
553 __time_t st_mtime;
554 c_ulong st_mtimensec;
555 __time_t st_ctime;
556 c_ulong st_ctimensec;
557 }
558 int[2] __unused;
559 }
560 }
561 else version (ARM)
562 {
563 private
564 {
565 alias __dev_t = ulong;
566 alias __ino_t = c_ulong;
567 alias __ino64_t = ulong;
568 alias __mode_t = uint;
569 alias __nlink_t = size_t;
570 alias __uid_t = uint;
571 alias __gid_t = uint;
572 alias __off_t = c_long;
573 alias __off64_t = long;
574 alias __blksize_t = c_long;
575 alias __blkcnt_t = c_long;
576 alias __blkcnt64_t = long;
577 alias __timespec = timespec;
578 alias __time_t = time_t;
579 }
580 struct stat_t
581 {
582 __dev_t st_dev;
583 ushort __pad1;
584
585 static if (!__USE_FILE_OFFSET64)
586 {
587 __ino_t st_ino;
588 }
589 else
590 {
591 __ino_t __st_ino;
592 }
593 __mode_t st_mode;
594 __nlink_t st_nlink;
595 __uid_t st_uid;
596 __gid_t st_gid;
597 __dev_t st_rdev;
598 ushort __pad2;
599
600 static if (!__USE_FILE_OFFSET64)
601 {
602 __off_t st_size;
603 }
604 else
605 {
606 __off64_t st_size;
607 }
608 __blksize_t st_blksize;
609
610 static if (!__USE_FILE_OFFSET64)
611 {
612 __blkcnt_t st_blocks;
613 }
614 else
615 {
616 __blkcnt64_t st_blocks;
617 }
618
619 static if ( _DEFAULT_SOURCE || _XOPEN_SOURCE >= 700)
620 {
621 __timespec st_atim;
622 __timespec st_mtim;
623 __timespec st_ctim;
624 extern(D) @safe @property inout pure nothrow
625 {
626 ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
627 ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
628 ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
629 }
630 }
631 else
632 {
633 __time_t st_atime;
634 c_ulong st_atimensec;
635 __time_t st_mtime;
636 c_ulong st_mtimensec;
637 __time_t st_ctime;
638 c_ulong st_ctimensec;
639 }
640
641 static if (!__USE_FILE_OFFSET64)
642 {
643 c_ulong __unused4;
644 c_ulong __unused5;
645 }
646 else
647 {
648 __ino64_t st_ino;
649 }
650 }
651 static if (__USE_FILE_OFFSET64)
652 static assert(stat_t.sizeof == 104);
653 else
654 static assert(stat_t.sizeof == 88);
655 }
656 else version (AArch64)
657 {
658 private
659 {
660 alias __dev_t = ulong;
661 alias __ino_t = c_ulong;
662 alias __ino64_t = ulong;
663 alias __mode_t = uint;
664 alias __nlink_t = uint;
665 alias __uid_t = uint;
666 alias __gid_t = uint;
667 alias __off_t = c_long;
668 alias __off64_t = long;
669 alias __blksize_t = int;
670 alias __blkcnt_t = c_long;
671 alias __blkcnt64_t = long;
672 alias __timespec = timespec;
673 alias __time_t = time_t;
674 }
675 struct stat_t
676 {
677 __dev_t st_dev;
678
679 static if (!__USE_FILE_OFFSET64)
680 {
681 __ino_t st_ino;
682 }
683 else
684 {
685 __ino64_t st_ino;
686 }
687 __mode_t st_mode;
688 __nlink_t st_nlink;
689 __uid_t st_uid;
690 __gid_t st_gid;
691 __dev_t st_rdev;
692 __dev_t __pad1;
693
694 static if (!__USE_FILE_OFFSET64)
695 {
696 __off_t st_size;
697 }
698 else
699 {
700 __off64_t st_size;
701 }
702 __blksize_t st_blksize;
703 int __pad2;
704
705 static if (!__USE_FILE_OFFSET64)
706 {
707 __blkcnt_t st_blocks;
708 }
709 else
710 {
711 __blkcnt64_t st_blocks;
712 }
713
714 static if (_DEFAULT_SOURCE)
715 {
716 __timespec st_atim;
717 __timespec st_mtim;
718 __timespec st_ctim;
719 extern(D) @safe @property inout pure nothrow
720 {
721 ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
722 ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
723 ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
724 }
725 }
726 else
727 {
728 __time_t st_atime;
729 c_ulong st_atimensec;
730 __time_t st_mtime;
731 c_ulong st_mtimensec;
732 __time_t st_ctime;
733 c_ulong st_ctimensec;
734 }
735 int[2] __unused;
736 }
737 version (D_LP64)
738 static assert(stat_t.sizeof == 128);
739 else
740 static assert(stat_t.sizeof == 104);
741 }
742 else version (SPARC_Any)
743 {
744 private
745 {
746 alias __dev_t = ulong;
747 alias __ino_t = c_ulong;
748 alias __ino64_t = ulong;
749 alias __mode_t = uint;
750 alias __nlink_t = uint;
751 alias __uid_t = uint;
752 alias __gid_t = uint;
753 alias __off_t = c_long;
754 alias __off64_t = long;
755 alias __blksize_t = c_long;
756 alias __blkcnt_t = c_long;
757 alias __blkcnt64_t = long;
758 alias __timespec = timespec;
759 alias __time_t = time_t;
760 }
761 struct stat_t
762 {
763 __dev_t st_dev;
764 static if (__WORDSIZE == 64 || !__USE_FILE_OFFSET64)
765 {
766 ushort __pad1;
767 __ino_t st_ino;
768 }
769 else
770 {
771 __ino64_t st_ino;
772 }
773 __mode_t st_mode;
774 __nlink_t st_nlink;
775 __uid_t st_uid;
776 __gid_t st_gid;
777 __dev_t st_rdev;
778 ushort __pad2;
779
780 static if (!__USE_FILE_OFFSET64)
781 {
782 __off_t st_size;
783 }
784 else
785 {
786 __off64_t st_size;
787 }
788 __blksize_t st_blksize;
789
790 static if (!__USE_FILE_OFFSET64)
791 {
792 __blkcnt_t st_blocks;
793 }
794 else
795 {
796 __blkcnt64_t st_blocks;
797 }
798
799 static if (_XOPEN_SOURCE >= 700)
800 {
801 __timespec st_atim;
802 __timespec st_mtim;
803 __timespec st_ctim;
804 extern(D) @safe @property inout pure nothrow
805 {
806 ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
807 ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
808 ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
809 }
810 }
811 else
812 {
813 __time_t st_atime;
814 c_ulong st_atimensec;
815 __time_t st_mtime;
816 c_ulong st_mtimensec;
817 __time_t st_ctime;
818 c_ulong st_ctimensec;
819 }
820
821 c_ulong __unused4;
822 c_ulong __unused5;
823 }
824 static if (__USE_LARGEFILE64) alias stat_t stat64_t;
825
826 static if (__WORDSIZE == 64)
827 static assert(stat_t.sizeof == 144);
828 else static if (__USE_FILE_OFFSET64)
829 static assert(stat_t.sizeof == 104);
830 else
831 static assert(stat_t.sizeof == 88);
832
833 }
834 else version (S390)
835 {
836 private
837 {
838 alias __dev_t = ulong;
839 alias __ino_t = c_ulong;
840 alias __ino64_t = ulong;
841 alias __mode_t = uint;
842 alias __nlink_t = uint;
843 alias __uid_t = uint;
844 alias __gid_t = uint;
845 alias __off_t = c_long;
846 alias __off64_t = long;
847 alias __blksize_t = c_long;
848 alias __blkcnt_t = c_long;
849 alias __blkcnt64_t = long;
850 alias __timespec = timespec;
851 alias __time_t = time_t;
852 }
853 struct stat_t
854 {
855 __dev_t st_dev;
856 uint __pad1;
857 static if (!__USE_FILE_OFFSET64)
858 __ino_t st_ino;
859 else
860 __ino_t __st_ino;
861 __mode_t st_mode;
862 __nlink_t st_nlink;
863 __uid_t st_uid;
864 __gid_t st_gid;
865 __dev_t st_rdev;
866 uint __pad2;
867 static if (!__USE_FILE_OFFSET64)
868 __off_t st_size;
869 else
870 __off64_t st_size;
871 __blksize_t st_blksize;
872 static if (!__USE_FILE_OFFSET64)
873 __blkcnt_t st_blocks;
874 else
875 __blkcnt64_t st_blocks;
876 static if (_XOPEN_SOURCE >= 700)
877 {
878 __timespec st_atim;
879 __timespec st_mtim;
880 __timespec st_ctim;
881 extern(D) @safe @property inout pure nothrow
882 {
883 ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
884 ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
885 ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
886 }
887 }
888 else
889 {
890 __time_t st_atime;
891 c_ulong st_atimensec;
892 __time_t st_mtime;
893 c_ulong st_mtimensec;
894 __time_t st_ctime;
895 c_ulong st_ctimensec;
896 }
897 static if (!__USE_FILE_OFFSET64)
898 {
899 c_ulong __glibc_reserved4;
900 c_ulong __glibc_reserved5;
901 }
902 else
903 __ino64_t st_ino;
904 }
905 static if (__USE_FILE_OFFSET64)
906 static assert(stat_t.sizeof == 104);
907 else
908 static assert(stat_t.sizeof == 88);
909 }
910 else version (SystemZ)
911 {
912 private
913 {
914 alias __dev_t = ulong;
915 alias __ino_t = c_ulong;
916 alias __ino64_t = ulong;
917 alias __mode_t = uint;
918 alias __nlink_t = ulong;
919 alias __uid_t = uint;
920 alias __gid_t = uint;
921 alias __off_t = c_long;
922 alias __off64_t = long;
923 alias __blksize_t = c_long;
924 alias __blkcnt_t = c_long;
925 alias __blkcnt64_t = long;
926 alias __timespec = timespec;
927 alias __time_t = time_t;
928 }
929 struct stat_t
930 {
931 __dev_t st_dev;
932 __ino_t st_ino;
933 __nlink_t st_nlink;
934 __mode_t st_mode;
935 __uid_t st_uid;
936 __gid_t st_gid;
937 int __glibc_reserved0;
938 __dev_t st_rdev;
939 __off_t st_size;
940 static if (_XOPEN_SOURCE >= 700)
941 {
942 __timespec st_atim;
943 __timespec st_mtim;
944 __timespec st_ctim;
945 extern(D) @safe @property inout pure nothrow
946 {
947 ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
948 ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
949 ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
950 }
951 }
952 else
953 {
954 __time_t st_atime;
955 c_ulong st_atimensec;
956 __time_t st_mtime;
957 c_ulong st_mtimensec;
958 __time_t st_ctime;
959 c_ulong st_ctimensec;
960 }
961 __blksize_t st_blksize;
962 __blkcnt_t st_blocks;
963 c_long[3] __glibc_reserved;
964 }
965 static if (_XOPEN_SOURCE >= 700)
966 static assert(stat_t.sizeof == 144);
967 else
968 static assert(stat_t.sizeof == 144);
969 }
970 else
971 static assert(0, "unimplemented");
972
973 enum S_ISUID = 0x800; // octal 04000
974 enum S_ISGID = 0x400; // octal 02000
975 enum S_ISVTX = 0x200; // octal 01000
976
977 static if ( true /*__USE_POSIX199309*/ )
978 {
979 extern bool S_TYPEISMQ( stat_t* buf ) { return false; }
980 extern bool S_TYPEISSEM( stat_t* buf ) { return false; }
981 extern bool S_TYPEISSHM( stat_t* buf ) { return false; }
982 }
983
984 enum UTIME_NOW = 0x3fffffff;
985 enum UTIME_OMIT = 0x3ffffffe;
986 }
987 else version (Darwin)
988 {
989 // _DARWIN_FEATURE_64_BIT_INODE stat is default for Mac OSX >10.5 and is
990 // only meaningful type for other OS X/Darwin variants (e.g. iOS).
991 // man stat(2) gives details.
992 struct stat_t
993 {
994 dev_t st_dev;
995 mode_t st_mode;
996 nlink_t st_nlink;
997 ino_t st_ino;
998 uid_t st_uid;
999 gid_t st_gid;
1000 dev_t st_rdev;
1001 union
1002 {
1003 struct
1004 {
1005 timespec st_atimespec;
1006 timespec st_mtimespec;
1007 timespec st_ctimespec;
1008 timespec st_birthtimespec;
1009 }
1010 struct
1011 {
1012 time_t st_atime;
1013 c_long st_atimensec;
1014 time_t st_mtime;
1015 c_long st_mtimensec;
1016 time_t st_ctime;
1017 c_long st_ctimensec;
1018 time_t st_birthtime;
1019 c_long st_birthtimensec;
1020 }
1021 }
1022 off_t st_size;
1023 blkcnt_t st_blocks;
1024 blksize_t st_blksize;
1025 uint st_flags;
1026 uint st_gen;
1027 int st_lspare;
1028 long[2] st_qspare;
1029 }
1030
1031 enum S_ISUID = 0x800; // octal 04000
1032 enum S_ISGID = 0x400; // octal 02000
1033 enum S_ISVTX = 0x200; // octal 01000
1034 }
1035 else version (FreeBSD)
1036 {
1037 import core.sys.freebsd.config;
1038
1039 // https://github.com/freebsd/freebsd/blob/master/sys/sys/stat.h
1040 static if (__FreeBSD_version >= INO64_FIRST)
1041 {
1042 struct stat_t
1043 {
1044 dev_t st_dev;
1045 ino_t st_ino;
1046 nlink_t st_nlink;
1047 mode_t st_mode;
1048 short st_padding0;
1049 uid_t st_uid;
1050 gid_t st_gid;
1051 int st_padding1;
1052 dev_t st_rdev;
1053
1054 version (X86) int st_atim_ext;
1055 timespec st_atim;
1056
1057 version (X86) int st_mtim_ext;
1058 timespec st_mtim;
1059
1060 version (X86) int st_ctim_ext;
1061 timespec st_ctim;
1062
1063 version (X86) int st_btim_ext;
1064 timespec st_birthtim;
1065
1066 off_t st_size;
1067 blkcnt_t st_blocks;
1068 blksize_t st_blksize;
1069 fflags_t st_flags;
1070 ulong st_gen;
1071 ulong[10] st_spare;
1072
1073 extern(D) @safe @property inout pure nothrow
1074 {
1075 ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
1076 ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
1077 ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
1078 ref inout(time_t) st_birthtime() return { return st_birthtim.tv_sec; }
1079 }
1080 }
1081 }
1082 else
1083 {
1084 struct stat_t
1085 {
1086 uint st_dev;
1087 uint st_ino;
1088 mode_t st_mode;
1089 ushort st_nlink;
1090 uid_t st_uid;
1091 gid_t st_gid;
1092 uint st_rdev;
1093 timespec st_atim;
1094 timespec st_mtim;
1095 timespec st_ctim;
1096 off_t st_size;
1097 blkcnt_t st_blocks;
1098 blksize_t st_blksize;
1099 fflags_t st_flags;
1100 uint st_gen;
1101 int st_lspare;
1102 timespec st_birthtim;
1103 ubyte[16 - timespec.sizeof] padding;
1104
1105 extern(D) @safe @property inout pure nothrow
1106 {
1107 ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
1108 ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
1109 ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
1110 ref inout(time_t) st_birthtime() return { return st_birthtim.tv_sec; }
1111 }
1112 }
1113 }
1114
1115 enum S_ISUID = 0x800; // octal 0004000
1116 enum S_ISGID = 0x400; // octal 0002000
1117 enum S_ISVTX = 0x200; // octal 0001000
1118
1119 enum UTIME_NOW = -1;
1120 enum UTIME_OMIT = -2;
1121 }
1122 else version (NetBSD)
1123 {
1124 struct stat_t
1125 {
1126 dev_t st_dev; /* inode's device */
1127 mode_t st_mode; /* inode protection mode */
1128 ino_t st_ino; /* inode's number */
1129 nlink_t st_nlink; /* number of hard links */
1130 uid_t st_uid; /* user ID of the file's owner */
1131 gid_t st_gid; /* group ID of the file's group */
1132 dev_t st_rdev; /* device type */
1133 time_t st_atime; /* time of last access */
1134 long st_atimensec; /* nsec of last access */
1135 time_t st_mtime; /* time of last data modification */
1136 long st_mtimensec; /* nsec of last data modification */
1137 time_t st_ctime; /* time of last file status change */
1138 long st_ctimensec; /* nsec of last file status change */
1139 time_t st_birthtime; /* time of creation */
1140 long st_birthtimensec; /* nsec of time of creation */
1141 off_t st_size; /* file size, in bytes */
1142 blkcnt_t st_blocks; /* blocks allocated for file */
1143 blksize_t st_blksize; /* optimal blocksize for I/O */
1144 uint32_t st_flags; /* user defined flags for file */
1145 uint32_t st_gen; /* file generation number */
1146 uint32_t[2] st_spare;
1147 }
1148
1149 enum S_ISUID = 0x800; // octal 0004000
1150 enum S_ISGID = 0x400; // octal 0002000
1151 enum S_ISVTX = 0x200; // octal 0001000
1152 }
1153 else version (OpenBSD)
1154 {
1155 import core.sys.openbsd.sys.cdefs;
1156
1157 struct stat_t
1158 {
1159 mode_t st_mode;
1160 dev_t st_dev;
1161 ino_t st_ino;
1162 nlink_t st_nlink;
1163 uid_t st_uid;
1164 gid_t st_gid;
1165 dev_t st_rdev;
1166 static if (__POSIX_VISIBLE >= 200809 || __BSD_VISIBLE)
1167 {
1168 timespec st_atim;
1169 timespec st_mtim;
1170 timespec st_ctim;
1171 extern(D) @safe @property inout pure nothrow
1172 {
1173 ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
1174 ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
1175 ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
1176 }
1177 }
1178 else
1179 {
1180 time_t st_atime;
1181 long st_atimensec;
1182 time_t st_mtime;
1183 long st_mtimensec;
1184 time_t st_ctime;
1185 long st_ctimensec;
1186 }
1187 off_t st_size;
1188 blkcnt_t st_blocks;
1189 blksize_t st_blksize;
1190 uint32_t st_flags;
1191 uint32_t st_gen;
1192 static if (__POSIX_VISIBLE >= 200809 || __BSD_VISIBLE)
1193 {
1194 timespec __st_birthtim;
1195 }
1196 else
1197 {
1198 time_t __st_birthtime;
1199 long __st_birthtimensec;
1200 }
1201 }
1202
1203 enum S_ISUID = 0x800; // octal 0004000
1204 enum S_ISGID = 0x400; // octal 0002000
1205 enum S_ISVTX = 0x200; // octal 0001000
1206 }
1207 else version (DragonFlyBSD)
1208 {
1209 struct stat_t {
1210 ino_t st_ino; /* inode's number */
1211 nlink_t st_nlink; /* number of hard links */
1212 dev_t st_dev; /* inode's device */
1213 mode_t st_mode; /* inode protection mode */
1214 uint16_t st_padding1;
1215 uid_t st_uid; /* user ID of the file's owner */
1216 gid_t st_gid; /* group ID of the file's group */
1217 dev_t st_rdev; /* device type */
1218 time_t st_atime;
1219 c_long __st_atimensec;
1220 time_t st_mtime;
1221 c_long __st_mtimensec;
1222 time_t st_ctime;
1223 c_long __st_ctimensec;
1224 off_t st_size; /* file size, in bytes */
1225 int64_t st_blocks; /* blocks allocated for file */
1226 uint32_t st_blksize; /* optimal blocksize for I/O */
1227 uint32_t st_flags; /* user defined flags for file */
1228 uint32_t st_gen; /* file generation number */
1229 int32_t st_lspare;
1230 int64_t st_qspare1; /* was recursive change detect */
1231 int64_t st_qspare2;
1232 }
1233
1234 enum S_ISUID = 0x800; // octal 0004000
1235 enum S_ISGID = 0x400; // octal 0002000
1236 enum S_ISVTX = 0x200; // octal 0001000
1237 }
1238 else version (Solaris)
1239 {
1240 private enum _ST_FSTYPSZ = 16;
1241
1242 version (D_LP64)
1243 {
1244 struct stat_t
1245 {
1246 dev_t st_dev;
1247 ino_t st_ino;
1248 mode_t st_mode;
1249 nlink_t st_nlink;
1250 uid_t st_uid;
1251 gid_t st_gid;
1252 dev_t st_rdev;
1253 off_t st_size;
1254 union
1255 {
1256 timestruc_t st_atim;
1257 time_t st_atime;
1258 }
1259 union
1260 {
1261 timestruc_t st_mtim;
1262 time_t st_mtime;
1263 }
1264 union
1265 {
1266 timestruc_t st_ctim;
1267 time_t st_ctime;
1268 }
1269 blksize_t st_blksize;
1270 blkcnt_t st_blocks;
1271 char[_ST_FSTYPSZ] st_fstype = 0;
1272 }
1273
1274 static if (__USE_LARGEFILE64) alias stat_t stat64_t;
1275 }
1276 else
1277 {
1278 struct stat32_t
1279 {
1280 dev_t st_dev;
1281 c_long[3] st_pad1;
1282 ino_t st_ino;
1283 mode_t st_mode;
1284 nlink_t st_nlink;
1285 uid_t st_uid;
1286 gid_t st_gid;
1287 dev_t st_rdev;
1288 c_long[2] st_pad2;
1289 off_t st_size;
1290 c_long st_pad3;
1291 union
1292 {
1293 timestruc_t st_atim;
1294 time_t st_atime;
1295 }
1296 union
1297 {
1298 timestruc_t st_mtim;
1299 time_t st_mtime;
1300 }
1301 union
1302 {
1303 timestruc_t st_ctim;
1304 time_t st_ctime;
1305 }
1306 blksize_t st_blksize;
1307 blkcnt_t st_blocks;
1308 char[_ST_FSTYPSZ] st_fstype = 0;
1309 c_long[8] st_pad4;
1310 }
1311
1312 struct stat64_t
1313 {
1314 dev_t st_dev;
1315 c_long[3] st_pad1;
1316 ino64_t st_ino;
1317 mode_t st_mode;
1318 nlink_t st_nlink;
1319 uid_t st_uid;
1320 gid_t st_gid;
1321 dev_t st_rdev;
1322 c_long[2] st_pad2;
1323 off64_t st_size;
1324 union
1325 {
1326 timestruc_t st_atim;
1327 time_t st_atime;
1328 }
1329 union
1330 {
1331 timestruc_t st_mtim;
1332 time_t st_mtime;
1333 }
1334 union
1335 {
1336 timestruc_t st_ctim;
1337 time_t st_ctime;
1338 }
1339 blksize_t st_blksize;
1340 blkcnt64_t st_blocks;
1341 char[_ST_FSTYPSZ] st_fstype = 0;
1342 c_long[8] st_pad4;
1343 }
1344
1345 static if (__USE_FILE_OFFSET64)
1346 alias stat64_t stat_t;
1347 else
1348 alias stat32_t stat_t;
1349
1350 }
1351
1352 enum S_ISUID = 0x800;
1353 enum S_ISGID = 0x400;
1354 enum S_ISVTX = 0x200;
1355 }
1356 else
1357 {
1358 static assert(false, "Unsupported platform");
1359 }
1360
1361 /*
1362 S_IRWXU
1363 S_IRUSR
1364 S_IWUSR
1365 S_IXUSR
1366 S_IRWXG
1367 S_IRGRP
1368 S_IWGRP
1369 S_IXGRP
1370 S_IRWXO
1371 S_IROTH
1372 S_IWOTH
1373 S_IXOTH
1374
1375 S_ISBLK(m)
1376 S_ISCHR(m)
1377 S_ISDIR(m)
1378 S_ISFIFO(m)
1379 S_ISREG(m)
1380 S_ISLNK(m)
1381 S_ISSOCK(m)
1382 */
1383
1384 version (CRuntime_Glibc)
1385 {
1386 enum S_IRUSR = 0x100; // octal 0400
1387 enum S_IWUSR = 0x080; // octal 0200
1388 enum S_IXUSR = 0x040; // octal 0100
1389 enum S_IRWXU = S_IRUSR | S_IWUSR | S_IXUSR;
1390
1391 enum S_IRGRP = S_IRUSR >> 3;
1392 enum S_IWGRP = S_IWUSR >> 3;
1393 enum S_IXGRP = S_IXUSR >> 3;
1394 enum S_IRWXG = S_IRWXU >> 3;
1395
1396 enum S_IROTH = S_IRGRP >> 3;
1397 enum S_IWOTH = S_IWGRP >> 3;
1398 enum S_IXOTH = S_IXGRP >> 3;
1399 enum S_IRWXO = S_IRWXG >> 3;
1400
1401 private
1402 {
1403 extern (D) bool S_ISTYPE( mode_t mode, uint mask )
1404 {
1405 return ( mode & S_IFMT ) == mask;
1406 }
1407 }
1408
1409 extern (D) bool S_ISBLK( mode_t mode ) { return S_ISTYPE( mode, S_IFBLK ); }
1410 extern (D) bool S_ISCHR( mode_t mode ) { return S_ISTYPE( mode, S_IFCHR ); }
1411 extern (D) bool S_ISDIR( mode_t mode ) { return S_ISTYPE( mode, S_IFDIR ); }
1412 extern (D) bool S_ISFIFO( mode_t mode ) { return S_ISTYPE( mode, S_IFIFO ); }
1413 extern (D) bool S_ISREG( mode_t mode ) { return S_ISTYPE( mode, S_IFREG ); }
1414 extern (D) bool S_ISLNK( mode_t mode ) { return S_ISTYPE( mode, S_IFLNK ); }
1415 extern (D) bool S_ISSOCK( mode_t mode ) { return S_ISTYPE( mode, S_IFSOCK ); }
1416
1417 int utimensat(int dirfd, const char *pathname,
1418 ref const(timespec)[2] times, int flags);
1419 int futimens(int fd, ref const(timespec)[2] times);
1420 }
1421 else version (Darwin)
1422 {
1423 enum S_IRUSR = 0x100; // octal 0400
1424 enum S_IWUSR = 0x080; // octal 0200
1425 enum S_IXUSR = 0x040; // octal 0100
1426 enum S_IRWXU = S_IRUSR | S_IWUSR | S_IXUSR;
1427
1428 enum S_IRGRP = S_IRUSR >> 3;
1429 enum S_IWGRP = S_IWUSR >> 3;
1430 enum S_IXGRP = S_IXUSR >> 3;
1431 enum S_IRWXG = S_IRWXU >> 3;
1432
1433 enum S_IROTH = S_IRGRP >> 3;
1434 enum S_IWOTH = S_IWGRP >> 3;
1435 enum S_IXOTH = S_IXGRP >> 3;
1436 enum S_IRWXO = S_IRWXG >> 3;
1437
1438 private
1439 {
1440 extern (D) bool S_ISTYPE( mode_t mode, uint mask )
1441 {
1442 return ( mode & S_IFMT ) == mask;
1443 }
1444 }
1445
1446 extern (D) bool S_ISBLK( mode_t mode ) { return S_ISTYPE( mode, S_IFBLK ); }
1447 extern (D) bool S_ISCHR( mode_t mode ) { return S_ISTYPE( mode, S_IFCHR ); }
1448 extern (D) bool S_ISDIR( mode_t mode ) { return S_ISTYPE( mode, S_IFDIR ); }
1449 extern (D) bool S_ISFIFO( mode_t mode ) { return S_ISTYPE( mode, S_IFIFO ); }
1450 extern (D) bool S_ISREG( mode_t mode ) { return S_ISTYPE( mode, S_IFREG ); }
1451 extern (D) bool S_ISLNK( mode_t mode ) { return S_ISTYPE( mode, S_IFLNK ); }
1452 extern (D) bool S_ISSOCK( mode_t mode ) { return S_ISTYPE( mode, S_IFSOCK ); }
1453 }
1454 else version (FreeBSD)
1455 {
1456 enum S_IRUSR = 0x100; // octal 0000400
1457 enum S_IWUSR = 0x080; // octal 0000200
1458 enum S_IXUSR = 0x040; // octal 0000100
1459 enum S_IRWXU = 0x1C0; // octal 0000700
1460
1461 enum S_IRGRP = 0x020; // octal 0000040
1462 enum S_IWGRP = 0x010; // octal 0000020
1463 enum S_IXGRP = 0x008; // octal 0000010
1464 enum S_IRWXG = 0x038; // octal 0000070
1465
1466 enum S_IROTH = 0x4; // 0000004
1467 enum S_IWOTH = 0x2; // 0000002
1468 enum S_IXOTH = 0x1; // 0000001
1469 enum S_IRWXO = 0x7; // 0000007
1470
1471 private
1472 {
1473 extern (D) bool S_ISTYPE( mode_t mode, uint mask )
1474 {
1475 return ( mode & S_IFMT ) == mask;
1476 }
1477 }
1478
1479 extern (D) bool S_ISBLK( mode_t mode ) { return S_ISTYPE( mode, S_IFBLK ); }
1480 extern (D) bool S_ISCHR( mode_t mode ) { return S_ISTYPE( mode, S_IFCHR ); }
1481 extern (D) bool S_ISDIR( mode_t mode ) { return S_ISTYPE( mode, S_IFDIR ); }
1482 extern (D) bool S_ISFIFO( mode_t mode ) { return S_ISTYPE( mode, S_IFIFO ); }
1483 extern (D) bool S_ISREG( mode_t mode ) { return S_ISTYPE( mode, S_IFREG ); }
1484 extern (D) bool S_ISLNK( mode_t mode ) { return S_ISTYPE( mode, S_IFLNK ); }
1485 extern (D) bool S_ISSOCK( mode_t mode ) { return S_ISTYPE( mode, S_IFSOCK ); }
1486
1487 // Since FreeBSD 11:
1488 version (none)
1489 {
1490 int utimensat(int dirfd, const char *pathname,
1491 ref const(timespec)[2] times, int flags);
1492 int futimens(int fd, ref const(timespec)[2] times);
1493 }
1494 }
1495 else version (NetBSD)
1496 {
1497 enum S_IRUSR = 0x100; // octal 0000400
1498 enum S_IWUSR = 0x080; // octal 0000200
1499 enum S_IXUSR = 0x040; // octal 0000100
1500 enum S_IRWXU = 0x1C0; // octal 0000700
1501
1502 enum S_IRGRP = 0x020; // octal 0000040
1503 enum S_IWGRP = 0x010; // octal 0000020
1504 enum S_IXGRP = 0x008; // octal 0000010
1505 enum S_IRWXG = 0x038; // octal 0000070
1506
1507 enum S_IROTH = 0x4; // 0000004
1508 enum S_IWOTH = 0x2; // 0000002
1509 enum S_IXOTH = 0x1; // 0000001
1510 enum S_IRWXO = 0x7; // 0000007
1511
1512 private
1513 {
1514 extern (D) bool S_ISTYPE( mode_t mode, uint mask )
1515 {
1516 return ( mode & S_IFMT ) == mask;
1517 }
1518 }
1519
1520 extern (D) bool S_ISBLK( mode_t mode ) { return S_ISTYPE( mode, S_IFBLK ); }
1521 extern (D) bool S_ISCHR( mode_t mode ) { return S_ISTYPE( mode, S_IFCHR ); }
1522 extern (D) bool S_ISDIR( mode_t mode ) { return S_ISTYPE( mode, S_IFDIR ); }
1523 extern (D) bool S_ISFIFO( mode_t mode ) { return S_ISTYPE( mode, S_IFIFO ); }
1524 extern (D) bool S_ISREG( mode_t mode ) { return S_ISTYPE( mode, S_IFREG ); }
1525 extern (D) bool S_ISLNK( mode_t mode ) { return S_ISTYPE( mode, S_IFLNK ); }
1526 extern (D) bool S_ISSOCK( mode_t mode ) { return S_ISTYPE( mode, S_IFSOCK ); }
1527 }
1528 else version (OpenBSD)
1529 {
1530 enum S_IRUSR = 0x100; // octal 0000400
1531 enum S_IWUSR = 0x080; // octal 0000200
1532 enum S_IXUSR = 0x040; // octal 0000100
1533 enum S_IRWXU = 0x1C0; // octal 0000700
1534
1535 enum S_IRGRP = 0x020; // octal 0000040
1536 enum S_IWGRP = 0x010; // octal 0000020
1537 enum S_IXGRP = 0x008; // octal 0000010
1538 enum S_IRWXG = 0x038; // octal 0000070
1539
1540 enum S_IROTH = 0x4; // 0000004
1541 enum S_IWOTH = 0x2; // 0000002
1542 enum S_IXOTH = 0x1; // 0000001
1543 enum S_IRWXO = 0x7; // 0000007
1544
1545 extern (D) bool S_ISBLK(mode_t mode) { return (mode & S_IFMT) == S_IFBLK; }
1546 extern (D) bool S_ISCHR(mode_t mode) { return (mode & S_IFMT) == S_IFCHR; }
1547 extern (D) bool S_ISDIR(mode_t mode) { return (mode & S_IFMT) == S_IFDIR; }
1548 extern (D) bool S_ISFIFO(mode_t mode) { return (mode & S_IFMT) == S_IFIFO; }
1549 extern (D) bool S_ISREG(mode_t mode) { return (mode & S_IFMT) == S_IFREG; }
1550 extern (D) bool S_ISLNK(mode_t mode) { return (mode & S_IFMT) == S_IFLNK; }
1551 extern (D) bool S_ISSOCK(mode_t mode) { return (mode & S_IFMT) == S_IFSOCK; }
1552 }
1553 else version (DragonFlyBSD)
1554 {
1555 enum S_IRUSR = 0x100; // octal 0000400
1556 enum S_IWUSR = 0x080; // octal 0000200
1557 enum S_IXUSR = 0x040; // octal 0000100
1558 enum S_IRWXU = 0x1C0; // octal 0000700
1559
1560 enum S_IRGRP = 0x020; // octal 0000040
1561 enum S_IWGRP = 0x010; // octal 0000020
1562 enum S_IXGRP = 0x008; // octal 0000010
1563 enum S_IRWXG = 0x038; // octal 0000070
1564
1565 enum S_IROTH = 0x4; // 0000004
1566 enum S_IWOTH = 0x2; // 0000002
1567 enum S_IXOTH = 0x1; // 0000001
1568 enum S_IRWXO = 0x7; // 0000007
1569
1570 private
1571 {
1572 extern (D) bool S_ISTYPE( mode_t mode, uint mask )
1573 {
1574 return ( mode & S_IFMT ) == mask;
1575 }
1576 }
1577
1578 extern (D) bool S_ISBLK( mode_t mode ) { return S_ISTYPE( mode, S_IFBLK ); }
1579 extern (D) bool S_ISCHR( mode_t mode ) { return S_ISTYPE( mode, S_IFCHR ); }
1580 extern (D) bool S_ISDIR( mode_t mode ) { return S_ISTYPE( mode, S_IFDIR ); }
1581 extern (D) bool S_ISFIFO( mode_t mode ) { return S_ISTYPE( mode, S_IFIFO ); }
1582 extern (D) bool S_ISREG( mode_t mode ) { return S_ISTYPE( mode, S_IFREG ); }
1583 extern (D) bool S_ISLNK( mode_t mode ) { return S_ISTYPE( mode, S_IFLNK ); }
1584 extern (D) bool S_ISSOCK( mode_t mode ) { return S_ISTYPE( mode, S_IFSOCK ); }
1585 }
1586 else version (Solaris)
1587 {
1588 enum S_IRUSR = 0x100;
1589 enum S_IWUSR = 0x080;
1590 enum S_IXUSR = 0x040;
1591 enum S_IRWXU = 0x1C0;
1592
1593 enum S_IRGRP = 0x020;
1594 enum S_IWGRP = 0x010;
1595 enum S_IXGRP = 0x008;
1596 enum S_IRWXG = 0x038;
1597
1598 enum S_IROTH = 0x4; // 0000004
1599 enum S_IWOTH = 0x2; // 0000002
1600 enum S_IXOTH = 0x1; // 0000001
1601 enum S_IRWXO = 0x7; // 0000007
1602
1603 private
1604 {
1605 extern (D) bool S_ISTYPE(mode_t mode, uint mask)
1606 {
1607 return (mode & S_IFMT) == mask;
1608 }
1609 }
1610
1611 extern (D) bool S_ISBLK(mode_t mode) { return S_ISTYPE(mode, S_IFBLK); }
1612 extern (D) bool S_ISCHR(mode_t mode) { return S_ISTYPE(mode, S_IFCHR); }
1613 extern (D) bool S_ISDIR(mode_t mode) { return S_ISTYPE(mode, S_IFDIR); }
1614 extern (D) bool S_ISFIFO(mode_t mode) { return S_ISTYPE(mode, S_IFIFO); }
1615 extern (D) bool S_ISREG(mode_t mode) { return S_ISTYPE(mode, S_IFREG); }
1616 extern (D) bool S_ISLNK(mode_t mode) { return S_ISTYPE(mode, S_IFLNK); }
1617 extern (D) bool S_ISSOCK(mode_t mode) { return S_ISTYPE(mode, S_IFSOCK); }
1618 extern (D) bool S_ISDOOR(mode_t mode) { return S_ISTYPE(mode, S_IFDOOR); }
1619 extern (D) bool S_ISPORT(mode_t mode) { return S_ISTYPE(mode, S_IFPORT); }
1620 }
1621 else version (CRuntime_Bionic)
1622 {
1623 enum S_IRUSR = 0x100; // octal 0000400
1624 enum S_IWUSR = 0x080; // octal 0000200
1625 enum S_IXUSR = 0x040; // octal 0000100
1626 enum S_IRWXU = 0x1C0; // octal 0000700
1627
1628 enum S_IRGRP = 0x020; // octal 0000040
1629 enum S_IWGRP = 0x010; // octal 0000020
1630 enum S_IXGRP = 0x008; // octal 0000010
1631 enum S_IRWXG = 0x038; // octal 0000070
1632
1633 enum S_IROTH = 0x4; // 0000004
1634 enum S_IWOTH = 0x2; // 0000002
1635 enum S_IXOTH = 0x1; // 0000001
1636 enum S_IRWXO = 0x7; // 0000007
1637
1638 private
1639 {
1640 extern (D) bool S_ISTYPE( uint mode, uint mask )
1641 {
1642 return ( mode & S_IFMT ) == mask;
1643 }
1644 }
1645
1646 extern (D) bool S_ISBLK( uint mode ) { return S_ISTYPE( mode, S_IFBLK ); }
1647 extern (D) bool S_ISCHR( uint mode ) { return S_ISTYPE( mode, S_IFCHR ); }
1648 extern (D) bool S_ISDIR( uint mode ) { return S_ISTYPE( mode, S_IFDIR ); }
1649 extern (D) bool S_ISFIFO( uint mode ) { return S_ISTYPE( mode, S_IFIFO ); }
1650 extern (D) bool S_ISREG( uint mode ) { return S_ISTYPE( mode, S_IFREG ); }
1651 extern (D) bool S_ISLNK( uint mode ) { return S_ISTYPE( mode, S_IFLNK ); }
1652 extern (D) bool S_ISSOCK( uint mode ) { return S_ISTYPE( mode, S_IFSOCK ); }
1653
1654 // Added since Lollipop
1655 int utimensat(int dirfd, const char *pathname,
1656 ref const(timespec)[2] times, int flags);
1657 }
1658 else version (CRuntime_Musl)
1659 {
1660 alias __mode_t = uint;
1661 enum {
1662 S_IRUSR = 0x100, // octal 0400
1663 S_IWUSR = 0x080, // octal 0200
1664 S_IXUSR = 0x040, // octal 0100
1665 S_IRWXU = S_IRUSR | S_IWUSR | S_IXUSR,
1666
1667 S_IRGRP = S_IRUSR >> 3,
1668 S_IWGRP = S_IWUSR >> 3,
1669 S_IXGRP = S_IXUSR >> 3,
1670 S_IRWXG = S_IRWXU >> 3,
1671
1672 S_IROTH = S_IRGRP >> 3,
1673 S_IWOTH = S_IWGRP >> 3,
1674 S_IXOTH = S_IXGRP >> 3,
1675 S_IRWXO = S_IRWXG >> 3,
1676 }
1677
1678 private
1679 {
1680 extern (D) bool S_ISTYPE( mode_t mode, uint mask )
1681 {
1682 return ( mode & S_IFMT ) == mask;
1683 }
1684 }
1685
1686 extern (D) bool S_ISBLK( mode_t mode ) { return S_ISTYPE( mode, S_IFBLK ); }
1687 extern (D) bool S_ISCHR( mode_t mode ) { return S_ISTYPE( mode, S_IFCHR ); }
1688 extern (D) bool S_ISDIR( mode_t mode ) { return S_ISTYPE( mode, S_IFDIR ); }
1689 extern (D) bool S_ISFIFO( mode_t mode ) { return S_ISTYPE( mode, S_IFIFO ); }
1690 extern (D) bool S_ISREG( mode_t mode ) { return S_ISTYPE( mode, S_IFREG ); }
1691 extern (D) bool S_ISLNK( mode_t mode ) { return S_ISTYPE( mode, S_IFLNK ); }
1692 extern (D) bool S_ISSOCK( mode_t mode ) { return S_ISTYPE( mode, S_IFSOCK ); }
1693
1694 int utimensat(int dirfd, const char *pathname,
1695 ref const(timespec)[2] times, int flags);
1696 }
1697 else version (CRuntime_UClibc)
1698 {
1699 enum S_IRUSR = 0x100; // octal 0400
1700 enum S_IWUSR = 0x080; // octal 0200
1701 enum S_IXUSR = 0x040; // octal 0100
1702 enum S_IRWXU = S_IRUSR | S_IWUSR | S_IXUSR;
1703
1704 enum S_IRGRP = S_IRUSR >> 3;
1705 enum S_IWGRP = S_IWUSR >> 3;
1706 enum S_IXGRP = S_IXUSR >> 3;
1707 enum S_IRWXG = S_IRWXU >> 3;
1708
1709 enum S_IROTH = S_IRGRP >> 3;
1710 enum S_IWOTH = S_IWGRP >> 3;
1711 enum S_IXOTH = S_IXGRP >> 3;
1712 enum S_IRWXO = S_IRWXG >> 3;
1713
1714 private
1715 {
1716 extern (D) bool S_ISTYPE( mode_t mode, uint mask )
1717 {
1718 return ( mode & S_IFMT ) == mask;
1719 }
1720 }
1721
1722 extern (D) bool S_ISBLK( mode_t mode ) { return S_ISTYPE( mode, S_IFBLK ); }
1723 extern (D) bool S_ISCHR( mode_t mode ) { return S_ISTYPE( mode, S_IFCHR ); }
1724 extern (D) bool S_ISDIR( mode_t mode ) { return S_ISTYPE( mode, S_IFDIR ); }
1725 extern (D) bool S_ISFIFO( mode_t mode ) { return S_ISTYPE( mode, S_IFIFO ); }
1726 extern (D) bool S_ISREG( mode_t mode ) { return S_ISTYPE( mode, S_IFREG ); }
1727 extern (D) bool S_ISLNK( mode_t mode ) { return S_ISTYPE( mode, S_IFLNK ); }
1728 extern (D) bool S_ISSOCK( mode_t mode ) { return S_ISTYPE( mode, S_IFSOCK ); }
1729
1730 int utimensat(int dirfd, const char *pathname,
1731 ref const(timespec)[2] times, int flags);
1732 int futimens(int fd, ref const(timespec)[2] times);
1733 }
1734 else
1735 {
1736 static assert(false, "Unsupported platform");
1737 }
1738
1739 /*
1740 int chmod(const scope char*, mode_t);
1741 int fchmod(int, mode_t);
1742 int fstat(int, stat*);
1743 int lstat(const scope char*, stat*);
1744 int mkdir(const scope char*, mode_t);
1745 int mkfifo(const scope char*, mode_t);
1746 int stat(const scope char*, stat*);
1747 mode_t umask(mode_t);
1748 */
1749
1750 int chmod(const scope char*, mode_t);
1751 int fchmod(int, mode_t);
1752 //int fstat(int, stat_t*);
1753 //int lstat(const scope char*, stat_t*);
1754 int mkdir(const scope char*, mode_t);
1755 int mkfifo(const scope char*, mode_t);
1756 //int stat(const scope char*, stat_t*);
1757 mode_t umask(mode_t);
1758
1759 version (CRuntime_Glibc)
1760 {
1761 static if ( __USE_LARGEFILE64 )
1762 {
1763 int fstat64(int, stat_t*) @trusted;
1764 alias fstat64 fstat;
1765
1766 int lstat64(const scope char*, stat_t*);
1767 alias lstat64 lstat;
1768
1769 int stat64(const scope char*, stat_t*);
1770 alias stat64 stat;
1771 }
1772 else
1773 {
1774 int fstat(int, stat_t*) @trusted;
1775 int lstat(const scope char*, stat_t*);
1776 int stat(const scope char*, stat_t*);
1777 }
1778 }
1779 else version (Solaris)
1780 {
1781 version (D_LP64)
1782 {
1783 int fstat(int, stat_t*) @trusted;
1784 int lstat(const scope char*, stat_t*);
1785 int stat(const scope char*, stat_t*);
1786
1787 static if (__USE_LARGEFILE64)
1788 {
1789 alias fstat fstat64;
1790 alias lstat lstat64;
1791 alias stat stat64;
1792 }
1793 }
1794 else
1795 {
1796 static if (__USE_LARGEFILE64)
1797 {
1798 int fstat64(int, stat_t*) @trusted;
1799 alias fstat64 fstat;
1800
1801 int lstat64(const scope char*, stat_t*);
1802 alias lstat64 lstat;
1803
1804 int stat64(const scope char*, stat_t*);
1805 alias stat64 stat;
1806 }
1807 else
1808 {
1809 int fstat(int, stat_t*) @trusted;
1810 int lstat(const scope char*, stat_t*);
1811 int stat(const scope char*, stat_t*);
1812 }
1813 }
1814 }
1815 else version (Darwin)
1816 {
1817 // OS X maintains backwards compatibility with older binaries using 32-bit
1818 // inode functions by appending $INODE64 to newer 64-bit inode functions.
1819 version (OSX)
1820 {
1821 version (AArch64)
1822 {
1823 int fstat(int, stat_t*);
1824 int lstat(const scope char*, stat_t*);
1825 int stat(const scope char*, stat_t*);
1826 }
1827 else
1828 {
1829 pragma(mangle, "fstat$INODE64") int fstat(int, stat_t*);
1830 pragma(mangle, "lstat$INODE64") int lstat(const scope char*, stat_t*);
1831 pragma(mangle, "stat$INODE64") int stat(const scope char*, stat_t*);
1832 }
1833 }
1834 else
1835 {
1836 int fstat(int, stat_t*);
1837 int lstat(const scope char*, stat_t*);
1838 int stat(const scope char*, stat_t*);
1839 }
1840 }
1841 else version (FreeBSD)
1842 {
1843 version (GNU)
1844 {
1845 int fstat(int, stat_t*);
1846 int lstat(const scope char*, stat_t*);
1847 int stat(const scope char*, stat_t*);
1848 }
1849 else
1850 {
1851 static if (__FreeBSD_version >= INO64_FIRST)
1852 {
1853 pragma(mangle, "fstat@FBSD_1.5") int fstat(int, stat_t*);
1854 pragma(mangle, "lstat@FBSD_1.5") int lstat(const scope char*, stat_t*);
1855 pragma(mangle, "stat@FBSD_1.5") int stat(const scope char*, stat_t*);
1856 }
1857 else
1858 {
1859 pragma(mangle, "fstat@FBSD_1.0") int fstat(int, stat_t*);
1860 pragma(mangle, "lstat@FBSD_1.0") int lstat(const scope char*, stat_t*);
1861 pragma(mangle, "stat@FBSD_1.0") int stat(const scope char*, stat_t*);
1862 }
1863 }
1864 }
1865 else version (NetBSD)
1866 {
1867 int __fstat50(int, stat_t*);
1868 int __lstat50(const scope char*, stat_t*);
1869 int __stat50(const scope char*, stat_t*);
1870 alias __fstat50 fstat;
1871 alias __lstat50 lstat;
1872 alias __stat50 stat;
1873 }
1874 else version (OpenBSD)
1875 {
1876 int fstat(int, stat_t*);
1877 int lstat(const scope char*, stat_t*);
1878 int stat(const scope char*, stat_t*);
1879 }
1880 else version (DragonFlyBSD)
1881 {
1882 int fstat(int, stat_t*);
1883 int lstat(const scope char*, stat_t*);
1884 int stat(const scope char*, stat_t*);
1885 }
1886 else version (CRuntime_Bionic)
1887 {
1888 int fstat(int, stat_t*) @trusted;
1889 int lstat(const scope char*, stat_t*);
1890 int stat(const scope char*, stat_t*);
1891 }
1892 else version (CRuntime_Musl)
1893 {
1894 int stat(const scope char*, stat_t*);
1895 int fstat(int, stat_t*);
1896 int lstat(const scope char*, stat_t*);
1897
1898 alias fstat fstat64;
1899 alias lstat lstat64;
1900 alias stat stat64;
1901 }
1902 else version (CRuntime_UClibc)
1903 {
1904 static if ( __USE_LARGEFILE64 )
1905 {
1906 int fstat64(int, stat_t*) @trusted;
1907 alias fstat64 fstat;
1908
1909 int lstat64(const scope char*, stat_t*);
1910 alias lstat64 lstat;
1911
1912 int stat64(const scope char*, stat_t*);
1913 alias stat64 stat;
1914 }
1915 else
1916 {
1917 int fstat(int, stat_t*) @trusted;
1918 int lstat(const scope char*, stat_t*);
1919 int stat(const scope char*, stat_t*);
1920 }
1921 }
1922
1923 //
1924 // Typed Memory Objects (TYM)
1925 //
1926 /*
1927 S_TYPEISTMO(buf)
1928 */
1929
1930 //
1931 // XOpen (XSI)
1932 //
1933 /*
1934 S_IFMT
1935 S_IFBLK
1936 S_IFCHR
1937 S_IFIFO
1938 S_IFREG
1939 S_IFDIR
1940 S_IFLNK
1941 S_IFSOCK
1942 */
1943
1944 version (linux)
1945 {
1946 enum S_IFMT = 0xF000; // octal 0170000
1947 enum S_IFBLK = 0x6000; // octal 0060000
1948 enum S_IFCHR = 0x2000; // octal 0020000
1949 enum S_IFIFO = 0x1000; // octal 0010000
1950 enum S_IFREG = 0x8000; // octal 0100000
1951 enum S_IFDIR = 0x4000; // octal 0040000
1952 enum S_IFLNK = 0xA000; // octal 0120000
1953 enum S_IFSOCK = 0xC000; // octal 0140000
1954 }
1955 else version (Darwin)
1956 {
1957 enum S_IFMT = 0xF000; // octal 0170000
1958 enum S_IFBLK = 0x6000; // octal 0060000
1959 enum S_IFCHR = 0x2000; // octal 0020000
1960 enum S_IFIFO = 0x1000; // octal 0010000
1961 enum S_IFREG = 0x8000; // octal 0100000
1962 enum S_IFDIR = 0x4000; // octal 0040000
1963 enum S_IFLNK = 0xA000; // octal 0120000
1964 enum S_IFSOCK = 0xC000; // octal 0140000
1965 }
1966 else version (FreeBSD)
1967 {
1968 enum S_IFMT = 0xF000; // octal 0170000
1969 enum S_IFBLK = 0x6000; // octal 0060000
1970 enum S_IFCHR = 0x2000; // octal 0020000
1971 enum S_IFIFO = 0x1000; // octal 0010000
1972 enum S_IFREG = 0x8000; // octal 0100000
1973 enum S_IFDIR = 0x4000; // octal 0040000
1974 enum S_IFLNK = 0xA000; // octal 0120000
1975 enum S_IFSOCK = 0xC000; // octal 0140000
1976 }
1977 else version (NetBSD)
1978 {
1979 enum S_IFMT = 0xF000; // octal 0170000
1980 enum S_IFBLK = 0x6000; // octal 0060000
1981 enum S_IFCHR = 0x2000; // octal 0020000
1982 enum S_IFIFO = 0x1000; // octal 0010000
1983 enum S_IFREG = 0x8000; // octal 0100000
1984 enum S_IFDIR = 0x4000; // octal 0040000
1985 enum S_IFLNK = 0xA000; // octal 0120000
1986 enum S_IFSOCK = 0xC000; // octal 0140000
1987 }
1988 else version (OpenBSD)
1989 {
1990 enum S_IFMT = 0xF000; // octal 0170000
1991 enum S_IFBLK = 0x6000; // octal 0060000
1992 enum S_IFCHR = 0x2000; // octal 0020000
1993 enum S_IFIFO = 0x1000; // octal 0010000
1994 enum S_IFREG = 0x8000; // octal 0100000
1995 enum S_IFDIR = 0x4000; // octal 0040000
1996 enum S_IFLNK = 0xA000; // octal 0120000
1997 enum S_IFSOCK = 0xC000; // octal 0140000
1998 }
1999 else version (DragonFlyBSD)
2000 {
2001 enum S_IFMT = 0xF000; // octal 0170000
2002 enum S_IFBLK = 0x6000; // octal 0060000
2003 enum S_IFCHR = 0x2000; // octal 0020000
2004 enum S_IFIFO = 0x1000; // octal 0010000
2005 enum S_IFREG = 0x8000; // octal 0100000
2006 enum S_IFDIR = 0x4000; // octal 0040000
2007 enum S_IFLNK = 0xA000; // octal 0120000
2008 enum S_IFSOCK = 0xC000; // octal 0140000
2009 }
2010 else version (Solaris)
2011 {
2012 enum S_IFMT = 0xF000;
2013 enum S_IFBLK = 0x6000;
2014 enum S_IFCHR = 0x2000;
2015 enum S_IFIFO = 0x1000;
2016 enum S_IFREG = 0x8000;
2017 enum S_IFDIR = 0x4000;
2018 enum S_IFLNK = 0xA000;
2019 enum S_IFSOCK = 0xC000;
2020 enum S_IFDOOR = 0xD000;
2021 enum S_IFPORT = 0xE000;
2022 }
2023 else
2024 {
2025 static assert(false, "Unsupported platform");
2026 }
2027
2028 /*
2029 int mknod(const scope char*, mode_t, dev_t);
2030 */
2031
2032 version (CRuntime_Glibc)
2033 {
2034 int mknod(const scope char*, mode_t, dev_t);
2035 }
2036 else version (Darwin)
2037 {
2038 int mknod(const scope char*, mode_t, dev_t);
2039 }
2040 else version (FreeBSD)
2041 {
2042 version (GNU)
2043 {
2044 int mknod(const scope char*, mode_t, dev_t);
2045 }
2046 else
2047 {
2048 static if (__FreeBSD_version >= INO64_FIRST)
2049 pragma(mangle, "mknod@FBSD_1.5") int mknod(const scope char*, mode_t, dev_t);
2050 else
2051 pragma(mangle, "mknod@FBSD_1.0") int mknod(const scope char*, mode_t, dev_t);
2052 }
2053 }
2054 else version (NetBSD)
2055 {
2056 int mknod(const scope char*, mode_t, dev_t);
2057 }
2058 else version (OpenBSD)
2059 {
2060 int mknod(const scope char*, mode_t, dev_t);
2061 }
2062 else version (DragonFlyBSD)
2063 {
2064 int mknod(const scope char*, mode_t, dev_t);
2065 }
2066 else version (Solaris)
2067 {
2068 int mknod(const scope char*, mode_t, dev_t);
2069 }
2070 else version (CRuntime_Bionic)
2071 {
2072 int mknod(const scope char*, mode_t, dev_t);
2073 }
2074 else version (CRuntime_Musl)
2075 {
2076 int mknod(const scope char*, mode_t, dev_t);
2077 }
2078 else version (CRuntime_UClibc)
2079 {
2080 int mknod(const scope char*, mode_t, dev_t);
2081 }
2082 else
2083 {
2084 static assert(false, "Unsupported platform");
2085 }
2086