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 | _PyLong_AsMode_t(PyObject *op) |
253 | { |
254 | unsigned long value; |
255 | mode_t mode; |
256 | |
257 | value = PyLong_AsUnsignedLong(op); |
258 | if ((value == (unsigned long)-1) && PyErr_Occurred()) |
259 | return (mode_t)-1; |
260 | |
261 | mode = (mode_t)value; |
262 | if ((unsigned long)mode != value) { |
263 | PyErr_SetString(PyExc_OverflowError, "mode out of range" ); |
264 | return (mode_t)-1; |
265 | } |
266 | 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 | stat_S_ISFUNC(S_ISDIR, |
282 | "S_ISDIR(mode) -> bool\n\n" |
283 | "Return True if mode is from a directory." ); |
284 | |
285 | 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 | 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 | stat_S_ISFUNC(S_ISREG, |
294 | "S_ISREG(mode) -> bool\n\n" |
295 | "Return True if mode is from a regular file." ); |
296 | |
297 | 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 | stat_S_ISFUNC(S_ISLNK, |
302 | "S_ISLNK(mode) -> bool\n\n" |
303 | "Return True if mode is from a symbolic link." ); |
304 | |
305 | stat_S_ISFUNC(S_ISSOCK, |
306 | "S_ISSOCK(mode) -> bool\n\n" |
307 | "Return True if mode is from a socket." ); |
308 | |
309 | stat_S_ISFUNC(S_ISDOOR, |
310 | "S_ISDOOR(mode) -> bool\n\n" |
311 | "Return True if mode is from a door." ); |
312 | |
313 | stat_S_ISFUNC(S_ISPORT, |
314 | "S_ISPORT(mode) -> bool\n\n" |
315 | "Return True if mode is from an event port." ); |
316 | |
317 | 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 | stat_S_IMODE(PyObject *self, PyObject *omode) |
327 | { |
328 | mode_t mode = _PyLong_AsMode_t(omode); |
329 | if ((mode == (mode_t)-1) && PyErr_Occurred()) |
330 | return NULL; |
331 | 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 | stat_S_IFMT(PyObject *self, PyObject *omode) |
340 | { |
341 | mode_t mode = _PyLong_AsMode_t(omode); |
342 | if ((mode == (mode_t)-1) && PyErr_Occurred()) |
343 | return NULL; |
344 | 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 | filetype(mode_t mode) |
352 | { |
353 | /* common cases first */ |
354 | if (S_ISREG(mode)) return '-'; |
355 | if (S_ISDIR(mode)) return 'd'; |
356 | if (S_ISLNK(mode)) return 'l'; |
357 | /* special files */ |
358 | if (S_ISBLK(mode)) return 'b'; |
359 | if (S_ISCHR(mode)) return 'c'; |
360 | if (S_ISFIFO(mode)) return 'p'; |
361 | 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 | return '?'; |
368 | } |
369 | |
370 | static void |
371 | fileperm(mode_t mode, char *buf) |
372 | { |
373 | buf[0] = mode & S_IRUSR ? 'r' : '-'; |
374 | buf[1] = mode & S_IWUSR ? 'w' : '-'; |
375 | if (mode & S_ISUID) { |
376 | buf[2] = mode & S_IXUSR ? 's' : 'S'; |
377 | } else { |
378 | buf[2] = mode & S_IXUSR ? 'x' : '-'; |
379 | } |
380 | buf[3] = mode & S_IRGRP ? 'r' : '-'; |
381 | buf[4] = mode & S_IWGRP ? 'w' : '-'; |
382 | if (mode & S_ISGID) { |
383 | buf[5] = mode & S_IXGRP ? 's' : 'S'; |
384 | } else { |
385 | buf[5] = mode & S_IXGRP ? 'x' : '-'; |
386 | } |
387 | buf[6] = mode & S_IROTH ? 'r' : '-'; |
388 | buf[7] = mode & S_IWOTH ? 'w' : '-'; |
389 | if (mode & S_ISVTX) { |
390 | buf[8] = mode & S_IXOTH ? 't' : 'T'; |
391 | } else { |
392 | buf[8] = mode & S_IXOTH ? 'x' : '-'; |
393 | } |
394 | } |
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 | stat_filemode(PyObject *self, PyObject *omode) |
401 | { |
402 | char buf[10]; |
403 | mode_t mode; |
404 | |
405 | mode = _PyLong_AsMode_t(omode); |
406 | if ((mode == (mode_t)-1) && PyErr_Occurred()) |
407 | return NULL; |
408 | |
409 | buf[0] = filetype(mode); |
410 | fileperm(mode, &buf[1]); |
411 | 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 | 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 | ADD_INT_MACRO(module, S_IFDIR); |
510 | ADD_INT_MACRO(module, S_IFCHR); |
511 | ADD_INT_MACRO(module, S_IFBLK); |
512 | ADD_INT_MACRO(module, S_IFREG); |
513 | ADD_INT_MACRO(module, S_IFIFO); |
514 | ADD_INT_MACRO(module, S_IFLNK); |
515 | ADD_INT_MACRO(module, S_IFSOCK); |
516 | ADD_INT_MACRO(module, S_IFDOOR); |
517 | ADD_INT_MACRO(module, S_IFPORT); |
518 | ADD_INT_MACRO(module, S_IFWHT); |
519 | |
520 | ADD_INT_MACRO(module, S_ISUID); |
521 | ADD_INT_MACRO(module, S_ISGID); |
522 | ADD_INT_MACRO(module, S_ISVTX); |
523 | ADD_INT_MACRO(module, S_ENFMT); |
524 | |
525 | ADD_INT_MACRO(module, S_IREAD); |
526 | ADD_INT_MACRO(module, S_IWRITE); |
527 | ADD_INT_MACRO(module, S_IEXEC); |
528 | |
529 | ADD_INT_MACRO(module, S_IRWXU); |
530 | ADD_INT_MACRO(module, S_IRUSR); |
531 | ADD_INT_MACRO(module, S_IWUSR); |
532 | ADD_INT_MACRO(module, S_IXUSR); |
533 | |
534 | ADD_INT_MACRO(module, S_IRWXG); |
535 | ADD_INT_MACRO(module, S_IRGRP); |
536 | ADD_INT_MACRO(module, S_IWGRP); |
537 | ADD_INT_MACRO(module, S_IXGRP); |
538 | |
539 | ADD_INT_MACRO(module, S_IRWXO); |
540 | ADD_INT_MACRO(module, S_IROTH); |
541 | ADD_INT_MACRO(module, S_IWOTH); |
542 | ADD_INT_MACRO(module, S_IXOTH); |
543 | |
544 | ADD_INT_MACRO(module, UF_NODUMP); |
545 | ADD_INT_MACRO(module, UF_IMMUTABLE); |
546 | ADD_INT_MACRO(module, UF_APPEND); |
547 | ADD_INT_MACRO(module, UF_OPAQUE); |
548 | ADD_INT_MACRO(module, UF_NOUNLINK); |
549 | ADD_INT_MACRO(module, UF_COMPRESSED); |
550 | ADD_INT_MACRO(module, UF_HIDDEN); |
551 | ADD_INT_MACRO(module, SF_ARCHIVED); |
552 | ADD_INT_MACRO(module, SF_IMMUTABLE); |
553 | ADD_INT_MACRO(module, SF_APPEND); |
554 | ADD_INT_MACRO(module, SF_NOUNLINK); |
555 | ADD_INT_MACRO(module, SF_SNAPSHOT); |
556 | |
557 | 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 | for (int i = 0; i < (int)Py_ARRAY_LENGTH(st_constants); i++) { |
571 | if (PyModule_AddIntConstant(module, st_constants[i], i) < 0) { |
572 | 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 | 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 | PyInit__stat(void) |
631 | { |
632 | return PyModuleDef_Init(&statmodule); |
633 | } |
634 | |
635 | #ifdef __cplusplus |
636 | } |
637 | #endif |
638 | |