1 /**
2  * D header file for POSIX.
3  *
4  * Copyright: Public Domain
5  * License:   Public Domain
6  * Authors:   Sean Kelly
7  * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
8  */
9 module tango.stdc.posix.sys.stat;
10 
11 private import tango.stdc.posix.config;
12 private import tango.stdc.stdint;
13 private import tango.stdc.posix.time;     // for timespec
14 public import tango.stdc.stddef;          // for size_t
15 public import tango.stdc.posix.sys.types; // for off_t, mode_t
16 private import tango.core.Octal;
17 
18 extern (C):
19 
20 //
21 // Required
22 //
23 /*
24 struct stat
25 {
26     dev_t   st_dev;
27     ino_t   st_ino;
28     mode_t  st_mode;
29     nlink_t st_nlink;
30     uid_t   st_uid;
31     gid_t   st_gid;
32     off_t   st_size;
33     time_t  st_atime;
34     time_t  st_mtime;
35     time_t  st_ctime;
36 }
37 
38 S_IRWXU
39     S_IRUSR
40     S_IWUSR
41     S_IXUSR
42 S_IRWXG
43     S_IRGRP
44     S_IWGRP
45     S_IXGRP
46 S_IRWXO
47     S_IROTH
48     S_IWOTH
49     S_IXOTH
50 S_ISUID
51 S_ISGID
52 S_ISVTX
53 
54 S_ISBLK(m)
55 S_ISCHR(m)
56 S_ISDIR(m)
57 S_ISFIFO(m)
58 S_ISREG(m)
59 S_ISLNK(m)
60 S_ISSOCK(m)
61 
62 S_TYPEISMQ(buf)
63 S_TYPEISSEM(buf)
64 S_TYPEISSHM(buf)
65 
66 int    chmod(in char*, mode_t);
67 int    fchmod(int, mode_t);
68 int    fstat(int, stat*);
69 int    lstat(in char*, stat*);
70 int    mkdir(in char*, mode_t);
71 int    mkfifo(in char*, mode_t);
72 int    stat(in char*, stat*);
73 mode_t umask(mode_t);
74 */
75 
76 version( linux )
77 {
78     static if( __USE_LARGEFILE64 )
79     {
80         private alias uint _pad_t;
81     }
82     else
83     {
84         private alias ushort _pad_t;
85     }
86 
87     align (4) struct stat_t
88     {
89         dev_t       st_dev;             /* Device.  */
90       version (X86_64) {} else {
91         _pad_t      __pad1;
92       }
93       static if( __USE_LARGEFILE64 )
94       {
95         ino_t      __st_ino;            /* 32bit file serial number.    */
96       }
97       else
98       {
99         ino_t       st_ino;             /* File serial number.  */
100       }
101       version (X86_64) {
102         nlink_t     st_nlink;
103         mode_t      st_mode;
104       } else {
105         mode_t      st_mode;            /* File mode.  */
106         nlink_t     st_nlink;           /* Link count.  */
107       }
108         uid_t       st_uid;             /* User ID of the file's owner. */
109         gid_t       st_gid;             /* Group ID of the file's group.*/
110       version (X86_64) {
111         int         pad0;
112         dev_t       st_rdev;
113       } else {
114         dev_t       st_rdev;            /* Device number, if device.  */
115         _pad_t      __pad2;
116       }
117         off_t       st_size;            /* Size of file, in bytes.  */
118         blksize_t   st_blksize;         /* Optimal block size for I/O.  */
119         blkcnt_t    st_blocks;          /* Number 512-byte blocks allocated. */
120       static if( false /*__USE_MISC*/ ) // true if _BSD_SOURCE || _SVID_SOURCE
121       {
122         timespec    st_atim;
123         timespec    st_mtim;
124         timespec    st_ctim;
125         alias st_atim.tv_sec st_atime;
126         alias st_mtim.tv_sec st_mtime;
127         alias st_ctim.tv_sec st_ctime;
128       }
129       else
130       {
131         time_t      st_atime;
132         c_ulong     st_atimensec;
133         time_t      st_mtime;
134         c_ulong     st_mtimensec;
135         time_t      st_ctime;
136         c_ulong     st_ctimensec;
137       }
138       version (X86_64) {
139         c_long[3]  __unused;
140       }
141       else static if( __USE_LARGEFILE64 )
142       {
143         ino64_t     st_ino;             /* File serial number.  */
144       }
145       else
146       {
147         c_ulong     __unused4;
148         c_ulong     __unused5;
149       }
150     }
151 
152     const S_IRUSR   = octal!(400);
153     const S_IWUSR   = octal!(200);
154     const S_IXUSR   = octal!(100);
155     const S_IRWXU   = S_IRUSR | S_IWUSR | S_IXUSR;
156 
157     const S_IRGRP   = S_IRUSR >> 3;
158     const S_IWGRP   = S_IWUSR >> 3;
159     const S_IXGRP   = S_IXUSR >> 3;
160     const S_IRWXG   = S_IRWXU >> 3;
161 
162     const S_IROTH   = S_IRGRP >> 3;
163     const S_IWOTH   = S_IWGRP >> 3;
164     const S_IXOTH   = S_IXGRP >> 3;
165     const S_IRWXO   = S_IRWXG >> 3;
166 
167     const S_ISUID   = octal!(4000);
168     const S_ISGID   = octal!(2000);
169     const S_ISVTX   = octal!(1000);
170 
171     private
172     {
173         extern (D) bool S_ISTYPE( mode_t mode, uint mask )
174         {
175             return ( mode & S_IFMT ) == mask;
176         }
177     }
178 
179     extern (D) bool S_ISBLK( mode_t mode )  { return S_ISTYPE( mode, S_IFBLK );  }
180     extern (D) bool S_ISCHR( mode_t mode )  { return S_ISTYPE( mode, S_IFCHR );  }
181     extern (D) bool S_ISDIR( mode_t mode )  { return S_ISTYPE( mode, S_IFDIR );  }
182     extern (D) bool S_ISFIFO( mode_t mode ) { return S_ISTYPE( mode, S_IFIFO );  }
183     extern (D) bool S_ISREG( mode_t mode )  { return S_ISTYPE( mode, S_IFREG );  }
184     extern (D) bool S_ISLNK( mode_t mode )  { return S_ISTYPE( mode, S_IFLNK );  }
185     extern (D) bool S_ISSOCK( mode_t mode ) { return S_ISTYPE( mode, S_IFSOCK ); }
186 
187     static if( true /*__USE_POSIX199309*/ )
188     {
189         extern bool S_TYPEISMQ( stat_t* buf )  { return false; }
190         extern bool S_TYPEISSEM( stat_t* buf ) { return false; }
191         extern bool S_TYPEISSHM( stat_t* buf ) { return false; }
192     }
193 }
194 else version(OSX)
195 {
196     struct stat_t
197     {
198         dev_t       st_dev;
199         ino_t       st_ino;
200         mode_t      st_mode;
201         nlink_t     st_nlink;
202         uid_t       st_uid;
203         gid_t       st_gid;
204         dev_t       st_rdev;
205         time_t      st_atime;
206         c_ulong     st_atimensec;
207         time_t      st_mtime;
208         c_ulong     st_mtimensec;
209         time_t      st_ctime;
210         c_ulong     st_ctimensec;
211         off_t       st_size;
212         blkcnt_t    st_blocks;
213         blksize_t   st_blksize;
214         uint        st_flags;
215         uint        st_gen;
216         int         st_lspare;
217         long[2]     st_qspare;
218     }
219 
220     const S_IRUSR   = octal!(400);
221     const S_IWUSR   = octal!(200);
222     const S_IXUSR   = octal!(100);
223     const S_IRWXU   = S_IRUSR | S_IWUSR | S_IXUSR;
224 
225     const S_IRGRP   = S_IRUSR >> 3;
226     const S_IWGRP   = S_IWUSR >> 3;
227     const S_IXGRP   = S_IXUSR >> 3;
228     const S_IRWXG   = S_IRWXU >> 3;
229 
230     const S_IROTH   = S_IRGRP >> 3;
231     const S_IWOTH   = S_IWGRP >> 3;
232     const S_IXOTH   = S_IXGRP >> 3;
233     const S_IRWXO   = S_IRWXG >> 3;
234 
235     const S_ISUID   = octal!(4000);
236     const S_ISGID   = octal!(2000);
237     const S_ISVTX   = octal!(1000);
238 
239     private
240     {
241         extern (D) bool S_ISTYPE( mode_t mode, uint mask )
242         {
243             return ( mode & S_IFMT ) == mask;
244         }
245     }
246 
247     extern (D) bool S_ISBLK( mode_t mode )  { return S_ISTYPE( mode, S_IFBLK );  }
248     extern (D) bool S_ISCHR( mode_t mode )  { return S_ISTYPE( mode, S_IFCHR );  }
249     extern (D) bool S_ISDIR( mode_t mode )  { return S_ISTYPE( mode, S_IFDIR );  }
250     extern (D) bool S_ISFIFO( mode_t mode ) { return S_ISTYPE( mode, S_IFIFO );  }
251     extern (D) bool S_ISREG( mode_t mode )  { return S_ISTYPE( mode, S_IFREG );  }
252     extern (D) bool S_ISLNK( mode_t mode )  { return S_ISTYPE( mode, S_IFLNK );  }
253     extern (D) bool S_ISSOCK( mode_t mode ) { return S_ISTYPE( mode, S_IFSOCK ); }
254 }
255 else version( FreeBSD )
256 {
257     struct stat_t
258     {
259         dev_t   st_dev;
260         ino_t   st_ino;
261         mode_t  st_mode;
262         nlink_t st_nlink;
263         uid_t   st_uid;
264         gid_t   st_gid;
265         dev_t   st_rdev;
266         time_t  st_atime;
267         c_ulong st_atimensec;
268         time_t  st_mtime;
269         c_ulong st_mtimensec;
270         time_t  st_ctime;
271         c_ulong st_ctimensec;
272     /*  Defined in C as:
273         timespec    st_atimespec;
274         timespec    st_mtimespec;
275         timespec    st_ctimespec; */
276         off_t       st_size;
277         blkcnt_t    st_blocks;
278         blksize_t   st_blksize;
279         fflags_t    st_flags;
280         uint        st_gen;
281         int         st_lspare;
282         timespec    st_birthtimespec;
283 
284         byte[16 - timespec.sizeof] padding;
285     }
286 
287     const S_IRUSR   = octal!(400);
288     const S_IWUSR   = octal!(200);
289     const S_IXUSR   = octal!(100);
290     const S_IRWXU   = octal!(700);
291 
292     const S_IRGRP   = octal!(40);
293     const S_IWGRP   = octal!(20);
294     const S_IXGRP   = octal!(10);
295     const S_IRWXG   = octal!(70);
296 
297     const S_IROTH   = octal!(4);
298     const S_IWOTH   = octal!(2);
299     const S_IXOTH   = octal!(1);
300     const S_IRWXO   = octal!(7);
301 
302     const S_ISUID   = octal!(4000);
303     const S_ISGID   = octal!(2000);
304     const S_ISVTX   = octal!(1000);
305 
306     private
307     {
308         extern (D) bool S_ISTYPE( mode_t mode, uint mask )
309         {
310             return ( mode & S_IFMT ) == mask;
311         }
312     }
313 
314     extern (D) bool S_ISBLK( mode_t mode )  { return S_ISTYPE( mode, S_IFBLK );  }
315     extern (D) bool S_ISCHR( mode_t mode )  { return S_ISTYPE( mode, S_IFCHR );  }
316     extern (D) bool S_ISDIR( mode_t mode )  { return S_ISTYPE( mode, S_IFDIR );  }
317     extern (D) bool S_ISFIFO( mode_t mode ) { return S_ISTYPE( mode, S_IFIFO );  }
318     extern (D) bool S_ISREG( mode_t mode )  { return S_ISTYPE( mode, S_IFREG );  }
319     extern (D) bool S_ISLNK( mode_t mode )  { return S_ISTYPE( mode, S_IFLNK );  }
320     extern (D) bool S_ISSOCK( mode_t mode ) { return S_ISTYPE( mode, S_IFSOCK ); }
321 }
322 else version( solaris )
323 {
324     const _ST_FSTYPSZ = 16;     /* array size for file system type name */
325     
326     struct stat_t
327     {
328         version (X86_64)
329         {
330             dev_t               st_dev;
331             ino_t               st_ino;
332             mode_t              st_mode;
333             nlink_t             st_nlink;
334             uid_t               st_uid;
335             gid_t               st_gid;
336             dev_t               st_rdev;
337             off_t               st_size;
338             
339             time_t              st_atime;
340             c_ulong             st_atimensec;
341             time_t              st_mtime;
342             c_ulong             st_mtimensec;
343             time_t              st_ctime;
344             c_ulong             st_ctimensec;
345         /*  Defined in C as:
346             timespec            st_atim;
347             timespec            st_mtim;
348             timespec            st_ctim; */
349             blksize_t           st_blksize;
350             blkcnt_t            st_blocks;
351             char[_ST_FSTYPSZ]   st_fstype;
352         }
353         else
354         {
355             dev_t               st_dev;
356             c_long[3]           st_pad1;    /* reserved for network id */
357             ino_t               st_ino;
358             mode_t              st_mode;
359             nlink_t             st_nlink;
360             uid_t               st_uid;
361             gid_t               st_gid;
362             dev_t               st_rdev;
363             c_long[2]           st_pad2;
364             off_t               st_size;
365           static if( !__USE_LARGEFILE64 ) {
366             c_long              st_pad3;    /* future off_t expansion */
367           } 
368             time_t              st_atime;
369             c_ulong             st_atimensec;
370             time_t              st_mtime;
371             c_ulong             st_mtimensec;
372             time_t              st_ctime;
373             c_ulong             st_ctimensec;
374         /*  Defined in C as:
375             timespec            st_atim;
376             timespec            st_mtim;
377             timespec            st_ctim; */
378             blksize_t           st_blksize;
379             blkcnt_t            st_blocks;
380             char[_ST_FSTYPSZ]   st_fstype;
381             c_long[8]           st_pad4;    /* expansion area */
382         }
383     }
384     
385     /* MODE MASKS */
386   enum {
387     /* de facto standard definitions */
388     S_IFMT      = 0xF000,   /* type of file */
389     S_IAMB      = 0x1FF,    /* access mode bits */
390     S_IFIFO     = 0x1000,   /* fifo */
391     S_IFCHR     = 0x2000,   /* character special */
392     S_IFDIR     = 0x4000,   /* directory */
393     /* XENIX definitions are not relevant to Solaris */
394     S_IFNAM     = 0x5000,   /* XENIX special named file */
395     S_INSEM     = 0x1,      /* XENIX semaphore subtype of IFNAM */
396     S_INSHD     = 0x2,      /* XENIX shared data subtype of IFNAM */
397     S_IFBLK     = 0x6000,   /* block special */
398     S_IFREG     = 0x8000,   /* regular */
399     S_IFLNK     = 0xA000,   /* symbolic link */
400     S_IFSOCK    = 0xC000,   /* socket */
401     S_IFDOOR    = 0xD000,   /* door */
402     S_IFPORT    = 0xE000,   /* event port */
403     S_ISUID     = 0x800,    /* set user id on execution */
404     S_ISGID     = 0x400,    /* set group id on execution */
405     S_ISVTX     = 0x200,    /* save swapped text even after use */
406     S_IREAD     = octal!(400),    /* read permission, owner */
407     S_IWRITE    = octal!(200),    /* write permission, owner */
408     S_IEXEC     = octal!(100),    /* execute/search permission, owner */
409     S_ENFMT     = S_ISGID,  /* record locking enforcement flag */
410 
411     S_IRWXU     = octal!(700),    /* read, write, execute: owner */
412     S_IRUSR     = octal!(400),    /* read permission: owner */
413     S_IWUSR     = octal!(200),    /* write permission: owner */
414     S_IXUSR     = octal!(100),    /* execute permission: owner */
415     S_IRWXG     = octal!(70),    /* read, write, execute: group */
416     S_IRGRP     = octal!(40),    /* read permission: group */
417     S_IWGRP     = octal!(20),    /* write permission: group */
418     S_IXGRP     = octal!(10),    /* execute permission: group */
419     S_IRWXO     = octal!(7),    /* read, write, execute: other */
420     S_IROTH     = octal!(4),    /* read permission: other */
421     S_IWOTH     = octal!(2),    /* write permission: other */
422     S_IXOTH     = octal!(1)     /* execute permission: other */
423   }
424 
425     extern (D) bool S_ISFIFO(mode_t mode)   { return (mode & 0xF000) == 0x1000; }
426     extern (D) bool S_ISCHR(mode_t mode)    { return (mode & 0xF000) == 0x2000; }
427     extern (D) bool S_ISDIR(mode_t mode)    { return (mode & 0xF000) == 0x4000; }
428     extern (D) bool S_ISBLK(mode_t mode)    { return (mode & 0xF000) == 0x6000; }
429     extern (D) bool S_ISREG(mode_t mode)    { return (mode & 0xF000) == 0x8000; }
430     extern (D) bool S_ISLNK(mode_t mode)    { return (mode & 0xF000) == 0xa000; }
431     extern (D) bool S_ISSOCK(mode_t mode)   { return (mode & 0xF000) == 0xc000; }
432     extern (D) bool S_ISDOOR(mode_t mode)   { return (mode & 0xF000) == 0xd000; }
433     extern (D) bool S_ISPORT(mode_t mode)   { return (mode & 0xF000) == 0xe000; }
434 
435 }
436 
437 int    chmod(in char*, mode_t);
438 int    fchmod(int, mode_t);
439 //int    fstat(int, stat_t*);
440 //int    lstat(in char*, stat_t*);
441 int    mkdir(in char*, mode_t);
442 int    mkfifo(in char*, mode_t);
443 //int    stat(in char*, stat_t*);
444 mode_t umask(mode_t);
445 
446 static if (__USE_LARGEFILE64)
447 {
448     int   fstat64(int, stat_t*);
449     alias fstat64 fstat;
450 
451     int   lstat64(in char*, stat_t*);
452     alias lstat64 lstat;
453 
454     int   stat64(in char*, stat_t*);
455     alias stat64 stat;
456 }
457 else
458 {
459     int   fstat(int, stat_t*);
460     int   lstat(in char*, stat_t*);
461     int   stat(in char*, stat_t*);
462 }
463 
464 //
465 // Typed Memory Objects (TYM)
466 //
467 /*
468 S_TYPEISTMO(buf)
469 */
470 
471 //
472 // XOpen (XSI)
473 //
474 /*
475 S_IFMT
476 S_IFBLK
477 S_IFCHR
478 S_IFIFO
479 S_IFREG
480 S_IFDIR
481 S_IFLNK
482 S_IFSOCK
483 
484 int mknod(in 3char*, mode_t, dev_t);
485 */
486 
487 version( linux )
488 {
489     const S_IFMT    = octal!(170000);
490     const S_IFBLK   = octal!(60000);
491     const S_IFCHR   = octal!(20000);
492     const S_IFIFO   = octal!(10000);
493     const S_IFREG   = octal!(100000);
494     const S_IFDIR   = octal!(40000);
495     const S_IFLNK   = octal!(120000);
496     const S_IFSOCK  = octal!(140000);
497 
498     int mknod(in char*, mode_t, dev_t);
499 }
500 else version(OSX)
501 {
502     const S_IFMT    = octal!(170000);
503     const S_IFBLK   = octal!(60000);
504     const S_IFCHR   = octal!(20000);
505     const S_IFIFO   = octal!(10000);
506     const S_IFREG   = octal!(100000);
507     const S_IFDIR   = octal!(40000);
508     const S_IFLNK   = octal!(120000);
509     const S_IFSOCK  = octal!(140000);
510 
511     int mknod(in char*, mode_t, dev_t);
512 }
513 else version( FreeBSD )
514 {
515     const S_IFMT    = octal!(170000);
516     const S_IFBLK   = octal!(60000);
517     const S_IFCHR   = octal!(20000);
518     const S_IFIFO   = octal!(10000);
519     const S_IFREG   = octal!(100000);
520     const S_IFDIR   = octal!(40000);
521     const S_IFLNK   = octal!(120000);
522     const S_IFSOCK  = octal!(140000);
523 
524     int mknod(in char*, mode_t, dev_t);
525 }
526 else version( solaris )
527 {
528     // Constants defined above
529     int mknod(in char*, mode_t, dev_t);
530 }