Branch data Line data Source code
1 : : /* stat.h interface
2 : : *
3 : : * The module defines all S_IF*, S_I*, UF_*, SF_* and ST_* constants to
4 : : * sensible default values as well as defines S_IS*() macros in order to keep
5 : : * backward compatibility with the old stat.py module.
6 : : *
7 : : * New constants and macros such as S_IFDOOR / S_ISDOOR() are always defined
8 : : * as int 0.
9 : : *
10 : : * NOTE: POSIX only defines the values of the S_I* permission bits.
11 : : *
12 : : */
13 : :
14 : : #define PY_SSIZE_T_CLEAN
15 : : #include "Python.h"
16 : :
17 : : #ifdef __cplusplus
18 : : extern "C" {
19 : : #endif
20 : :
21 : : #ifdef HAVE_SYS_TYPES_H
22 : : #include <sys/types.h>
23 : : #endif /* HAVE_SYS_TYPES_H */
24 : :
25 : : #ifdef HAVE_SYS_STAT_H
26 : : #include <sys/stat.h>
27 : : #endif /* HAVE_SYS_STAT_H */
28 : :
29 : : #ifdef MS_WINDOWS
30 : : #include <windows.h>
31 : : typedef unsigned short mode_t;
32 : :
33 : : /* FILE_ATTRIBUTE_INTEGRITY_STREAM and FILE_ATTRIBUTE_NO_SCRUB_DATA
34 : : are not present in VC2010, so define them manually */
35 : : #ifndef FILE_ATTRIBUTE_INTEGRITY_STREAM
36 : : # define FILE_ATTRIBUTE_INTEGRITY_STREAM 0x8000
37 : : #endif
38 : :
39 : : #ifndef FILE_ATTRIBUTE_NO_SCRUB_DATA
40 : : # define FILE_ATTRIBUTE_NO_SCRUB_DATA 0x20000
41 : : #endif
42 : :
43 : : #ifndef IO_REPARSE_TAG_APPEXECLINK
44 : : # define IO_REPARSE_TAG_APPEXECLINK 0x8000001BL
45 : : #endif
46 : :
47 : : #endif /* MS_WINDOWS */
48 : :
49 : : /* From Python's stat.py */
50 : : #ifndef S_IMODE
51 : : # define S_IMODE 07777
52 : : #endif
53 : :
54 : : /* S_IFXXX constants (file types)
55 : : *
56 : : * Only the names are defined by POSIX but not their value. All common file
57 : : * types seems to have the same numeric value on all platforms, though.
58 : : *
59 : : * pyport.h guarantees S_IFMT, S_IFDIR, S_IFCHR, S_IFREG and S_IFLNK
60 : : */
61 : :
62 : : #ifndef S_IFBLK
63 : : # define S_IFBLK 0060000
64 : : #endif
65 : :
66 : : #ifndef S_IFIFO
67 : : # define S_IFIFO 0010000
68 : : #endif
69 : :
70 : : #ifndef S_IFSOCK
71 : : # define S_IFSOCK 0140000
72 : : #endif
73 : :
74 : : #ifndef S_IFDOOR
75 : : # define S_IFDOOR 0
76 : : #endif
77 : :
78 : : #ifndef S_IFPORT
79 : : # define S_IFPORT 0
80 : : #endif
81 : :
82 : : #ifndef S_IFWHT
83 : : # define S_IFWHT 0
84 : : #endif
85 : :
86 : :
87 : : /* S_ISXXX()
88 : : * pyport.h defines S_ISDIR(), S_ISREG() and S_ISCHR()
89 : : */
90 : :
91 : : #ifndef S_ISBLK
92 : : # define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
93 : : #endif
94 : :
95 : : #ifndef S_ISFIFO
96 : : # define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
97 : : #endif
98 : :
99 : : #ifndef S_ISLNK
100 : : # define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
101 : : #endif
102 : :
103 : : #ifndef S_ISSOCK
104 : : # define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
105 : : #endif
106 : :
107 : : #ifndef S_ISDOOR
108 : : # define S_ISDOOR(mode) 0
109 : : #endif
110 : :
111 : : #ifndef S_ISPORT
112 : : # define S_ISPORT(mode) 0
113 : : #endif
114 : :
115 : : #ifndef S_ISWHT
116 : : # define S_ISWHT(mode) 0
117 : : #endif
118 : :
119 : :
120 : : /* S_I* file permission
121 : : *
122 : : * The permission bit value are defined by POSIX standards.
123 : : */
124 : : #ifndef S_ISUID
125 : : # define S_ISUID 04000
126 : : #endif
127 : :
128 : : #ifndef S_ISGID
129 : : # define S_ISGID 02000
130 : : #endif
131 : :
132 : : /* what is S_ENFMT? */
133 : : #ifndef S_ENFMT
134 : : # define S_ENFMT S_ISGID
135 : : #endif
136 : :
137 : : #ifndef S_ISVTX
138 : : # define S_ISVTX 01000
139 : : #endif
140 : :
141 : : #ifndef S_IREAD
142 : : # define S_IREAD 00400
143 : : #endif
144 : :
145 : : #ifndef S_IWRITE
146 : : # define S_IWRITE 00200
147 : : #endif
148 : :
149 : : #ifndef S_IEXEC
150 : : # define S_IEXEC 00100
151 : : #endif
152 : :
153 : : #ifndef S_IRWXU
154 : : # define S_IRWXU 00700
155 : : #endif
156 : :
157 : : #ifndef S_IRUSR
158 : : # define S_IRUSR 00400
159 : : #endif
160 : :
161 : : #ifndef S_IWUSR
162 : : # define S_IWUSR 00200
163 : : #endif
164 : :
165 : : #ifndef S_IXUSR
166 : : # define S_IXUSR 00100
167 : : #endif
168 : :
169 : : #ifndef S_IRWXG
170 : : # define S_IRWXG 00070
171 : : #endif
172 : :
173 : : #ifndef S_IRGRP
174 : : # define S_IRGRP 00040
175 : : #endif
176 : :
177 : : #ifndef S_IWGRP
178 : : # define S_IWGRP 00020
179 : : #endif
180 : :
181 : : #ifndef S_IXGRP
182 : : # define S_IXGRP 00010
183 : : #endif
184 : :
185 : : #ifndef S_IRWXO
186 : : # define S_IRWXO 00007
187 : : #endif
188 : :
189 : : #ifndef S_IROTH
190 : : # define S_IROTH 00004
191 : : #endif
192 : :
193 : : #ifndef S_IWOTH
194 : : # define S_IWOTH 00002
195 : : #endif
196 : :
197 : : #ifndef S_IXOTH
198 : : # define S_IXOTH 00001
199 : : #endif
200 : :
201 : :
202 : : /* Names for file flags */
203 : : #ifndef UF_NODUMP
204 : : # define UF_NODUMP 0x00000001
205 : : #endif
206 : :
207 : : #ifndef UF_IMMUTABLE
208 : : # define UF_IMMUTABLE 0x00000002
209 : : #endif
210 : :
211 : : #ifndef UF_APPEND
212 : : # define UF_APPEND 0x00000004
213 : : #endif
214 : :
215 : : #ifndef UF_OPAQUE
216 : : # define UF_OPAQUE 0x00000008
217 : : #endif
218 : :
219 : : #ifndef UF_NOUNLINK
220 : : # define UF_NOUNLINK 0x00000010
221 : : #endif
222 : :
223 : : #ifndef UF_COMPRESSED
224 : : # define UF_COMPRESSED 0x00000020
225 : : #endif
226 : :
227 : : #ifndef UF_HIDDEN
228 : : # define UF_HIDDEN 0x00008000
229 : : #endif
230 : :
231 : : #ifndef SF_ARCHIVED
232 : : # define SF_ARCHIVED 0x00010000
233 : : #endif
234 : :
235 : : #ifndef SF_IMMUTABLE
236 : : # define SF_IMMUTABLE 0x00020000
237 : : #endif
238 : :
239 : : #ifndef SF_APPEND
240 : : # define SF_APPEND 0x00040000
241 : : #endif
242 : :
243 : : #ifndef SF_NOUNLINK
244 : : # define SF_NOUNLINK 0x00100000
245 : : #endif
246 : :
247 : : #ifndef SF_SNAPSHOT
248 : : # define SF_SNAPSHOT 0x00200000
249 : : #endif
250 : :
251 : : static mode_t
252 : 228720 : _PyLong_AsMode_t(PyObject *op)
253 : : {
254 : : unsigned long value;
255 : : mode_t mode;
256 : :
257 : 228720 : value = PyLong_AsUnsignedLong(op);
258 [ - + - - ]: 228720 : if ((value == (unsigned long)-1) && PyErr_Occurred())
259 : 0 : return (mode_t)-1;
260 : :
261 : 228720 : mode = (mode_t)value;
262 [ - + ]: 228720 : if ((unsigned long)mode != value) {
263 : 0 : PyErr_SetString(PyExc_OverflowError, "mode out of range");
264 : 0 : return (mode_t)-1;
265 : : }
266 : 228720 : return mode;
267 : : }
268 : :
269 : :
270 : : #define stat_S_ISFUNC(isfunc, doc) \
271 : : static PyObject * \
272 : : stat_ ##isfunc (PyObject *self, PyObject *omode) \
273 : : { \
274 : : mode_t mode = _PyLong_AsMode_t(omode); \
275 : : if ((mode == (mode_t)-1) && PyErr_Occurred()) \
276 : : return NULL; \
277 : : return PyBool_FromLong(isfunc(mode)); \
278 : : } \
279 : : PyDoc_STRVAR(stat_ ## isfunc ## _doc, doc)
280 : :
281 [ - + - - ]: 27990 : stat_S_ISFUNC(S_ISDIR,
282 : : "S_ISDIR(mode) -> bool\n\n"
283 : : "Return True if mode is from a directory.");
284 : :
285 [ - + - - ]: 136 : stat_S_ISFUNC(S_ISCHR,
286 : : "S_ISCHR(mode) -> bool\n\n"
287 : : "Return True if mode is from a character special device file.");
288 : :
289 [ - + - - ]: 17 : stat_S_ISFUNC(S_ISBLK,
290 : : "S_ISBLK(mode) -> bool\n\n"
291 : : "Return True if mode is from a block special device file.");
292 : :
293 [ - + - - ]: 17494 : stat_S_ISFUNC(S_ISREG,
294 : : "S_ISREG(mode) -> bool\n\n"
295 : : "Return True if mode is from a regular file.");
296 : :
297 [ - + - - ]: 20960 : stat_S_ISFUNC(S_ISFIFO,
298 : : "S_ISFIFO(mode) -> bool\n\n"
299 : : "Return True if mode is from a FIFO (named pipe).");
300 : :
301 [ - + - - ]: 138823 : stat_S_ISFUNC(S_ISLNK,
302 : : "S_ISLNK(mode) -> bool\n\n"
303 : : "Return True if mode is from a symbolic link.");
304 : :
305 [ - + - - ]: 139 : stat_S_ISFUNC(S_ISSOCK,
306 : : "S_ISSOCK(mode) -> bool\n\n"
307 : : "Return True if mode is from a socket.");
308 : :
309 [ - + - - ]: 96 : stat_S_ISFUNC(S_ISDOOR,
310 : : "S_ISDOOR(mode) -> bool\n\n"
311 : : "Return True if mode is from a door.");
312 : :
313 [ - + - - ]: 11 : stat_S_ISFUNC(S_ISPORT,
314 : : "S_ISPORT(mode) -> bool\n\n"
315 : : "Return True if mode is from an event port.");
316 : :
317 [ - + - - ]: 11 : stat_S_ISFUNC(S_ISWHT,
318 : : "S_ISWHT(mode) -> bool\n\n"
319 : : "Return True if mode is from a whiteout.");
320 : :
321 : :
322 : : PyDoc_STRVAR(stat_S_IMODE_doc,
323 : : "Return the portion of the file's mode that can be set by os.chmod().");
324 : :
325 : : static PyObject *
326 : 22232 : stat_S_IMODE(PyObject *self, PyObject *omode)
327 : : {
328 : 22232 : mode_t mode = _PyLong_AsMode_t(omode);
329 [ - + - - ]: 22232 : if ((mode == (mode_t)-1) && PyErr_Occurred())
330 : 0 : return NULL;
331 : 22232 : return PyLong_FromUnsignedLong(mode & S_IMODE);
332 : : }
333 : :
334 : :
335 : : PyDoc_STRVAR(stat_S_IFMT_doc,
336 : : "Return the portion of the file's mode that describes the file type.");
337 : :
338 : : static PyObject *
339 : 165 : stat_S_IFMT(PyObject *self, PyObject *omode)
340 : : {
341 : 165 : mode_t mode = _PyLong_AsMode_t(omode);
342 [ - + - - ]: 165 : if ((mode == (mode_t)-1) && PyErr_Occurred())
343 : 0 : return NULL;
344 : 165 : return PyLong_FromUnsignedLong(mode & S_IFMT);
345 : : }
346 : :
347 : : /* file type chars according to
348 : : http://en.wikibooks.org/wiki/C_Programming/POSIX_Reference/sys/stat.h */
349 : :
350 : : static char
351 : 646 : filetype(mode_t mode)
352 : : {
353 : : /* common cases first */
354 [ + + ]: 646 : if (S_ISREG(mode)) return '-';
355 [ + + ]: 614 : if (S_ISDIR(mode)) return 'd';
356 [ + + ]: 597 : if (S_ISLNK(mode)) return 'l';
357 : : /* special files */
358 [ + + ]: 596 : if (S_ISBLK(mode)) return 'b';
359 [ + + ]: 595 : if (S_ISCHR(mode)) return 'c';
360 [ + + ]: 594 : if (S_ISFIFO(mode)) return 'p';
361 [ + + ]: 593 : if (S_ISSOCK(mode)) return 's';
362 : : /* non-standard types */
363 : : if (S_ISDOOR(mode)) return 'D';
364 : : if (S_ISPORT(mode)) return 'P';
365 : : if (S_ISWHT(mode)) return 'w';
366 : : /* unknown */
367 : 592 : return '?';
368 : : }
369 : :
370 : : static void
371 : 646 : fileperm(mode_t mode, char *buf)
372 : : {
373 [ + + ]: 646 : buf[0] = mode & S_IRUSR ? 'r' : '-';
374 [ + + ]: 646 : buf[1] = mode & S_IWUSR ? 'w' : '-';
375 [ - + ]: 646 : if (mode & S_ISUID) {
376 [ # # ]: 0 : buf[2] = mode & S_IXUSR ? 's' : 'S';
377 : : } else {
378 [ + + ]: 646 : buf[2] = mode & S_IXUSR ? 'x' : '-';
379 : : }
380 [ + + ]: 646 : buf[3] = mode & S_IRGRP ? 'r' : '-';
381 [ + + ]: 646 : buf[4] = mode & S_IWGRP ? 'w' : '-';
382 [ - + ]: 646 : if (mode & S_ISGID) {
383 [ # # ]: 0 : buf[5] = mode & S_IXGRP ? 's' : 'S';
384 : : } else {
385 [ + + ]: 646 : buf[5] = mode & S_IXGRP ? 'x' : '-';
386 : : }
387 [ + + ]: 646 : buf[6] = mode & S_IROTH ? 'r' : '-';
388 [ + + ]: 646 : buf[7] = mode & S_IWOTH ? 'w' : '-';
389 [ - + ]: 646 : if (mode & S_ISVTX) {
390 [ # # ]: 0 : buf[8] = mode & S_IXOTH ? 't' : 'T';
391 : : } else {
392 [ + + ]: 646 : buf[8] = mode & S_IXOTH ? 'x' : '-';
393 : : }
394 : 646 : }
395 : :
396 : : PyDoc_STRVAR(stat_filemode_doc,
397 : : "Convert a file's mode to a string of the form '-rwxrwxrwx'");
398 : :
399 : : static PyObject *
400 : 646 : stat_filemode(PyObject *self, PyObject *omode)
401 : : {
402 : : char buf[10];
403 : : mode_t mode;
404 : :
405 : 646 : mode = _PyLong_AsMode_t(omode);
406 [ - + - - ]: 646 : if ((mode == (mode_t)-1) && PyErr_Occurred())
407 : 0 : return NULL;
408 : :
409 : 646 : buf[0] = filetype(mode);
410 : 646 : fileperm(mode, &buf[1]);
411 : 646 : return PyUnicode_FromStringAndSize(buf, 10);
412 : : }
413 : :
414 : :
415 : : static PyMethodDef stat_methods[] = {
416 : : {"S_ISDIR", stat_S_ISDIR, METH_O, stat_S_ISDIR_doc},
417 : : {"S_ISCHR", stat_S_ISCHR, METH_O, stat_S_ISCHR_doc},
418 : : {"S_ISBLK", stat_S_ISBLK, METH_O, stat_S_ISBLK_doc},
419 : : {"S_ISREG", stat_S_ISREG, METH_O, stat_S_ISREG_doc},
420 : : {"S_ISFIFO", stat_S_ISFIFO, METH_O, stat_S_ISFIFO_doc},
421 : : {"S_ISLNK", stat_S_ISLNK, METH_O, stat_S_ISLNK_doc},
422 : : {"S_ISSOCK", stat_S_ISSOCK, METH_O, stat_S_ISSOCK_doc},
423 : : {"S_ISDOOR", stat_S_ISDOOR, METH_O, stat_S_ISDOOR_doc},
424 : : {"S_ISPORT", stat_S_ISPORT, METH_O, stat_S_ISPORT_doc},
425 : : {"S_ISWHT", stat_S_ISWHT, METH_O, stat_S_ISWHT_doc},
426 : : {"S_IMODE", stat_S_IMODE, METH_O, stat_S_IMODE_doc},
427 : : {"S_IFMT", stat_S_IFMT, METH_O, stat_S_IFMT_doc},
428 : : {"filemode", stat_filemode, METH_O, stat_filemode_doc},
429 : : {NULL, NULL} /* sentinel */
430 : : };
431 : :
432 : :
433 : : PyDoc_STRVAR(module_doc,
434 : : "S_IFMT_: file type bits\n\
435 : : S_IFDIR: directory\n\
436 : : S_IFCHR: character device\n\
437 : : S_IFBLK: block device\n\
438 : : S_IFREG: regular file\n\
439 : : S_IFIFO: fifo (named pipe)\n\
440 : : S_IFLNK: symbolic link\n\
441 : : S_IFSOCK: socket file\n\
442 : : S_IFDOOR: door\n\
443 : : S_IFPORT: event port\n\
444 : : S_IFWHT: whiteout\n\
445 : : \n"
446 : :
447 : : "S_ISUID: set UID bit\n\
448 : : S_ISGID: set GID bit\n\
449 : : S_ENFMT: file locking enforcement\n\
450 : : S_ISVTX: sticky bit\n\
451 : : S_IREAD: Unix V7 synonym for S_IRUSR\n\
452 : : S_IWRITE: Unix V7 synonym for S_IWUSR\n\
453 : : S_IEXEC: Unix V7 synonym for S_IXUSR\n\
454 : : S_IRWXU: mask for owner permissions\n\
455 : : S_IRUSR: read by owner\n\
456 : : S_IWUSR: write by owner\n\
457 : : S_IXUSR: execute by owner\n\
458 : : S_IRWXG: mask for group permissions\n\
459 : : S_IRGRP: read by group\n\
460 : : S_IWGRP: write by group\n\
461 : : S_IXGRP: execute by group\n\
462 : : S_IRWXO: mask for others (not in group) permissions\n\
463 : : S_IROTH: read by others\n\
464 : : S_IWOTH: write by others\n\
465 : : S_IXOTH: execute by others\n\
466 : : \n"
467 : :
468 : : "UF_NODUMP: do not dump file\n\
469 : : UF_IMMUTABLE: file may not be changed\n\
470 : : UF_APPEND: file may only be appended to\n\
471 : : UF_OPAQUE: directory is opaque when viewed through a union stack\n\
472 : : UF_NOUNLINK: file may not be renamed or deleted\n\
473 : : UF_COMPRESSED: OS X: file is hfs-compressed\n\
474 : : UF_HIDDEN: OS X: file should not be displayed\n\
475 : : SF_ARCHIVED: file may be archived\n\
476 : : SF_IMMUTABLE: file may not be changed\n\
477 : : SF_APPEND: file may only be appended to\n\
478 : : SF_NOUNLINK: file may not be renamed or deleted\n\
479 : : SF_SNAPSHOT: file is a snapshot file\n\
480 : : \n"
481 : :
482 : : "ST_MODE\n\
483 : : ST_INO\n\
484 : : ST_DEV\n\
485 : : ST_NLINK\n\
486 : : ST_UID\n\
487 : : ST_GID\n\
488 : : ST_SIZE\n\
489 : : ST_ATIME\n\
490 : : ST_MTIME\n\
491 : : ST_CTIME\n\
492 : : \n"
493 : :
494 : : "FILE_ATTRIBUTE_*: Windows file attribute constants\n\
495 : : (only present on Windows)\n\
496 : : ");
497 : :
498 : :
499 : : static int
500 : 3116 : stat_exec(PyObject *module)
501 : : {
502 : : #define ADD_INT_MACRO(module, macro) \
503 : : do { \
504 : : if (PyModule_AddIntConstant(module, #macro, macro) < 0) { \
505 : : return -1; \
506 : : } \
507 : : } while (0)
508 : :
509 [ - + ]: 3116 : ADD_INT_MACRO(module, S_IFDIR);
510 [ - + ]: 3116 : ADD_INT_MACRO(module, S_IFCHR);
511 [ - + ]: 3116 : ADD_INT_MACRO(module, S_IFBLK);
512 [ - + ]: 3116 : ADD_INT_MACRO(module, S_IFREG);
513 [ - + ]: 3116 : ADD_INT_MACRO(module, S_IFIFO);
514 [ - + ]: 3116 : ADD_INT_MACRO(module, S_IFLNK);
515 [ - + ]: 3116 : ADD_INT_MACRO(module, S_IFSOCK);
516 [ - + ]: 3116 : ADD_INT_MACRO(module, S_IFDOOR);
517 [ - + ]: 3116 : ADD_INT_MACRO(module, S_IFPORT);
518 [ - + ]: 3116 : ADD_INT_MACRO(module, S_IFWHT);
519 : :
520 [ - + ]: 3116 : ADD_INT_MACRO(module, S_ISUID);
521 [ - + ]: 3116 : ADD_INT_MACRO(module, S_ISGID);
522 [ - + ]: 3116 : ADD_INT_MACRO(module, S_ISVTX);
523 [ - + ]: 3116 : ADD_INT_MACRO(module, S_ENFMT);
524 : :
525 [ - + ]: 3116 : ADD_INT_MACRO(module, S_IREAD);
526 [ - + ]: 3116 : ADD_INT_MACRO(module, S_IWRITE);
527 [ - + ]: 3116 : ADD_INT_MACRO(module, S_IEXEC);
528 : :
529 [ - + ]: 3116 : ADD_INT_MACRO(module, S_IRWXU);
530 [ - + ]: 3116 : ADD_INT_MACRO(module, S_IRUSR);
531 [ - + ]: 3116 : ADD_INT_MACRO(module, S_IWUSR);
532 [ - + ]: 3116 : ADD_INT_MACRO(module, S_IXUSR);
533 : :
534 [ - + ]: 3116 : ADD_INT_MACRO(module, S_IRWXG);
535 [ - + ]: 3116 : ADD_INT_MACRO(module, S_IRGRP);
536 [ - + ]: 3116 : ADD_INT_MACRO(module, S_IWGRP);
537 [ - + ]: 3116 : ADD_INT_MACRO(module, S_IXGRP);
538 : :
539 [ - + ]: 3116 : ADD_INT_MACRO(module, S_IRWXO);
540 [ - + ]: 3116 : ADD_INT_MACRO(module, S_IROTH);
541 [ - + ]: 3116 : ADD_INT_MACRO(module, S_IWOTH);
542 [ - + ]: 3116 : ADD_INT_MACRO(module, S_IXOTH);
543 : :
544 [ - + ]: 3116 : ADD_INT_MACRO(module, UF_NODUMP);
545 [ - + ]: 3116 : ADD_INT_MACRO(module, UF_IMMUTABLE);
546 [ - + ]: 3116 : ADD_INT_MACRO(module, UF_APPEND);
547 [ - + ]: 3116 : ADD_INT_MACRO(module, UF_OPAQUE);
548 [ - + ]: 3116 : ADD_INT_MACRO(module, UF_NOUNLINK);
549 [ - + ]: 3116 : ADD_INT_MACRO(module, UF_COMPRESSED);
550 [ - + ]: 3116 : ADD_INT_MACRO(module, UF_HIDDEN);
551 [ - + ]: 3116 : ADD_INT_MACRO(module, SF_ARCHIVED);
552 [ - + ]: 3116 : ADD_INT_MACRO(module, SF_IMMUTABLE);
553 [ - + ]: 3116 : ADD_INT_MACRO(module, SF_APPEND);
554 [ - + ]: 3116 : ADD_INT_MACRO(module, SF_NOUNLINK);
555 [ - + ]: 3116 : ADD_INT_MACRO(module, SF_SNAPSHOT);
556 : :
557 : 3116 : const char* st_constants[] = {
558 : : "ST_MODE",
559 : : "ST_INO",
560 : : "ST_DEV",
561 : : "ST_NLINK",
562 : : "ST_UID",
563 : : "ST_GID",
564 : : "ST_SIZE",
565 : : "ST_ATIME",
566 : : "ST_MTIME",
567 : : "ST_CTIME"
568 : : };
569 : :
570 [ + + ]: 34276 : for (int i = 0; i < (int)Py_ARRAY_LENGTH(st_constants); i++) {
571 [ - + ]: 31160 : if (PyModule_AddIntConstant(module, st_constants[i], i) < 0) {
572 : 0 : return -1;
573 : : }
574 : : }
575 : :
576 : : #ifdef MS_WINDOWS
577 : : ADD_INT_MACRO(module, FILE_ATTRIBUTE_ARCHIVE);
578 : : ADD_INT_MACRO(module, FILE_ATTRIBUTE_COMPRESSED);
579 : : ADD_INT_MACRO(module, FILE_ATTRIBUTE_DEVICE);
580 : : ADD_INT_MACRO(module, FILE_ATTRIBUTE_DIRECTORY);
581 : : ADD_INT_MACRO(module, FILE_ATTRIBUTE_ENCRYPTED);
582 : : ADD_INT_MACRO(module, FILE_ATTRIBUTE_HIDDEN);
583 : : ADD_INT_MACRO(module, FILE_ATTRIBUTE_INTEGRITY_STREAM);
584 : : ADD_INT_MACRO(module, FILE_ATTRIBUTE_NORMAL);
585 : : ADD_INT_MACRO(module, FILE_ATTRIBUTE_NOT_CONTENT_INDEXED);
586 : : ADD_INT_MACRO(module, FILE_ATTRIBUTE_NO_SCRUB_DATA);
587 : : ADD_INT_MACRO(module, FILE_ATTRIBUTE_OFFLINE);
588 : : ADD_INT_MACRO(module, FILE_ATTRIBUTE_READONLY);
589 : : ADD_INT_MACRO(module, FILE_ATTRIBUTE_REPARSE_POINT);
590 : : ADD_INT_MACRO(module, FILE_ATTRIBUTE_SPARSE_FILE);
591 : : ADD_INT_MACRO(module, FILE_ATTRIBUTE_SYSTEM);
592 : : ADD_INT_MACRO(module, FILE_ATTRIBUTE_TEMPORARY);
593 : : ADD_INT_MACRO(module, FILE_ATTRIBUTE_VIRTUAL);
594 : :
595 : : if (PyModule_AddObject(module, "IO_REPARSE_TAG_SYMLINK",
596 : : PyLong_FromUnsignedLong(IO_REPARSE_TAG_SYMLINK)) < 0) {
597 : : return -1;
598 : : }
599 : : if (PyModule_AddObject(module, "IO_REPARSE_TAG_MOUNT_POINT",
600 : : PyLong_FromUnsignedLong(IO_REPARSE_TAG_MOUNT_POINT)) < 0) {
601 : : return -1;
602 : : }
603 : : if (PyModule_AddObject(module, "IO_REPARSE_TAG_APPEXECLINK",
604 : : PyLong_FromUnsignedLong(IO_REPARSE_TAG_APPEXECLINK)) < 0) {
605 : : return -1;
606 : : }
607 : : #endif
608 : :
609 : 3116 : return 0;
610 : : }
611 : :
612 : :
613 : : static PyModuleDef_Slot stat_slots[] = {
614 : : {Py_mod_exec, stat_exec},
615 : : {0, NULL}
616 : : };
617 : :
618 : :
619 : : static struct PyModuleDef statmodule = {
620 : : PyModuleDef_HEAD_INIT,
621 : : .m_name = "_stat",
622 : : .m_doc = module_doc,
623 : : .m_size = 0,
624 : : .m_methods = stat_methods,
625 : : .m_slots = stat_slots,
626 : : };
627 : :
628 : :
629 : : PyMODINIT_FUNC
630 : 3116 : PyInit__stat(void)
631 : : {
632 : 3116 : return PyModuleDef_Init(&statmodule);
633 : : }
634 : :
635 : : #ifdef __cplusplus
636 : : }
637 : : #endif
|