17db96d56Sopenharmony_ci/* stat.h interface
27db96d56Sopenharmony_ci *
37db96d56Sopenharmony_ci * The module defines all S_IF*, S_I*, UF_*, SF_* and ST_* constants to
47db96d56Sopenharmony_ci * sensible default values as well as defines S_IS*() macros in order to keep
57db96d56Sopenharmony_ci * backward compatibility with the old stat.py module.
67db96d56Sopenharmony_ci *
77db96d56Sopenharmony_ci * New constants and macros such as S_IFDOOR / S_ISDOOR() are always defined
87db96d56Sopenharmony_ci * as int 0.
97db96d56Sopenharmony_ci *
107db96d56Sopenharmony_ci * NOTE: POSIX only defines the values of the S_I* permission bits.
117db96d56Sopenharmony_ci *
127db96d56Sopenharmony_ci */
137db96d56Sopenharmony_ci
147db96d56Sopenharmony_ci#define PY_SSIZE_T_CLEAN
157db96d56Sopenharmony_ci#include "Python.h"
167db96d56Sopenharmony_ci
177db96d56Sopenharmony_ci#ifdef __cplusplus
187db96d56Sopenharmony_ciextern "C" {
197db96d56Sopenharmony_ci#endif
207db96d56Sopenharmony_ci
217db96d56Sopenharmony_ci#ifdef HAVE_SYS_TYPES_H
227db96d56Sopenharmony_ci#include <sys/types.h>
237db96d56Sopenharmony_ci#endif /* HAVE_SYS_TYPES_H */
247db96d56Sopenharmony_ci
257db96d56Sopenharmony_ci#ifdef HAVE_SYS_STAT_H
267db96d56Sopenharmony_ci#include <sys/stat.h>
277db96d56Sopenharmony_ci#endif /* HAVE_SYS_STAT_H */
287db96d56Sopenharmony_ci
297db96d56Sopenharmony_ci#ifdef MS_WINDOWS
307db96d56Sopenharmony_ci#include <windows.h>
317db96d56Sopenharmony_citypedef unsigned short mode_t;
327db96d56Sopenharmony_ci
337db96d56Sopenharmony_ci/* FILE_ATTRIBUTE_INTEGRITY_STREAM and FILE_ATTRIBUTE_NO_SCRUB_DATA
347db96d56Sopenharmony_ci   are not present in VC2010, so define them manually */
357db96d56Sopenharmony_ci#ifndef FILE_ATTRIBUTE_INTEGRITY_STREAM
367db96d56Sopenharmony_ci#  define FILE_ATTRIBUTE_INTEGRITY_STREAM 0x8000
377db96d56Sopenharmony_ci#endif
387db96d56Sopenharmony_ci
397db96d56Sopenharmony_ci#ifndef FILE_ATTRIBUTE_NO_SCRUB_DATA
407db96d56Sopenharmony_ci#  define FILE_ATTRIBUTE_NO_SCRUB_DATA 0x20000
417db96d56Sopenharmony_ci#endif
427db96d56Sopenharmony_ci
437db96d56Sopenharmony_ci#ifndef IO_REPARSE_TAG_APPEXECLINK
447db96d56Sopenharmony_ci#  define IO_REPARSE_TAG_APPEXECLINK 0x8000001BL
457db96d56Sopenharmony_ci#endif
467db96d56Sopenharmony_ci
477db96d56Sopenharmony_ci#endif /* MS_WINDOWS */
487db96d56Sopenharmony_ci
497db96d56Sopenharmony_ci/* From Python's stat.py */
507db96d56Sopenharmony_ci#ifndef S_IMODE
517db96d56Sopenharmony_ci#  define S_IMODE 07777
527db96d56Sopenharmony_ci#endif
537db96d56Sopenharmony_ci
547db96d56Sopenharmony_ci/* S_IFXXX constants (file types)
557db96d56Sopenharmony_ci *
567db96d56Sopenharmony_ci * Only the names are defined by POSIX but not their value. All common file
577db96d56Sopenharmony_ci * types seems to have the same numeric value on all platforms, though.
587db96d56Sopenharmony_ci *
597db96d56Sopenharmony_ci * pyport.h guarantees S_IFMT, S_IFDIR, S_IFCHR, S_IFREG and S_IFLNK
607db96d56Sopenharmony_ci */
617db96d56Sopenharmony_ci
627db96d56Sopenharmony_ci#ifndef S_IFBLK
637db96d56Sopenharmony_ci#  define S_IFBLK 0060000
647db96d56Sopenharmony_ci#endif
657db96d56Sopenharmony_ci
667db96d56Sopenharmony_ci#ifndef S_IFIFO
677db96d56Sopenharmony_ci#  define S_IFIFO 0010000
687db96d56Sopenharmony_ci#endif
697db96d56Sopenharmony_ci
707db96d56Sopenharmony_ci#ifndef S_IFSOCK
717db96d56Sopenharmony_ci#  define S_IFSOCK 0140000
727db96d56Sopenharmony_ci#endif
737db96d56Sopenharmony_ci
747db96d56Sopenharmony_ci#ifndef S_IFDOOR
757db96d56Sopenharmony_ci#  define S_IFDOOR 0
767db96d56Sopenharmony_ci#endif
777db96d56Sopenharmony_ci
787db96d56Sopenharmony_ci#ifndef S_IFPORT
797db96d56Sopenharmony_ci#  define S_IFPORT 0
807db96d56Sopenharmony_ci#endif
817db96d56Sopenharmony_ci
827db96d56Sopenharmony_ci#ifndef S_IFWHT
837db96d56Sopenharmony_ci#  define S_IFWHT 0
847db96d56Sopenharmony_ci#endif
857db96d56Sopenharmony_ci
867db96d56Sopenharmony_ci
877db96d56Sopenharmony_ci/* S_ISXXX()
887db96d56Sopenharmony_ci * pyport.h defines S_ISDIR(), S_ISREG() and S_ISCHR()
897db96d56Sopenharmony_ci */
907db96d56Sopenharmony_ci
917db96d56Sopenharmony_ci#ifndef S_ISBLK
927db96d56Sopenharmony_ci#  define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
937db96d56Sopenharmony_ci#endif
947db96d56Sopenharmony_ci
957db96d56Sopenharmony_ci#ifndef S_ISFIFO
967db96d56Sopenharmony_ci#  define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
977db96d56Sopenharmony_ci#endif
987db96d56Sopenharmony_ci
997db96d56Sopenharmony_ci#ifndef S_ISLNK
1007db96d56Sopenharmony_ci#  define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
1017db96d56Sopenharmony_ci#endif
1027db96d56Sopenharmony_ci
1037db96d56Sopenharmony_ci#ifndef S_ISSOCK
1047db96d56Sopenharmony_ci#  define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
1057db96d56Sopenharmony_ci#endif
1067db96d56Sopenharmony_ci
1077db96d56Sopenharmony_ci#ifndef S_ISDOOR
1087db96d56Sopenharmony_ci#  define S_ISDOOR(mode) 0
1097db96d56Sopenharmony_ci#endif
1107db96d56Sopenharmony_ci
1117db96d56Sopenharmony_ci#ifndef S_ISPORT
1127db96d56Sopenharmony_ci#  define S_ISPORT(mode) 0
1137db96d56Sopenharmony_ci#endif
1147db96d56Sopenharmony_ci
1157db96d56Sopenharmony_ci#ifndef S_ISWHT
1167db96d56Sopenharmony_ci#  define S_ISWHT(mode) 0
1177db96d56Sopenharmony_ci#endif
1187db96d56Sopenharmony_ci
1197db96d56Sopenharmony_ci
1207db96d56Sopenharmony_ci/* S_I* file permission
1217db96d56Sopenharmony_ci *
1227db96d56Sopenharmony_ci * The permission bit value are defined by POSIX standards.
1237db96d56Sopenharmony_ci */
1247db96d56Sopenharmony_ci#ifndef S_ISUID
1257db96d56Sopenharmony_ci#  define S_ISUID 04000
1267db96d56Sopenharmony_ci#endif
1277db96d56Sopenharmony_ci
1287db96d56Sopenharmony_ci#ifndef S_ISGID
1297db96d56Sopenharmony_ci#  define S_ISGID 02000
1307db96d56Sopenharmony_ci#endif
1317db96d56Sopenharmony_ci
1327db96d56Sopenharmony_ci/* what is S_ENFMT? */
1337db96d56Sopenharmony_ci#ifndef S_ENFMT
1347db96d56Sopenharmony_ci#  define S_ENFMT S_ISGID
1357db96d56Sopenharmony_ci#endif
1367db96d56Sopenharmony_ci
1377db96d56Sopenharmony_ci#ifndef S_ISVTX
1387db96d56Sopenharmony_ci#  define S_ISVTX 01000
1397db96d56Sopenharmony_ci#endif
1407db96d56Sopenharmony_ci
1417db96d56Sopenharmony_ci#ifndef S_IREAD
1427db96d56Sopenharmony_ci#  define S_IREAD 00400
1437db96d56Sopenharmony_ci#endif
1447db96d56Sopenharmony_ci
1457db96d56Sopenharmony_ci#ifndef S_IWRITE
1467db96d56Sopenharmony_ci#  define S_IWRITE 00200
1477db96d56Sopenharmony_ci#endif
1487db96d56Sopenharmony_ci
1497db96d56Sopenharmony_ci#ifndef S_IEXEC
1507db96d56Sopenharmony_ci#  define S_IEXEC 00100
1517db96d56Sopenharmony_ci#endif
1527db96d56Sopenharmony_ci
1537db96d56Sopenharmony_ci#ifndef S_IRWXU
1547db96d56Sopenharmony_ci#  define S_IRWXU 00700
1557db96d56Sopenharmony_ci#endif
1567db96d56Sopenharmony_ci
1577db96d56Sopenharmony_ci#ifndef S_IRUSR
1587db96d56Sopenharmony_ci#  define S_IRUSR 00400
1597db96d56Sopenharmony_ci#endif
1607db96d56Sopenharmony_ci
1617db96d56Sopenharmony_ci#ifndef S_IWUSR
1627db96d56Sopenharmony_ci#  define S_IWUSR 00200
1637db96d56Sopenharmony_ci#endif
1647db96d56Sopenharmony_ci
1657db96d56Sopenharmony_ci#ifndef S_IXUSR
1667db96d56Sopenharmony_ci#  define S_IXUSR 00100
1677db96d56Sopenharmony_ci#endif
1687db96d56Sopenharmony_ci
1697db96d56Sopenharmony_ci#ifndef S_IRWXG
1707db96d56Sopenharmony_ci#  define S_IRWXG 00070
1717db96d56Sopenharmony_ci#endif
1727db96d56Sopenharmony_ci
1737db96d56Sopenharmony_ci#ifndef S_IRGRP
1747db96d56Sopenharmony_ci#  define S_IRGRP 00040
1757db96d56Sopenharmony_ci#endif
1767db96d56Sopenharmony_ci
1777db96d56Sopenharmony_ci#ifndef S_IWGRP
1787db96d56Sopenharmony_ci#  define S_IWGRP 00020
1797db96d56Sopenharmony_ci#endif
1807db96d56Sopenharmony_ci
1817db96d56Sopenharmony_ci#ifndef S_IXGRP
1827db96d56Sopenharmony_ci#  define S_IXGRP 00010
1837db96d56Sopenharmony_ci#endif
1847db96d56Sopenharmony_ci
1857db96d56Sopenharmony_ci#ifndef S_IRWXO
1867db96d56Sopenharmony_ci#  define S_IRWXO 00007
1877db96d56Sopenharmony_ci#endif
1887db96d56Sopenharmony_ci
1897db96d56Sopenharmony_ci#ifndef S_IROTH
1907db96d56Sopenharmony_ci#  define S_IROTH 00004
1917db96d56Sopenharmony_ci#endif
1927db96d56Sopenharmony_ci
1937db96d56Sopenharmony_ci#ifndef S_IWOTH
1947db96d56Sopenharmony_ci#  define S_IWOTH 00002
1957db96d56Sopenharmony_ci#endif
1967db96d56Sopenharmony_ci
1977db96d56Sopenharmony_ci#ifndef S_IXOTH
1987db96d56Sopenharmony_ci#  define S_IXOTH 00001
1997db96d56Sopenharmony_ci#endif
2007db96d56Sopenharmony_ci
2017db96d56Sopenharmony_ci
2027db96d56Sopenharmony_ci/* Names for file flags */
2037db96d56Sopenharmony_ci#ifndef UF_NODUMP
2047db96d56Sopenharmony_ci#  define UF_NODUMP 0x00000001
2057db96d56Sopenharmony_ci#endif
2067db96d56Sopenharmony_ci
2077db96d56Sopenharmony_ci#ifndef UF_IMMUTABLE
2087db96d56Sopenharmony_ci#  define UF_IMMUTABLE 0x00000002
2097db96d56Sopenharmony_ci#endif
2107db96d56Sopenharmony_ci
2117db96d56Sopenharmony_ci#ifndef UF_APPEND
2127db96d56Sopenharmony_ci#  define UF_APPEND 0x00000004
2137db96d56Sopenharmony_ci#endif
2147db96d56Sopenharmony_ci
2157db96d56Sopenharmony_ci#ifndef UF_OPAQUE
2167db96d56Sopenharmony_ci#  define UF_OPAQUE 0x00000008
2177db96d56Sopenharmony_ci#endif
2187db96d56Sopenharmony_ci
2197db96d56Sopenharmony_ci#ifndef UF_NOUNLINK
2207db96d56Sopenharmony_ci#  define UF_NOUNLINK 0x00000010
2217db96d56Sopenharmony_ci#endif
2227db96d56Sopenharmony_ci
2237db96d56Sopenharmony_ci#ifndef UF_COMPRESSED
2247db96d56Sopenharmony_ci#  define UF_COMPRESSED 0x00000020
2257db96d56Sopenharmony_ci#endif
2267db96d56Sopenharmony_ci
2277db96d56Sopenharmony_ci#ifndef UF_HIDDEN
2287db96d56Sopenharmony_ci#  define UF_HIDDEN 0x00008000
2297db96d56Sopenharmony_ci#endif
2307db96d56Sopenharmony_ci
2317db96d56Sopenharmony_ci#ifndef SF_ARCHIVED
2327db96d56Sopenharmony_ci#  define SF_ARCHIVED 0x00010000
2337db96d56Sopenharmony_ci#endif
2347db96d56Sopenharmony_ci
2357db96d56Sopenharmony_ci#ifndef SF_IMMUTABLE
2367db96d56Sopenharmony_ci#  define SF_IMMUTABLE 0x00020000
2377db96d56Sopenharmony_ci#endif
2387db96d56Sopenharmony_ci
2397db96d56Sopenharmony_ci#ifndef SF_APPEND
2407db96d56Sopenharmony_ci#  define SF_APPEND 0x00040000
2417db96d56Sopenharmony_ci#endif
2427db96d56Sopenharmony_ci
2437db96d56Sopenharmony_ci#ifndef SF_NOUNLINK
2447db96d56Sopenharmony_ci#  define SF_NOUNLINK 0x00100000
2457db96d56Sopenharmony_ci#endif
2467db96d56Sopenharmony_ci
2477db96d56Sopenharmony_ci#ifndef SF_SNAPSHOT
2487db96d56Sopenharmony_ci#  define SF_SNAPSHOT 0x00200000
2497db96d56Sopenharmony_ci#endif
2507db96d56Sopenharmony_ci
2517db96d56Sopenharmony_cistatic mode_t
2527db96d56Sopenharmony_ci_PyLong_AsMode_t(PyObject *op)
2537db96d56Sopenharmony_ci{
2547db96d56Sopenharmony_ci    unsigned long value;
2557db96d56Sopenharmony_ci    mode_t mode;
2567db96d56Sopenharmony_ci
2577db96d56Sopenharmony_ci    value = PyLong_AsUnsignedLong(op);
2587db96d56Sopenharmony_ci    if ((value == (unsigned long)-1) && PyErr_Occurred())
2597db96d56Sopenharmony_ci        return (mode_t)-1;
2607db96d56Sopenharmony_ci
2617db96d56Sopenharmony_ci    mode = (mode_t)value;
2627db96d56Sopenharmony_ci    if ((unsigned long)mode != value) {
2637db96d56Sopenharmony_ci        PyErr_SetString(PyExc_OverflowError, "mode out of range");
2647db96d56Sopenharmony_ci        return (mode_t)-1;
2657db96d56Sopenharmony_ci    }
2667db96d56Sopenharmony_ci    return mode;
2677db96d56Sopenharmony_ci}
2687db96d56Sopenharmony_ci
2697db96d56Sopenharmony_ci
2707db96d56Sopenharmony_ci#define stat_S_ISFUNC(isfunc, doc)                             \
2717db96d56Sopenharmony_ci    static PyObject *                                          \
2727db96d56Sopenharmony_ci    stat_ ##isfunc (PyObject *self, PyObject *omode)           \
2737db96d56Sopenharmony_ci    {                                                          \
2747db96d56Sopenharmony_ci       mode_t mode = _PyLong_AsMode_t(omode);                   \
2757db96d56Sopenharmony_ci       if ((mode == (mode_t)-1) && PyErr_Occurred())           \
2767db96d56Sopenharmony_ci           return NULL;                                        \
2777db96d56Sopenharmony_ci       return PyBool_FromLong(isfunc(mode));                   \
2787db96d56Sopenharmony_ci    }                                                          \
2797db96d56Sopenharmony_ci    PyDoc_STRVAR(stat_ ## isfunc ## _doc, doc)
2807db96d56Sopenharmony_ci
2817db96d56Sopenharmony_cistat_S_ISFUNC(S_ISDIR,
2827db96d56Sopenharmony_ci    "S_ISDIR(mode) -> bool\n\n"
2837db96d56Sopenharmony_ci    "Return True if mode is from a directory.");
2847db96d56Sopenharmony_ci
2857db96d56Sopenharmony_cistat_S_ISFUNC(S_ISCHR,
2867db96d56Sopenharmony_ci    "S_ISCHR(mode) -> bool\n\n"
2877db96d56Sopenharmony_ci    "Return True if mode is from a character special device file.");
2887db96d56Sopenharmony_ci
2897db96d56Sopenharmony_cistat_S_ISFUNC(S_ISBLK,
2907db96d56Sopenharmony_ci    "S_ISBLK(mode) -> bool\n\n"
2917db96d56Sopenharmony_ci    "Return True if mode is from a block special device file.");
2927db96d56Sopenharmony_ci
2937db96d56Sopenharmony_cistat_S_ISFUNC(S_ISREG,
2947db96d56Sopenharmony_ci    "S_ISREG(mode) -> bool\n\n"
2957db96d56Sopenharmony_ci    "Return True if mode is from a regular file.");
2967db96d56Sopenharmony_ci
2977db96d56Sopenharmony_cistat_S_ISFUNC(S_ISFIFO,
2987db96d56Sopenharmony_ci    "S_ISFIFO(mode) -> bool\n\n"
2997db96d56Sopenharmony_ci    "Return True if mode is from a FIFO (named pipe).");
3007db96d56Sopenharmony_ci
3017db96d56Sopenharmony_cistat_S_ISFUNC(S_ISLNK,
3027db96d56Sopenharmony_ci    "S_ISLNK(mode) -> bool\n\n"
3037db96d56Sopenharmony_ci    "Return True if mode is from a symbolic link.");
3047db96d56Sopenharmony_ci
3057db96d56Sopenharmony_cistat_S_ISFUNC(S_ISSOCK,
3067db96d56Sopenharmony_ci    "S_ISSOCK(mode) -> bool\n\n"
3077db96d56Sopenharmony_ci    "Return True if mode is from a socket.");
3087db96d56Sopenharmony_ci
3097db96d56Sopenharmony_cistat_S_ISFUNC(S_ISDOOR,
3107db96d56Sopenharmony_ci    "S_ISDOOR(mode) -> bool\n\n"
3117db96d56Sopenharmony_ci    "Return True if mode is from a door.");
3127db96d56Sopenharmony_ci
3137db96d56Sopenharmony_cistat_S_ISFUNC(S_ISPORT,
3147db96d56Sopenharmony_ci    "S_ISPORT(mode) -> bool\n\n"
3157db96d56Sopenharmony_ci    "Return True if mode is from an event port.");
3167db96d56Sopenharmony_ci
3177db96d56Sopenharmony_cistat_S_ISFUNC(S_ISWHT,
3187db96d56Sopenharmony_ci    "S_ISWHT(mode) -> bool\n\n"
3197db96d56Sopenharmony_ci    "Return True if mode is from a whiteout.");
3207db96d56Sopenharmony_ci
3217db96d56Sopenharmony_ci
3227db96d56Sopenharmony_ciPyDoc_STRVAR(stat_S_IMODE_doc,
3237db96d56Sopenharmony_ci"Return the portion of the file's mode that can be set by os.chmod().");
3247db96d56Sopenharmony_ci
3257db96d56Sopenharmony_cistatic PyObject *
3267db96d56Sopenharmony_cistat_S_IMODE(PyObject *self, PyObject *omode)
3277db96d56Sopenharmony_ci{
3287db96d56Sopenharmony_ci    mode_t mode = _PyLong_AsMode_t(omode);
3297db96d56Sopenharmony_ci    if ((mode == (mode_t)-1) && PyErr_Occurred())
3307db96d56Sopenharmony_ci        return NULL;
3317db96d56Sopenharmony_ci    return PyLong_FromUnsignedLong(mode & S_IMODE);
3327db96d56Sopenharmony_ci}
3337db96d56Sopenharmony_ci
3347db96d56Sopenharmony_ci
3357db96d56Sopenharmony_ciPyDoc_STRVAR(stat_S_IFMT_doc,
3367db96d56Sopenharmony_ci"Return the portion of the file's mode that describes the file type.");
3377db96d56Sopenharmony_ci
3387db96d56Sopenharmony_cistatic PyObject *
3397db96d56Sopenharmony_cistat_S_IFMT(PyObject *self, PyObject *omode)
3407db96d56Sopenharmony_ci{
3417db96d56Sopenharmony_ci    mode_t mode = _PyLong_AsMode_t(omode);
3427db96d56Sopenharmony_ci    if ((mode == (mode_t)-1) && PyErr_Occurred())
3437db96d56Sopenharmony_ci        return NULL;
3447db96d56Sopenharmony_ci    return PyLong_FromUnsignedLong(mode & S_IFMT);
3457db96d56Sopenharmony_ci}
3467db96d56Sopenharmony_ci
3477db96d56Sopenharmony_ci/* file type chars according to
3487db96d56Sopenharmony_ci   http://en.wikibooks.org/wiki/C_Programming/POSIX_Reference/sys/stat.h */
3497db96d56Sopenharmony_ci
3507db96d56Sopenharmony_cistatic char
3517db96d56Sopenharmony_cifiletype(mode_t mode)
3527db96d56Sopenharmony_ci{
3537db96d56Sopenharmony_ci    /* common cases first */
3547db96d56Sopenharmony_ci    if (S_ISREG(mode))  return '-';
3557db96d56Sopenharmony_ci    if (S_ISDIR(mode))  return 'd';
3567db96d56Sopenharmony_ci    if (S_ISLNK(mode))  return 'l';
3577db96d56Sopenharmony_ci    /* special files */
3587db96d56Sopenharmony_ci    if (S_ISBLK(mode))  return 'b';
3597db96d56Sopenharmony_ci    if (S_ISCHR(mode))  return 'c';
3607db96d56Sopenharmony_ci    if (S_ISFIFO(mode)) return 'p';
3617db96d56Sopenharmony_ci    if (S_ISSOCK(mode)) return 's';
3627db96d56Sopenharmony_ci    /* non-standard types */
3637db96d56Sopenharmony_ci    if (S_ISDOOR(mode)) return 'D';
3647db96d56Sopenharmony_ci    if (S_ISPORT(mode)) return 'P';
3657db96d56Sopenharmony_ci    if (S_ISWHT(mode))  return 'w';
3667db96d56Sopenharmony_ci    /* unknown */
3677db96d56Sopenharmony_ci    return '?';
3687db96d56Sopenharmony_ci}
3697db96d56Sopenharmony_ci
3707db96d56Sopenharmony_cistatic void
3717db96d56Sopenharmony_cifileperm(mode_t mode, char *buf)
3727db96d56Sopenharmony_ci{
3737db96d56Sopenharmony_ci    buf[0] = mode & S_IRUSR ? 'r' : '-';
3747db96d56Sopenharmony_ci    buf[1] = mode & S_IWUSR ? 'w' : '-';
3757db96d56Sopenharmony_ci    if (mode & S_ISUID) {
3767db96d56Sopenharmony_ci        buf[2] = mode & S_IXUSR ? 's' : 'S';
3777db96d56Sopenharmony_ci    } else {
3787db96d56Sopenharmony_ci        buf[2] = mode & S_IXUSR ? 'x' : '-';
3797db96d56Sopenharmony_ci    }
3807db96d56Sopenharmony_ci    buf[3] = mode & S_IRGRP ? 'r' : '-';
3817db96d56Sopenharmony_ci    buf[4] = mode & S_IWGRP ? 'w' : '-';
3827db96d56Sopenharmony_ci    if (mode & S_ISGID) {
3837db96d56Sopenharmony_ci        buf[5] = mode & S_IXGRP ? 's' : 'S';
3847db96d56Sopenharmony_ci    } else {
3857db96d56Sopenharmony_ci        buf[5] = mode & S_IXGRP ? 'x' : '-';
3867db96d56Sopenharmony_ci    }
3877db96d56Sopenharmony_ci    buf[6] = mode & S_IROTH ? 'r' : '-';
3887db96d56Sopenharmony_ci    buf[7] = mode & S_IWOTH ? 'w' : '-';
3897db96d56Sopenharmony_ci    if (mode & S_ISVTX) {
3907db96d56Sopenharmony_ci        buf[8] = mode & S_IXOTH ? 't' : 'T';
3917db96d56Sopenharmony_ci    } else {
3927db96d56Sopenharmony_ci        buf[8] = mode & S_IXOTH ? 'x' : '-';
3937db96d56Sopenharmony_ci    }
3947db96d56Sopenharmony_ci}
3957db96d56Sopenharmony_ci
3967db96d56Sopenharmony_ciPyDoc_STRVAR(stat_filemode_doc,
3977db96d56Sopenharmony_ci"Convert a file's mode to a string of the form '-rwxrwxrwx'");
3987db96d56Sopenharmony_ci
3997db96d56Sopenharmony_cistatic PyObject *
4007db96d56Sopenharmony_cistat_filemode(PyObject *self, PyObject *omode)
4017db96d56Sopenharmony_ci{
4027db96d56Sopenharmony_ci    char buf[10];
4037db96d56Sopenharmony_ci    mode_t mode;
4047db96d56Sopenharmony_ci
4057db96d56Sopenharmony_ci    mode = _PyLong_AsMode_t(omode);
4067db96d56Sopenharmony_ci    if ((mode == (mode_t)-1) && PyErr_Occurred())
4077db96d56Sopenharmony_ci        return NULL;
4087db96d56Sopenharmony_ci
4097db96d56Sopenharmony_ci    buf[0] = filetype(mode);
4107db96d56Sopenharmony_ci    fileperm(mode, &buf[1]);
4117db96d56Sopenharmony_ci    return PyUnicode_FromStringAndSize(buf, 10);
4127db96d56Sopenharmony_ci}
4137db96d56Sopenharmony_ci
4147db96d56Sopenharmony_ci
4157db96d56Sopenharmony_cistatic PyMethodDef stat_methods[] = {
4167db96d56Sopenharmony_ci    {"S_ISDIR",         stat_S_ISDIR,  METH_O, stat_S_ISDIR_doc},
4177db96d56Sopenharmony_ci    {"S_ISCHR",         stat_S_ISCHR,  METH_O, stat_S_ISCHR_doc},
4187db96d56Sopenharmony_ci    {"S_ISBLK",         stat_S_ISBLK,  METH_O, stat_S_ISBLK_doc},
4197db96d56Sopenharmony_ci    {"S_ISREG",         stat_S_ISREG,  METH_O, stat_S_ISREG_doc},
4207db96d56Sopenharmony_ci    {"S_ISFIFO",        stat_S_ISFIFO, METH_O, stat_S_ISFIFO_doc},
4217db96d56Sopenharmony_ci    {"S_ISLNK",         stat_S_ISLNK,  METH_O, stat_S_ISLNK_doc},
4227db96d56Sopenharmony_ci    {"S_ISSOCK",        stat_S_ISSOCK, METH_O, stat_S_ISSOCK_doc},
4237db96d56Sopenharmony_ci    {"S_ISDOOR",        stat_S_ISDOOR, METH_O, stat_S_ISDOOR_doc},
4247db96d56Sopenharmony_ci    {"S_ISPORT",        stat_S_ISPORT, METH_O, stat_S_ISPORT_doc},
4257db96d56Sopenharmony_ci    {"S_ISWHT",         stat_S_ISWHT,  METH_O, stat_S_ISWHT_doc},
4267db96d56Sopenharmony_ci    {"S_IMODE",         stat_S_IMODE,  METH_O, stat_S_IMODE_doc},
4277db96d56Sopenharmony_ci    {"S_IFMT",          stat_S_IFMT,   METH_O, stat_S_IFMT_doc},
4287db96d56Sopenharmony_ci    {"filemode",        stat_filemode, METH_O, stat_filemode_doc},
4297db96d56Sopenharmony_ci    {NULL,              NULL}           /* sentinel */
4307db96d56Sopenharmony_ci};
4317db96d56Sopenharmony_ci
4327db96d56Sopenharmony_ci
4337db96d56Sopenharmony_ciPyDoc_STRVAR(module_doc,
4347db96d56Sopenharmony_ci"S_IFMT_: file type bits\n\
4357db96d56Sopenharmony_ciS_IFDIR: directory\n\
4367db96d56Sopenharmony_ciS_IFCHR: character device\n\
4377db96d56Sopenharmony_ciS_IFBLK: block device\n\
4387db96d56Sopenharmony_ciS_IFREG: regular file\n\
4397db96d56Sopenharmony_ciS_IFIFO: fifo (named pipe)\n\
4407db96d56Sopenharmony_ciS_IFLNK: symbolic link\n\
4417db96d56Sopenharmony_ciS_IFSOCK: socket file\n\
4427db96d56Sopenharmony_ciS_IFDOOR: door\n\
4437db96d56Sopenharmony_ciS_IFPORT: event port\n\
4447db96d56Sopenharmony_ciS_IFWHT: whiteout\n\
4457db96d56Sopenharmony_ci\n"
4467db96d56Sopenharmony_ci
4477db96d56Sopenharmony_ci"S_ISUID: set UID bit\n\
4487db96d56Sopenharmony_ciS_ISGID: set GID bit\n\
4497db96d56Sopenharmony_ciS_ENFMT: file locking enforcement\n\
4507db96d56Sopenharmony_ciS_ISVTX: sticky bit\n\
4517db96d56Sopenharmony_ciS_IREAD: Unix V7 synonym for S_IRUSR\n\
4527db96d56Sopenharmony_ciS_IWRITE: Unix V7 synonym for S_IWUSR\n\
4537db96d56Sopenharmony_ciS_IEXEC: Unix V7 synonym for S_IXUSR\n\
4547db96d56Sopenharmony_ciS_IRWXU: mask for owner permissions\n\
4557db96d56Sopenharmony_ciS_IRUSR: read by owner\n\
4567db96d56Sopenharmony_ciS_IWUSR: write by owner\n\
4577db96d56Sopenharmony_ciS_IXUSR: execute by owner\n\
4587db96d56Sopenharmony_ciS_IRWXG: mask for group permissions\n\
4597db96d56Sopenharmony_ciS_IRGRP: read by group\n\
4607db96d56Sopenharmony_ciS_IWGRP: write by group\n\
4617db96d56Sopenharmony_ciS_IXGRP: execute by group\n\
4627db96d56Sopenharmony_ciS_IRWXO: mask for others (not in group) permissions\n\
4637db96d56Sopenharmony_ciS_IROTH: read by others\n\
4647db96d56Sopenharmony_ciS_IWOTH: write by others\n\
4657db96d56Sopenharmony_ciS_IXOTH: execute by others\n\
4667db96d56Sopenharmony_ci\n"
4677db96d56Sopenharmony_ci
4687db96d56Sopenharmony_ci"UF_NODUMP: do not dump file\n\
4697db96d56Sopenharmony_ciUF_IMMUTABLE: file may not be changed\n\
4707db96d56Sopenharmony_ciUF_APPEND: file may only be appended to\n\
4717db96d56Sopenharmony_ciUF_OPAQUE: directory is opaque when viewed through a union stack\n\
4727db96d56Sopenharmony_ciUF_NOUNLINK: file may not be renamed or deleted\n\
4737db96d56Sopenharmony_ciUF_COMPRESSED: OS X: file is hfs-compressed\n\
4747db96d56Sopenharmony_ciUF_HIDDEN: OS X: file should not be displayed\n\
4757db96d56Sopenharmony_ciSF_ARCHIVED: file may be archived\n\
4767db96d56Sopenharmony_ciSF_IMMUTABLE: file may not be changed\n\
4777db96d56Sopenharmony_ciSF_APPEND: file may only be appended to\n\
4787db96d56Sopenharmony_ciSF_NOUNLINK: file may not be renamed or deleted\n\
4797db96d56Sopenharmony_ciSF_SNAPSHOT: file is a snapshot file\n\
4807db96d56Sopenharmony_ci\n"
4817db96d56Sopenharmony_ci
4827db96d56Sopenharmony_ci"ST_MODE\n\
4837db96d56Sopenharmony_ciST_INO\n\
4847db96d56Sopenharmony_ciST_DEV\n\
4857db96d56Sopenharmony_ciST_NLINK\n\
4867db96d56Sopenharmony_ciST_UID\n\
4877db96d56Sopenharmony_ciST_GID\n\
4887db96d56Sopenharmony_ciST_SIZE\n\
4897db96d56Sopenharmony_ciST_ATIME\n\
4907db96d56Sopenharmony_ciST_MTIME\n\
4917db96d56Sopenharmony_ciST_CTIME\n\
4927db96d56Sopenharmony_ci\n"
4937db96d56Sopenharmony_ci
4947db96d56Sopenharmony_ci"FILE_ATTRIBUTE_*: Windows file attribute constants\n\
4957db96d56Sopenharmony_ci                   (only present on Windows)\n\
4967db96d56Sopenharmony_ci");
4977db96d56Sopenharmony_ci
4987db96d56Sopenharmony_ci
4997db96d56Sopenharmony_cistatic int
5007db96d56Sopenharmony_cistat_exec(PyObject *module)
5017db96d56Sopenharmony_ci{
5027db96d56Sopenharmony_ci#define ADD_INT_MACRO(module, macro)                                  \
5037db96d56Sopenharmony_ci    do {                                                              \
5047db96d56Sopenharmony_ci        if (PyModule_AddIntConstant(module, #macro, macro) < 0) {     \
5057db96d56Sopenharmony_ci            return -1;                                                \
5067db96d56Sopenharmony_ci        }                                                             \
5077db96d56Sopenharmony_ci    } while (0)
5087db96d56Sopenharmony_ci
5097db96d56Sopenharmony_ci    ADD_INT_MACRO(module, S_IFDIR);
5107db96d56Sopenharmony_ci    ADD_INT_MACRO(module, S_IFCHR);
5117db96d56Sopenharmony_ci    ADD_INT_MACRO(module, S_IFBLK);
5127db96d56Sopenharmony_ci    ADD_INT_MACRO(module, S_IFREG);
5137db96d56Sopenharmony_ci    ADD_INT_MACRO(module, S_IFIFO);
5147db96d56Sopenharmony_ci    ADD_INT_MACRO(module, S_IFLNK);
5157db96d56Sopenharmony_ci    ADD_INT_MACRO(module, S_IFSOCK);
5167db96d56Sopenharmony_ci    ADD_INT_MACRO(module, S_IFDOOR);
5177db96d56Sopenharmony_ci    ADD_INT_MACRO(module, S_IFPORT);
5187db96d56Sopenharmony_ci    ADD_INT_MACRO(module, S_IFWHT);
5197db96d56Sopenharmony_ci
5207db96d56Sopenharmony_ci    ADD_INT_MACRO(module, S_ISUID);
5217db96d56Sopenharmony_ci    ADD_INT_MACRO(module, S_ISGID);
5227db96d56Sopenharmony_ci    ADD_INT_MACRO(module, S_ISVTX);
5237db96d56Sopenharmony_ci    ADD_INT_MACRO(module, S_ENFMT);
5247db96d56Sopenharmony_ci
5257db96d56Sopenharmony_ci    ADD_INT_MACRO(module, S_IREAD);
5267db96d56Sopenharmony_ci    ADD_INT_MACRO(module, S_IWRITE);
5277db96d56Sopenharmony_ci    ADD_INT_MACRO(module, S_IEXEC);
5287db96d56Sopenharmony_ci
5297db96d56Sopenharmony_ci    ADD_INT_MACRO(module, S_IRWXU);
5307db96d56Sopenharmony_ci    ADD_INT_MACRO(module, S_IRUSR);
5317db96d56Sopenharmony_ci    ADD_INT_MACRO(module, S_IWUSR);
5327db96d56Sopenharmony_ci    ADD_INT_MACRO(module, S_IXUSR);
5337db96d56Sopenharmony_ci
5347db96d56Sopenharmony_ci    ADD_INT_MACRO(module, S_IRWXG);
5357db96d56Sopenharmony_ci    ADD_INT_MACRO(module, S_IRGRP);
5367db96d56Sopenharmony_ci    ADD_INT_MACRO(module, S_IWGRP);
5377db96d56Sopenharmony_ci    ADD_INT_MACRO(module, S_IXGRP);
5387db96d56Sopenharmony_ci
5397db96d56Sopenharmony_ci    ADD_INT_MACRO(module, S_IRWXO);
5407db96d56Sopenharmony_ci    ADD_INT_MACRO(module, S_IROTH);
5417db96d56Sopenharmony_ci    ADD_INT_MACRO(module, S_IWOTH);
5427db96d56Sopenharmony_ci    ADD_INT_MACRO(module, S_IXOTH);
5437db96d56Sopenharmony_ci
5447db96d56Sopenharmony_ci    ADD_INT_MACRO(module, UF_NODUMP);
5457db96d56Sopenharmony_ci    ADD_INT_MACRO(module, UF_IMMUTABLE);
5467db96d56Sopenharmony_ci    ADD_INT_MACRO(module, UF_APPEND);
5477db96d56Sopenharmony_ci    ADD_INT_MACRO(module, UF_OPAQUE);
5487db96d56Sopenharmony_ci    ADD_INT_MACRO(module, UF_NOUNLINK);
5497db96d56Sopenharmony_ci    ADD_INT_MACRO(module, UF_COMPRESSED);
5507db96d56Sopenharmony_ci    ADD_INT_MACRO(module, UF_HIDDEN);
5517db96d56Sopenharmony_ci    ADD_INT_MACRO(module, SF_ARCHIVED);
5527db96d56Sopenharmony_ci    ADD_INT_MACRO(module, SF_IMMUTABLE);
5537db96d56Sopenharmony_ci    ADD_INT_MACRO(module, SF_APPEND);
5547db96d56Sopenharmony_ci    ADD_INT_MACRO(module, SF_NOUNLINK);
5557db96d56Sopenharmony_ci    ADD_INT_MACRO(module, SF_SNAPSHOT);
5567db96d56Sopenharmony_ci
5577db96d56Sopenharmony_ci    const char* st_constants[] = {
5587db96d56Sopenharmony_ci        "ST_MODE",
5597db96d56Sopenharmony_ci        "ST_INO",
5607db96d56Sopenharmony_ci        "ST_DEV",
5617db96d56Sopenharmony_ci        "ST_NLINK",
5627db96d56Sopenharmony_ci        "ST_UID",
5637db96d56Sopenharmony_ci        "ST_GID",
5647db96d56Sopenharmony_ci        "ST_SIZE",
5657db96d56Sopenharmony_ci        "ST_ATIME",
5667db96d56Sopenharmony_ci        "ST_MTIME",
5677db96d56Sopenharmony_ci        "ST_CTIME"
5687db96d56Sopenharmony_ci    };
5697db96d56Sopenharmony_ci
5707db96d56Sopenharmony_ci    for (int i = 0; i < (int)Py_ARRAY_LENGTH(st_constants); i++) {
5717db96d56Sopenharmony_ci        if (PyModule_AddIntConstant(module, st_constants[i], i) < 0) {
5727db96d56Sopenharmony_ci            return -1;
5737db96d56Sopenharmony_ci        }
5747db96d56Sopenharmony_ci    }
5757db96d56Sopenharmony_ci
5767db96d56Sopenharmony_ci#ifdef MS_WINDOWS
5777db96d56Sopenharmony_ci    ADD_INT_MACRO(module, FILE_ATTRIBUTE_ARCHIVE);
5787db96d56Sopenharmony_ci    ADD_INT_MACRO(module, FILE_ATTRIBUTE_COMPRESSED);
5797db96d56Sopenharmony_ci    ADD_INT_MACRO(module, FILE_ATTRIBUTE_DEVICE);
5807db96d56Sopenharmony_ci    ADD_INT_MACRO(module, FILE_ATTRIBUTE_DIRECTORY);
5817db96d56Sopenharmony_ci    ADD_INT_MACRO(module, FILE_ATTRIBUTE_ENCRYPTED);
5827db96d56Sopenharmony_ci    ADD_INT_MACRO(module, FILE_ATTRIBUTE_HIDDEN);
5837db96d56Sopenharmony_ci    ADD_INT_MACRO(module, FILE_ATTRIBUTE_INTEGRITY_STREAM);
5847db96d56Sopenharmony_ci    ADD_INT_MACRO(module, FILE_ATTRIBUTE_NORMAL);
5857db96d56Sopenharmony_ci    ADD_INT_MACRO(module, FILE_ATTRIBUTE_NOT_CONTENT_INDEXED);
5867db96d56Sopenharmony_ci    ADD_INT_MACRO(module, FILE_ATTRIBUTE_NO_SCRUB_DATA);
5877db96d56Sopenharmony_ci    ADD_INT_MACRO(module, FILE_ATTRIBUTE_OFFLINE);
5887db96d56Sopenharmony_ci    ADD_INT_MACRO(module, FILE_ATTRIBUTE_READONLY);
5897db96d56Sopenharmony_ci    ADD_INT_MACRO(module, FILE_ATTRIBUTE_REPARSE_POINT);
5907db96d56Sopenharmony_ci    ADD_INT_MACRO(module, FILE_ATTRIBUTE_SPARSE_FILE);
5917db96d56Sopenharmony_ci    ADD_INT_MACRO(module, FILE_ATTRIBUTE_SYSTEM);
5927db96d56Sopenharmony_ci    ADD_INT_MACRO(module, FILE_ATTRIBUTE_TEMPORARY);
5937db96d56Sopenharmony_ci    ADD_INT_MACRO(module, FILE_ATTRIBUTE_VIRTUAL);
5947db96d56Sopenharmony_ci
5957db96d56Sopenharmony_ci    if (PyModule_AddObject(module, "IO_REPARSE_TAG_SYMLINK",
5967db96d56Sopenharmony_ci                           PyLong_FromUnsignedLong(IO_REPARSE_TAG_SYMLINK)) < 0) {
5977db96d56Sopenharmony_ci            return -1;
5987db96d56Sopenharmony_ci    }
5997db96d56Sopenharmony_ci    if (PyModule_AddObject(module, "IO_REPARSE_TAG_MOUNT_POINT",
6007db96d56Sopenharmony_ci                           PyLong_FromUnsignedLong(IO_REPARSE_TAG_MOUNT_POINT)) < 0) {
6017db96d56Sopenharmony_ci            return -1;
6027db96d56Sopenharmony_ci    }
6037db96d56Sopenharmony_ci    if (PyModule_AddObject(module, "IO_REPARSE_TAG_APPEXECLINK",
6047db96d56Sopenharmony_ci                           PyLong_FromUnsignedLong(IO_REPARSE_TAG_APPEXECLINK)) < 0) {
6057db96d56Sopenharmony_ci            return -1;
6067db96d56Sopenharmony_ci    }
6077db96d56Sopenharmony_ci#endif
6087db96d56Sopenharmony_ci
6097db96d56Sopenharmony_ci    return 0;
6107db96d56Sopenharmony_ci}
6117db96d56Sopenharmony_ci
6127db96d56Sopenharmony_ci
6137db96d56Sopenharmony_cistatic PyModuleDef_Slot stat_slots[] = {
6147db96d56Sopenharmony_ci    {Py_mod_exec, stat_exec},
6157db96d56Sopenharmony_ci    {0, NULL}
6167db96d56Sopenharmony_ci};
6177db96d56Sopenharmony_ci
6187db96d56Sopenharmony_ci
6197db96d56Sopenharmony_cistatic struct PyModuleDef statmodule = {
6207db96d56Sopenharmony_ci    PyModuleDef_HEAD_INIT,
6217db96d56Sopenharmony_ci    .m_name = "_stat",
6227db96d56Sopenharmony_ci    .m_doc = module_doc,
6237db96d56Sopenharmony_ci    .m_size = 0,
6247db96d56Sopenharmony_ci    .m_methods = stat_methods,
6257db96d56Sopenharmony_ci    .m_slots = stat_slots,
6267db96d56Sopenharmony_ci};
6277db96d56Sopenharmony_ci
6287db96d56Sopenharmony_ci
6297db96d56Sopenharmony_ciPyMODINIT_FUNC
6307db96d56Sopenharmony_ciPyInit__stat(void)
6317db96d56Sopenharmony_ci{
6327db96d56Sopenharmony_ci    return PyModuleDef_Init(&statmodule);
6337db96d56Sopenharmony_ci}
6347db96d56Sopenharmony_ci
6357db96d56Sopenharmony_ci#ifdef __cplusplus
6367db96d56Sopenharmony_ci}
6377db96d56Sopenharmony_ci#endif
638