1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2014 Garrett D'Amore <garrett@damore.org>
  25  */
  26 
  27 /*      Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */
  28 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T       */
  29 /*      All Rights Reserved     */
  30 
  31 #ifndef _SYS_STAT_H
  32 #define _SYS_STAT_H
  33 
  34 #include <sys/feature_tests.h>
  35 #include <sys/types.h>
  36 
  37 #ifdef  __cplusplus
  38 extern "C" {
  39 #endif
  40 
  41 /*
  42  * The implementation specific header <sys/time_impl.h> includes a
  43  * definition for timestruc_t needed by the stat structure.  However,
  44  * including either <time.h>, which includes <sys/time_impl.h>, or
  45  * including <sys/time_impl.h> directly will break both X/Open and
  46  * POSIX namespace. Preceeding tag, structure, and structure member
  47  * names with underscores eliminates the namespace breakage and at the
  48  * same time, with unique type names, eliminates the possibility of
  49  * timespec_t or timestruct_t naming conflicts that could otherwise
  50  * result based on the order of inclusion of <sys/stat.h> and
  51  * <sys/time.h>.  The header <sys/time_std_impl.h> contains the
  52  * standards namespace safe versions of these definitions.
  53  */
  54 #if !defined(__XOPEN_OR_POSIX) || defined(__EXTENSIONS__)
  55 #include <sys/time_impl.h>
  56 #else
  57 #include <sys/time_std_impl.h>
  58 #endif /* !defined(__XOPEN_OR_POSIX) || defined(__EXTENSIONS__) */
  59 
  60 #define _ST_FSTYPSZ 16          /* array size for file system type name */
  61 
  62 /*
  63  * stat structure, used by stat(2) and fstat(2)
  64  */
  65 
  66 #if defined(_KERNEL)
  67 
  68         /* Expanded stat structure */
  69 
  70 #if defined(_LP64)
  71 
  72 struct stat {
  73         dev_t           st_dev;
  74         ino_t           st_ino;
  75         mode_t          st_mode;
  76         nlink_t         st_nlink;
  77         uid_t           st_uid;
  78         gid_t           st_gid;
  79         dev_t           st_rdev;
  80         off_t           st_size;
  81         timestruc_t     st_atim;
  82         timestruc_t     st_mtim;
  83         timestruc_t     st_ctim;
  84         blksize_t       st_blksize;
  85         blkcnt_t        st_blocks;
  86         char            st_fstype[_ST_FSTYPSZ];
  87 };
  88 
  89 struct stat64 {
  90         dev_t           st_dev;
  91         ino_t           st_ino;
  92         mode_t          st_mode;
  93         nlink_t         st_nlink;
  94         uid_t           st_uid;
  95         gid_t           st_gid;
  96         dev_t           st_rdev;
  97         off_t           st_size;
  98         timestruc_t     st_atim;
  99         timestruc_t     st_mtim;
 100         timestruc_t     st_ctim;
 101         blksize_t       st_blksize;
 102         blkcnt_t        st_blocks;
 103         char            st_fstype[_ST_FSTYPSZ];
 104 };
 105 
 106 #else   /* _LP64 */
 107 
 108 struct  stat {
 109         dev_t           st_dev;
 110         long            st_pad1[3];     /* reserve for dev expansion, */
 111                                         /* sysid definition */
 112         ino_t           st_ino;
 113         mode_t          st_mode;
 114         nlink_t         st_nlink;
 115         uid_t           st_uid;
 116         gid_t           st_gid;
 117         dev_t           st_rdev;
 118         long            st_pad2[2];
 119         off_t           st_size;
 120         long            st_pad3;        /* pad for future off_t expansion */
 121         timestruc_t     st_atim;
 122         timestruc_t     st_mtim;
 123         timestruc_t     st_ctim;
 124         blksize_t       st_blksize;
 125         blkcnt_t        st_blocks;
 126         char            st_fstype[_ST_FSTYPSZ];
 127         long            st_pad4[8];     /* expansion area */
 128 };
 129 
 130 struct  stat64 {
 131         dev_t           st_dev;
 132         long            st_pad1[3];     /* reserve for dev expansion, */
 133                                 /* sysid definition */
 134         ino64_t         st_ino;
 135         mode_t          st_mode;
 136         nlink_t         st_nlink;
 137         uid_t           st_uid;
 138         gid_t           st_gid;
 139         dev_t           st_rdev;
 140         long            st_pad2[2];
 141         off64_t         st_size;        /* large file support */
 142         timestruc_t     st_atim;
 143         timestruc_t     st_mtim;
 144         timestruc_t     st_ctim;
 145         blksize_t       st_blksize;
 146         blkcnt64_t      st_blocks;      /* large file support */
 147         char            st_fstype[_ST_FSTYPSZ];
 148         long            st_pad4[8];     /* expansion area */
 149 };
 150 
 151 #endif  /* _LP64 */
 152 
 153 #else /* !defined(_KERNEL) */
 154 
 155 /*
 156  * large file compilation environment setup
 157  */
 158 #if !defined(_LP64) && _FILE_OFFSET_BITS == 64
 159 #ifdef  __PRAGMA_REDEFINE_EXTNAME
 160 #pragma redefine_extname        fstat   fstat64
 161 #pragma redefine_extname        stat    stat64
 162 #if !defined(__XOPEN_OR_POSIX) || defined(__EXTENSIONS__) || \
 163         defined(_ATFILE_SOURCE)
 164 #pragma redefine_extname        fstatat fstatat64
 165 #endif /* defined (_ATFILE_SOURCE) */
 166 
 167 #if !defined(__XOPEN_OR_POSIX) || defined(_XPG_2) || defined(__EXTENSIONS__)
 168 #pragma redefine_extname        lstat   lstat64
 169 #endif
 170 #else   /* __PRAGMA_REDEFINE_EXTNAME */
 171 #define fstat   fstat64
 172 #define stat    stat64
 173 #if !defined(__XOPEN_OR_POSIX) || defined(__EXTENSIONS__) || \
 174         defined(_ATFILE_SOURCE)
 175 #define fstatat fstatat64
 176 #endif /* defined (_ATFILE_SOURCE) */
 177 #if !defined(__XOPEN_OR_POSIX) || defined(_XPG_2) || defined(__EXTENSIONS__)
 178 #define lstat   lstat64
 179 #endif
 180 #endif  /* __PRAGMA_REDEFINE_EXTNAME */
 181 #endif  /* !_LP64 && _FILE_OFFSET_BITS == 64 */
 182 
 183 /*
 184  * In the LP64 compilation environment, map large file interfaces
 185  * back to native versions where possible.
 186  */
 187 #if defined(_LP64) && defined(_LARGEFILE64_SOURCE)
 188 #ifdef  __PRAGMA_REDEFINE_EXTNAME
 189 #pragma redefine_extname        fstat64 fstat
 190 #pragma redefine_extname        stat64  stat
 191 #if !defined(__XOPEN_OR_POSIX) || defined(__EXTENSIONS__) || \
 192         defined(_ATFILE_SOURCE)
 193 #pragma redefine_extname        fstatat64 fstatat
 194 #endif /* defined (_ATFILE_SOURCE) */
 195 #if !defined(__XOPEN_OR_POSIX) || defined(_XPG_2) || defined(__EXTENSIONS__)
 196 #pragma redefine_extname        lstat64 lstat
 197 #endif
 198 #else   /* __PRAGMA_REDEFINE_EXTNAME */
 199 #define fstat64 fstat
 200 #define stat64  stat
 201 #if !defined(__XOPEN_OR_POSIX) || defined(__EXTENSIONS__) || \
 202         defined(_ATFILE_SOURCE)
 203 #define fstatat64       fstatat
 204 #endif /* defined (_ATFILE_SOURCE) */
 205 #if !defined(__XOPEN_OR_POSIX) || defined(_XPG_2) || defined(__EXTENSIONS__)
 206 #define lstat64 lstat
 207 #endif
 208 #endif  /* __PRAGMA_REDEFINE_EXTNAME */
 209 #endif  /* _LP64 && _LARGEFILE64_SOURCE */
 210 
 211 /*
 212  * User level stat structure definitions.
 213  */
 214 
 215 #if defined(_LP64)
 216 
 217 struct stat {
 218         dev_t           st_dev;
 219         ino_t           st_ino;
 220         mode_t          st_mode;
 221         nlink_t         st_nlink;
 222         uid_t           st_uid;
 223         gid_t           st_gid;
 224         dev_t           st_rdev;
 225         off_t           st_size;
 226 #if !defined(__XOPEN_OR_POSIX) || defined(__EXTENSIONS__)
 227         timestruc_t     st_atim;
 228         timestruc_t     st_mtim;
 229         timestruc_t     st_ctim;
 230 #else
 231         _timestruc_t    st_atim;
 232         _timestruc_t    st_mtim;
 233         _timestruc_t    st_ctim;
 234 #endif
 235         blksize_t       st_blksize;
 236         blkcnt_t        st_blocks;
 237         char            st_fstype[_ST_FSTYPSZ];
 238 };
 239 
 240 #else   /* _LP64 */
 241 
 242 struct  stat {
 243         dev_t           st_dev;
 244         long            st_pad1[3];     /* reserved for network id */
 245         ino_t           st_ino;
 246         mode_t          st_mode;
 247         nlink_t         st_nlink;
 248         uid_t           st_uid;
 249         gid_t           st_gid;
 250         dev_t           st_rdev;
 251         long            st_pad2[2];
 252         off_t           st_size;
 253 #if _FILE_OFFSET_BITS != 64
 254         long            st_pad3;        /* future off_t expansion */
 255 #endif
 256 #if !defined(__XOPEN_OR_POSIX) || defined(__EXTENSIONS__)
 257         timestruc_t     st_atim;
 258         timestruc_t     st_mtim;
 259         timestruc_t     st_ctim;
 260 #else
 261         _timestruc_t    st_atim;
 262         _timestruc_t    st_mtim;
 263         _timestruc_t    st_ctim;
 264 #endif
 265         blksize_t       st_blksize;
 266         blkcnt_t        st_blocks;
 267         char            st_fstype[_ST_FSTYPSZ];
 268         long            st_pad4[8];     /* expansion area */
 269 };
 270 
 271 #endif  /* _LP64 */
 272 
 273 /* transitional large file interface version */
 274 #if     defined(_LARGEFILE64_SOURCE) && !((_FILE_OFFSET_BITS == 64) && \
 275             !defined(__PRAGMA_REDEFINE_EXTNAME))
 276 #if defined(_LP64)
 277 
 278 struct stat64 {
 279         dev_t           st_dev;
 280         ino_t           st_ino;
 281         mode_t          st_mode;
 282         nlink_t         st_nlink;
 283         uid_t           st_uid;
 284         gid_t           st_gid;
 285         dev_t           st_rdev;
 286         off_t           st_size;
 287 #if !defined(__XOPEN_OR_POSIX) || defined(__EXTENSIONS__)
 288         timestruc_t     st_atim;
 289         timestruc_t     st_mtim;
 290         timestruc_t     st_ctim;
 291 #else
 292         _timestruc_t    st_atim;
 293         _timestruc_t    st_mtim;
 294         _timestruc_t    st_ctim;
 295 #endif
 296         blksize_t       st_blksize;
 297         blkcnt_t        st_blocks;
 298         char            st_fstype[_ST_FSTYPSZ];
 299 };
 300 
 301 #else   /* _LP64 */
 302 
 303 struct  stat64 {
 304         dev_t           st_dev;
 305         long            st_pad1[3];     /* reserved for network id */
 306         ino64_t         st_ino;
 307         mode_t          st_mode;
 308         nlink_t         st_nlink;
 309         uid_t           st_uid;
 310         gid_t           st_gid;
 311         dev_t           st_rdev;
 312         long            st_pad2[2];
 313         off64_t         st_size;
 314 #if !defined(__XOPEN_OR_POSIX) || defined(__EXTENSIONS__)
 315         timestruc_t     st_atim;
 316         timestruc_t     st_mtim;
 317         timestruc_t     st_ctim;
 318 #else
 319         _timestruc_t    st_atim;
 320         _timestruc_t    st_mtim;
 321         _timestruc_t    st_ctim;
 322 #endif
 323         blksize_t       st_blksize;
 324         blkcnt64_t      st_blocks;
 325         char            st_fstype[_ST_FSTYPSZ];
 326         long            st_pad4[8];     /* expansion area */
 327 };
 328 
 329 #endif  /* _LP64 */
 330 #endif
 331 
 332 #if !defined(__XOPEN_OR_POSIX) || defined(__EXTENSIONS__)
 333 #define st_atime        st_atim.tv_sec
 334 #define st_mtime        st_mtim.tv_sec
 335 #define st_ctime        st_ctim.tv_sec
 336 #else
 337 #define st_atime        st_atim.__tv_sec
 338 #define st_mtime        st_mtim.__tv_sec
 339 #define st_ctime        st_ctim.__tv_sec
 340 #endif /* !defined(__XOPEN_OR_POSIX) || defined(__EXTENSIONS__) */
 341 
 342 #endif /* end defined(_KERNEL) */
 343 
 344 #if defined(_SYSCALL32)
 345 
 346 /*
 347  * Kernel's view of user ILP32 stat and stat64 structures
 348  */
 349 
 350 struct stat32 {
 351         dev32_t         st_dev;
 352         int32_t         st_pad1[3];
 353         ino32_t         st_ino;
 354         mode32_t        st_mode;
 355         nlink32_t       st_nlink;
 356         uid32_t         st_uid;
 357         gid32_t         st_gid;
 358         dev32_t         st_rdev;
 359         int32_t         st_pad2[2];
 360         off32_t         st_size;
 361         int32_t         st_pad3;
 362         timestruc32_t   st_atim;
 363         timestruc32_t   st_mtim;
 364         timestruc32_t   st_ctim;
 365         int32_t         st_blksize;
 366         blkcnt32_t      st_blocks;
 367         char            st_fstype[_ST_FSTYPSZ];
 368         int32_t         st_pad4[8];
 369 };
 370 
 371 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
 372 #pragma pack(4)
 373 #endif
 374 
 375 struct stat64_32 {
 376         dev32_t         st_dev;
 377         int32_t         st_pad1[3];
 378         ino64_t         st_ino;
 379         mode32_t        st_mode;
 380         nlink32_t       st_nlink;
 381         uid32_t         st_uid;
 382         gid32_t         st_gid;
 383         dev32_t         st_rdev;
 384         int32_t         st_pad2[2];
 385         off64_t         st_size;
 386         timestruc32_t   st_atim;
 387         timestruc32_t   st_mtim;
 388         timestruc32_t   st_ctim;
 389         int32_t         st_blksize;
 390         blkcnt64_t      st_blocks;
 391         char            st_fstype[_ST_FSTYPSZ];
 392         int32_t         st_pad4[8];
 393 };
 394 
 395 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
 396 #pragma pack()
 397 #endif
 398 
 399 #endif  /* _SYSCALL32 */
 400 
 401 /* MODE MASKS */
 402 
 403 /* de facto standard definitions */
 404 
 405 #define S_IFMT          0xF000  /* type of file */
 406 #define S_IAMB          0x1FF   /* access mode bits */
 407 #define S_IFIFO         0x1000  /* fifo */
 408 #define S_IFCHR         0x2000  /* character special */
 409 #define S_IFDIR         0x4000  /* directory */
 410 /* XENIX definitions are not relevant to Solaris */
 411 #define S_IFNAM         0x5000  /* XENIX special named file */
 412 #define S_INSEM         0x1     /* XENIX semaphore subtype of IFNAM */
 413 #define S_INSHD         0x2     /* XENIX shared data subtype of IFNAM */
 414 #define S_IFBLK         0x6000  /* block special */
 415 #define S_IFREG         0x8000  /* regular */
 416 #define S_IFLNK         0xA000  /* symbolic link */
 417 #define S_IFSOCK        0xC000  /* socket */
 418 #define S_IFDOOR        0xD000  /* door */
 419 #define S_IFPORT        0xE000  /* event port */
 420 #define S_ISUID         0x800   /* set user id on execution */
 421 #define S_ISGID         0x400   /* set group id on execution */
 422 #define S_ISVTX         0x200   /* save swapped text even after use */
 423 #define S_IREAD         00400   /* read permission, owner */
 424 #define S_IWRITE        00200   /* write permission, owner */
 425 #define S_IEXEC         00100   /* execute/search permission, owner */
 426 #define S_ENFMT         S_ISGID /* record locking enforcement flag */
 427 
 428 /* the following macros are for POSIX conformance */
 429 
 430 #define S_IRWXU         00700   /* read, write, execute: owner */
 431 #define S_IRUSR         00400   /* read permission: owner */
 432 #define S_IWUSR         00200   /* write permission: owner */
 433 #define S_IXUSR         00100   /* execute permission: owner */
 434 #define S_IRWXG         00070   /* read, write, execute: group */
 435 #define S_IRGRP         00040   /* read permission: group */
 436 #define S_IWGRP         00020   /* write permission: group */
 437 #define S_IXGRP         00010   /* execute permission: group */
 438 #define S_IRWXO         00007   /* read, write, execute: other */
 439 #define S_IROTH         00004   /* read permission: other */
 440 #define S_IWOTH         00002   /* write permission: other */
 441 #define S_IXOTH         00001   /* execute permission: other */
 442 
 443 
 444 #define S_ISFIFO(mode)  (((mode)&0xF000) == 0x1000)
 445 #define S_ISCHR(mode)   (((mode)&0xF000) == 0x2000)
 446 #define S_ISDIR(mode)   (((mode)&0xF000) == 0x4000)
 447 #define S_ISBLK(mode)   (((mode)&0xF000) == 0x6000)
 448 #define S_ISREG(mode)   (((mode)&0xF000) == 0x8000)
 449 #define S_ISLNK(mode)   (((mode)&0xF000) == 0xa000)
 450 #define S_ISSOCK(mode)  (((mode)&0xF000) == 0xc000)
 451 #define S_ISDOOR(mode)  (((mode)&0xF000) == 0xd000)
 452 #define S_ISPORT(mode)  (((mode)&0xF000) == 0xe000)
 453 
 454 /* POSIX.4 macros */
 455 #define S_TYPEISMQ(_buf)        (0)
 456 #define S_TYPEISSEM(_buf)       (0)
 457 #define S_TYPEISSHM(_buf)       (0)
 458 
 459 #if defined(__i386) || (defined(__i386_COMPAT) && defined(_KERNEL))
 460 
 461 /*
 462  * A version number is included in the x86 SVR4 stat and mknod interfaces
 463  * so that SVR4 binaries can be supported.  An LP64 kernel that supports
 464  * the i386 ABI need to be aware of this too.
 465  */
 466 
 467 #define _R3_MKNOD_VER   1       /* SVR3.0 mknod */
 468 #define _MKNOD_VER      2       /* current version of mknod */
 469 #define _R3_STAT_VER    1       /* SVR3.0 stat */
 470 #define _STAT_VER       2       /* current version of stat */
 471 
 472 #endif  /* __i386 || (__i386_COMPAT && _KERNEL) */
 473 
 474 #if !defined(_KERNEL) || defined(_BOOT)
 475 
 476 #if !defined(__XOPEN_OR_POSIX) || (_POSIX_C_SOURCE > 2) || \
 477         defined(_XPG4_2) || defined(__EXTENSIONS__)
 478 extern int fchmod(int, mode_t);
 479 #endif /* !defined(__XOPEN_OR_POSIX) || (_POSIX_C_SOURCE > 2)... */
 480 
 481 extern int chmod(const char *, mode_t);
 482 extern int mkdir(const char *, mode_t);
 483 extern int mkfifo(const char *, mode_t);
 484 extern mode_t umask(mode_t);
 485 
 486 /* transitional large file interfaces */
 487 #if     defined(_LARGEFILE64_SOURCE) && !((_FILE_OFFSET_BITS == 64) && \
 488             !defined(__PRAGMA_REDEFINE_EXTNAME))
 489 extern int fstat64(int, struct stat64 *);
 490 extern int stat64(const char *_RESTRICT_KYWD, struct stat64 *_RESTRICT_KYWD);
 491 extern int lstat64(const char *_RESTRICT_KYWD, struct stat64 *_RESTRICT_KYWD);
 492 #if !defined(__XOPEN_OR_POSIX) || defined(__EXTENSIONS__) || \
 493         defined(_ATFILE_SOURCE)
 494 extern int fstatat64(int, const char *, struct stat64 *, int);
 495 #endif /* defined (_ATFILE_SOURCE) */
 496 #endif
 497 
 498 #if defined(_XPG7) || defined(_ATFILE_SOURCE)
 499 extern int mkdirat(int, const char *, mode_t);
 500 extern int mkfifoat(int, const char *, mode_t);
 501 extern int mknodat(int, const char *, mode_t, dev_t);
 502 extern int fchmodat(int, const char *, mode_t, int);
 503 #endif
 504 
 505 #if defined(_XPG7) || !defined(_STRICT_SYMBOLS)
 506 #define UTIME_NOW       -1L
 507 #define UTIME_OMIT      -2L
 508 extern int futimens(int, const struct timespec[2]);
 509 extern int utimensat(int, const char *, const struct timespec[2], int);
 510 #endif
 511 
 512 #include <sys/stat_impl.h>
 513 
 514 #endif /* !defined(_KERNEL) */
 515 
 516 #ifdef  __cplusplus
 517 }
 518 #endif
 519 
 520 #endif  /* _SYS_STAT_H */