1 | n/a | |
---|
2 | n/a | /* POSIX module implementation */ |
---|
3 | n/a | |
---|
4 | n/a | /* This file is also used for Windows NT/MS-Win. In that case the |
---|
5 | n/a | module actually calls itself 'nt', not 'posix', and a few |
---|
6 | n/a | functions are either unimplemented or implemented differently. The source |
---|
7 | n/a | assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent |
---|
8 | n/a | of the compiler used. Different compilers define their own feature |
---|
9 | n/a | test macro, e.g. '_MSC_VER'. */ |
---|
10 | n/a | |
---|
11 | n/a | |
---|
12 | n/a | |
---|
13 | n/a | #ifdef __APPLE__ |
---|
14 | n/a | /* |
---|
15 | n/a | * Step 1 of support for weak-linking a number of symbols existing on |
---|
16 | n/a | * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block |
---|
17 | n/a | * at the end of this file for more information. |
---|
18 | n/a | */ |
---|
19 | n/a | # pragma weak lchown |
---|
20 | n/a | # pragma weak statvfs |
---|
21 | n/a | # pragma weak fstatvfs |
---|
22 | n/a | |
---|
23 | n/a | #endif /* __APPLE__ */ |
---|
24 | n/a | |
---|
25 | n/a | #define PY_SSIZE_T_CLEAN |
---|
26 | n/a | |
---|
27 | n/a | #include "Python.h" |
---|
28 | n/a | #include "structmember.h" |
---|
29 | n/a | #ifndef MS_WINDOWS |
---|
30 | n/a | #include "posixmodule.h" |
---|
31 | n/a | #else |
---|
32 | n/a | #include "winreparse.h" |
---|
33 | n/a | #endif |
---|
34 | n/a | |
---|
35 | n/a | /* On android API level 21, 'AT_EACCESS' is not declared although |
---|
36 | n/a | * HAVE_FACCESSAT is defined. */ |
---|
37 | n/a | #ifdef __ANDROID__ |
---|
38 | n/a | #undef HAVE_FACCESSAT |
---|
39 | n/a | #endif |
---|
40 | n/a | |
---|
41 | n/a | #include <stdio.h> /* needed for ctermid() */ |
---|
42 | n/a | |
---|
43 | n/a | #ifdef __cplusplus |
---|
44 | n/a | extern "C" { |
---|
45 | n/a | #endif |
---|
46 | n/a | |
---|
47 | n/a | PyDoc_STRVAR(posix__doc__, |
---|
48 | n/a | "This module provides access to operating system functionality that is\n\ |
---|
49 | n/a | standardized by the C Standard and the POSIX standard (a thinly\n\ |
---|
50 | n/a | disguised Unix interface). Refer to the library manual and\n\ |
---|
51 | n/a | corresponding Unix manual entries for more information on calls."); |
---|
52 | n/a | |
---|
53 | n/a | |
---|
54 | n/a | #ifdef HAVE_SYS_UIO_H |
---|
55 | n/a | #include <sys/uio.h> |
---|
56 | n/a | #endif |
---|
57 | n/a | |
---|
58 | n/a | #ifdef HAVE_SYS_TYPES_H |
---|
59 | n/a | #include <sys/types.h> |
---|
60 | n/a | #endif /* HAVE_SYS_TYPES_H */ |
---|
61 | n/a | |
---|
62 | n/a | #ifdef HAVE_SYS_STAT_H |
---|
63 | n/a | #include <sys/stat.h> |
---|
64 | n/a | #endif /* HAVE_SYS_STAT_H */ |
---|
65 | n/a | |
---|
66 | n/a | #ifdef HAVE_SYS_WAIT_H |
---|
67 | n/a | #include <sys/wait.h> /* For WNOHANG */ |
---|
68 | n/a | #endif |
---|
69 | n/a | |
---|
70 | n/a | #ifdef HAVE_SIGNAL_H |
---|
71 | n/a | #include <signal.h> |
---|
72 | n/a | #endif |
---|
73 | n/a | |
---|
74 | n/a | #ifdef HAVE_FCNTL_H |
---|
75 | n/a | #include <fcntl.h> |
---|
76 | n/a | #endif /* HAVE_FCNTL_H */ |
---|
77 | n/a | |
---|
78 | n/a | #ifdef HAVE_GRP_H |
---|
79 | n/a | #include <grp.h> |
---|
80 | n/a | #endif |
---|
81 | n/a | |
---|
82 | n/a | #ifdef HAVE_SYSEXITS_H |
---|
83 | n/a | #include <sysexits.h> |
---|
84 | n/a | #endif /* HAVE_SYSEXITS_H */ |
---|
85 | n/a | |
---|
86 | n/a | #ifdef HAVE_SYS_LOADAVG_H |
---|
87 | n/a | #include <sys/loadavg.h> |
---|
88 | n/a | #endif |
---|
89 | n/a | |
---|
90 | n/a | #ifdef HAVE_LANGINFO_H |
---|
91 | n/a | #include <langinfo.h> |
---|
92 | n/a | #endif |
---|
93 | n/a | |
---|
94 | n/a | #ifdef HAVE_SYS_SENDFILE_H |
---|
95 | n/a | #include <sys/sendfile.h> |
---|
96 | n/a | #endif |
---|
97 | n/a | |
---|
98 | n/a | #ifdef HAVE_SCHED_H |
---|
99 | n/a | #include <sched.h> |
---|
100 | n/a | #endif |
---|
101 | n/a | |
---|
102 | n/a | #if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY) |
---|
103 | n/a | #undef HAVE_SCHED_SETAFFINITY |
---|
104 | n/a | #endif |
---|
105 | n/a | |
---|
106 | n/a | #if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__) |
---|
107 | n/a | #define USE_XATTRS |
---|
108 | n/a | #endif |
---|
109 | n/a | |
---|
110 | n/a | #ifdef USE_XATTRS |
---|
111 | n/a | #include <sys/xattr.h> |
---|
112 | n/a | #endif |
---|
113 | n/a | |
---|
114 | n/a | #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__) |
---|
115 | n/a | #ifdef HAVE_SYS_SOCKET_H |
---|
116 | n/a | #include <sys/socket.h> |
---|
117 | n/a | #endif |
---|
118 | n/a | #endif |
---|
119 | n/a | |
---|
120 | n/a | #ifdef HAVE_DLFCN_H |
---|
121 | n/a | #include <dlfcn.h> |
---|
122 | n/a | #endif |
---|
123 | n/a | |
---|
124 | n/a | #ifdef __hpux |
---|
125 | n/a | #include <sys/mpctl.h> |
---|
126 | n/a | #endif |
---|
127 | n/a | |
---|
128 | n/a | #if defined(__DragonFly__) || \ |
---|
129 | n/a | defined(__OpenBSD__) || \ |
---|
130 | n/a | defined(__FreeBSD__) || \ |
---|
131 | n/a | defined(__NetBSD__) || \ |
---|
132 | n/a | defined(__APPLE__) |
---|
133 | n/a | #include <sys/sysctl.h> |
---|
134 | n/a | #endif |
---|
135 | n/a | |
---|
136 | n/a | #ifdef HAVE_LINUX_RANDOM_H |
---|
137 | n/a | # include <linux/random.h> |
---|
138 | n/a | #endif |
---|
139 | n/a | #ifdef HAVE_GETRANDOM_SYSCALL |
---|
140 | n/a | # include <sys/syscall.h> |
---|
141 | n/a | #endif |
---|
142 | n/a | |
---|
143 | n/a | #if defined(MS_WINDOWS) |
---|
144 | n/a | # define TERMSIZE_USE_CONIO |
---|
145 | n/a | #elif defined(HAVE_SYS_IOCTL_H) |
---|
146 | n/a | # include <sys/ioctl.h> |
---|
147 | n/a | # if defined(HAVE_TERMIOS_H) |
---|
148 | n/a | # include <termios.h> |
---|
149 | n/a | # endif |
---|
150 | n/a | # if defined(TIOCGWINSZ) |
---|
151 | n/a | # define TERMSIZE_USE_IOCTL |
---|
152 | n/a | # endif |
---|
153 | n/a | #endif /* MS_WINDOWS */ |
---|
154 | n/a | |
---|
155 | n/a | /* Various compilers have only certain posix functions */ |
---|
156 | n/a | /* XXX Gosh I wish these were all moved into pyconfig.h */ |
---|
157 | n/a | #if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */ |
---|
158 | n/a | #define HAVE_OPENDIR 1 |
---|
159 | n/a | #define HAVE_SYSTEM 1 |
---|
160 | n/a | #include <process.h> |
---|
161 | n/a | #else |
---|
162 | n/a | #ifdef _MSC_VER /* Microsoft compiler */ |
---|
163 | n/a | #define HAVE_GETPPID 1 |
---|
164 | n/a | #define HAVE_GETLOGIN 1 |
---|
165 | n/a | #define HAVE_SPAWNV 1 |
---|
166 | n/a | #define HAVE_EXECV 1 |
---|
167 | n/a | #define HAVE_WSPAWNV 1 |
---|
168 | n/a | #define HAVE_WEXECV 1 |
---|
169 | n/a | #define HAVE_PIPE 1 |
---|
170 | n/a | #define HAVE_SYSTEM 1 |
---|
171 | n/a | #define HAVE_CWAIT 1 |
---|
172 | n/a | #define HAVE_FSYNC 1 |
---|
173 | n/a | #define fsync _commit |
---|
174 | n/a | #else |
---|
175 | n/a | /* Unix functions that the configure script doesn't check for */ |
---|
176 | n/a | #define HAVE_EXECV 1 |
---|
177 | n/a | #define HAVE_FORK 1 |
---|
178 | n/a | #if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */ |
---|
179 | n/a | #define HAVE_FORK1 1 |
---|
180 | n/a | #endif |
---|
181 | n/a | #define HAVE_GETEGID 1 |
---|
182 | n/a | #define HAVE_GETEUID 1 |
---|
183 | n/a | #define HAVE_GETGID 1 |
---|
184 | n/a | #define HAVE_GETPPID 1 |
---|
185 | n/a | #define HAVE_GETUID 1 |
---|
186 | n/a | #define HAVE_KILL 1 |
---|
187 | n/a | #define HAVE_OPENDIR 1 |
---|
188 | n/a | #define HAVE_PIPE 1 |
---|
189 | n/a | #define HAVE_SYSTEM 1 |
---|
190 | n/a | #define HAVE_WAIT 1 |
---|
191 | n/a | #define HAVE_TTYNAME 1 |
---|
192 | n/a | #endif /* _MSC_VER */ |
---|
193 | n/a | #endif /* ! __WATCOMC__ || __QNX__ */ |
---|
194 | n/a | |
---|
195 | n/a | |
---|
196 | n/a | /*[clinic input] |
---|
197 | n/a | # one of the few times we lie about this name! |
---|
198 | n/a | module os |
---|
199 | n/a | [clinic start generated code]*/ |
---|
200 | n/a | /*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/ |
---|
201 | n/a | |
---|
202 | n/a | #ifndef _MSC_VER |
---|
203 | n/a | |
---|
204 | n/a | #if defined(__sgi)&&_COMPILER_VERSION>=700 |
---|
205 | n/a | /* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode |
---|
206 | n/a | (default) */ |
---|
207 | n/a | extern char *ctermid_r(char *); |
---|
208 | n/a | #endif |
---|
209 | n/a | |
---|
210 | n/a | #ifndef HAVE_UNISTD_H |
---|
211 | n/a | #if defined(PYCC_VACPP) |
---|
212 | n/a | extern int mkdir(char *); |
---|
213 | n/a | #else |
---|
214 | n/a | #if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__) |
---|
215 | n/a | extern int mkdir(const char *); |
---|
216 | n/a | #else |
---|
217 | n/a | extern int mkdir(const char *, mode_t); |
---|
218 | n/a | #endif |
---|
219 | n/a | #endif |
---|
220 | n/a | #if defined(__IBMC__) || defined(__IBMCPP__) |
---|
221 | n/a | extern int chdir(char *); |
---|
222 | n/a | extern int rmdir(char *); |
---|
223 | n/a | #else |
---|
224 | n/a | extern int chdir(const char *); |
---|
225 | n/a | extern int rmdir(const char *); |
---|
226 | n/a | #endif |
---|
227 | n/a | extern int chmod(const char *, mode_t); |
---|
228 | n/a | /*#ifdef HAVE_FCHMOD |
---|
229 | n/a | extern int fchmod(int, mode_t); |
---|
230 | n/a | #endif*/ |
---|
231 | n/a | /*#ifdef HAVE_LCHMOD |
---|
232 | n/a | extern int lchmod(const char *, mode_t); |
---|
233 | n/a | #endif*/ |
---|
234 | n/a | extern int chown(const char *, uid_t, gid_t); |
---|
235 | n/a | extern char *getcwd(char *, int); |
---|
236 | n/a | extern char *strerror(int); |
---|
237 | n/a | extern int link(const char *, const char *); |
---|
238 | n/a | extern int rename(const char *, const char *); |
---|
239 | n/a | extern int stat(const char *, struct stat *); |
---|
240 | n/a | extern int unlink(const char *); |
---|
241 | n/a | #ifdef HAVE_SYMLINK |
---|
242 | n/a | extern int symlink(const char *, const char *); |
---|
243 | n/a | #endif /* HAVE_SYMLINK */ |
---|
244 | n/a | #ifdef HAVE_LSTAT |
---|
245 | n/a | extern int lstat(const char *, struct stat *); |
---|
246 | n/a | #endif /* HAVE_LSTAT */ |
---|
247 | n/a | #endif /* !HAVE_UNISTD_H */ |
---|
248 | n/a | |
---|
249 | n/a | #endif /* !_MSC_VER */ |
---|
250 | n/a | |
---|
251 | n/a | #ifdef HAVE_UTIME_H |
---|
252 | n/a | #include <utime.h> |
---|
253 | n/a | #endif /* HAVE_UTIME_H */ |
---|
254 | n/a | |
---|
255 | n/a | #ifdef HAVE_SYS_UTIME_H |
---|
256 | n/a | #include <sys/utime.h> |
---|
257 | n/a | #define HAVE_UTIME_H /* pretend we do for the rest of this file */ |
---|
258 | n/a | #endif /* HAVE_SYS_UTIME_H */ |
---|
259 | n/a | |
---|
260 | n/a | #ifdef HAVE_SYS_TIMES_H |
---|
261 | n/a | #include <sys/times.h> |
---|
262 | n/a | #endif /* HAVE_SYS_TIMES_H */ |
---|
263 | n/a | |
---|
264 | n/a | #ifdef HAVE_SYS_PARAM_H |
---|
265 | n/a | #include <sys/param.h> |
---|
266 | n/a | #endif /* HAVE_SYS_PARAM_H */ |
---|
267 | n/a | |
---|
268 | n/a | #ifdef HAVE_SYS_UTSNAME_H |
---|
269 | n/a | #include <sys/utsname.h> |
---|
270 | n/a | #endif /* HAVE_SYS_UTSNAME_H */ |
---|
271 | n/a | |
---|
272 | n/a | #ifdef HAVE_DIRENT_H |
---|
273 | n/a | #include <dirent.h> |
---|
274 | n/a | #define NAMLEN(dirent) strlen((dirent)->d_name) |
---|
275 | n/a | #else |
---|
276 | n/a | #if defined(__WATCOMC__) && !defined(__QNX__) |
---|
277 | n/a | #include <direct.h> |
---|
278 | n/a | #define NAMLEN(dirent) strlen((dirent)->d_name) |
---|
279 | n/a | #else |
---|
280 | n/a | #define dirent direct |
---|
281 | n/a | #define NAMLEN(dirent) (dirent)->d_namlen |
---|
282 | n/a | #endif |
---|
283 | n/a | #ifdef HAVE_SYS_NDIR_H |
---|
284 | n/a | #include <sys/ndir.h> |
---|
285 | n/a | #endif |
---|
286 | n/a | #ifdef HAVE_SYS_DIR_H |
---|
287 | n/a | #include <sys/dir.h> |
---|
288 | n/a | #endif |
---|
289 | n/a | #ifdef HAVE_NDIR_H |
---|
290 | n/a | #include <ndir.h> |
---|
291 | n/a | #endif |
---|
292 | n/a | #endif |
---|
293 | n/a | |
---|
294 | n/a | #ifdef _MSC_VER |
---|
295 | n/a | #ifdef HAVE_DIRECT_H |
---|
296 | n/a | #include <direct.h> |
---|
297 | n/a | #endif |
---|
298 | n/a | #ifdef HAVE_IO_H |
---|
299 | n/a | #include <io.h> |
---|
300 | n/a | #endif |
---|
301 | n/a | #ifdef HAVE_PROCESS_H |
---|
302 | n/a | #include <process.h> |
---|
303 | n/a | #endif |
---|
304 | n/a | #ifndef VOLUME_NAME_DOS |
---|
305 | n/a | #define VOLUME_NAME_DOS 0x0 |
---|
306 | n/a | #endif |
---|
307 | n/a | #ifndef VOLUME_NAME_NT |
---|
308 | n/a | #define VOLUME_NAME_NT 0x2 |
---|
309 | n/a | #endif |
---|
310 | n/a | #ifndef IO_REPARSE_TAG_SYMLINK |
---|
311 | n/a | #define IO_REPARSE_TAG_SYMLINK (0xA000000CL) |
---|
312 | n/a | #endif |
---|
313 | n/a | #ifndef IO_REPARSE_TAG_MOUNT_POINT |
---|
314 | n/a | #define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L) |
---|
315 | n/a | #endif |
---|
316 | n/a | #include "osdefs.h" |
---|
317 | n/a | #include <malloc.h> |
---|
318 | n/a | #include <windows.h> |
---|
319 | n/a | #include <shellapi.h> /* for ShellExecute() */ |
---|
320 | n/a | #include <lmcons.h> /* for UNLEN */ |
---|
321 | n/a | #ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */ |
---|
322 | n/a | #define HAVE_SYMLINK |
---|
323 | n/a | static int win32_can_symlink = 0; |
---|
324 | n/a | #endif |
---|
325 | n/a | #endif /* _MSC_VER */ |
---|
326 | n/a | |
---|
327 | n/a | #ifndef MAXPATHLEN |
---|
328 | n/a | #if defined(PATH_MAX) && PATH_MAX > 1024 |
---|
329 | n/a | #define MAXPATHLEN PATH_MAX |
---|
330 | n/a | #else |
---|
331 | n/a | #define MAXPATHLEN 1024 |
---|
332 | n/a | #endif |
---|
333 | n/a | #endif /* MAXPATHLEN */ |
---|
334 | n/a | |
---|
335 | n/a | #ifdef UNION_WAIT |
---|
336 | n/a | /* Emulate some macros on systems that have a union instead of macros */ |
---|
337 | n/a | |
---|
338 | n/a | #ifndef WIFEXITED |
---|
339 | n/a | #define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump) |
---|
340 | n/a | #endif |
---|
341 | n/a | |
---|
342 | n/a | #ifndef WEXITSTATUS |
---|
343 | n/a | #define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1) |
---|
344 | n/a | #endif |
---|
345 | n/a | |
---|
346 | n/a | #ifndef WTERMSIG |
---|
347 | n/a | #define WTERMSIG(u_wait) ((u_wait).w_termsig) |
---|
348 | n/a | #endif |
---|
349 | n/a | |
---|
350 | n/a | #define WAIT_TYPE union wait |
---|
351 | n/a | #define WAIT_STATUS_INT(s) (s.w_status) |
---|
352 | n/a | |
---|
353 | n/a | #else /* !UNION_WAIT */ |
---|
354 | n/a | #define WAIT_TYPE int |
---|
355 | n/a | #define WAIT_STATUS_INT(s) (s) |
---|
356 | n/a | #endif /* UNION_WAIT */ |
---|
357 | n/a | |
---|
358 | n/a | /* Don't use the "_r" form if we don't need it (also, won't have a |
---|
359 | n/a | prototype for it, at least on Solaris -- maybe others as well?). */ |
---|
360 | n/a | #if defined(HAVE_CTERMID_R) && defined(WITH_THREAD) |
---|
361 | n/a | #define USE_CTERMID_R |
---|
362 | n/a | #endif |
---|
363 | n/a | |
---|
364 | n/a | /* choose the appropriate stat and fstat functions and return structs */ |
---|
365 | n/a | #undef STAT |
---|
366 | n/a | #undef FSTAT |
---|
367 | n/a | #undef STRUCT_STAT |
---|
368 | n/a | #ifdef MS_WINDOWS |
---|
369 | n/a | # define STAT win32_stat |
---|
370 | n/a | # define LSTAT win32_lstat |
---|
371 | n/a | # define FSTAT _Py_fstat_noraise |
---|
372 | n/a | # define STRUCT_STAT struct _Py_stat_struct |
---|
373 | n/a | #else |
---|
374 | n/a | # define STAT stat |
---|
375 | n/a | # define LSTAT lstat |
---|
376 | n/a | # define FSTAT fstat |
---|
377 | n/a | # define STRUCT_STAT struct stat |
---|
378 | n/a | #endif |
---|
379 | n/a | |
---|
380 | n/a | #if defined(MAJOR_IN_MKDEV) |
---|
381 | n/a | #include <sys/mkdev.h> |
---|
382 | n/a | #else |
---|
383 | n/a | #if defined(MAJOR_IN_SYSMACROS) |
---|
384 | n/a | #include <sys/sysmacros.h> |
---|
385 | n/a | #endif |
---|
386 | n/a | #if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H) |
---|
387 | n/a | #include <sys/mkdev.h> |
---|
388 | n/a | #endif |
---|
389 | n/a | #endif |
---|
390 | n/a | |
---|
391 | n/a | #define DWORD_MAX 4294967295U |
---|
392 | n/a | |
---|
393 | n/a | #ifdef MS_WINDOWS |
---|
394 | n/a | #define INITFUNC PyInit_nt |
---|
395 | n/a | #define MODNAME "nt" |
---|
396 | n/a | #else |
---|
397 | n/a | #define INITFUNC PyInit_posix |
---|
398 | n/a | #define MODNAME "posix" |
---|
399 | n/a | #endif |
---|
400 | n/a | |
---|
401 | n/a | #ifdef MS_WINDOWS |
---|
402 | n/a | /* defined in fileutils.c */ |
---|
403 | n/a | PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *); |
---|
404 | n/a | PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *, |
---|
405 | n/a | ULONG, struct _Py_stat_struct *); |
---|
406 | n/a | #endif |
---|
407 | n/a | |
---|
408 | n/a | #ifdef MS_WINDOWS |
---|
409 | n/a | static int |
---|
410 | n/a | win32_warn_bytes_api() |
---|
411 | n/a | { |
---|
412 | n/a | return PyErr_WarnEx(PyExc_DeprecationWarning, |
---|
413 | n/a | "The Windows bytes API has been deprecated, " |
---|
414 | n/a | "use Unicode filenames instead", |
---|
415 | n/a | 1); |
---|
416 | n/a | } |
---|
417 | n/a | #endif |
---|
418 | n/a | |
---|
419 | n/a | |
---|
420 | n/a | #ifndef MS_WINDOWS |
---|
421 | n/a | PyObject * |
---|
422 | n/a | _PyLong_FromUid(uid_t uid) |
---|
423 | n/a | { |
---|
424 | n/a | if (uid == (uid_t)-1) |
---|
425 | n/a | return PyLong_FromLong(-1); |
---|
426 | n/a | return PyLong_FromUnsignedLong(uid); |
---|
427 | n/a | } |
---|
428 | n/a | |
---|
429 | n/a | PyObject * |
---|
430 | n/a | _PyLong_FromGid(gid_t gid) |
---|
431 | n/a | { |
---|
432 | n/a | if (gid == (gid_t)-1) |
---|
433 | n/a | return PyLong_FromLong(-1); |
---|
434 | n/a | return PyLong_FromUnsignedLong(gid); |
---|
435 | n/a | } |
---|
436 | n/a | |
---|
437 | n/a | int |
---|
438 | n/a | _Py_Uid_Converter(PyObject *obj, void *p) |
---|
439 | n/a | { |
---|
440 | n/a | uid_t uid; |
---|
441 | n/a | PyObject *index; |
---|
442 | n/a | int overflow; |
---|
443 | n/a | long result; |
---|
444 | n/a | unsigned long uresult; |
---|
445 | n/a | |
---|
446 | n/a | index = PyNumber_Index(obj); |
---|
447 | n/a | if (index == NULL) { |
---|
448 | n/a | PyErr_Format(PyExc_TypeError, |
---|
449 | n/a | "uid should be integer, not %.200s", |
---|
450 | n/a | Py_TYPE(obj)->tp_name); |
---|
451 | n/a | return 0; |
---|
452 | n/a | } |
---|
453 | n/a | |
---|
454 | n/a | /* |
---|
455 | n/a | * Handling uid_t is complicated for two reasons: |
---|
456 | n/a | * * Although uid_t is (always?) unsigned, it still |
---|
457 | n/a | * accepts -1. |
---|
458 | n/a | * * We don't know its size in advance--it may be |
---|
459 | n/a | * bigger than an int, or it may be smaller than |
---|
460 | n/a | * a long. |
---|
461 | n/a | * |
---|
462 | n/a | * So a bit of defensive programming is in order. |
---|
463 | n/a | * Start with interpreting the value passed |
---|
464 | n/a | * in as a signed long and see if it works. |
---|
465 | n/a | */ |
---|
466 | n/a | |
---|
467 | n/a | result = PyLong_AsLongAndOverflow(index, &overflow); |
---|
468 | n/a | |
---|
469 | n/a | if (!overflow) { |
---|
470 | n/a | uid = (uid_t)result; |
---|
471 | n/a | |
---|
472 | n/a | if (result == -1) { |
---|
473 | n/a | if (PyErr_Occurred()) |
---|
474 | n/a | goto fail; |
---|
475 | n/a | /* It's a legitimate -1, we're done. */ |
---|
476 | n/a | goto success; |
---|
477 | n/a | } |
---|
478 | n/a | |
---|
479 | n/a | /* Any other negative number is disallowed. */ |
---|
480 | n/a | if (result < 0) |
---|
481 | n/a | goto underflow; |
---|
482 | n/a | |
---|
483 | n/a | /* Ensure the value wasn't truncated. */ |
---|
484 | n/a | if (sizeof(uid_t) < sizeof(long) && |
---|
485 | n/a | (long)uid != result) |
---|
486 | n/a | goto underflow; |
---|
487 | n/a | goto success; |
---|
488 | n/a | } |
---|
489 | n/a | |
---|
490 | n/a | if (overflow < 0) |
---|
491 | n/a | goto underflow; |
---|
492 | n/a | |
---|
493 | n/a | /* |
---|
494 | n/a | * Okay, the value overflowed a signed long. If it |
---|
495 | n/a | * fits in an *unsigned* long, it may still be okay, |
---|
496 | n/a | * as uid_t may be unsigned long on this platform. |
---|
497 | n/a | */ |
---|
498 | n/a | uresult = PyLong_AsUnsignedLong(index); |
---|
499 | n/a | if (PyErr_Occurred()) { |
---|
500 | n/a | if (PyErr_ExceptionMatches(PyExc_OverflowError)) |
---|
501 | n/a | goto overflow; |
---|
502 | n/a | goto fail; |
---|
503 | n/a | } |
---|
504 | n/a | |
---|
505 | n/a | uid = (uid_t)uresult; |
---|
506 | n/a | |
---|
507 | n/a | /* |
---|
508 | n/a | * If uid == (uid_t)-1, the user actually passed in ULONG_MAX, |
---|
509 | n/a | * but this value would get interpreted as (uid_t)-1 by chown |
---|
510 | n/a | * and its siblings. That's not what the user meant! So we |
---|
511 | n/a | * throw an overflow exception instead. (We already |
---|
512 | n/a | * handled a real -1 with PyLong_AsLongAndOverflow() above.) |
---|
513 | n/a | */ |
---|
514 | n/a | if (uid == (uid_t)-1) |
---|
515 | n/a | goto overflow; |
---|
516 | n/a | |
---|
517 | n/a | /* Ensure the value wasn't truncated. */ |
---|
518 | n/a | if (sizeof(uid_t) < sizeof(long) && |
---|
519 | n/a | (unsigned long)uid != uresult) |
---|
520 | n/a | goto overflow; |
---|
521 | n/a | /* fallthrough */ |
---|
522 | n/a | |
---|
523 | n/a | success: |
---|
524 | n/a | Py_DECREF(index); |
---|
525 | n/a | *(uid_t *)p = uid; |
---|
526 | n/a | return 1; |
---|
527 | n/a | |
---|
528 | n/a | underflow: |
---|
529 | n/a | PyErr_SetString(PyExc_OverflowError, |
---|
530 | n/a | "uid is less than minimum"); |
---|
531 | n/a | goto fail; |
---|
532 | n/a | |
---|
533 | n/a | overflow: |
---|
534 | n/a | PyErr_SetString(PyExc_OverflowError, |
---|
535 | n/a | "uid is greater than maximum"); |
---|
536 | n/a | /* fallthrough */ |
---|
537 | n/a | |
---|
538 | n/a | fail: |
---|
539 | n/a | Py_DECREF(index); |
---|
540 | n/a | return 0; |
---|
541 | n/a | } |
---|
542 | n/a | |
---|
543 | n/a | int |
---|
544 | n/a | _Py_Gid_Converter(PyObject *obj, void *p) |
---|
545 | n/a | { |
---|
546 | n/a | gid_t gid; |
---|
547 | n/a | PyObject *index; |
---|
548 | n/a | int overflow; |
---|
549 | n/a | long result; |
---|
550 | n/a | unsigned long uresult; |
---|
551 | n/a | |
---|
552 | n/a | index = PyNumber_Index(obj); |
---|
553 | n/a | if (index == NULL) { |
---|
554 | n/a | PyErr_Format(PyExc_TypeError, |
---|
555 | n/a | "gid should be integer, not %.200s", |
---|
556 | n/a | Py_TYPE(obj)->tp_name); |
---|
557 | n/a | return 0; |
---|
558 | n/a | } |
---|
559 | n/a | |
---|
560 | n/a | /* |
---|
561 | n/a | * Handling gid_t is complicated for two reasons: |
---|
562 | n/a | * * Although gid_t is (always?) unsigned, it still |
---|
563 | n/a | * accepts -1. |
---|
564 | n/a | * * We don't know its size in advance--it may be |
---|
565 | n/a | * bigger than an int, or it may be smaller than |
---|
566 | n/a | * a long. |
---|
567 | n/a | * |
---|
568 | n/a | * So a bit of defensive programming is in order. |
---|
569 | n/a | * Start with interpreting the value passed |
---|
570 | n/a | * in as a signed long and see if it works. |
---|
571 | n/a | */ |
---|
572 | n/a | |
---|
573 | n/a | result = PyLong_AsLongAndOverflow(index, &overflow); |
---|
574 | n/a | |
---|
575 | n/a | if (!overflow) { |
---|
576 | n/a | gid = (gid_t)result; |
---|
577 | n/a | |
---|
578 | n/a | if (result == -1) { |
---|
579 | n/a | if (PyErr_Occurred()) |
---|
580 | n/a | goto fail; |
---|
581 | n/a | /* It's a legitimate -1, we're done. */ |
---|
582 | n/a | goto success; |
---|
583 | n/a | } |
---|
584 | n/a | |
---|
585 | n/a | /* Any other negative number is disallowed. */ |
---|
586 | n/a | if (result < 0) { |
---|
587 | n/a | goto underflow; |
---|
588 | n/a | } |
---|
589 | n/a | |
---|
590 | n/a | /* Ensure the value wasn't truncated. */ |
---|
591 | n/a | if (sizeof(gid_t) < sizeof(long) && |
---|
592 | n/a | (long)gid != result) |
---|
593 | n/a | goto underflow; |
---|
594 | n/a | goto success; |
---|
595 | n/a | } |
---|
596 | n/a | |
---|
597 | n/a | if (overflow < 0) |
---|
598 | n/a | goto underflow; |
---|
599 | n/a | |
---|
600 | n/a | /* |
---|
601 | n/a | * Okay, the value overflowed a signed long. If it |
---|
602 | n/a | * fits in an *unsigned* long, it may still be okay, |
---|
603 | n/a | * as gid_t may be unsigned long on this platform. |
---|
604 | n/a | */ |
---|
605 | n/a | uresult = PyLong_AsUnsignedLong(index); |
---|
606 | n/a | if (PyErr_Occurred()) { |
---|
607 | n/a | if (PyErr_ExceptionMatches(PyExc_OverflowError)) |
---|
608 | n/a | goto overflow; |
---|
609 | n/a | goto fail; |
---|
610 | n/a | } |
---|
611 | n/a | |
---|
612 | n/a | gid = (gid_t)uresult; |
---|
613 | n/a | |
---|
614 | n/a | /* |
---|
615 | n/a | * If gid == (gid_t)-1, the user actually passed in ULONG_MAX, |
---|
616 | n/a | * but this value would get interpreted as (gid_t)-1 by chown |
---|
617 | n/a | * and its siblings. That's not what the user meant! So we |
---|
618 | n/a | * throw an overflow exception instead. (We already |
---|
619 | n/a | * handled a real -1 with PyLong_AsLongAndOverflow() above.) |
---|
620 | n/a | */ |
---|
621 | n/a | if (gid == (gid_t)-1) |
---|
622 | n/a | goto overflow; |
---|
623 | n/a | |
---|
624 | n/a | /* Ensure the value wasn't truncated. */ |
---|
625 | n/a | if (sizeof(gid_t) < sizeof(long) && |
---|
626 | n/a | (unsigned long)gid != uresult) |
---|
627 | n/a | goto overflow; |
---|
628 | n/a | /* fallthrough */ |
---|
629 | n/a | |
---|
630 | n/a | success: |
---|
631 | n/a | Py_DECREF(index); |
---|
632 | n/a | *(gid_t *)p = gid; |
---|
633 | n/a | return 1; |
---|
634 | n/a | |
---|
635 | n/a | underflow: |
---|
636 | n/a | PyErr_SetString(PyExc_OverflowError, |
---|
637 | n/a | "gid is less than minimum"); |
---|
638 | n/a | goto fail; |
---|
639 | n/a | |
---|
640 | n/a | overflow: |
---|
641 | n/a | PyErr_SetString(PyExc_OverflowError, |
---|
642 | n/a | "gid is greater than maximum"); |
---|
643 | n/a | /* fallthrough */ |
---|
644 | n/a | |
---|
645 | n/a | fail: |
---|
646 | n/a | Py_DECREF(index); |
---|
647 | n/a | return 0; |
---|
648 | n/a | } |
---|
649 | n/a | #endif /* MS_WINDOWS */ |
---|
650 | n/a | |
---|
651 | n/a | |
---|
652 | n/a | #define _PyLong_FromDev PyLong_FromLongLong |
---|
653 | n/a | |
---|
654 | n/a | |
---|
655 | n/a | #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) |
---|
656 | n/a | static int |
---|
657 | n/a | _Py_Dev_Converter(PyObject *obj, void *p) |
---|
658 | n/a | { |
---|
659 | n/a | *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj); |
---|
660 | n/a | if (PyErr_Occurred()) |
---|
661 | n/a | return 0; |
---|
662 | n/a | return 1; |
---|
663 | n/a | } |
---|
664 | n/a | #endif /* HAVE_MKNOD && HAVE_MAKEDEV */ |
---|
665 | n/a | |
---|
666 | n/a | |
---|
667 | n/a | #ifdef AT_FDCWD |
---|
668 | n/a | /* |
---|
669 | n/a | * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965); |
---|
670 | n/a | * without the int cast, the value gets interpreted as uint (4291925331), |
---|
671 | n/a | * which doesn't play nicely with all the initializer lines in this file that |
---|
672 | n/a | * look like this: |
---|
673 | n/a | * int dir_fd = DEFAULT_DIR_FD; |
---|
674 | n/a | */ |
---|
675 | n/a | #define DEFAULT_DIR_FD (int)AT_FDCWD |
---|
676 | n/a | #else |
---|
677 | n/a | #define DEFAULT_DIR_FD (-100) |
---|
678 | n/a | #endif |
---|
679 | n/a | |
---|
680 | n/a | static int |
---|
681 | n/a | _fd_converter(PyObject *o, int *p) |
---|
682 | n/a | { |
---|
683 | n/a | int overflow; |
---|
684 | n/a | long long_value; |
---|
685 | n/a | |
---|
686 | n/a | PyObject *index = PyNumber_Index(o); |
---|
687 | n/a | if (index == NULL) { |
---|
688 | n/a | return 0; |
---|
689 | n/a | } |
---|
690 | n/a | |
---|
691 | n/a | assert(PyLong_Check(index)); |
---|
692 | n/a | long_value = PyLong_AsLongAndOverflow(index, &overflow); |
---|
693 | n/a | Py_DECREF(index); |
---|
694 | n/a | assert(!PyErr_Occurred()); |
---|
695 | n/a | if (overflow > 0 || long_value > INT_MAX) { |
---|
696 | n/a | PyErr_SetString(PyExc_OverflowError, |
---|
697 | n/a | "fd is greater than maximum"); |
---|
698 | n/a | return 0; |
---|
699 | n/a | } |
---|
700 | n/a | if (overflow < 0 || long_value < INT_MIN) { |
---|
701 | n/a | PyErr_SetString(PyExc_OverflowError, |
---|
702 | n/a | "fd is less than minimum"); |
---|
703 | n/a | return 0; |
---|
704 | n/a | } |
---|
705 | n/a | |
---|
706 | n/a | *p = (int)long_value; |
---|
707 | n/a | return 1; |
---|
708 | n/a | } |
---|
709 | n/a | |
---|
710 | n/a | static int |
---|
711 | n/a | dir_fd_converter(PyObject *o, void *p) |
---|
712 | n/a | { |
---|
713 | n/a | if (o == Py_None) { |
---|
714 | n/a | *(int *)p = DEFAULT_DIR_FD; |
---|
715 | n/a | return 1; |
---|
716 | n/a | } |
---|
717 | n/a | else if (PyIndex_Check(o)) { |
---|
718 | n/a | return _fd_converter(o, (int *)p); |
---|
719 | n/a | } |
---|
720 | n/a | else { |
---|
721 | n/a | PyErr_Format(PyExc_TypeError, |
---|
722 | n/a | "argument should be integer or None, not %.200s", |
---|
723 | n/a | Py_TYPE(o)->tp_name); |
---|
724 | n/a | return 0; |
---|
725 | n/a | } |
---|
726 | n/a | } |
---|
727 | n/a | |
---|
728 | n/a | |
---|
729 | n/a | /* |
---|
730 | n/a | * A PyArg_ParseTuple "converter" function |
---|
731 | n/a | * that handles filesystem paths in the manner |
---|
732 | n/a | * preferred by the os module. |
---|
733 | n/a | * |
---|
734 | n/a | * path_converter accepts (Unicode) strings and their |
---|
735 | n/a | * subclasses, and bytes and their subclasses. What |
---|
736 | n/a | * it does with the argument depends on the platform: |
---|
737 | n/a | * |
---|
738 | n/a | * * On Windows, if we get a (Unicode) string we |
---|
739 | n/a | * extract the wchar_t * and return it; if we get |
---|
740 | n/a | * bytes we decode to wchar_t * and return that. |
---|
741 | n/a | * |
---|
742 | n/a | * * On all other platforms, strings are encoded |
---|
743 | n/a | * to bytes using PyUnicode_FSConverter, then we |
---|
744 | n/a | * extract the char * from the bytes object and |
---|
745 | n/a | * return that. |
---|
746 | n/a | * |
---|
747 | n/a | * path_converter also optionally accepts signed |
---|
748 | n/a | * integers (representing open file descriptors) instead |
---|
749 | n/a | * of path strings. |
---|
750 | n/a | * |
---|
751 | n/a | * Input fields: |
---|
752 | n/a | * path.nullable |
---|
753 | n/a | * If nonzero, the path is permitted to be None. |
---|
754 | n/a | * path.allow_fd |
---|
755 | n/a | * If nonzero, the path is permitted to be a file handle |
---|
756 | n/a | * (a signed int) instead of a string. |
---|
757 | n/a | * path.function_name |
---|
758 | n/a | * If non-NULL, path_converter will use that as the name |
---|
759 | n/a | * of the function in error messages. |
---|
760 | n/a | * (If path.function_name is NULL it omits the function name.) |
---|
761 | n/a | * path.argument_name |
---|
762 | n/a | * If non-NULL, path_converter will use that as the name |
---|
763 | n/a | * of the parameter in error messages. |
---|
764 | n/a | * (If path.argument_name is NULL it uses "path".) |
---|
765 | n/a | * |
---|
766 | n/a | * Output fields: |
---|
767 | n/a | * path.wide |
---|
768 | n/a | * Points to the path if it was expressed as Unicode |
---|
769 | n/a | * and was not encoded. (Only used on Windows.) |
---|
770 | n/a | * path.narrow |
---|
771 | n/a | * Points to the path if it was expressed as bytes, |
---|
772 | n/a | * or it was Unicode and was encoded to bytes. (On Windows, |
---|
773 | n/a | * is a non-zero integer if the path was expressed as bytes. |
---|
774 | n/a | * The type is deliberately incompatible to prevent misuse.) |
---|
775 | n/a | * path.fd |
---|
776 | n/a | * Contains a file descriptor if path.accept_fd was true |
---|
777 | n/a | * and the caller provided a signed integer instead of any |
---|
778 | n/a | * sort of string. |
---|
779 | n/a | * |
---|
780 | n/a | * WARNING: if your "path" parameter is optional, and is |
---|
781 | n/a | * unspecified, path_converter will never get called. |
---|
782 | n/a | * So if you set allow_fd, you *MUST* initialize path.fd = -1 |
---|
783 | n/a | * yourself! |
---|
784 | n/a | * path.length |
---|
785 | n/a | * The length of the path in characters, if specified as |
---|
786 | n/a | * a string. |
---|
787 | n/a | * path.object |
---|
788 | n/a | * The original object passed in (if get a PathLike object, |
---|
789 | n/a | * the result of PyOS_FSPath() is treated as the original object). |
---|
790 | n/a | * Own a reference to the object. |
---|
791 | n/a | * path.cleanup |
---|
792 | n/a | * For internal use only. May point to a temporary object. |
---|
793 | n/a | * (Pay no attention to the man behind the curtain.) |
---|
794 | n/a | * |
---|
795 | n/a | * At most one of path.wide or path.narrow will be non-NULL. |
---|
796 | n/a | * If path was None and path.nullable was set, |
---|
797 | n/a | * or if path was an integer and path.allow_fd was set, |
---|
798 | n/a | * both path.wide and path.narrow will be NULL |
---|
799 | n/a | * and path.length will be 0. |
---|
800 | n/a | * |
---|
801 | n/a | * path_converter takes care to not write to the path_t |
---|
802 | n/a | * unless it's successful. However it must reset the |
---|
803 | n/a | * "cleanup" field each time it's called. |
---|
804 | n/a | * |
---|
805 | n/a | * Use as follows: |
---|
806 | n/a | * path_t path; |
---|
807 | n/a | * memset(&path, 0, sizeof(path)); |
---|
808 | n/a | * PyArg_ParseTuple(args, "O&", path_converter, &path); |
---|
809 | n/a | * // ... use values from path ... |
---|
810 | n/a | * path_cleanup(&path); |
---|
811 | n/a | * |
---|
812 | n/a | * (Note that if PyArg_Parse fails you don't need to call |
---|
813 | n/a | * path_cleanup(). However it is safe to do so.) |
---|
814 | n/a | */ |
---|
815 | n/a | typedef struct { |
---|
816 | n/a | const char *function_name; |
---|
817 | n/a | const char *argument_name; |
---|
818 | n/a | int nullable; |
---|
819 | n/a | int allow_fd; |
---|
820 | n/a | const wchar_t *wide; |
---|
821 | n/a | #ifdef MS_WINDOWS |
---|
822 | n/a | BOOL narrow; |
---|
823 | n/a | #else |
---|
824 | n/a | const char *narrow; |
---|
825 | n/a | #endif |
---|
826 | n/a | int fd; |
---|
827 | n/a | Py_ssize_t length; |
---|
828 | n/a | PyObject *object; |
---|
829 | n/a | PyObject *cleanup; |
---|
830 | n/a | } path_t; |
---|
831 | n/a | |
---|
832 | n/a | #ifdef MS_WINDOWS |
---|
833 | n/a | #define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \ |
---|
834 | n/a | {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL} |
---|
835 | n/a | #else |
---|
836 | n/a | #define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \ |
---|
837 | n/a | {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL} |
---|
838 | n/a | #endif |
---|
839 | n/a | |
---|
840 | n/a | static void |
---|
841 | n/a | path_cleanup(path_t *path) |
---|
842 | n/a | { |
---|
843 | n/a | Py_CLEAR(path->object); |
---|
844 | n/a | Py_CLEAR(path->cleanup); |
---|
845 | n/a | } |
---|
846 | n/a | |
---|
847 | n/a | static int |
---|
848 | n/a | path_converter(PyObject *o, void *p) |
---|
849 | n/a | { |
---|
850 | n/a | path_t *path = (path_t *)p; |
---|
851 | n/a | PyObject *bytes = NULL; |
---|
852 | n/a | Py_ssize_t length = 0; |
---|
853 | n/a | int is_index, is_buffer, is_bytes, is_unicode; |
---|
854 | n/a | const char *narrow; |
---|
855 | n/a | #ifdef MS_WINDOWS |
---|
856 | n/a | PyObject *wo = NULL; |
---|
857 | n/a | const wchar_t *wide; |
---|
858 | n/a | #endif |
---|
859 | n/a | |
---|
860 | n/a | #define FORMAT_EXCEPTION(exc, fmt) \ |
---|
861 | n/a | PyErr_Format(exc, "%s%s" fmt, \ |
---|
862 | n/a | path->function_name ? path->function_name : "", \ |
---|
863 | n/a | path->function_name ? ": " : "", \ |
---|
864 | n/a | path->argument_name ? path->argument_name : "path") |
---|
865 | n/a | |
---|
866 | n/a | /* Py_CLEANUP_SUPPORTED support */ |
---|
867 | n/a | if (o == NULL) { |
---|
868 | n/a | path_cleanup(path); |
---|
869 | n/a | return 1; |
---|
870 | n/a | } |
---|
871 | n/a | |
---|
872 | n/a | /* Ensure it's always safe to call path_cleanup(). */ |
---|
873 | n/a | path->object = path->cleanup = NULL; |
---|
874 | n/a | /* path->object owns a reference to the original object */ |
---|
875 | n/a | Py_INCREF(o); |
---|
876 | n/a | |
---|
877 | n/a | if ((o == Py_None) && path->nullable) { |
---|
878 | n/a | path->wide = NULL; |
---|
879 | n/a | #ifdef MS_WINDOWS |
---|
880 | n/a | path->narrow = FALSE; |
---|
881 | n/a | #else |
---|
882 | n/a | path->narrow = NULL; |
---|
883 | n/a | #endif |
---|
884 | n/a | path->fd = -1; |
---|
885 | n/a | goto success_exit; |
---|
886 | n/a | } |
---|
887 | n/a | |
---|
888 | n/a | /* Only call this here so that we don't treat the return value of |
---|
889 | n/a | os.fspath() as an fd or buffer. */ |
---|
890 | n/a | is_index = path->allow_fd && PyIndex_Check(o); |
---|
891 | n/a | is_buffer = PyObject_CheckBuffer(o); |
---|
892 | n/a | is_bytes = PyBytes_Check(o); |
---|
893 | n/a | is_unicode = PyUnicode_Check(o); |
---|
894 | n/a | |
---|
895 | n/a | if (!is_index && !is_buffer && !is_unicode && !is_bytes) { |
---|
896 | n/a | /* Inline PyOS_FSPath() for better error messages. */ |
---|
897 | n/a | _Py_IDENTIFIER(__fspath__); |
---|
898 | n/a | PyObject *func = NULL; |
---|
899 | n/a | |
---|
900 | n/a | func = _PyObject_LookupSpecial(o, &PyId___fspath__); |
---|
901 | n/a | if (NULL == func) { |
---|
902 | n/a | goto error_format; |
---|
903 | n/a | } |
---|
904 | n/a | /* still owns a reference to the original object */ |
---|
905 | n/a | Py_DECREF(o); |
---|
906 | n/a | o = _PyObject_CallNoArg(func); |
---|
907 | n/a | Py_DECREF(func); |
---|
908 | n/a | if (NULL == o) { |
---|
909 | n/a | goto error_exit; |
---|
910 | n/a | } |
---|
911 | n/a | else if (PyUnicode_Check(o)) { |
---|
912 | n/a | is_unicode = 1; |
---|
913 | n/a | } |
---|
914 | n/a | else if (PyBytes_Check(o)) { |
---|
915 | n/a | is_bytes = 1; |
---|
916 | n/a | } |
---|
917 | n/a | else { |
---|
918 | n/a | goto error_format; |
---|
919 | n/a | } |
---|
920 | n/a | } |
---|
921 | n/a | |
---|
922 | n/a | if (is_unicode) { |
---|
923 | n/a | #ifdef MS_WINDOWS |
---|
924 | n/a | wide = PyUnicode_AsUnicodeAndSize(o, &length); |
---|
925 | n/a | if (!wide) { |
---|
926 | n/a | goto error_exit; |
---|
927 | n/a | } |
---|
928 | n/a | if (length > 32767) { |
---|
929 | n/a | FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows"); |
---|
930 | n/a | goto error_exit; |
---|
931 | n/a | } |
---|
932 | n/a | if (wcslen(wide) != length) { |
---|
933 | n/a | FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s"); |
---|
934 | n/a | goto error_exit; |
---|
935 | n/a | } |
---|
936 | n/a | |
---|
937 | n/a | path->wide = wide; |
---|
938 | n/a | path->narrow = FALSE; |
---|
939 | n/a | path->fd = -1; |
---|
940 | n/a | goto success_exit; |
---|
941 | n/a | #else |
---|
942 | n/a | if (!PyUnicode_FSConverter(o, &bytes)) { |
---|
943 | n/a | goto error_exit; |
---|
944 | n/a | } |
---|
945 | n/a | #endif |
---|
946 | n/a | } |
---|
947 | n/a | else if (is_bytes) { |
---|
948 | n/a | bytes = o; |
---|
949 | n/a | Py_INCREF(bytes); |
---|
950 | n/a | } |
---|
951 | n/a | else if (is_buffer) { |
---|
952 | n/a | if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, |
---|
953 | n/a | "%s%s%s should be %s, not %.200s", |
---|
954 | n/a | path->function_name ? path->function_name : "", |
---|
955 | n/a | path->function_name ? ": " : "", |
---|
956 | n/a | path->argument_name ? path->argument_name : "path", |
---|
957 | n/a | path->allow_fd && path->nullable ? "string, bytes, os.PathLike, " |
---|
958 | n/a | "integer or None" : |
---|
959 | n/a | path->allow_fd ? "string, bytes, os.PathLike or integer" : |
---|
960 | n/a | path->nullable ? "string, bytes, os.PathLike or None" : |
---|
961 | n/a | "string, bytes or os.PathLike", |
---|
962 | n/a | Py_TYPE(o)->tp_name)) { |
---|
963 | n/a | goto error_exit; |
---|
964 | n/a | } |
---|
965 | n/a | bytes = PyBytes_FromObject(o); |
---|
966 | n/a | if (!bytes) { |
---|
967 | n/a | goto error_exit; |
---|
968 | n/a | } |
---|
969 | n/a | } |
---|
970 | n/a | else if (is_index) { |
---|
971 | n/a | if (!_fd_converter(o, &path->fd)) { |
---|
972 | n/a | goto error_exit; |
---|
973 | n/a | } |
---|
974 | n/a | path->wide = NULL; |
---|
975 | n/a | #ifdef MS_WINDOWS |
---|
976 | n/a | path->narrow = FALSE; |
---|
977 | n/a | #else |
---|
978 | n/a | path->narrow = NULL; |
---|
979 | n/a | #endif |
---|
980 | n/a | goto success_exit; |
---|
981 | n/a | } |
---|
982 | n/a | else { |
---|
983 | n/a | error_format: |
---|
984 | n/a | PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s", |
---|
985 | n/a | path->function_name ? path->function_name : "", |
---|
986 | n/a | path->function_name ? ": " : "", |
---|
987 | n/a | path->argument_name ? path->argument_name : "path", |
---|
988 | n/a | path->allow_fd && path->nullable ? "string, bytes, os.PathLike, " |
---|
989 | n/a | "integer or None" : |
---|
990 | n/a | path->allow_fd ? "string, bytes, os.PathLike or integer" : |
---|
991 | n/a | path->nullable ? "string, bytes, os.PathLike or None" : |
---|
992 | n/a | "string, bytes or os.PathLike", |
---|
993 | n/a | Py_TYPE(o)->tp_name); |
---|
994 | n/a | goto error_exit; |
---|
995 | n/a | } |
---|
996 | n/a | |
---|
997 | n/a | length = PyBytes_GET_SIZE(bytes); |
---|
998 | n/a | narrow = PyBytes_AS_STRING(bytes); |
---|
999 | n/a | if ((size_t)length != strlen(narrow)) { |
---|
1000 | n/a | FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s"); |
---|
1001 | n/a | goto error_exit; |
---|
1002 | n/a | } |
---|
1003 | n/a | |
---|
1004 | n/a | #ifdef MS_WINDOWS |
---|
1005 | n/a | wo = PyUnicode_DecodeFSDefaultAndSize( |
---|
1006 | n/a | narrow, |
---|
1007 | n/a | length |
---|
1008 | n/a | ); |
---|
1009 | n/a | if (!wo) { |
---|
1010 | n/a | goto error_exit; |
---|
1011 | n/a | } |
---|
1012 | n/a | |
---|
1013 | n/a | wide = PyUnicode_AsUnicodeAndSize(wo, &length); |
---|
1014 | n/a | if (!wide) { |
---|
1015 | n/a | goto error_exit; |
---|
1016 | n/a | } |
---|
1017 | n/a | if (length > 32767) { |
---|
1018 | n/a | FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows"); |
---|
1019 | n/a | goto error_exit; |
---|
1020 | n/a | } |
---|
1021 | n/a | if (wcslen(wide) != length) { |
---|
1022 | n/a | FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s"); |
---|
1023 | n/a | goto error_exit; |
---|
1024 | n/a | } |
---|
1025 | n/a | path->wide = wide; |
---|
1026 | n/a | path->narrow = TRUE; |
---|
1027 | n/a | path->cleanup = wo; |
---|
1028 | n/a | Py_DECREF(bytes); |
---|
1029 | n/a | #else |
---|
1030 | n/a | path->wide = NULL; |
---|
1031 | n/a | path->narrow = narrow; |
---|
1032 | n/a | if (bytes == o) { |
---|
1033 | n/a | /* Still a reference owned by path->object, don't have to |
---|
1034 | n/a | worry about path->narrow is used after free. */ |
---|
1035 | n/a | Py_DECREF(bytes); |
---|
1036 | n/a | } |
---|
1037 | n/a | else { |
---|
1038 | n/a | path->cleanup = bytes; |
---|
1039 | n/a | } |
---|
1040 | n/a | #endif |
---|
1041 | n/a | path->fd = -1; |
---|
1042 | n/a | |
---|
1043 | n/a | success_exit: |
---|
1044 | n/a | path->length = length; |
---|
1045 | n/a | path->object = o; |
---|
1046 | n/a | return Py_CLEANUP_SUPPORTED; |
---|
1047 | n/a | |
---|
1048 | n/a | error_exit: |
---|
1049 | n/a | Py_XDECREF(o); |
---|
1050 | n/a | Py_XDECREF(bytes); |
---|
1051 | n/a | #ifdef MS_WINDOWS |
---|
1052 | n/a | Py_XDECREF(wo); |
---|
1053 | n/a | #endif |
---|
1054 | n/a | return 0; |
---|
1055 | n/a | } |
---|
1056 | n/a | |
---|
1057 | n/a | static void |
---|
1058 | n/a | argument_unavailable_error(const char *function_name, const char *argument_name) |
---|
1059 | n/a | { |
---|
1060 | n/a | PyErr_Format(PyExc_NotImplementedError, |
---|
1061 | n/a | "%s%s%s unavailable on this platform", |
---|
1062 | n/a | (function_name != NULL) ? function_name : "", |
---|
1063 | n/a | (function_name != NULL) ? ": ": "", |
---|
1064 | n/a | argument_name); |
---|
1065 | n/a | } |
---|
1066 | n/a | |
---|
1067 | n/a | static int |
---|
1068 | n/a | dir_fd_unavailable(PyObject *o, void *p) |
---|
1069 | n/a | { |
---|
1070 | n/a | int dir_fd; |
---|
1071 | n/a | if (!dir_fd_converter(o, &dir_fd)) |
---|
1072 | n/a | return 0; |
---|
1073 | n/a | if (dir_fd != DEFAULT_DIR_FD) { |
---|
1074 | n/a | argument_unavailable_error(NULL, "dir_fd"); |
---|
1075 | n/a | return 0; |
---|
1076 | n/a | } |
---|
1077 | n/a | *(int *)p = dir_fd; |
---|
1078 | n/a | return 1; |
---|
1079 | n/a | } |
---|
1080 | n/a | |
---|
1081 | n/a | static int |
---|
1082 | n/a | fd_specified(const char *function_name, int fd) |
---|
1083 | n/a | { |
---|
1084 | n/a | if (fd == -1) |
---|
1085 | n/a | return 0; |
---|
1086 | n/a | |
---|
1087 | n/a | argument_unavailable_error(function_name, "fd"); |
---|
1088 | n/a | return 1; |
---|
1089 | n/a | } |
---|
1090 | n/a | |
---|
1091 | n/a | static int |
---|
1092 | n/a | follow_symlinks_specified(const char *function_name, int follow_symlinks) |
---|
1093 | n/a | { |
---|
1094 | n/a | if (follow_symlinks) |
---|
1095 | n/a | return 0; |
---|
1096 | n/a | |
---|
1097 | n/a | argument_unavailable_error(function_name, "follow_symlinks"); |
---|
1098 | n/a | return 1; |
---|
1099 | n/a | } |
---|
1100 | n/a | |
---|
1101 | n/a | static int |
---|
1102 | n/a | path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd) |
---|
1103 | n/a | { |
---|
1104 | n/a | if (!path->wide && (dir_fd != DEFAULT_DIR_FD) |
---|
1105 | n/a | #ifndef MS_WINDOWS |
---|
1106 | n/a | && !path->narrow |
---|
1107 | n/a | #endif |
---|
1108 | n/a | ) { |
---|
1109 | n/a | PyErr_Format(PyExc_ValueError, |
---|
1110 | n/a | "%s: can't specify dir_fd without matching path", |
---|
1111 | n/a | function_name); |
---|
1112 | n/a | return 1; |
---|
1113 | n/a | } |
---|
1114 | n/a | return 0; |
---|
1115 | n/a | } |
---|
1116 | n/a | |
---|
1117 | n/a | static int |
---|
1118 | n/a | dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd) |
---|
1119 | n/a | { |
---|
1120 | n/a | if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) { |
---|
1121 | n/a | PyErr_Format(PyExc_ValueError, |
---|
1122 | n/a | "%s: can't specify both dir_fd and fd", |
---|
1123 | n/a | function_name); |
---|
1124 | n/a | return 1; |
---|
1125 | n/a | } |
---|
1126 | n/a | return 0; |
---|
1127 | n/a | } |
---|
1128 | n/a | |
---|
1129 | n/a | static int |
---|
1130 | n/a | fd_and_follow_symlinks_invalid(const char *function_name, int fd, |
---|
1131 | n/a | int follow_symlinks) |
---|
1132 | n/a | { |
---|
1133 | n/a | if ((fd > 0) && (!follow_symlinks)) { |
---|
1134 | n/a | PyErr_Format(PyExc_ValueError, |
---|
1135 | n/a | "%s: cannot use fd and follow_symlinks together", |
---|
1136 | n/a | function_name); |
---|
1137 | n/a | return 1; |
---|
1138 | n/a | } |
---|
1139 | n/a | return 0; |
---|
1140 | n/a | } |
---|
1141 | n/a | |
---|
1142 | n/a | static int |
---|
1143 | n/a | dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd, |
---|
1144 | n/a | int follow_symlinks) |
---|
1145 | n/a | { |
---|
1146 | n/a | if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) { |
---|
1147 | n/a | PyErr_Format(PyExc_ValueError, |
---|
1148 | n/a | "%s: cannot use dir_fd and follow_symlinks together", |
---|
1149 | n/a | function_name); |
---|
1150 | n/a | return 1; |
---|
1151 | n/a | } |
---|
1152 | n/a | return 0; |
---|
1153 | n/a | } |
---|
1154 | n/a | |
---|
1155 | n/a | #ifdef MS_WINDOWS |
---|
1156 | n/a | typedef long long Py_off_t; |
---|
1157 | n/a | #else |
---|
1158 | n/a | typedef off_t Py_off_t; |
---|
1159 | n/a | #endif |
---|
1160 | n/a | |
---|
1161 | n/a | static int |
---|
1162 | n/a | Py_off_t_converter(PyObject *arg, void *addr) |
---|
1163 | n/a | { |
---|
1164 | n/a | #ifdef HAVE_LARGEFILE_SUPPORT |
---|
1165 | n/a | *((Py_off_t *)addr) = PyLong_AsLongLong(arg); |
---|
1166 | n/a | #else |
---|
1167 | n/a | *((Py_off_t *)addr) = PyLong_AsLong(arg); |
---|
1168 | n/a | #endif |
---|
1169 | n/a | if (PyErr_Occurred()) |
---|
1170 | n/a | return 0; |
---|
1171 | n/a | return 1; |
---|
1172 | n/a | } |
---|
1173 | n/a | |
---|
1174 | n/a | static PyObject * |
---|
1175 | n/a | PyLong_FromPy_off_t(Py_off_t offset) |
---|
1176 | n/a | { |
---|
1177 | n/a | #ifdef HAVE_LARGEFILE_SUPPORT |
---|
1178 | n/a | return PyLong_FromLongLong(offset); |
---|
1179 | n/a | #else |
---|
1180 | n/a | return PyLong_FromLong(offset); |
---|
1181 | n/a | #endif |
---|
1182 | n/a | } |
---|
1183 | n/a | |
---|
1184 | n/a | #ifdef MS_WINDOWS |
---|
1185 | n/a | |
---|
1186 | n/a | static int |
---|
1187 | n/a | win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag) |
---|
1188 | n/a | { |
---|
1189 | n/a | char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; |
---|
1190 | n/a | _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer; |
---|
1191 | n/a | DWORD n_bytes_returned; |
---|
1192 | n/a | |
---|
1193 | n/a | if (0 == DeviceIoControl( |
---|
1194 | n/a | reparse_point_handle, |
---|
1195 | n/a | FSCTL_GET_REPARSE_POINT, |
---|
1196 | n/a | NULL, 0, /* in buffer */ |
---|
1197 | n/a | target_buffer, sizeof(target_buffer), |
---|
1198 | n/a | &n_bytes_returned, |
---|
1199 | n/a | NULL)) /* we're not using OVERLAPPED_IO */ |
---|
1200 | n/a | return FALSE; |
---|
1201 | n/a | |
---|
1202 | n/a | if (reparse_tag) |
---|
1203 | n/a | *reparse_tag = rdb->ReparseTag; |
---|
1204 | n/a | |
---|
1205 | n/a | return TRUE; |
---|
1206 | n/a | } |
---|
1207 | n/a | |
---|
1208 | n/a | #endif /* MS_WINDOWS */ |
---|
1209 | n/a | |
---|
1210 | n/a | /* Return a dictionary corresponding to the POSIX environment table */ |
---|
1211 | n/a | #if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED)) |
---|
1212 | n/a | /* On Darwin/MacOSX a shared library or framework has no access to |
---|
1213 | n/a | ** environ directly, we must obtain it with _NSGetEnviron(). See also |
---|
1214 | n/a | ** man environ(7). |
---|
1215 | n/a | */ |
---|
1216 | n/a | #include <crt_externs.h> |
---|
1217 | n/a | static char **environ; |
---|
1218 | n/a | #elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) ) |
---|
1219 | n/a | extern char **environ; |
---|
1220 | n/a | #endif /* !_MSC_VER */ |
---|
1221 | n/a | |
---|
1222 | n/a | static PyObject * |
---|
1223 | n/a | convertenviron(void) |
---|
1224 | n/a | { |
---|
1225 | n/a | PyObject *d; |
---|
1226 | n/a | #ifdef MS_WINDOWS |
---|
1227 | n/a | wchar_t **e; |
---|
1228 | n/a | #else |
---|
1229 | n/a | char **e; |
---|
1230 | n/a | #endif |
---|
1231 | n/a | |
---|
1232 | n/a | d = PyDict_New(); |
---|
1233 | n/a | if (d == NULL) |
---|
1234 | n/a | return NULL; |
---|
1235 | n/a | #if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED)) |
---|
1236 | n/a | if (environ == NULL) |
---|
1237 | n/a | environ = *_NSGetEnviron(); |
---|
1238 | n/a | #endif |
---|
1239 | n/a | #ifdef MS_WINDOWS |
---|
1240 | n/a | /* _wenviron must be initialized in this way if the program is started |
---|
1241 | n/a | through main() instead of wmain(). */ |
---|
1242 | n/a | _wgetenv(L""); |
---|
1243 | n/a | if (_wenviron == NULL) |
---|
1244 | n/a | return d; |
---|
1245 | n/a | /* This part ignores errors */ |
---|
1246 | n/a | for (e = _wenviron; *e != NULL; e++) { |
---|
1247 | n/a | PyObject *k; |
---|
1248 | n/a | PyObject *v; |
---|
1249 | n/a | const wchar_t *p = wcschr(*e, L'='); |
---|
1250 | n/a | if (p == NULL) |
---|
1251 | n/a | continue; |
---|
1252 | n/a | k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e)); |
---|
1253 | n/a | if (k == NULL) { |
---|
1254 | n/a | PyErr_Clear(); |
---|
1255 | n/a | continue; |
---|
1256 | n/a | } |
---|
1257 | n/a | v = PyUnicode_FromWideChar(p+1, wcslen(p+1)); |
---|
1258 | n/a | if (v == NULL) { |
---|
1259 | n/a | PyErr_Clear(); |
---|
1260 | n/a | Py_DECREF(k); |
---|
1261 | n/a | continue; |
---|
1262 | n/a | } |
---|
1263 | n/a | if (PyDict_GetItem(d, k) == NULL) { |
---|
1264 | n/a | if (PyDict_SetItem(d, k, v) != 0) |
---|
1265 | n/a | PyErr_Clear(); |
---|
1266 | n/a | } |
---|
1267 | n/a | Py_DECREF(k); |
---|
1268 | n/a | Py_DECREF(v); |
---|
1269 | n/a | } |
---|
1270 | n/a | #else |
---|
1271 | n/a | if (environ == NULL) |
---|
1272 | n/a | return d; |
---|
1273 | n/a | /* This part ignores errors */ |
---|
1274 | n/a | for (e = environ; *e != NULL; e++) { |
---|
1275 | n/a | PyObject *k; |
---|
1276 | n/a | PyObject *v; |
---|
1277 | n/a | const char *p = strchr(*e, '='); |
---|
1278 | n/a | if (p == NULL) |
---|
1279 | n/a | continue; |
---|
1280 | n/a | k = PyBytes_FromStringAndSize(*e, (int)(p-*e)); |
---|
1281 | n/a | if (k == NULL) { |
---|
1282 | n/a | PyErr_Clear(); |
---|
1283 | n/a | continue; |
---|
1284 | n/a | } |
---|
1285 | n/a | v = PyBytes_FromStringAndSize(p+1, strlen(p+1)); |
---|
1286 | n/a | if (v == NULL) { |
---|
1287 | n/a | PyErr_Clear(); |
---|
1288 | n/a | Py_DECREF(k); |
---|
1289 | n/a | continue; |
---|
1290 | n/a | } |
---|
1291 | n/a | if (PyDict_GetItem(d, k) == NULL) { |
---|
1292 | n/a | if (PyDict_SetItem(d, k, v) != 0) |
---|
1293 | n/a | PyErr_Clear(); |
---|
1294 | n/a | } |
---|
1295 | n/a | Py_DECREF(k); |
---|
1296 | n/a | Py_DECREF(v); |
---|
1297 | n/a | } |
---|
1298 | n/a | #endif |
---|
1299 | n/a | return d; |
---|
1300 | n/a | } |
---|
1301 | n/a | |
---|
1302 | n/a | /* Set a POSIX-specific error from errno, and return NULL */ |
---|
1303 | n/a | |
---|
1304 | n/a | static PyObject * |
---|
1305 | n/a | posix_error(void) |
---|
1306 | n/a | { |
---|
1307 | n/a | return PyErr_SetFromErrno(PyExc_OSError); |
---|
1308 | n/a | } |
---|
1309 | n/a | |
---|
1310 | n/a | #ifdef MS_WINDOWS |
---|
1311 | n/a | static PyObject * |
---|
1312 | n/a | win32_error(const char* function, const char* filename) |
---|
1313 | n/a | { |
---|
1314 | n/a | /* XXX We should pass the function name along in the future. |
---|
1315 | n/a | (winreg.c also wants to pass the function name.) |
---|
1316 | n/a | This would however require an additional param to the |
---|
1317 | n/a | Windows error object, which is non-trivial. |
---|
1318 | n/a | */ |
---|
1319 | n/a | errno = GetLastError(); |
---|
1320 | n/a | if (filename) |
---|
1321 | n/a | return PyErr_SetFromWindowsErrWithFilename(errno, filename); |
---|
1322 | n/a | else |
---|
1323 | n/a | return PyErr_SetFromWindowsErr(errno); |
---|
1324 | n/a | } |
---|
1325 | n/a | |
---|
1326 | n/a | static PyObject * |
---|
1327 | n/a | win32_error_object(const char* function, PyObject* filename) |
---|
1328 | n/a | { |
---|
1329 | n/a | /* XXX - see win32_error for comments on 'function' */ |
---|
1330 | n/a | errno = GetLastError(); |
---|
1331 | n/a | if (filename) |
---|
1332 | n/a | return PyErr_SetExcFromWindowsErrWithFilenameObject( |
---|
1333 | n/a | PyExc_OSError, |
---|
1334 | n/a | errno, |
---|
1335 | n/a | filename); |
---|
1336 | n/a | else |
---|
1337 | n/a | return PyErr_SetFromWindowsErr(errno); |
---|
1338 | n/a | } |
---|
1339 | n/a | |
---|
1340 | n/a | #endif /* MS_WINDOWS */ |
---|
1341 | n/a | |
---|
1342 | n/a | static PyObject * |
---|
1343 | n/a | path_object_error(PyObject *path) |
---|
1344 | n/a | { |
---|
1345 | n/a | #ifdef MS_WINDOWS |
---|
1346 | n/a | return PyErr_SetExcFromWindowsErrWithFilenameObject( |
---|
1347 | n/a | PyExc_OSError, 0, path); |
---|
1348 | n/a | #else |
---|
1349 | n/a | return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path); |
---|
1350 | n/a | #endif |
---|
1351 | n/a | } |
---|
1352 | n/a | |
---|
1353 | n/a | static PyObject * |
---|
1354 | n/a | path_object_error2(PyObject *path, PyObject *path2) |
---|
1355 | n/a | { |
---|
1356 | n/a | #ifdef MS_WINDOWS |
---|
1357 | n/a | return PyErr_SetExcFromWindowsErrWithFilenameObjects( |
---|
1358 | n/a | PyExc_OSError, 0, path, path2); |
---|
1359 | n/a | #else |
---|
1360 | n/a | return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, path, path2); |
---|
1361 | n/a | #endif |
---|
1362 | n/a | } |
---|
1363 | n/a | |
---|
1364 | n/a | static PyObject * |
---|
1365 | n/a | path_error(path_t *path) |
---|
1366 | n/a | { |
---|
1367 | n/a | return path_object_error(path->object); |
---|
1368 | n/a | } |
---|
1369 | n/a | |
---|
1370 | n/a | static PyObject * |
---|
1371 | n/a | path_error2(path_t *path, path_t *path2) |
---|
1372 | n/a | { |
---|
1373 | n/a | return path_object_error2(path->object, path2->object); |
---|
1374 | n/a | } |
---|
1375 | n/a | |
---|
1376 | n/a | |
---|
1377 | n/a | /* POSIX generic methods */ |
---|
1378 | n/a | |
---|
1379 | n/a | static int |
---|
1380 | n/a | fildes_converter(PyObject *o, void *p) |
---|
1381 | n/a | { |
---|
1382 | n/a | int fd; |
---|
1383 | n/a | int *pointer = (int *)p; |
---|
1384 | n/a | fd = PyObject_AsFileDescriptor(o); |
---|
1385 | n/a | if (fd < 0) |
---|
1386 | n/a | return 0; |
---|
1387 | n/a | *pointer = fd; |
---|
1388 | n/a | return 1; |
---|
1389 | n/a | } |
---|
1390 | n/a | |
---|
1391 | n/a | static PyObject * |
---|
1392 | n/a | posix_fildes_fd(int fd, int (*func)(int)) |
---|
1393 | n/a | { |
---|
1394 | n/a | int res; |
---|
1395 | n/a | int async_err = 0; |
---|
1396 | n/a | |
---|
1397 | n/a | do { |
---|
1398 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
1399 | n/a | _Py_BEGIN_SUPPRESS_IPH |
---|
1400 | n/a | res = (*func)(fd); |
---|
1401 | n/a | _Py_END_SUPPRESS_IPH |
---|
1402 | n/a | Py_END_ALLOW_THREADS |
---|
1403 | n/a | } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); |
---|
1404 | n/a | if (res != 0) |
---|
1405 | n/a | return (!async_err) ? posix_error() : NULL; |
---|
1406 | n/a | Py_RETURN_NONE; |
---|
1407 | n/a | } |
---|
1408 | n/a | |
---|
1409 | n/a | |
---|
1410 | n/a | #ifdef MS_WINDOWS |
---|
1411 | n/a | /* This is a reimplementation of the C library's chdir function, |
---|
1412 | n/a | but one that produces Win32 errors instead of DOS error codes. |
---|
1413 | n/a | chdir is essentially a wrapper around SetCurrentDirectory; however, |
---|
1414 | n/a | it also needs to set "magic" environment variables indicating |
---|
1415 | n/a | the per-drive current directory, which are of the form =<drive>: */ |
---|
1416 | n/a | static BOOL __stdcall |
---|
1417 | n/a | win32_wchdir(LPCWSTR path) |
---|
1418 | n/a | { |
---|
1419 | n/a | wchar_t path_buf[MAX_PATH], *new_path = path_buf; |
---|
1420 | n/a | int result; |
---|
1421 | n/a | wchar_t env[4] = L"=x:"; |
---|
1422 | n/a | |
---|
1423 | n/a | if(!SetCurrentDirectoryW(path)) |
---|
1424 | n/a | return FALSE; |
---|
1425 | n/a | result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path); |
---|
1426 | n/a | if (!result) |
---|
1427 | n/a | return FALSE; |
---|
1428 | n/a | if (result > Py_ARRAY_LENGTH(path_buf)) { |
---|
1429 | n/a | new_path = PyMem_RawMalloc(result * sizeof(wchar_t)); |
---|
1430 | n/a | if (!new_path) { |
---|
1431 | n/a | SetLastError(ERROR_OUTOFMEMORY); |
---|
1432 | n/a | return FALSE; |
---|
1433 | n/a | } |
---|
1434 | n/a | result = GetCurrentDirectoryW(result, new_path); |
---|
1435 | n/a | if (!result) { |
---|
1436 | n/a | PyMem_RawFree(new_path); |
---|
1437 | n/a | return FALSE; |
---|
1438 | n/a | } |
---|
1439 | n/a | } |
---|
1440 | n/a | if (wcsncmp(new_path, L"\\\\", 2) == 0 || |
---|
1441 | n/a | wcsncmp(new_path, L"//", 2) == 0) |
---|
1442 | n/a | /* UNC path, nothing to do. */ |
---|
1443 | n/a | return TRUE; |
---|
1444 | n/a | env[1] = new_path[0]; |
---|
1445 | n/a | result = SetEnvironmentVariableW(env, new_path); |
---|
1446 | n/a | if (new_path != path_buf) |
---|
1447 | n/a | PyMem_RawFree(new_path); |
---|
1448 | n/a | return result; |
---|
1449 | n/a | } |
---|
1450 | n/a | #endif |
---|
1451 | n/a | |
---|
1452 | n/a | #ifdef MS_WINDOWS |
---|
1453 | n/a | /* The CRT of Windows has a number of flaws wrt. its stat() implementation: |
---|
1454 | n/a | - time stamps are restricted to second resolution |
---|
1455 | n/a | - file modification times suffer from forth-and-back conversions between |
---|
1456 | n/a | UTC and local time |
---|
1457 | n/a | Therefore, we implement our own stat, based on the Win32 API directly. |
---|
1458 | n/a | */ |
---|
1459 | n/a | #define HAVE_STAT_NSEC 1 |
---|
1460 | n/a | #define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1 |
---|
1461 | n/a | |
---|
1462 | n/a | static void |
---|
1463 | n/a | find_data_to_file_info(WIN32_FIND_DATAW *pFileData, |
---|
1464 | n/a | BY_HANDLE_FILE_INFORMATION *info, |
---|
1465 | n/a | ULONG *reparse_tag) |
---|
1466 | n/a | { |
---|
1467 | n/a | memset(info, 0, sizeof(*info)); |
---|
1468 | n/a | info->dwFileAttributes = pFileData->dwFileAttributes; |
---|
1469 | n/a | info->ftCreationTime = pFileData->ftCreationTime; |
---|
1470 | n/a | info->ftLastAccessTime = pFileData->ftLastAccessTime; |
---|
1471 | n/a | info->ftLastWriteTime = pFileData->ftLastWriteTime; |
---|
1472 | n/a | info->nFileSizeHigh = pFileData->nFileSizeHigh; |
---|
1473 | n/a | info->nFileSizeLow = pFileData->nFileSizeLow; |
---|
1474 | n/a | /* info->nNumberOfLinks = 1; */ |
---|
1475 | n/a | if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) |
---|
1476 | n/a | *reparse_tag = pFileData->dwReserved0; |
---|
1477 | n/a | else |
---|
1478 | n/a | *reparse_tag = 0; |
---|
1479 | n/a | } |
---|
1480 | n/a | |
---|
1481 | n/a | static BOOL |
---|
1482 | n/a | attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag) |
---|
1483 | n/a | { |
---|
1484 | n/a | HANDLE hFindFile; |
---|
1485 | n/a | WIN32_FIND_DATAW FileData; |
---|
1486 | n/a | hFindFile = FindFirstFileW(pszFile, &FileData); |
---|
1487 | n/a | if (hFindFile == INVALID_HANDLE_VALUE) |
---|
1488 | n/a | return FALSE; |
---|
1489 | n/a | FindClose(hFindFile); |
---|
1490 | n/a | find_data_to_file_info(&FileData, info, reparse_tag); |
---|
1491 | n/a | return TRUE; |
---|
1492 | n/a | } |
---|
1493 | n/a | |
---|
1494 | n/a | static BOOL |
---|
1495 | n/a | get_target_path(HANDLE hdl, wchar_t **target_path) |
---|
1496 | n/a | { |
---|
1497 | n/a | int buf_size, result_length; |
---|
1498 | n/a | wchar_t *buf; |
---|
1499 | n/a | |
---|
1500 | n/a | /* We have a good handle to the target, use it to determine |
---|
1501 | n/a | the target path name (then we'll call lstat on it). */ |
---|
1502 | n/a | buf_size = GetFinalPathNameByHandleW(hdl, 0, 0, |
---|
1503 | n/a | VOLUME_NAME_DOS); |
---|
1504 | n/a | if(!buf_size) |
---|
1505 | n/a | return FALSE; |
---|
1506 | n/a | |
---|
1507 | n/a | buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t)); |
---|
1508 | n/a | if (!buf) { |
---|
1509 | n/a | SetLastError(ERROR_OUTOFMEMORY); |
---|
1510 | n/a | return FALSE; |
---|
1511 | n/a | } |
---|
1512 | n/a | |
---|
1513 | n/a | result_length = GetFinalPathNameByHandleW(hdl, |
---|
1514 | n/a | buf, buf_size, VOLUME_NAME_DOS); |
---|
1515 | n/a | |
---|
1516 | n/a | if(!result_length) { |
---|
1517 | n/a | PyMem_RawFree(buf); |
---|
1518 | n/a | return FALSE; |
---|
1519 | n/a | } |
---|
1520 | n/a | |
---|
1521 | n/a | if(!CloseHandle(hdl)) { |
---|
1522 | n/a | PyMem_RawFree(buf); |
---|
1523 | n/a | return FALSE; |
---|
1524 | n/a | } |
---|
1525 | n/a | |
---|
1526 | n/a | buf[result_length] = 0; |
---|
1527 | n/a | |
---|
1528 | n/a | *target_path = buf; |
---|
1529 | n/a | return TRUE; |
---|
1530 | n/a | } |
---|
1531 | n/a | |
---|
1532 | n/a | static int |
---|
1533 | n/a | win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result, |
---|
1534 | n/a | BOOL traverse) |
---|
1535 | n/a | { |
---|
1536 | n/a | int code; |
---|
1537 | n/a | HANDLE hFile, hFile2; |
---|
1538 | n/a | BY_HANDLE_FILE_INFORMATION info; |
---|
1539 | n/a | ULONG reparse_tag = 0; |
---|
1540 | n/a | wchar_t *target_path; |
---|
1541 | n/a | const wchar_t *dot; |
---|
1542 | n/a | |
---|
1543 | n/a | hFile = CreateFileW( |
---|
1544 | n/a | path, |
---|
1545 | n/a | FILE_READ_ATTRIBUTES, /* desired access */ |
---|
1546 | n/a | 0, /* share mode */ |
---|
1547 | n/a | NULL, /* security attributes */ |
---|
1548 | n/a | OPEN_EXISTING, |
---|
1549 | n/a | /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */ |
---|
1550 | n/a | /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink. |
---|
1551 | n/a | Because of this, calls like GetFinalPathNameByHandle will return |
---|
1552 | n/a | the symlink path again and not the actual final path. */ |
---|
1553 | n/a | FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS| |
---|
1554 | n/a | FILE_FLAG_OPEN_REPARSE_POINT, |
---|
1555 | n/a | NULL); |
---|
1556 | n/a | |
---|
1557 | n/a | if (hFile == INVALID_HANDLE_VALUE) { |
---|
1558 | n/a | /* Either the target doesn't exist, or we don't have access to |
---|
1559 | n/a | get a handle to it. If the former, we need to return an error. |
---|
1560 | n/a | If the latter, we can use attributes_from_dir. */ |
---|
1561 | n/a | DWORD lastError = GetLastError(); |
---|
1562 | n/a | if (lastError != ERROR_ACCESS_DENIED && |
---|
1563 | n/a | lastError != ERROR_SHARING_VIOLATION) |
---|
1564 | n/a | return -1; |
---|
1565 | n/a | /* Could not get attributes on open file. Fall back to |
---|
1566 | n/a | reading the directory. */ |
---|
1567 | n/a | if (!attributes_from_dir(path, &info, &reparse_tag)) |
---|
1568 | n/a | /* Very strange. This should not fail now */ |
---|
1569 | n/a | return -1; |
---|
1570 | n/a | if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { |
---|
1571 | n/a | if (traverse) { |
---|
1572 | n/a | /* Should traverse, but could not open reparse point handle */ |
---|
1573 | n/a | SetLastError(lastError); |
---|
1574 | n/a | return -1; |
---|
1575 | n/a | } |
---|
1576 | n/a | } |
---|
1577 | n/a | } else { |
---|
1578 | n/a | if (!GetFileInformationByHandle(hFile, &info)) { |
---|
1579 | n/a | CloseHandle(hFile); |
---|
1580 | n/a | return -1; |
---|
1581 | n/a | } |
---|
1582 | n/a | if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { |
---|
1583 | n/a | if (!win32_get_reparse_tag(hFile, &reparse_tag)) |
---|
1584 | n/a | return -1; |
---|
1585 | n/a | |
---|
1586 | n/a | /* Close the outer open file handle now that we're about to |
---|
1587 | n/a | reopen it with different flags. */ |
---|
1588 | n/a | if (!CloseHandle(hFile)) |
---|
1589 | n/a | return -1; |
---|
1590 | n/a | |
---|
1591 | n/a | if (traverse) { |
---|
1592 | n/a | /* In order to call GetFinalPathNameByHandle we need to open |
---|
1593 | n/a | the file without the reparse handling flag set. */ |
---|
1594 | n/a | hFile2 = CreateFileW( |
---|
1595 | n/a | path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, |
---|
1596 | n/a | NULL, OPEN_EXISTING, |
---|
1597 | n/a | FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS, |
---|
1598 | n/a | NULL); |
---|
1599 | n/a | if (hFile2 == INVALID_HANDLE_VALUE) |
---|
1600 | n/a | return -1; |
---|
1601 | n/a | |
---|
1602 | n/a | if (!get_target_path(hFile2, &target_path)) |
---|
1603 | n/a | return -1; |
---|
1604 | n/a | |
---|
1605 | n/a | code = win32_xstat_impl(target_path, result, FALSE); |
---|
1606 | n/a | PyMem_RawFree(target_path); |
---|
1607 | n/a | return code; |
---|
1608 | n/a | } |
---|
1609 | n/a | } else |
---|
1610 | n/a | CloseHandle(hFile); |
---|
1611 | n/a | } |
---|
1612 | n/a | _Py_attribute_data_to_stat(&info, reparse_tag, result); |
---|
1613 | n/a | |
---|
1614 | n/a | /* Set S_IEXEC if it is an .exe, .bat, ... */ |
---|
1615 | n/a | dot = wcsrchr(path, '.'); |
---|
1616 | n/a | if (dot) { |
---|
1617 | n/a | if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 || |
---|
1618 | n/a | _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0) |
---|
1619 | n/a | result->st_mode |= 0111; |
---|
1620 | n/a | } |
---|
1621 | n/a | return 0; |
---|
1622 | n/a | } |
---|
1623 | n/a | |
---|
1624 | n/a | static int |
---|
1625 | n/a | win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse) |
---|
1626 | n/a | { |
---|
1627 | n/a | /* Protocol violation: we explicitly clear errno, instead of |
---|
1628 | n/a | setting it to a POSIX error. Callers should use GetLastError. */ |
---|
1629 | n/a | int code = win32_xstat_impl(path, result, traverse); |
---|
1630 | n/a | errno = 0; |
---|
1631 | n/a | return code; |
---|
1632 | n/a | } |
---|
1633 | n/a | /* About the following functions: win32_lstat_w, win32_stat, win32_stat_w |
---|
1634 | n/a | |
---|
1635 | n/a | In Posix, stat automatically traverses symlinks and returns the stat |
---|
1636 | n/a | structure for the target. In Windows, the equivalent GetFileAttributes by |
---|
1637 | n/a | default does not traverse symlinks and instead returns attributes for |
---|
1638 | n/a | the symlink. |
---|
1639 | n/a | |
---|
1640 | n/a | Therefore, win32_lstat will get the attributes traditionally, and |
---|
1641 | n/a | win32_stat will first explicitly resolve the symlink target and then will |
---|
1642 | n/a | call win32_lstat on that result. */ |
---|
1643 | n/a | |
---|
1644 | n/a | static int |
---|
1645 | n/a | win32_lstat(const wchar_t* path, struct _Py_stat_struct *result) |
---|
1646 | n/a | { |
---|
1647 | n/a | return win32_xstat(path, result, FALSE); |
---|
1648 | n/a | } |
---|
1649 | n/a | |
---|
1650 | n/a | static int |
---|
1651 | n/a | win32_stat(const wchar_t* path, struct _Py_stat_struct *result) |
---|
1652 | n/a | { |
---|
1653 | n/a | return win32_xstat(path, result, TRUE); |
---|
1654 | n/a | } |
---|
1655 | n/a | |
---|
1656 | n/a | #endif /* MS_WINDOWS */ |
---|
1657 | n/a | |
---|
1658 | n/a | PyDoc_STRVAR(stat_result__doc__, |
---|
1659 | n/a | "stat_result: Result from stat, fstat, or lstat.\n\n\ |
---|
1660 | n/a | This object may be accessed either as a tuple of\n\ |
---|
1661 | n/a | (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\ |
---|
1662 | n/a | or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\ |
---|
1663 | n/a | \n\ |
---|
1664 | n/a | Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\ |
---|
1665 | n/a | or st_flags, they are available as attributes only.\n\ |
---|
1666 | n/a | \n\ |
---|
1667 | n/a | See os.stat for more information."); |
---|
1668 | n/a | |
---|
1669 | n/a | static PyStructSequence_Field stat_result_fields[] = { |
---|
1670 | n/a | {"st_mode", "protection bits"}, |
---|
1671 | n/a | {"st_ino", "inode"}, |
---|
1672 | n/a | {"st_dev", "device"}, |
---|
1673 | n/a | {"st_nlink", "number of hard links"}, |
---|
1674 | n/a | {"st_uid", "user ID of owner"}, |
---|
1675 | n/a | {"st_gid", "group ID of owner"}, |
---|
1676 | n/a | {"st_size", "total size, in bytes"}, |
---|
1677 | n/a | /* The NULL is replaced with PyStructSequence_UnnamedField later. */ |
---|
1678 | n/a | {NULL, "integer time of last access"}, |
---|
1679 | n/a | {NULL, "integer time of last modification"}, |
---|
1680 | n/a | {NULL, "integer time of last change"}, |
---|
1681 | n/a | {"st_atime", "time of last access"}, |
---|
1682 | n/a | {"st_mtime", "time of last modification"}, |
---|
1683 | n/a | {"st_ctime", "time of last change"}, |
---|
1684 | n/a | {"st_atime_ns", "time of last access in nanoseconds"}, |
---|
1685 | n/a | {"st_mtime_ns", "time of last modification in nanoseconds"}, |
---|
1686 | n/a | {"st_ctime_ns", "time of last change in nanoseconds"}, |
---|
1687 | n/a | #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE |
---|
1688 | n/a | {"st_blksize", "blocksize for filesystem I/O"}, |
---|
1689 | n/a | #endif |
---|
1690 | n/a | #ifdef HAVE_STRUCT_STAT_ST_BLOCKS |
---|
1691 | n/a | {"st_blocks", "number of blocks allocated"}, |
---|
1692 | n/a | #endif |
---|
1693 | n/a | #ifdef HAVE_STRUCT_STAT_ST_RDEV |
---|
1694 | n/a | {"st_rdev", "device type (if inode device)"}, |
---|
1695 | n/a | #endif |
---|
1696 | n/a | #ifdef HAVE_STRUCT_STAT_ST_FLAGS |
---|
1697 | n/a | {"st_flags", "user defined flags for file"}, |
---|
1698 | n/a | #endif |
---|
1699 | n/a | #ifdef HAVE_STRUCT_STAT_ST_GEN |
---|
1700 | n/a | {"st_gen", "generation number"}, |
---|
1701 | n/a | #endif |
---|
1702 | n/a | #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME |
---|
1703 | n/a | {"st_birthtime", "time of creation"}, |
---|
1704 | n/a | #endif |
---|
1705 | n/a | #ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES |
---|
1706 | n/a | {"st_file_attributes", "Windows file attribute bits"}, |
---|
1707 | n/a | #endif |
---|
1708 | n/a | {0} |
---|
1709 | n/a | }; |
---|
1710 | n/a | |
---|
1711 | n/a | #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE |
---|
1712 | n/a | #define ST_BLKSIZE_IDX 16 |
---|
1713 | n/a | #else |
---|
1714 | n/a | #define ST_BLKSIZE_IDX 15 |
---|
1715 | n/a | #endif |
---|
1716 | n/a | |
---|
1717 | n/a | #ifdef HAVE_STRUCT_STAT_ST_BLOCKS |
---|
1718 | n/a | #define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1) |
---|
1719 | n/a | #else |
---|
1720 | n/a | #define ST_BLOCKS_IDX ST_BLKSIZE_IDX |
---|
1721 | n/a | #endif |
---|
1722 | n/a | |
---|
1723 | n/a | #ifdef HAVE_STRUCT_STAT_ST_RDEV |
---|
1724 | n/a | #define ST_RDEV_IDX (ST_BLOCKS_IDX+1) |
---|
1725 | n/a | #else |
---|
1726 | n/a | #define ST_RDEV_IDX ST_BLOCKS_IDX |
---|
1727 | n/a | #endif |
---|
1728 | n/a | |
---|
1729 | n/a | #ifdef HAVE_STRUCT_STAT_ST_FLAGS |
---|
1730 | n/a | #define ST_FLAGS_IDX (ST_RDEV_IDX+1) |
---|
1731 | n/a | #else |
---|
1732 | n/a | #define ST_FLAGS_IDX ST_RDEV_IDX |
---|
1733 | n/a | #endif |
---|
1734 | n/a | |
---|
1735 | n/a | #ifdef HAVE_STRUCT_STAT_ST_GEN |
---|
1736 | n/a | #define ST_GEN_IDX (ST_FLAGS_IDX+1) |
---|
1737 | n/a | #else |
---|
1738 | n/a | #define ST_GEN_IDX ST_FLAGS_IDX |
---|
1739 | n/a | #endif |
---|
1740 | n/a | |
---|
1741 | n/a | #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME |
---|
1742 | n/a | #define ST_BIRTHTIME_IDX (ST_GEN_IDX+1) |
---|
1743 | n/a | #else |
---|
1744 | n/a | #define ST_BIRTHTIME_IDX ST_GEN_IDX |
---|
1745 | n/a | #endif |
---|
1746 | n/a | |
---|
1747 | n/a | #ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES |
---|
1748 | n/a | #define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1) |
---|
1749 | n/a | #else |
---|
1750 | n/a | #define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX |
---|
1751 | n/a | #endif |
---|
1752 | n/a | |
---|
1753 | n/a | static PyStructSequence_Desc stat_result_desc = { |
---|
1754 | n/a | "stat_result", /* name */ |
---|
1755 | n/a | stat_result__doc__, /* doc */ |
---|
1756 | n/a | stat_result_fields, |
---|
1757 | n/a | 10 |
---|
1758 | n/a | }; |
---|
1759 | n/a | |
---|
1760 | n/a | PyDoc_STRVAR(statvfs_result__doc__, |
---|
1761 | n/a | "statvfs_result: Result from statvfs or fstatvfs.\n\n\ |
---|
1762 | n/a | This object may be accessed either as a tuple of\n\ |
---|
1763 | n/a | (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\ |
---|
1764 | n/a | or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\ |
---|
1765 | n/a | \n\ |
---|
1766 | n/a | See os.statvfs for more information."); |
---|
1767 | n/a | |
---|
1768 | n/a | static PyStructSequence_Field statvfs_result_fields[] = { |
---|
1769 | n/a | {"f_bsize", }, |
---|
1770 | n/a | {"f_frsize", }, |
---|
1771 | n/a | {"f_blocks", }, |
---|
1772 | n/a | {"f_bfree", }, |
---|
1773 | n/a | {"f_bavail", }, |
---|
1774 | n/a | {"f_files", }, |
---|
1775 | n/a | {"f_ffree", }, |
---|
1776 | n/a | {"f_favail", }, |
---|
1777 | n/a | {"f_flag", }, |
---|
1778 | n/a | {"f_namemax",}, |
---|
1779 | n/a | {0} |
---|
1780 | n/a | }; |
---|
1781 | n/a | |
---|
1782 | n/a | static PyStructSequence_Desc statvfs_result_desc = { |
---|
1783 | n/a | "statvfs_result", /* name */ |
---|
1784 | n/a | statvfs_result__doc__, /* doc */ |
---|
1785 | n/a | statvfs_result_fields, |
---|
1786 | n/a | 10 |
---|
1787 | n/a | }; |
---|
1788 | n/a | |
---|
1789 | n/a | #if defined(HAVE_WAITID) && !defined(__APPLE__) |
---|
1790 | n/a | PyDoc_STRVAR(waitid_result__doc__, |
---|
1791 | n/a | "waitid_result: Result from waitid.\n\n\ |
---|
1792 | n/a | This object may be accessed either as a tuple of\n\ |
---|
1793 | n/a | (si_pid, si_uid, si_signo, si_status, si_code),\n\ |
---|
1794 | n/a | or via the attributes si_pid, si_uid, and so on.\n\ |
---|
1795 | n/a | \n\ |
---|
1796 | n/a | See os.waitid for more information."); |
---|
1797 | n/a | |
---|
1798 | n/a | static PyStructSequence_Field waitid_result_fields[] = { |
---|
1799 | n/a | {"si_pid", }, |
---|
1800 | n/a | {"si_uid", }, |
---|
1801 | n/a | {"si_signo", }, |
---|
1802 | n/a | {"si_status", }, |
---|
1803 | n/a | {"si_code", }, |
---|
1804 | n/a | {0} |
---|
1805 | n/a | }; |
---|
1806 | n/a | |
---|
1807 | n/a | static PyStructSequence_Desc waitid_result_desc = { |
---|
1808 | n/a | "waitid_result", /* name */ |
---|
1809 | n/a | waitid_result__doc__, /* doc */ |
---|
1810 | n/a | waitid_result_fields, |
---|
1811 | n/a | 5 |
---|
1812 | n/a | }; |
---|
1813 | n/a | static PyTypeObject WaitidResultType; |
---|
1814 | n/a | #endif |
---|
1815 | n/a | |
---|
1816 | n/a | static int initialized; |
---|
1817 | n/a | static PyTypeObject StatResultType; |
---|
1818 | n/a | static PyTypeObject StatVFSResultType; |
---|
1819 | n/a | #if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) |
---|
1820 | n/a | static PyTypeObject SchedParamType; |
---|
1821 | n/a | #endif |
---|
1822 | n/a | static newfunc structseq_new; |
---|
1823 | n/a | |
---|
1824 | n/a | static PyObject * |
---|
1825 | n/a | statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds) |
---|
1826 | n/a | { |
---|
1827 | n/a | PyStructSequence *result; |
---|
1828 | n/a | int i; |
---|
1829 | n/a | |
---|
1830 | n/a | result = (PyStructSequence*)structseq_new(type, args, kwds); |
---|
1831 | n/a | if (!result) |
---|
1832 | n/a | return NULL; |
---|
1833 | n/a | /* If we have been initialized from a tuple, |
---|
1834 | n/a | st_?time might be set to None. Initialize it |
---|
1835 | n/a | from the int slots. */ |
---|
1836 | n/a | for (i = 7; i <= 9; i++) { |
---|
1837 | n/a | if (result->ob_item[i+3] == Py_None) { |
---|
1838 | n/a | Py_DECREF(Py_None); |
---|
1839 | n/a | Py_INCREF(result->ob_item[i]); |
---|
1840 | n/a | result->ob_item[i+3] = result->ob_item[i]; |
---|
1841 | n/a | } |
---|
1842 | n/a | } |
---|
1843 | n/a | return (PyObject*)result; |
---|
1844 | n/a | } |
---|
1845 | n/a | |
---|
1846 | n/a | |
---|
1847 | n/a | |
---|
1848 | n/a | /* If true, st_?time is float. */ |
---|
1849 | n/a | static int _stat_float_times = 1; |
---|
1850 | n/a | |
---|
1851 | n/a | PyDoc_STRVAR(stat_float_times__doc__, |
---|
1852 | n/a | "stat_float_times([newval]) -> oldval\n\n\ |
---|
1853 | n/a | Determine whether os.[lf]stat represents time stamps as float objects.\n\ |
---|
1854 | n/a | \n\ |
---|
1855 | n/a | If value is True, future calls to stat() return floats; if it is False,\n\ |
---|
1856 | n/a | future calls return ints.\n\ |
---|
1857 | n/a | If value is omitted, return the current setting.\n"); |
---|
1858 | n/a | |
---|
1859 | n/a | /* AC 3.5: the public default value should be None, not ready for that yet */ |
---|
1860 | n/a | static PyObject* |
---|
1861 | n/a | stat_float_times(PyObject* self, PyObject *args) |
---|
1862 | n/a | { |
---|
1863 | n/a | int newval = -1; |
---|
1864 | n/a | if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval)) |
---|
1865 | n/a | return NULL; |
---|
1866 | n/a | if (PyErr_WarnEx(PyExc_DeprecationWarning, |
---|
1867 | n/a | "stat_float_times() is deprecated", |
---|
1868 | n/a | 1)) |
---|
1869 | n/a | return NULL; |
---|
1870 | n/a | if (newval == -1) |
---|
1871 | n/a | /* Return old value */ |
---|
1872 | n/a | return PyBool_FromLong(_stat_float_times); |
---|
1873 | n/a | _stat_float_times = newval; |
---|
1874 | n/a | Py_RETURN_NONE; |
---|
1875 | n/a | } |
---|
1876 | n/a | |
---|
1877 | n/a | static PyObject *billion = NULL; |
---|
1878 | n/a | |
---|
1879 | n/a | static void |
---|
1880 | n/a | fill_time(PyObject *v, int index, time_t sec, unsigned long nsec) |
---|
1881 | n/a | { |
---|
1882 | n/a | PyObject *s = _PyLong_FromTime_t(sec); |
---|
1883 | n/a | PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec); |
---|
1884 | n/a | PyObject *s_in_ns = NULL; |
---|
1885 | n/a | PyObject *ns_total = NULL; |
---|
1886 | n/a | PyObject *float_s = NULL; |
---|
1887 | n/a | |
---|
1888 | n/a | if (!(s && ns_fractional)) |
---|
1889 | n/a | goto exit; |
---|
1890 | n/a | |
---|
1891 | n/a | s_in_ns = PyNumber_Multiply(s, billion); |
---|
1892 | n/a | if (!s_in_ns) |
---|
1893 | n/a | goto exit; |
---|
1894 | n/a | |
---|
1895 | n/a | ns_total = PyNumber_Add(s_in_ns, ns_fractional); |
---|
1896 | n/a | if (!ns_total) |
---|
1897 | n/a | goto exit; |
---|
1898 | n/a | |
---|
1899 | n/a | if (_stat_float_times) { |
---|
1900 | n/a | float_s = PyFloat_FromDouble(sec + 1e-9*nsec); |
---|
1901 | n/a | if (!float_s) |
---|
1902 | n/a | goto exit; |
---|
1903 | n/a | } |
---|
1904 | n/a | else { |
---|
1905 | n/a | float_s = s; |
---|
1906 | n/a | Py_INCREF(float_s); |
---|
1907 | n/a | } |
---|
1908 | n/a | |
---|
1909 | n/a | PyStructSequence_SET_ITEM(v, index, s); |
---|
1910 | n/a | PyStructSequence_SET_ITEM(v, index+3, float_s); |
---|
1911 | n/a | PyStructSequence_SET_ITEM(v, index+6, ns_total); |
---|
1912 | n/a | s = NULL; |
---|
1913 | n/a | float_s = NULL; |
---|
1914 | n/a | ns_total = NULL; |
---|
1915 | n/a | exit: |
---|
1916 | n/a | Py_XDECREF(s); |
---|
1917 | n/a | Py_XDECREF(ns_fractional); |
---|
1918 | n/a | Py_XDECREF(s_in_ns); |
---|
1919 | n/a | Py_XDECREF(ns_total); |
---|
1920 | n/a | Py_XDECREF(float_s); |
---|
1921 | n/a | } |
---|
1922 | n/a | |
---|
1923 | n/a | /* pack a system stat C structure into the Python stat tuple |
---|
1924 | n/a | (used by posix_stat() and posix_fstat()) */ |
---|
1925 | n/a | static PyObject* |
---|
1926 | n/a | _pystat_fromstructstat(STRUCT_STAT *st) |
---|
1927 | n/a | { |
---|
1928 | n/a | unsigned long ansec, mnsec, cnsec; |
---|
1929 | n/a | PyObject *v = PyStructSequence_New(&StatResultType); |
---|
1930 | n/a | if (v == NULL) |
---|
1931 | n/a | return NULL; |
---|
1932 | n/a | |
---|
1933 | n/a | PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode)); |
---|
1934 | n/a | #ifdef HAVE_LARGEFILE_SUPPORT |
---|
1935 | n/a | PyStructSequence_SET_ITEM(v, 1, |
---|
1936 | n/a | PyLong_FromLongLong((long long)st->st_ino)); |
---|
1937 | n/a | #else |
---|
1938 | n/a | PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino)); |
---|
1939 | n/a | #endif |
---|
1940 | n/a | #ifdef MS_WINDOWS |
---|
1941 | n/a | PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev)); |
---|
1942 | n/a | #else |
---|
1943 | n/a | PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev)); |
---|
1944 | n/a | #endif |
---|
1945 | n/a | PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink)); |
---|
1946 | n/a | #if defined(MS_WINDOWS) |
---|
1947 | n/a | PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0)); |
---|
1948 | n/a | PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0)); |
---|
1949 | n/a | #else |
---|
1950 | n/a | PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid)); |
---|
1951 | n/a | PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid)); |
---|
1952 | n/a | #endif |
---|
1953 | n/a | #ifdef HAVE_LARGEFILE_SUPPORT |
---|
1954 | n/a | PyStructSequence_SET_ITEM(v, 6, |
---|
1955 | n/a | PyLong_FromLongLong((long long)st->st_size)); |
---|
1956 | n/a | #else |
---|
1957 | n/a | PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size)); |
---|
1958 | n/a | #endif |
---|
1959 | n/a | |
---|
1960 | n/a | #if defined(HAVE_STAT_TV_NSEC) |
---|
1961 | n/a | ansec = st->st_atim.tv_nsec; |
---|
1962 | n/a | mnsec = st->st_mtim.tv_nsec; |
---|
1963 | n/a | cnsec = st->st_ctim.tv_nsec; |
---|
1964 | n/a | #elif defined(HAVE_STAT_TV_NSEC2) |
---|
1965 | n/a | ansec = st->st_atimespec.tv_nsec; |
---|
1966 | n/a | mnsec = st->st_mtimespec.tv_nsec; |
---|
1967 | n/a | cnsec = st->st_ctimespec.tv_nsec; |
---|
1968 | n/a | #elif defined(HAVE_STAT_NSEC) |
---|
1969 | n/a | ansec = st->st_atime_nsec; |
---|
1970 | n/a | mnsec = st->st_mtime_nsec; |
---|
1971 | n/a | cnsec = st->st_ctime_nsec; |
---|
1972 | n/a | #else |
---|
1973 | n/a | ansec = mnsec = cnsec = 0; |
---|
1974 | n/a | #endif |
---|
1975 | n/a | fill_time(v, 7, st->st_atime, ansec); |
---|
1976 | n/a | fill_time(v, 8, st->st_mtime, mnsec); |
---|
1977 | n/a | fill_time(v, 9, st->st_ctime, cnsec); |
---|
1978 | n/a | |
---|
1979 | n/a | #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE |
---|
1980 | n/a | PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX, |
---|
1981 | n/a | PyLong_FromLong((long)st->st_blksize)); |
---|
1982 | n/a | #endif |
---|
1983 | n/a | #ifdef HAVE_STRUCT_STAT_ST_BLOCKS |
---|
1984 | n/a | PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX, |
---|
1985 | n/a | PyLong_FromLong((long)st->st_blocks)); |
---|
1986 | n/a | #endif |
---|
1987 | n/a | #ifdef HAVE_STRUCT_STAT_ST_RDEV |
---|
1988 | n/a | PyStructSequence_SET_ITEM(v, ST_RDEV_IDX, |
---|
1989 | n/a | PyLong_FromLong((long)st->st_rdev)); |
---|
1990 | n/a | #endif |
---|
1991 | n/a | #ifdef HAVE_STRUCT_STAT_ST_GEN |
---|
1992 | n/a | PyStructSequence_SET_ITEM(v, ST_GEN_IDX, |
---|
1993 | n/a | PyLong_FromLong((long)st->st_gen)); |
---|
1994 | n/a | #endif |
---|
1995 | n/a | #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME |
---|
1996 | n/a | { |
---|
1997 | n/a | PyObject *val; |
---|
1998 | n/a | unsigned long bsec,bnsec; |
---|
1999 | n/a | bsec = (long)st->st_birthtime; |
---|
2000 | n/a | #ifdef HAVE_STAT_TV_NSEC2 |
---|
2001 | n/a | bnsec = st->st_birthtimespec.tv_nsec; |
---|
2002 | n/a | #else |
---|
2003 | n/a | bnsec = 0; |
---|
2004 | n/a | #endif |
---|
2005 | n/a | if (_stat_float_times) { |
---|
2006 | n/a | val = PyFloat_FromDouble(bsec + 1e-9*bnsec); |
---|
2007 | n/a | } else { |
---|
2008 | n/a | val = PyLong_FromLong((long)bsec); |
---|
2009 | n/a | } |
---|
2010 | n/a | PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX, |
---|
2011 | n/a | val); |
---|
2012 | n/a | } |
---|
2013 | n/a | #endif |
---|
2014 | n/a | #ifdef HAVE_STRUCT_STAT_ST_FLAGS |
---|
2015 | n/a | PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX, |
---|
2016 | n/a | PyLong_FromLong((long)st->st_flags)); |
---|
2017 | n/a | #endif |
---|
2018 | n/a | #ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES |
---|
2019 | n/a | PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX, |
---|
2020 | n/a | PyLong_FromUnsignedLong(st->st_file_attributes)); |
---|
2021 | n/a | #endif |
---|
2022 | n/a | |
---|
2023 | n/a | if (PyErr_Occurred()) { |
---|
2024 | n/a | Py_DECREF(v); |
---|
2025 | n/a | return NULL; |
---|
2026 | n/a | } |
---|
2027 | n/a | |
---|
2028 | n/a | return v; |
---|
2029 | n/a | } |
---|
2030 | n/a | |
---|
2031 | n/a | /* POSIX methods */ |
---|
2032 | n/a | |
---|
2033 | n/a | |
---|
2034 | n/a | static PyObject * |
---|
2035 | n/a | posix_do_stat(const char *function_name, path_t *path, |
---|
2036 | n/a | int dir_fd, int follow_symlinks) |
---|
2037 | n/a | { |
---|
2038 | n/a | STRUCT_STAT st; |
---|
2039 | n/a | int result; |
---|
2040 | n/a | |
---|
2041 | n/a | #if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT) |
---|
2042 | n/a | if (follow_symlinks_specified(function_name, follow_symlinks)) |
---|
2043 | n/a | return NULL; |
---|
2044 | n/a | #endif |
---|
2045 | n/a | |
---|
2046 | n/a | if (path_and_dir_fd_invalid("stat", path, dir_fd) || |
---|
2047 | n/a | dir_fd_and_fd_invalid("stat", dir_fd, path->fd) || |
---|
2048 | n/a | fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks)) |
---|
2049 | n/a | return NULL; |
---|
2050 | n/a | |
---|
2051 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
2052 | n/a | if (path->fd != -1) |
---|
2053 | n/a | result = FSTAT(path->fd, &st); |
---|
2054 | n/a | #ifdef MS_WINDOWS |
---|
2055 | n/a | else if (follow_symlinks) |
---|
2056 | n/a | result = win32_stat(path->wide, &st); |
---|
2057 | n/a | else |
---|
2058 | n/a | result = win32_lstat(path->wide, &st); |
---|
2059 | n/a | #else |
---|
2060 | n/a | else |
---|
2061 | n/a | #if defined(HAVE_LSTAT) |
---|
2062 | n/a | if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD)) |
---|
2063 | n/a | result = LSTAT(path->narrow, &st); |
---|
2064 | n/a | else |
---|
2065 | n/a | #endif /* HAVE_LSTAT */ |
---|
2066 | n/a | #ifdef HAVE_FSTATAT |
---|
2067 | n/a | if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) |
---|
2068 | n/a | result = fstatat(dir_fd, path->narrow, &st, |
---|
2069 | n/a | follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW); |
---|
2070 | n/a | else |
---|
2071 | n/a | #endif /* HAVE_FSTATAT */ |
---|
2072 | n/a | result = STAT(path->narrow, &st); |
---|
2073 | n/a | #endif /* MS_WINDOWS */ |
---|
2074 | n/a | Py_END_ALLOW_THREADS |
---|
2075 | n/a | |
---|
2076 | n/a | if (result != 0) { |
---|
2077 | n/a | return path_error(path); |
---|
2078 | n/a | } |
---|
2079 | n/a | |
---|
2080 | n/a | return _pystat_fromstructstat(&st); |
---|
2081 | n/a | } |
---|
2082 | n/a | |
---|
2083 | n/a | /*[python input] |
---|
2084 | n/a | |
---|
2085 | n/a | for s in """ |
---|
2086 | n/a | |
---|
2087 | n/a | FACCESSAT |
---|
2088 | n/a | FCHMODAT |
---|
2089 | n/a | FCHOWNAT |
---|
2090 | n/a | FSTATAT |
---|
2091 | n/a | LINKAT |
---|
2092 | n/a | MKDIRAT |
---|
2093 | n/a | MKFIFOAT |
---|
2094 | n/a | MKNODAT |
---|
2095 | n/a | OPENAT |
---|
2096 | n/a | READLINKAT |
---|
2097 | n/a | SYMLINKAT |
---|
2098 | n/a | UNLINKAT |
---|
2099 | n/a | |
---|
2100 | n/a | """.strip().split(): |
---|
2101 | n/a | s = s.strip() |
---|
2102 | n/a | print(""" |
---|
2103 | n/a | #ifdef HAVE_{s} |
---|
2104 | n/a | #define {s}_DIR_FD_CONVERTER dir_fd_converter |
---|
2105 | n/a | #else |
---|
2106 | n/a | #define {s}_DIR_FD_CONVERTER dir_fd_unavailable |
---|
2107 | n/a | #endif |
---|
2108 | n/a | """.rstrip().format(s=s)) |
---|
2109 | n/a | |
---|
2110 | n/a | for s in """ |
---|
2111 | n/a | |
---|
2112 | n/a | FCHDIR |
---|
2113 | n/a | FCHMOD |
---|
2114 | n/a | FCHOWN |
---|
2115 | n/a | FDOPENDIR |
---|
2116 | n/a | FEXECVE |
---|
2117 | n/a | FPATHCONF |
---|
2118 | n/a | FSTATVFS |
---|
2119 | n/a | FTRUNCATE |
---|
2120 | n/a | |
---|
2121 | n/a | """.strip().split(): |
---|
2122 | n/a | s = s.strip() |
---|
2123 | n/a | print(""" |
---|
2124 | n/a | #ifdef HAVE_{s} |
---|
2125 | n/a | #define PATH_HAVE_{s} 1 |
---|
2126 | n/a | #else |
---|
2127 | n/a | #define PATH_HAVE_{s} 0 |
---|
2128 | n/a | #endif |
---|
2129 | n/a | |
---|
2130 | n/a | """.rstrip().format(s=s)) |
---|
2131 | n/a | [python start generated code]*/ |
---|
2132 | n/a | |
---|
2133 | n/a | #ifdef HAVE_FACCESSAT |
---|
2134 | n/a | #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter |
---|
2135 | n/a | #else |
---|
2136 | n/a | #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable |
---|
2137 | n/a | #endif |
---|
2138 | n/a | |
---|
2139 | n/a | #ifdef HAVE_FCHMODAT |
---|
2140 | n/a | #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter |
---|
2141 | n/a | #else |
---|
2142 | n/a | #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable |
---|
2143 | n/a | #endif |
---|
2144 | n/a | |
---|
2145 | n/a | #ifdef HAVE_FCHOWNAT |
---|
2146 | n/a | #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter |
---|
2147 | n/a | #else |
---|
2148 | n/a | #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable |
---|
2149 | n/a | #endif |
---|
2150 | n/a | |
---|
2151 | n/a | #ifdef HAVE_FSTATAT |
---|
2152 | n/a | #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter |
---|
2153 | n/a | #else |
---|
2154 | n/a | #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable |
---|
2155 | n/a | #endif |
---|
2156 | n/a | |
---|
2157 | n/a | #ifdef HAVE_LINKAT |
---|
2158 | n/a | #define LINKAT_DIR_FD_CONVERTER dir_fd_converter |
---|
2159 | n/a | #else |
---|
2160 | n/a | #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable |
---|
2161 | n/a | #endif |
---|
2162 | n/a | |
---|
2163 | n/a | #ifdef HAVE_MKDIRAT |
---|
2164 | n/a | #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter |
---|
2165 | n/a | #else |
---|
2166 | n/a | #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable |
---|
2167 | n/a | #endif |
---|
2168 | n/a | |
---|
2169 | n/a | #ifdef HAVE_MKFIFOAT |
---|
2170 | n/a | #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter |
---|
2171 | n/a | #else |
---|
2172 | n/a | #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable |
---|
2173 | n/a | #endif |
---|
2174 | n/a | |
---|
2175 | n/a | #ifdef HAVE_MKNODAT |
---|
2176 | n/a | #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter |
---|
2177 | n/a | #else |
---|
2178 | n/a | #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable |
---|
2179 | n/a | #endif |
---|
2180 | n/a | |
---|
2181 | n/a | #ifdef HAVE_OPENAT |
---|
2182 | n/a | #define OPENAT_DIR_FD_CONVERTER dir_fd_converter |
---|
2183 | n/a | #else |
---|
2184 | n/a | #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable |
---|
2185 | n/a | #endif |
---|
2186 | n/a | |
---|
2187 | n/a | #ifdef HAVE_READLINKAT |
---|
2188 | n/a | #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter |
---|
2189 | n/a | #else |
---|
2190 | n/a | #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable |
---|
2191 | n/a | #endif |
---|
2192 | n/a | |
---|
2193 | n/a | #ifdef HAVE_SYMLINKAT |
---|
2194 | n/a | #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter |
---|
2195 | n/a | #else |
---|
2196 | n/a | #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable |
---|
2197 | n/a | #endif |
---|
2198 | n/a | |
---|
2199 | n/a | #ifdef HAVE_UNLINKAT |
---|
2200 | n/a | #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter |
---|
2201 | n/a | #else |
---|
2202 | n/a | #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable |
---|
2203 | n/a | #endif |
---|
2204 | n/a | |
---|
2205 | n/a | #ifdef HAVE_FCHDIR |
---|
2206 | n/a | #define PATH_HAVE_FCHDIR 1 |
---|
2207 | n/a | #else |
---|
2208 | n/a | #define PATH_HAVE_FCHDIR 0 |
---|
2209 | n/a | #endif |
---|
2210 | n/a | |
---|
2211 | n/a | #ifdef HAVE_FCHMOD |
---|
2212 | n/a | #define PATH_HAVE_FCHMOD 1 |
---|
2213 | n/a | #else |
---|
2214 | n/a | #define PATH_HAVE_FCHMOD 0 |
---|
2215 | n/a | #endif |
---|
2216 | n/a | |
---|
2217 | n/a | #ifdef HAVE_FCHOWN |
---|
2218 | n/a | #define PATH_HAVE_FCHOWN 1 |
---|
2219 | n/a | #else |
---|
2220 | n/a | #define PATH_HAVE_FCHOWN 0 |
---|
2221 | n/a | #endif |
---|
2222 | n/a | |
---|
2223 | n/a | #ifdef HAVE_FDOPENDIR |
---|
2224 | n/a | #define PATH_HAVE_FDOPENDIR 1 |
---|
2225 | n/a | #else |
---|
2226 | n/a | #define PATH_HAVE_FDOPENDIR 0 |
---|
2227 | n/a | #endif |
---|
2228 | n/a | |
---|
2229 | n/a | #ifdef HAVE_FEXECVE |
---|
2230 | n/a | #define PATH_HAVE_FEXECVE 1 |
---|
2231 | n/a | #else |
---|
2232 | n/a | #define PATH_HAVE_FEXECVE 0 |
---|
2233 | n/a | #endif |
---|
2234 | n/a | |
---|
2235 | n/a | #ifdef HAVE_FPATHCONF |
---|
2236 | n/a | #define PATH_HAVE_FPATHCONF 1 |
---|
2237 | n/a | #else |
---|
2238 | n/a | #define PATH_HAVE_FPATHCONF 0 |
---|
2239 | n/a | #endif |
---|
2240 | n/a | |
---|
2241 | n/a | #ifdef HAVE_FSTATVFS |
---|
2242 | n/a | #define PATH_HAVE_FSTATVFS 1 |
---|
2243 | n/a | #else |
---|
2244 | n/a | #define PATH_HAVE_FSTATVFS 0 |
---|
2245 | n/a | #endif |
---|
2246 | n/a | |
---|
2247 | n/a | #ifdef HAVE_FTRUNCATE |
---|
2248 | n/a | #define PATH_HAVE_FTRUNCATE 1 |
---|
2249 | n/a | #else |
---|
2250 | n/a | #define PATH_HAVE_FTRUNCATE 0 |
---|
2251 | n/a | #endif |
---|
2252 | n/a | /*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/ |
---|
2253 | n/a | |
---|
2254 | n/a | #ifdef MS_WINDOWS |
---|
2255 | n/a | #undef PATH_HAVE_FTRUNCATE |
---|
2256 | n/a | #define PATH_HAVE_FTRUNCATE 1 |
---|
2257 | n/a | #endif |
---|
2258 | n/a | |
---|
2259 | n/a | /*[python input] |
---|
2260 | n/a | |
---|
2261 | n/a | class path_t_converter(CConverter): |
---|
2262 | n/a | |
---|
2263 | n/a | type = "path_t" |
---|
2264 | n/a | impl_by_reference = True |
---|
2265 | n/a | parse_by_reference = True |
---|
2266 | n/a | |
---|
2267 | n/a | converter = 'path_converter' |
---|
2268 | n/a | |
---|
2269 | n/a | def converter_init(self, *, allow_fd=False, nullable=False): |
---|
2270 | n/a | # right now path_t doesn't support default values. |
---|
2271 | n/a | # to support a default value, you'll need to override initialize(). |
---|
2272 | n/a | if self.default not in (unspecified, None): |
---|
2273 | n/a | fail("Can't specify a default to the path_t converter!") |
---|
2274 | n/a | |
---|
2275 | n/a | if self.c_default not in (None, 'Py_None'): |
---|
2276 | n/a | raise RuntimeError("Can't specify a c_default to the path_t converter!") |
---|
2277 | n/a | |
---|
2278 | n/a | self.nullable = nullable |
---|
2279 | n/a | self.allow_fd = allow_fd |
---|
2280 | n/a | |
---|
2281 | n/a | def pre_render(self): |
---|
2282 | n/a | def strify(value): |
---|
2283 | n/a | if isinstance(value, str): |
---|
2284 | n/a | return value |
---|
2285 | n/a | return str(int(bool(value))) |
---|
2286 | n/a | |
---|
2287 | n/a | # add self.py_name here when merging with posixmodule conversion |
---|
2288 | n/a | self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format( |
---|
2289 | n/a | self.function.name, |
---|
2290 | n/a | self.name, |
---|
2291 | n/a | strify(self.nullable), |
---|
2292 | n/a | strify(self.allow_fd), |
---|
2293 | n/a | ) |
---|
2294 | n/a | |
---|
2295 | n/a | def cleanup(self): |
---|
2296 | n/a | return "path_cleanup(&" + self.name + ");\n" |
---|
2297 | n/a | |
---|
2298 | n/a | |
---|
2299 | n/a | class dir_fd_converter(CConverter): |
---|
2300 | n/a | type = 'int' |
---|
2301 | n/a | |
---|
2302 | n/a | def converter_init(self, requires=None): |
---|
2303 | n/a | if self.default in (unspecified, None): |
---|
2304 | n/a | self.c_default = 'DEFAULT_DIR_FD' |
---|
2305 | n/a | if isinstance(requires, str): |
---|
2306 | n/a | self.converter = requires.upper() + '_DIR_FD_CONVERTER' |
---|
2307 | n/a | else: |
---|
2308 | n/a | self.converter = 'dir_fd_converter' |
---|
2309 | n/a | |
---|
2310 | n/a | class fildes_converter(CConverter): |
---|
2311 | n/a | type = 'int' |
---|
2312 | n/a | converter = 'fildes_converter' |
---|
2313 | n/a | |
---|
2314 | n/a | class uid_t_converter(CConverter): |
---|
2315 | n/a | type = "uid_t" |
---|
2316 | n/a | converter = '_Py_Uid_Converter' |
---|
2317 | n/a | |
---|
2318 | n/a | class gid_t_converter(CConverter): |
---|
2319 | n/a | type = "gid_t" |
---|
2320 | n/a | converter = '_Py_Gid_Converter' |
---|
2321 | n/a | |
---|
2322 | n/a | class dev_t_converter(CConverter): |
---|
2323 | n/a | type = 'dev_t' |
---|
2324 | n/a | converter = '_Py_Dev_Converter' |
---|
2325 | n/a | |
---|
2326 | n/a | class dev_t_return_converter(unsigned_long_return_converter): |
---|
2327 | n/a | type = 'dev_t' |
---|
2328 | n/a | conversion_fn = '_PyLong_FromDev' |
---|
2329 | n/a | unsigned_cast = '(dev_t)' |
---|
2330 | n/a | |
---|
2331 | n/a | class FSConverter_converter(CConverter): |
---|
2332 | n/a | type = 'PyObject *' |
---|
2333 | n/a | converter = 'PyUnicode_FSConverter' |
---|
2334 | n/a | def converter_init(self): |
---|
2335 | n/a | if self.default is not unspecified: |
---|
2336 | n/a | fail("FSConverter_converter does not support default values") |
---|
2337 | n/a | self.c_default = 'NULL' |
---|
2338 | n/a | |
---|
2339 | n/a | def cleanup(self): |
---|
2340 | n/a | return "Py_XDECREF(" + self.name + ");\n" |
---|
2341 | n/a | |
---|
2342 | n/a | class pid_t_converter(CConverter): |
---|
2343 | n/a | type = 'pid_t' |
---|
2344 | n/a | format_unit = '" _Py_PARSE_PID "' |
---|
2345 | n/a | |
---|
2346 | n/a | class idtype_t_converter(int_converter): |
---|
2347 | n/a | type = 'idtype_t' |
---|
2348 | n/a | |
---|
2349 | n/a | class id_t_converter(CConverter): |
---|
2350 | n/a | type = 'id_t' |
---|
2351 | n/a | format_unit = '" _Py_PARSE_PID "' |
---|
2352 | n/a | |
---|
2353 | n/a | class intptr_t_converter(CConverter): |
---|
2354 | n/a | type = 'intptr_t' |
---|
2355 | n/a | format_unit = '" _Py_PARSE_INTPTR "' |
---|
2356 | n/a | |
---|
2357 | n/a | class Py_off_t_converter(CConverter): |
---|
2358 | n/a | type = 'Py_off_t' |
---|
2359 | n/a | converter = 'Py_off_t_converter' |
---|
2360 | n/a | |
---|
2361 | n/a | class Py_off_t_return_converter(long_return_converter): |
---|
2362 | n/a | type = 'Py_off_t' |
---|
2363 | n/a | conversion_fn = 'PyLong_FromPy_off_t' |
---|
2364 | n/a | |
---|
2365 | n/a | class path_confname_converter(CConverter): |
---|
2366 | n/a | type="int" |
---|
2367 | n/a | converter="conv_path_confname" |
---|
2368 | n/a | |
---|
2369 | n/a | class confstr_confname_converter(path_confname_converter): |
---|
2370 | n/a | converter='conv_confstr_confname' |
---|
2371 | n/a | |
---|
2372 | n/a | class sysconf_confname_converter(path_confname_converter): |
---|
2373 | n/a | converter="conv_sysconf_confname" |
---|
2374 | n/a | |
---|
2375 | n/a | class sched_param_converter(CConverter): |
---|
2376 | n/a | type = 'struct sched_param' |
---|
2377 | n/a | converter = 'convert_sched_param' |
---|
2378 | n/a | impl_by_reference = True; |
---|
2379 | n/a | |
---|
2380 | n/a | [python start generated code]*/ |
---|
2381 | n/a | /*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/ |
---|
2382 | n/a | |
---|
2383 | n/a | /*[clinic input] |
---|
2384 | n/a | |
---|
2385 | n/a | os.stat |
---|
2386 | n/a | |
---|
2387 | n/a | path : path_t(allow_fd=True) |
---|
2388 | n/a | Path to be examined; can be string, bytes, path-like object or |
---|
2389 | n/a | open-file-descriptor int. |
---|
2390 | n/a | |
---|
2391 | n/a | * |
---|
2392 | n/a | |
---|
2393 | n/a | dir_fd : dir_fd(requires='fstatat') = None |
---|
2394 | n/a | If not None, it should be a file descriptor open to a directory, |
---|
2395 | n/a | and path should be a relative string; path will then be relative to |
---|
2396 | n/a | that directory. |
---|
2397 | n/a | |
---|
2398 | n/a | follow_symlinks: bool = True |
---|
2399 | n/a | If False, and the last element of the path is a symbolic link, |
---|
2400 | n/a | stat will examine the symbolic link itself instead of the file |
---|
2401 | n/a | the link points to. |
---|
2402 | n/a | |
---|
2403 | n/a | Perform a stat system call on the given path. |
---|
2404 | n/a | |
---|
2405 | n/a | dir_fd and follow_symlinks may not be implemented |
---|
2406 | n/a | on your platform. If they are unavailable, using them will raise a |
---|
2407 | n/a | NotImplementedError. |
---|
2408 | n/a | |
---|
2409 | n/a | It's an error to use dir_fd or follow_symlinks when specifying path as |
---|
2410 | n/a | an open file descriptor. |
---|
2411 | n/a | |
---|
2412 | n/a | [clinic start generated code]*/ |
---|
2413 | n/a | |
---|
2414 | n/a | static PyObject * |
---|
2415 | n/a | os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks) |
---|
2416 | n/a | /*[clinic end generated code: output=7d4976e6f18a59c5 input=270bd64e7bb3c8f7]*/ |
---|
2417 | n/a | { |
---|
2418 | n/a | return posix_do_stat("stat", path, dir_fd, follow_symlinks); |
---|
2419 | n/a | } |
---|
2420 | n/a | |
---|
2421 | n/a | |
---|
2422 | n/a | /*[clinic input] |
---|
2423 | n/a | os.lstat |
---|
2424 | n/a | |
---|
2425 | n/a | path : path_t |
---|
2426 | n/a | |
---|
2427 | n/a | * |
---|
2428 | n/a | |
---|
2429 | n/a | dir_fd : dir_fd(requires='fstatat') = None |
---|
2430 | n/a | |
---|
2431 | n/a | Perform a stat system call on the given path, without following symbolic links. |
---|
2432 | n/a | |
---|
2433 | n/a | Like stat(), but do not follow symbolic links. |
---|
2434 | n/a | Equivalent to stat(path, follow_symlinks=False). |
---|
2435 | n/a | [clinic start generated code]*/ |
---|
2436 | n/a | |
---|
2437 | n/a | static PyObject * |
---|
2438 | n/a | os_lstat_impl(PyObject *module, path_t *path, int dir_fd) |
---|
2439 | n/a | /*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/ |
---|
2440 | n/a | { |
---|
2441 | n/a | int follow_symlinks = 0; |
---|
2442 | n/a | return posix_do_stat("lstat", path, dir_fd, follow_symlinks); |
---|
2443 | n/a | } |
---|
2444 | n/a | |
---|
2445 | n/a | |
---|
2446 | n/a | /*[clinic input] |
---|
2447 | n/a | os.access -> bool |
---|
2448 | n/a | |
---|
2449 | n/a | path: path_t |
---|
2450 | n/a | Path to be tested; can be string or bytes |
---|
2451 | n/a | |
---|
2452 | n/a | mode: int |
---|
2453 | n/a | Operating-system mode bitfield. Can be F_OK to test existence, |
---|
2454 | n/a | or the inclusive-OR of R_OK, W_OK, and X_OK. |
---|
2455 | n/a | |
---|
2456 | n/a | * |
---|
2457 | n/a | |
---|
2458 | n/a | dir_fd : dir_fd(requires='faccessat') = None |
---|
2459 | n/a | If not None, it should be a file descriptor open to a directory, |
---|
2460 | n/a | and path should be relative; path will then be relative to that |
---|
2461 | n/a | directory. |
---|
2462 | n/a | |
---|
2463 | n/a | effective_ids: bool = False |
---|
2464 | n/a | If True, access will use the effective uid/gid instead of |
---|
2465 | n/a | the real uid/gid. |
---|
2466 | n/a | |
---|
2467 | n/a | follow_symlinks: bool = True |
---|
2468 | n/a | If False, and the last element of the path is a symbolic link, |
---|
2469 | n/a | access will examine the symbolic link itself instead of the file |
---|
2470 | n/a | the link points to. |
---|
2471 | n/a | |
---|
2472 | n/a | Use the real uid/gid to test for access to a path. |
---|
2473 | n/a | |
---|
2474 | n/a | {parameters} |
---|
2475 | n/a | dir_fd, effective_ids, and follow_symlinks may not be implemented |
---|
2476 | n/a | on your platform. If they are unavailable, using them will raise a |
---|
2477 | n/a | NotImplementedError. |
---|
2478 | n/a | |
---|
2479 | n/a | Note that most operations will use the effective uid/gid, therefore this |
---|
2480 | n/a | routine can be used in a suid/sgid environment to test if the invoking user |
---|
2481 | n/a | has the specified access to the path. |
---|
2482 | n/a | |
---|
2483 | n/a | [clinic start generated code]*/ |
---|
2484 | n/a | |
---|
2485 | n/a | static int |
---|
2486 | n/a | os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd, |
---|
2487 | n/a | int effective_ids, int follow_symlinks) |
---|
2488 | n/a | /*[clinic end generated code: output=cf84158bc90b1a77 input=8e8c3a6ba791fee3]*/ |
---|
2489 | n/a | { |
---|
2490 | n/a | int return_value; |
---|
2491 | n/a | |
---|
2492 | n/a | #ifdef MS_WINDOWS |
---|
2493 | n/a | DWORD attr; |
---|
2494 | n/a | #else |
---|
2495 | n/a | int result; |
---|
2496 | n/a | #endif |
---|
2497 | n/a | |
---|
2498 | n/a | #ifndef HAVE_FACCESSAT |
---|
2499 | n/a | if (follow_symlinks_specified("access", follow_symlinks)) |
---|
2500 | n/a | return -1; |
---|
2501 | n/a | |
---|
2502 | n/a | if (effective_ids) { |
---|
2503 | n/a | argument_unavailable_error("access", "effective_ids"); |
---|
2504 | n/a | return -1; |
---|
2505 | n/a | } |
---|
2506 | n/a | #endif |
---|
2507 | n/a | |
---|
2508 | n/a | #ifdef MS_WINDOWS |
---|
2509 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
2510 | n/a | attr = GetFileAttributesW(path->wide); |
---|
2511 | n/a | Py_END_ALLOW_THREADS |
---|
2512 | n/a | |
---|
2513 | n/a | /* |
---|
2514 | n/a | * Access is possible if |
---|
2515 | n/a | * * we didn't get a -1, and |
---|
2516 | n/a | * * write access wasn't requested, |
---|
2517 | n/a | * * or the file isn't read-only, |
---|
2518 | n/a | * * or it's a directory. |
---|
2519 | n/a | * (Directories cannot be read-only on Windows.) |
---|
2520 | n/a | */ |
---|
2521 | n/a | return_value = (attr != INVALID_FILE_ATTRIBUTES) && |
---|
2522 | n/a | (!(mode & 2) || |
---|
2523 | n/a | !(attr & FILE_ATTRIBUTE_READONLY) || |
---|
2524 | n/a | (attr & FILE_ATTRIBUTE_DIRECTORY)); |
---|
2525 | n/a | #else |
---|
2526 | n/a | |
---|
2527 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
2528 | n/a | #ifdef HAVE_FACCESSAT |
---|
2529 | n/a | if ((dir_fd != DEFAULT_DIR_FD) || |
---|
2530 | n/a | effective_ids || |
---|
2531 | n/a | !follow_symlinks) { |
---|
2532 | n/a | int flags = 0; |
---|
2533 | n/a | if (!follow_symlinks) |
---|
2534 | n/a | flags |= AT_SYMLINK_NOFOLLOW; |
---|
2535 | n/a | if (effective_ids) |
---|
2536 | n/a | flags |= AT_EACCESS; |
---|
2537 | n/a | result = faccessat(dir_fd, path->narrow, mode, flags); |
---|
2538 | n/a | } |
---|
2539 | n/a | else |
---|
2540 | n/a | #endif |
---|
2541 | n/a | result = access(path->narrow, mode); |
---|
2542 | n/a | Py_END_ALLOW_THREADS |
---|
2543 | n/a | return_value = !result; |
---|
2544 | n/a | #endif |
---|
2545 | n/a | |
---|
2546 | n/a | return return_value; |
---|
2547 | n/a | } |
---|
2548 | n/a | |
---|
2549 | n/a | #ifndef F_OK |
---|
2550 | n/a | #define F_OK 0 |
---|
2551 | n/a | #endif |
---|
2552 | n/a | #ifndef R_OK |
---|
2553 | n/a | #define R_OK 4 |
---|
2554 | n/a | #endif |
---|
2555 | n/a | #ifndef W_OK |
---|
2556 | n/a | #define W_OK 2 |
---|
2557 | n/a | #endif |
---|
2558 | n/a | #ifndef X_OK |
---|
2559 | n/a | #define X_OK 1 |
---|
2560 | n/a | #endif |
---|
2561 | n/a | |
---|
2562 | n/a | |
---|
2563 | n/a | #ifdef HAVE_TTYNAME |
---|
2564 | n/a | /*[clinic input] |
---|
2565 | n/a | os.ttyname -> DecodeFSDefault |
---|
2566 | n/a | |
---|
2567 | n/a | fd: int |
---|
2568 | n/a | Integer file descriptor handle. |
---|
2569 | n/a | |
---|
2570 | n/a | / |
---|
2571 | n/a | |
---|
2572 | n/a | Return the name of the terminal device connected to 'fd'. |
---|
2573 | n/a | [clinic start generated code]*/ |
---|
2574 | n/a | |
---|
2575 | n/a | static char * |
---|
2576 | n/a | os_ttyname_impl(PyObject *module, int fd) |
---|
2577 | n/a | /*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/ |
---|
2578 | n/a | { |
---|
2579 | n/a | char *ret; |
---|
2580 | n/a | |
---|
2581 | n/a | ret = ttyname(fd); |
---|
2582 | n/a | if (ret == NULL) |
---|
2583 | n/a | posix_error(); |
---|
2584 | n/a | return ret; |
---|
2585 | n/a | } |
---|
2586 | n/a | #endif |
---|
2587 | n/a | |
---|
2588 | n/a | #ifdef HAVE_CTERMID |
---|
2589 | n/a | /*[clinic input] |
---|
2590 | n/a | os.ctermid |
---|
2591 | n/a | |
---|
2592 | n/a | Return the name of the controlling terminal for this process. |
---|
2593 | n/a | [clinic start generated code]*/ |
---|
2594 | n/a | |
---|
2595 | n/a | static PyObject * |
---|
2596 | n/a | os_ctermid_impl(PyObject *module) |
---|
2597 | n/a | /*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/ |
---|
2598 | n/a | { |
---|
2599 | n/a | char *ret; |
---|
2600 | n/a | char buffer[L_ctermid]; |
---|
2601 | n/a | |
---|
2602 | n/a | #ifdef USE_CTERMID_R |
---|
2603 | n/a | ret = ctermid_r(buffer); |
---|
2604 | n/a | #else |
---|
2605 | n/a | ret = ctermid(buffer); |
---|
2606 | n/a | #endif |
---|
2607 | n/a | if (ret == NULL) |
---|
2608 | n/a | return posix_error(); |
---|
2609 | n/a | return PyUnicode_DecodeFSDefault(buffer); |
---|
2610 | n/a | } |
---|
2611 | n/a | #endif /* HAVE_CTERMID */ |
---|
2612 | n/a | |
---|
2613 | n/a | |
---|
2614 | n/a | /*[clinic input] |
---|
2615 | n/a | os.chdir |
---|
2616 | n/a | |
---|
2617 | n/a | path: path_t(allow_fd='PATH_HAVE_FCHDIR') |
---|
2618 | n/a | |
---|
2619 | n/a | Change the current working directory to the specified path. |
---|
2620 | n/a | |
---|
2621 | n/a | path may always be specified as a string. |
---|
2622 | n/a | On some platforms, path may also be specified as an open file descriptor. |
---|
2623 | n/a | If this functionality is unavailable, using it raises an exception. |
---|
2624 | n/a | [clinic start generated code]*/ |
---|
2625 | n/a | |
---|
2626 | n/a | static PyObject * |
---|
2627 | n/a | os_chdir_impl(PyObject *module, path_t *path) |
---|
2628 | n/a | /*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/ |
---|
2629 | n/a | { |
---|
2630 | n/a | int result; |
---|
2631 | n/a | |
---|
2632 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
2633 | n/a | #ifdef MS_WINDOWS |
---|
2634 | n/a | /* on unix, success = 0, on windows, success = !0 */ |
---|
2635 | n/a | result = !win32_wchdir(path->wide); |
---|
2636 | n/a | #else |
---|
2637 | n/a | #ifdef HAVE_FCHDIR |
---|
2638 | n/a | if (path->fd != -1) |
---|
2639 | n/a | result = fchdir(path->fd); |
---|
2640 | n/a | else |
---|
2641 | n/a | #endif |
---|
2642 | n/a | result = chdir(path->narrow); |
---|
2643 | n/a | #endif |
---|
2644 | n/a | Py_END_ALLOW_THREADS |
---|
2645 | n/a | |
---|
2646 | n/a | if (result) { |
---|
2647 | n/a | return path_error(path); |
---|
2648 | n/a | } |
---|
2649 | n/a | |
---|
2650 | n/a | Py_RETURN_NONE; |
---|
2651 | n/a | } |
---|
2652 | n/a | |
---|
2653 | n/a | |
---|
2654 | n/a | #ifdef HAVE_FCHDIR |
---|
2655 | n/a | /*[clinic input] |
---|
2656 | n/a | os.fchdir |
---|
2657 | n/a | |
---|
2658 | n/a | fd: fildes |
---|
2659 | n/a | |
---|
2660 | n/a | Change to the directory of the given file descriptor. |
---|
2661 | n/a | |
---|
2662 | n/a | fd must be opened on a directory, not a file. |
---|
2663 | n/a | Equivalent to os.chdir(fd). |
---|
2664 | n/a | |
---|
2665 | n/a | [clinic start generated code]*/ |
---|
2666 | n/a | |
---|
2667 | n/a | static PyObject * |
---|
2668 | n/a | os_fchdir_impl(PyObject *module, int fd) |
---|
2669 | n/a | /*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/ |
---|
2670 | n/a | { |
---|
2671 | n/a | return posix_fildes_fd(fd, fchdir); |
---|
2672 | n/a | } |
---|
2673 | n/a | #endif /* HAVE_FCHDIR */ |
---|
2674 | n/a | |
---|
2675 | n/a | |
---|
2676 | n/a | /*[clinic input] |
---|
2677 | n/a | os.chmod |
---|
2678 | n/a | |
---|
2679 | n/a | path: path_t(allow_fd='PATH_HAVE_FCHMOD') |
---|
2680 | n/a | Path to be modified. May always be specified as a str or bytes. |
---|
2681 | n/a | On some platforms, path may also be specified as an open file descriptor. |
---|
2682 | n/a | If this functionality is unavailable, using it raises an exception. |
---|
2683 | n/a | |
---|
2684 | n/a | mode: int |
---|
2685 | n/a | Operating-system mode bitfield. |
---|
2686 | n/a | |
---|
2687 | n/a | * |
---|
2688 | n/a | |
---|
2689 | n/a | dir_fd : dir_fd(requires='fchmodat') = None |
---|
2690 | n/a | If not None, it should be a file descriptor open to a directory, |
---|
2691 | n/a | and path should be relative; path will then be relative to that |
---|
2692 | n/a | directory. |
---|
2693 | n/a | |
---|
2694 | n/a | follow_symlinks: bool = True |
---|
2695 | n/a | If False, and the last element of the path is a symbolic link, |
---|
2696 | n/a | chmod will modify the symbolic link itself instead of the file |
---|
2697 | n/a | the link points to. |
---|
2698 | n/a | |
---|
2699 | n/a | Change the access permissions of a file. |
---|
2700 | n/a | |
---|
2701 | n/a | It is an error to use dir_fd or follow_symlinks when specifying path as |
---|
2702 | n/a | an open file descriptor. |
---|
2703 | n/a | dir_fd and follow_symlinks may not be implemented on your platform. |
---|
2704 | n/a | If they are unavailable, using them will raise a NotImplementedError. |
---|
2705 | n/a | |
---|
2706 | n/a | [clinic start generated code]*/ |
---|
2707 | n/a | |
---|
2708 | n/a | static PyObject * |
---|
2709 | n/a | os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd, |
---|
2710 | n/a | int follow_symlinks) |
---|
2711 | n/a | /*[clinic end generated code: output=5cf6a94915cc7bff input=7f1618e5e15cc196]*/ |
---|
2712 | n/a | { |
---|
2713 | n/a | int result; |
---|
2714 | n/a | |
---|
2715 | n/a | #ifdef MS_WINDOWS |
---|
2716 | n/a | DWORD attr; |
---|
2717 | n/a | #endif |
---|
2718 | n/a | |
---|
2719 | n/a | #ifdef HAVE_FCHMODAT |
---|
2720 | n/a | int fchmodat_nofollow_unsupported = 0; |
---|
2721 | n/a | #endif |
---|
2722 | n/a | |
---|
2723 | n/a | #if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD)) |
---|
2724 | n/a | if (follow_symlinks_specified("chmod", follow_symlinks)) |
---|
2725 | n/a | return NULL; |
---|
2726 | n/a | #endif |
---|
2727 | n/a | |
---|
2728 | n/a | #ifdef MS_WINDOWS |
---|
2729 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
2730 | n/a | attr = GetFileAttributesW(path->wide); |
---|
2731 | n/a | if (attr == INVALID_FILE_ATTRIBUTES) |
---|
2732 | n/a | result = 0; |
---|
2733 | n/a | else { |
---|
2734 | n/a | if (mode & _S_IWRITE) |
---|
2735 | n/a | attr &= ~FILE_ATTRIBUTE_READONLY; |
---|
2736 | n/a | else |
---|
2737 | n/a | attr |= FILE_ATTRIBUTE_READONLY; |
---|
2738 | n/a | result = SetFileAttributesW(path->wide, attr); |
---|
2739 | n/a | } |
---|
2740 | n/a | Py_END_ALLOW_THREADS |
---|
2741 | n/a | |
---|
2742 | n/a | if (!result) { |
---|
2743 | n/a | return path_error(path); |
---|
2744 | n/a | } |
---|
2745 | n/a | #else /* MS_WINDOWS */ |
---|
2746 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
2747 | n/a | #ifdef HAVE_FCHMOD |
---|
2748 | n/a | if (path->fd != -1) |
---|
2749 | n/a | result = fchmod(path->fd, mode); |
---|
2750 | n/a | else |
---|
2751 | n/a | #endif |
---|
2752 | n/a | #ifdef HAVE_LCHMOD |
---|
2753 | n/a | if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD)) |
---|
2754 | n/a | result = lchmod(path->narrow, mode); |
---|
2755 | n/a | else |
---|
2756 | n/a | #endif |
---|
2757 | n/a | #ifdef HAVE_FCHMODAT |
---|
2758 | n/a | if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) { |
---|
2759 | n/a | /* |
---|
2760 | n/a | * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW! |
---|
2761 | n/a | * The documentation specifically shows how to use it, |
---|
2762 | n/a | * and then says it isn't implemented yet. |
---|
2763 | n/a | * (true on linux with glibc 2.15, and openindiana 3.x) |
---|
2764 | n/a | * |
---|
2765 | n/a | * Once it is supported, os.chmod will automatically |
---|
2766 | n/a | * support dir_fd and follow_symlinks=False. (Hopefully.) |
---|
2767 | n/a | * Until then, we need to be careful what exception we raise. |
---|
2768 | n/a | */ |
---|
2769 | n/a | result = fchmodat(dir_fd, path->narrow, mode, |
---|
2770 | n/a | follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW); |
---|
2771 | n/a | /* |
---|
2772 | n/a | * But wait! We can't throw the exception without allowing threads, |
---|
2773 | n/a | * and we can't do that in this nested scope. (Macro trickery, sigh.) |
---|
2774 | n/a | */ |
---|
2775 | n/a | fchmodat_nofollow_unsupported = |
---|
2776 | n/a | result && |
---|
2777 | n/a | ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) && |
---|
2778 | n/a | !follow_symlinks; |
---|
2779 | n/a | } |
---|
2780 | n/a | else |
---|
2781 | n/a | #endif |
---|
2782 | n/a | result = chmod(path->narrow, mode); |
---|
2783 | n/a | Py_END_ALLOW_THREADS |
---|
2784 | n/a | |
---|
2785 | n/a | if (result) { |
---|
2786 | n/a | #ifdef HAVE_FCHMODAT |
---|
2787 | n/a | if (fchmodat_nofollow_unsupported) { |
---|
2788 | n/a | if (dir_fd != DEFAULT_DIR_FD) |
---|
2789 | n/a | dir_fd_and_follow_symlinks_invalid("chmod", |
---|
2790 | n/a | dir_fd, follow_symlinks); |
---|
2791 | n/a | else |
---|
2792 | n/a | follow_symlinks_specified("chmod", follow_symlinks); |
---|
2793 | n/a | } |
---|
2794 | n/a | else |
---|
2795 | n/a | #endif |
---|
2796 | n/a | return path_error(path); |
---|
2797 | n/a | } |
---|
2798 | n/a | #endif |
---|
2799 | n/a | |
---|
2800 | n/a | Py_RETURN_NONE; |
---|
2801 | n/a | } |
---|
2802 | n/a | |
---|
2803 | n/a | |
---|
2804 | n/a | #ifdef HAVE_FCHMOD |
---|
2805 | n/a | /*[clinic input] |
---|
2806 | n/a | os.fchmod |
---|
2807 | n/a | |
---|
2808 | n/a | fd: int |
---|
2809 | n/a | mode: int |
---|
2810 | n/a | |
---|
2811 | n/a | Change the access permissions of the file given by file descriptor fd. |
---|
2812 | n/a | |
---|
2813 | n/a | Equivalent to os.chmod(fd, mode). |
---|
2814 | n/a | [clinic start generated code]*/ |
---|
2815 | n/a | |
---|
2816 | n/a | static PyObject * |
---|
2817 | n/a | os_fchmod_impl(PyObject *module, int fd, int mode) |
---|
2818 | n/a | /*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/ |
---|
2819 | n/a | { |
---|
2820 | n/a | int res; |
---|
2821 | n/a | int async_err = 0; |
---|
2822 | n/a | |
---|
2823 | n/a | do { |
---|
2824 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
2825 | n/a | res = fchmod(fd, mode); |
---|
2826 | n/a | Py_END_ALLOW_THREADS |
---|
2827 | n/a | } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); |
---|
2828 | n/a | if (res != 0) |
---|
2829 | n/a | return (!async_err) ? posix_error() : NULL; |
---|
2830 | n/a | |
---|
2831 | n/a | Py_RETURN_NONE; |
---|
2832 | n/a | } |
---|
2833 | n/a | #endif /* HAVE_FCHMOD */ |
---|
2834 | n/a | |
---|
2835 | n/a | |
---|
2836 | n/a | #ifdef HAVE_LCHMOD |
---|
2837 | n/a | /*[clinic input] |
---|
2838 | n/a | os.lchmod |
---|
2839 | n/a | |
---|
2840 | n/a | path: path_t |
---|
2841 | n/a | mode: int |
---|
2842 | n/a | |
---|
2843 | n/a | Change the access permissions of a file, without following symbolic links. |
---|
2844 | n/a | |
---|
2845 | n/a | If path is a symlink, this affects the link itself rather than the target. |
---|
2846 | n/a | Equivalent to chmod(path, mode, follow_symlinks=False)." |
---|
2847 | n/a | [clinic start generated code]*/ |
---|
2848 | n/a | |
---|
2849 | n/a | static PyObject * |
---|
2850 | n/a | os_lchmod_impl(PyObject *module, path_t *path, int mode) |
---|
2851 | n/a | /*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/ |
---|
2852 | n/a | { |
---|
2853 | n/a | int res; |
---|
2854 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
2855 | n/a | res = lchmod(path->narrow, mode); |
---|
2856 | n/a | Py_END_ALLOW_THREADS |
---|
2857 | n/a | if (res < 0) { |
---|
2858 | n/a | path_error(path); |
---|
2859 | n/a | return NULL; |
---|
2860 | n/a | } |
---|
2861 | n/a | Py_RETURN_NONE; |
---|
2862 | n/a | } |
---|
2863 | n/a | #endif /* HAVE_LCHMOD */ |
---|
2864 | n/a | |
---|
2865 | n/a | |
---|
2866 | n/a | #ifdef HAVE_CHFLAGS |
---|
2867 | n/a | /*[clinic input] |
---|
2868 | n/a | os.chflags |
---|
2869 | n/a | |
---|
2870 | n/a | path: path_t |
---|
2871 | n/a | flags: unsigned_long(bitwise=True) |
---|
2872 | n/a | follow_symlinks: bool=True |
---|
2873 | n/a | |
---|
2874 | n/a | Set file flags. |
---|
2875 | n/a | |
---|
2876 | n/a | If follow_symlinks is False, and the last element of the path is a symbolic |
---|
2877 | n/a | link, chflags will change flags on the symbolic link itself instead of the |
---|
2878 | n/a | file the link points to. |
---|
2879 | n/a | follow_symlinks may not be implemented on your platform. If it is |
---|
2880 | n/a | unavailable, using it will raise a NotImplementedError. |
---|
2881 | n/a | |
---|
2882 | n/a | [clinic start generated code]*/ |
---|
2883 | n/a | |
---|
2884 | n/a | static PyObject * |
---|
2885 | n/a | os_chflags_impl(PyObject *module, path_t *path, unsigned long flags, |
---|
2886 | n/a | int follow_symlinks) |
---|
2887 | n/a | /*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/ |
---|
2888 | n/a | { |
---|
2889 | n/a | int result; |
---|
2890 | n/a | |
---|
2891 | n/a | #ifndef HAVE_LCHFLAGS |
---|
2892 | n/a | if (follow_symlinks_specified("chflags", follow_symlinks)) |
---|
2893 | n/a | return NULL; |
---|
2894 | n/a | #endif |
---|
2895 | n/a | |
---|
2896 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
2897 | n/a | #ifdef HAVE_LCHFLAGS |
---|
2898 | n/a | if (!follow_symlinks) |
---|
2899 | n/a | result = lchflags(path->narrow, flags); |
---|
2900 | n/a | else |
---|
2901 | n/a | #endif |
---|
2902 | n/a | result = chflags(path->narrow, flags); |
---|
2903 | n/a | Py_END_ALLOW_THREADS |
---|
2904 | n/a | |
---|
2905 | n/a | if (result) |
---|
2906 | n/a | return path_error(path); |
---|
2907 | n/a | |
---|
2908 | n/a | Py_RETURN_NONE; |
---|
2909 | n/a | } |
---|
2910 | n/a | #endif /* HAVE_CHFLAGS */ |
---|
2911 | n/a | |
---|
2912 | n/a | |
---|
2913 | n/a | #ifdef HAVE_LCHFLAGS |
---|
2914 | n/a | /*[clinic input] |
---|
2915 | n/a | os.lchflags |
---|
2916 | n/a | |
---|
2917 | n/a | path: path_t |
---|
2918 | n/a | flags: unsigned_long(bitwise=True) |
---|
2919 | n/a | |
---|
2920 | n/a | Set file flags. |
---|
2921 | n/a | |
---|
2922 | n/a | This function will not follow symbolic links. |
---|
2923 | n/a | Equivalent to chflags(path, flags, follow_symlinks=False). |
---|
2924 | n/a | [clinic start generated code]*/ |
---|
2925 | n/a | |
---|
2926 | n/a | static PyObject * |
---|
2927 | n/a | os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags) |
---|
2928 | n/a | /*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/ |
---|
2929 | n/a | { |
---|
2930 | n/a | int res; |
---|
2931 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
2932 | n/a | res = lchflags(path->narrow, flags); |
---|
2933 | n/a | Py_END_ALLOW_THREADS |
---|
2934 | n/a | if (res < 0) { |
---|
2935 | n/a | return path_error(path); |
---|
2936 | n/a | } |
---|
2937 | n/a | Py_RETURN_NONE; |
---|
2938 | n/a | } |
---|
2939 | n/a | #endif /* HAVE_LCHFLAGS */ |
---|
2940 | n/a | |
---|
2941 | n/a | |
---|
2942 | n/a | #ifdef HAVE_CHROOT |
---|
2943 | n/a | /*[clinic input] |
---|
2944 | n/a | os.chroot |
---|
2945 | n/a | path: path_t |
---|
2946 | n/a | |
---|
2947 | n/a | Change root directory to path. |
---|
2948 | n/a | |
---|
2949 | n/a | [clinic start generated code]*/ |
---|
2950 | n/a | |
---|
2951 | n/a | static PyObject * |
---|
2952 | n/a | os_chroot_impl(PyObject *module, path_t *path) |
---|
2953 | n/a | /*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/ |
---|
2954 | n/a | { |
---|
2955 | n/a | int res; |
---|
2956 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
2957 | n/a | res = chroot(path->narrow); |
---|
2958 | n/a | Py_END_ALLOW_THREADS |
---|
2959 | n/a | if (res < 0) |
---|
2960 | n/a | return path_error(path); |
---|
2961 | n/a | Py_RETURN_NONE; |
---|
2962 | n/a | } |
---|
2963 | n/a | #endif /* HAVE_CHROOT */ |
---|
2964 | n/a | |
---|
2965 | n/a | |
---|
2966 | n/a | #ifdef HAVE_FSYNC |
---|
2967 | n/a | /*[clinic input] |
---|
2968 | n/a | os.fsync |
---|
2969 | n/a | |
---|
2970 | n/a | fd: fildes |
---|
2971 | n/a | |
---|
2972 | n/a | Force write of fd to disk. |
---|
2973 | n/a | [clinic start generated code]*/ |
---|
2974 | n/a | |
---|
2975 | n/a | static PyObject * |
---|
2976 | n/a | os_fsync_impl(PyObject *module, int fd) |
---|
2977 | n/a | /*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/ |
---|
2978 | n/a | { |
---|
2979 | n/a | return posix_fildes_fd(fd, fsync); |
---|
2980 | n/a | } |
---|
2981 | n/a | #endif /* HAVE_FSYNC */ |
---|
2982 | n/a | |
---|
2983 | n/a | |
---|
2984 | n/a | #ifdef HAVE_SYNC |
---|
2985 | n/a | /*[clinic input] |
---|
2986 | n/a | os.sync |
---|
2987 | n/a | |
---|
2988 | n/a | Force write of everything to disk. |
---|
2989 | n/a | [clinic start generated code]*/ |
---|
2990 | n/a | |
---|
2991 | n/a | static PyObject * |
---|
2992 | n/a | os_sync_impl(PyObject *module) |
---|
2993 | n/a | /*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/ |
---|
2994 | n/a | { |
---|
2995 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
2996 | n/a | sync(); |
---|
2997 | n/a | Py_END_ALLOW_THREADS |
---|
2998 | n/a | Py_RETURN_NONE; |
---|
2999 | n/a | } |
---|
3000 | n/a | #endif /* HAVE_SYNC */ |
---|
3001 | n/a | |
---|
3002 | n/a | |
---|
3003 | n/a | #ifdef HAVE_FDATASYNC |
---|
3004 | n/a | #ifdef __hpux |
---|
3005 | n/a | extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */ |
---|
3006 | n/a | #endif |
---|
3007 | n/a | |
---|
3008 | n/a | /*[clinic input] |
---|
3009 | n/a | os.fdatasync |
---|
3010 | n/a | |
---|
3011 | n/a | fd: fildes |
---|
3012 | n/a | |
---|
3013 | n/a | Force write of fd to disk without forcing update of metadata. |
---|
3014 | n/a | [clinic start generated code]*/ |
---|
3015 | n/a | |
---|
3016 | n/a | static PyObject * |
---|
3017 | n/a | os_fdatasync_impl(PyObject *module, int fd) |
---|
3018 | n/a | /*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/ |
---|
3019 | n/a | { |
---|
3020 | n/a | return posix_fildes_fd(fd, fdatasync); |
---|
3021 | n/a | } |
---|
3022 | n/a | #endif /* HAVE_FDATASYNC */ |
---|
3023 | n/a | |
---|
3024 | n/a | |
---|
3025 | n/a | #ifdef HAVE_CHOWN |
---|
3026 | n/a | /*[clinic input] |
---|
3027 | n/a | os.chown |
---|
3028 | n/a | |
---|
3029 | n/a | path : path_t(allow_fd='PATH_HAVE_FCHOWN') |
---|
3030 | n/a | Path to be examined; can be string, bytes, or open-file-descriptor int. |
---|
3031 | n/a | |
---|
3032 | n/a | uid: uid_t |
---|
3033 | n/a | |
---|
3034 | n/a | gid: gid_t |
---|
3035 | n/a | |
---|
3036 | n/a | * |
---|
3037 | n/a | |
---|
3038 | n/a | dir_fd : dir_fd(requires='fchownat') = None |
---|
3039 | n/a | If not None, it should be a file descriptor open to a directory, |
---|
3040 | n/a | and path should be relative; path will then be relative to that |
---|
3041 | n/a | directory. |
---|
3042 | n/a | |
---|
3043 | n/a | follow_symlinks: bool = True |
---|
3044 | n/a | If False, and the last element of the path is a symbolic link, |
---|
3045 | n/a | stat will examine the symbolic link itself instead of the file |
---|
3046 | n/a | the link points to. |
---|
3047 | n/a | |
---|
3048 | n/a | Change the owner and group id of path to the numeric uid and gid.\ |
---|
3049 | n/a | |
---|
3050 | n/a | path may always be specified as a string. |
---|
3051 | n/a | On some platforms, path may also be specified as an open file descriptor. |
---|
3052 | n/a | If this functionality is unavailable, using it raises an exception. |
---|
3053 | n/a | If dir_fd is not None, it should be a file descriptor open to a directory, |
---|
3054 | n/a | and path should be relative; path will then be relative to that directory. |
---|
3055 | n/a | If follow_symlinks is False, and the last element of the path is a symbolic |
---|
3056 | n/a | link, chown will modify the symbolic link itself instead of the file the |
---|
3057 | n/a | link points to. |
---|
3058 | n/a | It is an error to use dir_fd or follow_symlinks when specifying path as |
---|
3059 | n/a | an open file descriptor. |
---|
3060 | n/a | dir_fd and follow_symlinks may not be implemented on your platform. |
---|
3061 | n/a | If they are unavailable, using them will raise a NotImplementedError. |
---|
3062 | n/a | |
---|
3063 | n/a | [clinic start generated code]*/ |
---|
3064 | n/a | |
---|
3065 | n/a | static PyObject * |
---|
3066 | n/a | os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid, |
---|
3067 | n/a | int dir_fd, int follow_symlinks) |
---|
3068 | n/a | /*[clinic end generated code: output=4beadab0db5f70cd input=a61cc35574814d5d]*/ |
---|
3069 | n/a | { |
---|
3070 | n/a | int result; |
---|
3071 | n/a | |
---|
3072 | n/a | #if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT)) |
---|
3073 | n/a | if (follow_symlinks_specified("chown", follow_symlinks)) |
---|
3074 | n/a | return NULL; |
---|
3075 | n/a | #endif |
---|
3076 | n/a | if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) || |
---|
3077 | n/a | fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks)) |
---|
3078 | n/a | return NULL; |
---|
3079 | n/a | |
---|
3080 | n/a | #ifdef __APPLE__ |
---|
3081 | n/a | /* |
---|
3082 | n/a | * This is for Mac OS X 10.3, which doesn't have lchown. |
---|
3083 | n/a | * (But we still have an lchown symbol because of weak-linking.) |
---|
3084 | n/a | * It doesn't have fchownat either. So there's no possibility |
---|
3085 | n/a | * of a graceful failover. |
---|
3086 | n/a | */ |
---|
3087 | n/a | if ((!follow_symlinks) && (lchown == NULL)) { |
---|
3088 | n/a | follow_symlinks_specified("chown", follow_symlinks); |
---|
3089 | n/a | return NULL; |
---|
3090 | n/a | } |
---|
3091 | n/a | #endif |
---|
3092 | n/a | |
---|
3093 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
3094 | n/a | #ifdef HAVE_FCHOWN |
---|
3095 | n/a | if (path->fd != -1) |
---|
3096 | n/a | result = fchown(path->fd, uid, gid); |
---|
3097 | n/a | else |
---|
3098 | n/a | #endif |
---|
3099 | n/a | #ifdef HAVE_LCHOWN |
---|
3100 | n/a | if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD)) |
---|
3101 | n/a | result = lchown(path->narrow, uid, gid); |
---|
3102 | n/a | else |
---|
3103 | n/a | #endif |
---|
3104 | n/a | #ifdef HAVE_FCHOWNAT |
---|
3105 | n/a | if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks)) |
---|
3106 | n/a | result = fchownat(dir_fd, path->narrow, uid, gid, |
---|
3107 | n/a | follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW); |
---|
3108 | n/a | else |
---|
3109 | n/a | #endif |
---|
3110 | n/a | result = chown(path->narrow, uid, gid); |
---|
3111 | n/a | Py_END_ALLOW_THREADS |
---|
3112 | n/a | |
---|
3113 | n/a | if (result) |
---|
3114 | n/a | return path_error(path); |
---|
3115 | n/a | |
---|
3116 | n/a | Py_RETURN_NONE; |
---|
3117 | n/a | } |
---|
3118 | n/a | #endif /* HAVE_CHOWN */ |
---|
3119 | n/a | |
---|
3120 | n/a | |
---|
3121 | n/a | #ifdef HAVE_FCHOWN |
---|
3122 | n/a | /*[clinic input] |
---|
3123 | n/a | os.fchown |
---|
3124 | n/a | |
---|
3125 | n/a | fd: int |
---|
3126 | n/a | uid: uid_t |
---|
3127 | n/a | gid: gid_t |
---|
3128 | n/a | |
---|
3129 | n/a | Change the owner and group id of the file specified by file descriptor. |
---|
3130 | n/a | |
---|
3131 | n/a | Equivalent to os.chown(fd, uid, gid). |
---|
3132 | n/a | |
---|
3133 | n/a | [clinic start generated code]*/ |
---|
3134 | n/a | |
---|
3135 | n/a | static PyObject * |
---|
3136 | n/a | os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid) |
---|
3137 | n/a | /*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/ |
---|
3138 | n/a | { |
---|
3139 | n/a | int res; |
---|
3140 | n/a | int async_err = 0; |
---|
3141 | n/a | |
---|
3142 | n/a | do { |
---|
3143 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
3144 | n/a | res = fchown(fd, uid, gid); |
---|
3145 | n/a | Py_END_ALLOW_THREADS |
---|
3146 | n/a | } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); |
---|
3147 | n/a | if (res != 0) |
---|
3148 | n/a | return (!async_err) ? posix_error() : NULL; |
---|
3149 | n/a | |
---|
3150 | n/a | Py_RETURN_NONE; |
---|
3151 | n/a | } |
---|
3152 | n/a | #endif /* HAVE_FCHOWN */ |
---|
3153 | n/a | |
---|
3154 | n/a | |
---|
3155 | n/a | #ifdef HAVE_LCHOWN |
---|
3156 | n/a | /*[clinic input] |
---|
3157 | n/a | os.lchown |
---|
3158 | n/a | |
---|
3159 | n/a | path : path_t |
---|
3160 | n/a | uid: uid_t |
---|
3161 | n/a | gid: gid_t |
---|
3162 | n/a | |
---|
3163 | n/a | Change the owner and group id of path to the numeric uid and gid. |
---|
3164 | n/a | |
---|
3165 | n/a | This function will not follow symbolic links. |
---|
3166 | n/a | Equivalent to os.chown(path, uid, gid, follow_symlinks=False). |
---|
3167 | n/a | [clinic start generated code]*/ |
---|
3168 | n/a | |
---|
3169 | n/a | static PyObject * |
---|
3170 | n/a | os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid) |
---|
3171 | n/a | /*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/ |
---|
3172 | n/a | { |
---|
3173 | n/a | int res; |
---|
3174 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
3175 | n/a | res = lchown(path->narrow, uid, gid); |
---|
3176 | n/a | Py_END_ALLOW_THREADS |
---|
3177 | n/a | if (res < 0) { |
---|
3178 | n/a | return path_error(path); |
---|
3179 | n/a | } |
---|
3180 | n/a | Py_RETURN_NONE; |
---|
3181 | n/a | } |
---|
3182 | n/a | #endif /* HAVE_LCHOWN */ |
---|
3183 | n/a | |
---|
3184 | n/a | |
---|
3185 | n/a | static PyObject * |
---|
3186 | n/a | posix_getcwd(int use_bytes) |
---|
3187 | n/a | { |
---|
3188 | n/a | char *buf, *tmpbuf; |
---|
3189 | n/a | char *cwd; |
---|
3190 | n/a | const size_t chunk = 1024; |
---|
3191 | n/a | size_t buflen = 0; |
---|
3192 | n/a | PyObject *obj; |
---|
3193 | n/a | |
---|
3194 | n/a | #ifdef MS_WINDOWS |
---|
3195 | n/a | if (!use_bytes) { |
---|
3196 | n/a | wchar_t wbuf[MAXPATHLEN]; |
---|
3197 | n/a | wchar_t *wbuf2 = wbuf; |
---|
3198 | n/a | PyObject *resobj; |
---|
3199 | n/a | DWORD len; |
---|
3200 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
3201 | n/a | len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf); |
---|
3202 | n/a | /* If the buffer is large enough, len does not include the |
---|
3203 | n/a | terminating \0. If the buffer is too small, len includes |
---|
3204 | n/a | the space needed for the terminator. */ |
---|
3205 | n/a | if (len >= Py_ARRAY_LENGTH(wbuf)) { |
---|
3206 | n/a | wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t)); |
---|
3207 | n/a | if (wbuf2) |
---|
3208 | n/a | len = GetCurrentDirectoryW(len, wbuf2); |
---|
3209 | n/a | } |
---|
3210 | n/a | Py_END_ALLOW_THREADS |
---|
3211 | n/a | if (!wbuf2) { |
---|
3212 | n/a | PyErr_NoMemory(); |
---|
3213 | n/a | return NULL; |
---|
3214 | n/a | } |
---|
3215 | n/a | if (!len) { |
---|
3216 | n/a | if (wbuf2 != wbuf) |
---|
3217 | n/a | PyMem_RawFree(wbuf2); |
---|
3218 | n/a | return PyErr_SetFromWindowsErr(0); |
---|
3219 | n/a | } |
---|
3220 | n/a | resobj = PyUnicode_FromWideChar(wbuf2, len); |
---|
3221 | n/a | if (wbuf2 != wbuf) |
---|
3222 | n/a | PyMem_RawFree(wbuf2); |
---|
3223 | n/a | return resobj; |
---|
3224 | n/a | } |
---|
3225 | n/a | |
---|
3226 | n/a | if (win32_warn_bytes_api()) |
---|
3227 | n/a | return NULL; |
---|
3228 | n/a | #endif |
---|
3229 | n/a | |
---|
3230 | n/a | buf = cwd = NULL; |
---|
3231 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
3232 | n/a | do { |
---|
3233 | n/a | buflen += chunk; |
---|
3234 | n/a | #ifdef MS_WINDOWS |
---|
3235 | n/a | if (buflen > INT_MAX) { |
---|
3236 | n/a | PyErr_NoMemory(); |
---|
3237 | n/a | break; |
---|
3238 | n/a | } |
---|
3239 | n/a | #endif |
---|
3240 | n/a | tmpbuf = PyMem_RawRealloc(buf, buflen); |
---|
3241 | n/a | if (tmpbuf == NULL) |
---|
3242 | n/a | break; |
---|
3243 | n/a | |
---|
3244 | n/a | buf = tmpbuf; |
---|
3245 | n/a | #ifdef MS_WINDOWS |
---|
3246 | n/a | cwd = getcwd(buf, (int)buflen); |
---|
3247 | n/a | #else |
---|
3248 | n/a | cwd = getcwd(buf, buflen); |
---|
3249 | n/a | #endif |
---|
3250 | n/a | } while (cwd == NULL && errno == ERANGE); |
---|
3251 | n/a | Py_END_ALLOW_THREADS |
---|
3252 | n/a | |
---|
3253 | n/a | if (cwd == NULL) { |
---|
3254 | n/a | PyMem_RawFree(buf); |
---|
3255 | n/a | return posix_error(); |
---|
3256 | n/a | } |
---|
3257 | n/a | |
---|
3258 | n/a | if (use_bytes) |
---|
3259 | n/a | obj = PyBytes_FromStringAndSize(buf, strlen(buf)); |
---|
3260 | n/a | else |
---|
3261 | n/a | obj = PyUnicode_DecodeFSDefault(buf); |
---|
3262 | n/a | PyMem_RawFree(buf); |
---|
3263 | n/a | |
---|
3264 | n/a | return obj; |
---|
3265 | n/a | } |
---|
3266 | n/a | |
---|
3267 | n/a | |
---|
3268 | n/a | /*[clinic input] |
---|
3269 | n/a | os.getcwd |
---|
3270 | n/a | |
---|
3271 | n/a | Return a unicode string representing the current working directory. |
---|
3272 | n/a | [clinic start generated code]*/ |
---|
3273 | n/a | |
---|
3274 | n/a | static PyObject * |
---|
3275 | n/a | os_getcwd_impl(PyObject *module) |
---|
3276 | n/a | /*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/ |
---|
3277 | n/a | { |
---|
3278 | n/a | return posix_getcwd(0); |
---|
3279 | n/a | } |
---|
3280 | n/a | |
---|
3281 | n/a | |
---|
3282 | n/a | /*[clinic input] |
---|
3283 | n/a | os.getcwdb |
---|
3284 | n/a | |
---|
3285 | n/a | Return a bytes string representing the current working directory. |
---|
3286 | n/a | [clinic start generated code]*/ |
---|
3287 | n/a | |
---|
3288 | n/a | static PyObject * |
---|
3289 | n/a | os_getcwdb_impl(PyObject *module) |
---|
3290 | n/a | /*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/ |
---|
3291 | n/a | { |
---|
3292 | n/a | return posix_getcwd(1); |
---|
3293 | n/a | } |
---|
3294 | n/a | |
---|
3295 | n/a | |
---|
3296 | n/a | #if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS)) |
---|
3297 | n/a | #define HAVE_LINK 1 |
---|
3298 | n/a | #endif |
---|
3299 | n/a | |
---|
3300 | n/a | #ifdef HAVE_LINK |
---|
3301 | n/a | /*[clinic input] |
---|
3302 | n/a | |
---|
3303 | n/a | os.link |
---|
3304 | n/a | |
---|
3305 | n/a | src : path_t |
---|
3306 | n/a | dst : path_t |
---|
3307 | n/a | * |
---|
3308 | n/a | src_dir_fd : dir_fd = None |
---|
3309 | n/a | dst_dir_fd : dir_fd = None |
---|
3310 | n/a | follow_symlinks: bool = True |
---|
3311 | n/a | |
---|
3312 | n/a | Create a hard link to a file. |
---|
3313 | n/a | |
---|
3314 | n/a | If either src_dir_fd or dst_dir_fd is not None, it should be a file |
---|
3315 | n/a | descriptor open to a directory, and the respective path string (src or dst) |
---|
3316 | n/a | should be relative; the path will then be relative to that directory. |
---|
3317 | n/a | If follow_symlinks is False, and the last element of src is a symbolic |
---|
3318 | n/a | link, link will create a link to the symbolic link itself instead of the |
---|
3319 | n/a | file the link points to. |
---|
3320 | n/a | src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your |
---|
3321 | n/a | platform. If they are unavailable, using them will raise a |
---|
3322 | n/a | NotImplementedError. |
---|
3323 | n/a | [clinic start generated code]*/ |
---|
3324 | n/a | |
---|
3325 | n/a | static PyObject * |
---|
3326 | n/a | os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd, |
---|
3327 | n/a | int dst_dir_fd, int follow_symlinks) |
---|
3328 | n/a | /*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/ |
---|
3329 | n/a | { |
---|
3330 | n/a | #ifdef MS_WINDOWS |
---|
3331 | n/a | BOOL result = FALSE; |
---|
3332 | n/a | #else |
---|
3333 | n/a | int result; |
---|
3334 | n/a | #endif |
---|
3335 | n/a | |
---|
3336 | n/a | #ifndef HAVE_LINKAT |
---|
3337 | n/a | if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) { |
---|
3338 | n/a | argument_unavailable_error("link", "src_dir_fd and dst_dir_fd"); |
---|
3339 | n/a | return NULL; |
---|
3340 | n/a | } |
---|
3341 | n/a | #endif |
---|
3342 | n/a | |
---|
3343 | n/a | #ifndef MS_WINDOWS |
---|
3344 | n/a | if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) { |
---|
3345 | n/a | PyErr_SetString(PyExc_NotImplementedError, |
---|
3346 | n/a | "link: src and dst must be the same type"); |
---|
3347 | n/a | return NULL; |
---|
3348 | n/a | } |
---|
3349 | n/a | #endif |
---|
3350 | n/a | |
---|
3351 | n/a | #ifdef MS_WINDOWS |
---|
3352 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
3353 | n/a | result = CreateHardLinkW(dst->wide, src->wide, NULL); |
---|
3354 | n/a | Py_END_ALLOW_THREADS |
---|
3355 | n/a | |
---|
3356 | n/a | if (!result) |
---|
3357 | n/a | return path_error2(src, dst); |
---|
3358 | n/a | #else |
---|
3359 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
3360 | n/a | #ifdef HAVE_LINKAT |
---|
3361 | n/a | if ((src_dir_fd != DEFAULT_DIR_FD) || |
---|
3362 | n/a | (dst_dir_fd != DEFAULT_DIR_FD) || |
---|
3363 | n/a | (!follow_symlinks)) |
---|
3364 | n/a | result = linkat(src_dir_fd, src->narrow, |
---|
3365 | n/a | dst_dir_fd, dst->narrow, |
---|
3366 | n/a | follow_symlinks ? AT_SYMLINK_FOLLOW : 0); |
---|
3367 | n/a | else |
---|
3368 | n/a | #endif /* HAVE_LINKAT */ |
---|
3369 | n/a | result = link(src->narrow, dst->narrow); |
---|
3370 | n/a | Py_END_ALLOW_THREADS |
---|
3371 | n/a | |
---|
3372 | n/a | if (result) |
---|
3373 | n/a | return path_error2(src, dst); |
---|
3374 | n/a | #endif /* MS_WINDOWS */ |
---|
3375 | n/a | |
---|
3376 | n/a | Py_RETURN_NONE; |
---|
3377 | n/a | } |
---|
3378 | n/a | #endif |
---|
3379 | n/a | |
---|
3380 | n/a | |
---|
3381 | n/a | #if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR) |
---|
3382 | n/a | static PyObject * |
---|
3383 | n/a | _listdir_windows_no_opendir(path_t *path, PyObject *list) |
---|
3384 | n/a | { |
---|
3385 | n/a | PyObject *v; |
---|
3386 | n/a | HANDLE hFindFile = INVALID_HANDLE_VALUE; |
---|
3387 | n/a | BOOL result; |
---|
3388 | n/a | wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */ |
---|
3389 | n/a | /* only claim to have space for MAX_PATH */ |
---|
3390 | n/a | Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4; |
---|
3391 | n/a | wchar_t *wnamebuf = NULL; |
---|
3392 | n/a | |
---|
3393 | n/a | WIN32_FIND_DATAW wFileData; |
---|
3394 | n/a | const wchar_t *po_wchars; |
---|
3395 | n/a | |
---|
3396 | n/a | if (!path->wide) { /* Default arg: "." */ |
---|
3397 | n/a | po_wchars = L"."; |
---|
3398 | n/a | len = 1; |
---|
3399 | n/a | } else { |
---|
3400 | n/a | po_wchars = path->wide; |
---|
3401 | n/a | len = wcslen(path->wide); |
---|
3402 | n/a | } |
---|
3403 | n/a | /* The +5 is so we can append "\\*.*\0" */ |
---|
3404 | n/a | wnamebuf = PyMem_New(wchar_t, len + 5); |
---|
3405 | n/a | if (!wnamebuf) { |
---|
3406 | n/a | PyErr_NoMemory(); |
---|
3407 | n/a | goto exit; |
---|
3408 | n/a | } |
---|
3409 | n/a | wcscpy(wnamebuf, po_wchars); |
---|
3410 | n/a | if (len > 0) { |
---|
3411 | n/a | wchar_t wch = wnamebuf[len-1]; |
---|
3412 | n/a | if (wch != SEP && wch != ALTSEP && wch != L':') |
---|
3413 | n/a | wnamebuf[len++] = SEP; |
---|
3414 | n/a | wcscpy(wnamebuf + len, L"*.*"); |
---|
3415 | n/a | } |
---|
3416 | n/a | if ((list = PyList_New(0)) == NULL) { |
---|
3417 | n/a | goto exit; |
---|
3418 | n/a | } |
---|
3419 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
3420 | n/a | hFindFile = FindFirstFileW(wnamebuf, &wFileData); |
---|
3421 | n/a | Py_END_ALLOW_THREADS |
---|
3422 | n/a | if (hFindFile == INVALID_HANDLE_VALUE) { |
---|
3423 | n/a | int error = GetLastError(); |
---|
3424 | n/a | if (error == ERROR_FILE_NOT_FOUND) |
---|
3425 | n/a | goto exit; |
---|
3426 | n/a | Py_DECREF(list); |
---|
3427 | n/a | list = path_error(path); |
---|
3428 | n/a | goto exit; |
---|
3429 | n/a | } |
---|
3430 | n/a | do { |
---|
3431 | n/a | /* Skip over . and .. */ |
---|
3432 | n/a | if (wcscmp(wFileData.cFileName, L".") != 0 && |
---|
3433 | n/a | wcscmp(wFileData.cFileName, L"..") != 0) { |
---|
3434 | n/a | v = PyUnicode_FromWideChar(wFileData.cFileName, |
---|
3435 | n/a | wcslen(wFileData.cFileName)); |
---|
3436 | n/a | if (path->narrow && v) { |
---|
3437 | n/a | Py_SETREF(v, PyUnicode_EncodeFSDefault(v)); |
---|
3438 | n/a | } |
---|
3439 | n/a | if (v == NULL) { |
---|
3440 | n/a | Py_DECREF(list); |
---|
3441 | n/a | list = NULL; |
---|
3442 | n/a | break; |
---|
3443 | n/a | } |
---|
3444 | n/a | if (PyList_Append(list, v) != 0) { |
---|
3445 | n/a | Py_DECREF(v); |
---|
3446 | n/a | Py_DECREF(list); |
---|
3447 | n/a | list = NULL; |
---|
3448 | n/a | break; |
---|
3449 | n/a | } |
---|
3450 | n/a | Py_DECREF(v); |
---|
3451 | n/a | } |
---|
3452 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
3453 | n/a | result = FindNextFileW(hFindFile, &wFileData); |
---|
3454 | n/a | Py_END_ALLOW_THREADS |
---|
3455 | n/a | /* FindNextFile sets error to ERROR_NO_MORE_FILES if |
---|
3456 | n/a | it got to the end of the directory. */ |
---|
3457 | n/a | if (!result && GetLastError() != ERROR_NO_MORE_FILES) { |
---|
3458 | n/a | Py_DECREF(list); |
---|
3459 | n/a | list = path_error(path); |
---|
3460 | n/a | goto exit; |
---|
3461 | n/a | } |
---|
3462 | n/a | } while (result == TRUE); |
---|
3463 | n/a | |
---|
3464 | n/a | exit: |
---|
3465 | n/a | if (hFindFile != INVALID_HANDLE_VALUE) { |
---|
3466 | n/a | if (FindClose(hFindFile) == FALSE) { |
---|
3467 | n/a | if (list != NULL) { |
---|
3468 | n/a | Py_DECREF(list); |
---|
3469 | n/a | list = path_error(path); |
---|
3470 | n/a | } |
---|
3471 | n/a | } |
---|
3472 | n/a | } |
---|
3473 | n/a | PyMem_Free(wnamebuf); |
---|
3474 | n/a | |
---|
3475 | n/a | return list; |
---|
3476 | n/a | } /* end of _listdir_windows_no_opendir */ |
---|
3477 | n/a | |
---|
3478 | n/a | #else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */ |
---|
3479 | n/a | |
---|
3480 | n/a | static PyObject * |
---|
3481 | n/a | _posix_listdir(path_t *path, PyObject *list) |
---|
3482 | n/a | { |
---|
3483 | n/a | PyObject *v; |
---|
3484 | n/a | DIR *dirp = NULL; |
---|
3485 | n/a | struct dirent *ep; |
---|
3486 | n/a | int return_str; /* if false, return bytes */ |
---|
3487 | n/a | #ifdef HAVE_FDOPENDIR |
---|
3488 | n/a | int fd = -1; |
---|
3489 | n/a | #endif |
---|
3490 | n/a | |
---|
3491 | n/a | errno = 0; |
---|
3492 | n/a | #ifdef HAVE_FDOPENDIR |
---|
3493 | n/a | if (path->fd != -1) { |
---|
3494 | n/a | /* closedir() closes the FD, so we duplicate it */ |
---|
3495 | n/a | fd = _Py_dup(path->fd); |
---|
3496 | n/a | if (fd == -1) |
---|
3497 | n/a | return NULL; |
---|
3498 | n/a | |
---|
3499 | n/a | return_str = 1; |
---|
3500 | n/a | |
---|
3501 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
3502 | n/a | dirp = fdopendir(fd); |
---|
3503 | n/a | Py_END_ALLOW_THREADS |
---|
3504 | n/a | } |
---|
3505 | n/a | else |
---|
3506 | n/a | #endif |
---|
3507 | n/a | { |
---|
3508 | n/a | const char *name; |
---|
3509 | n/a | if (path->narrow) { |
---|
3510 | n/a | name = path->narrow; |
---|
3511 | n/a | /* only return bytes if they specified a bytes object */ |
---|
3512 | n/a | return_str = !(PyBytes_Check(path->object)); |
---|
3513 | n/a | } |
---|
3514 | n/a | else { |
---|
3515 | n/a | name = "."; |
---|
3516 | n/a | return_str = 1; |
---|
3517 | n/a | } |
---|
3518 | n/a | |
---|
3519 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
3520 | n/a | dirp = opendir(name); |
---|
3521 | n/a | Py_END_ALLOW_THREADS |
---|
3522 | n/a | } |
---|
3523 | n/a | |
---|
3524 | n/a | if (dirp == NULL) { |
---|
3525 | n/a | list = path_error(path); |
---|
3526 | n/a | #ifdef HAVE_FDOPENDIR |
---|
3527 | n/a | if (fd != -1) { |
---|
3528 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
3529 | n/a | close(fd); |
---|
3530 | n/a | Py_END_ALLOW_THREADS |
---|
3531 | n/a | } |
---|
3532 | n/a | #endif |
---|
3533 | n/a | goto exit; |
---|
3534 | n/a | } |
---|
3535 | n/a | if ((list = PyList_New(0)) == NULL) { |
---|
3536 | n/a | goto exit; |
---|
3537 | n/a | } |
---|
3538 | n/a | for (;;) { |
---|
3539 | n/a | errno = 0; |
---|
3540 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
3541 | n/a | ep = readdir(dirp); |
---|
3542 | n/a | Py_END_ALLOW_THREADS |
---|
3543 | n/a | if (ep == NULL) { |
---|
3544 | n/a | if (errno == 0) { |
---|
3545 | n/a | break; |
---|
3546 | n/a | } else { |
---|
3547 | n/a | Py_DECREF(list); |
---|
3548 | n/a | list = path_error(path); |
---|
3549 | n/a | goto exit; |
---|
3550 | n/a | } |
---|
3551 | n/a | } |
---|
3552 | n/a | if (ep->d_name[0] == '.' && |
---|
3553 | n/a | (NAMLEN(ep) == 1 || |
---|
3554 | n/a | (ep->d_name[1] == '.' && NAMLEN(ep) == 2))) |
---|
3555 | n/a | continue; |
---|
3556 | n/a | if (return_str) |
---|
3557 | n/a | v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep)); |
---|
3558 | n/a | else |
---|
3559 | n/a | v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep)); |
---|
3560 | n/a | if (v == NULL) { |
---|
3561 | n/a | Py_CLEAR(list); |
---|
3562 | n/a | break; |
---|
3563 | n/a | } |
---|
3564 | n/a | if (PyList_Append(list, v) != 0) { |
---|
3565 | n/a | Py_DECREF(v); |
---|
3566 | n/a | Py_CLEAR(list); |
---|
3567 | n/a | break; |
---|
3568 | n/a | } |
---|
3569 | n/a | Py_DECREF(v); |
---|
3570 | n/a | } |
---|
3571 | n/a | |
---|
3572 | n/a | exit: |
---|
3573 | n/a | if (dirp != NULL) { |
---|
3574 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
3575 | n/a | #ifdef HAVE_FDOPENDIR |
---|
3576 | n/a | if (fd > -1) |
---|
3577 | n/a | rewinddir(dirp); |
---|
3578 | n/a | #endif |
---|
3579 | n/a | closedir(dirp); |
---|
3580 | n/a | Py_END_ALLOW_THREADS |
---|
3581 | n/a | } |
---|
3582 | n/a | |
---|
3583 | n/a | return list; |
---|
3584 | n/a | } /* end of _posix_listdir */ |
---|
3585 | n/a | #endif /* which OS */ |
---|
3586 | n/a | |
---|
3587 | n/a | |
---|
3588 | n/a | /*[clinic input] |
---|
3589 | n/a | os.listdir |
---|
3590 | n/a | |
---|
3591 | n/a | path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None |
---|
3592 | n/a | |
---|
3593 | n/a | Return a list containing the names of the files in the directory. |
---|
3594 | n/a | |
---|
3595 | n/a | path can be specified as either str or bytes. If path is bytes, |
---|
3596 | n/a | the filenames returned will also be bytes; in all other circumstances |
---|
3597 | n/a | the filenames returned will be str. |
---|
3598 | n/a | If path is None, uses the path='.'. |
---|
3599 | n/a | On some platforms, path may also be specified as an open file descriptor;\ |
---|
3600 | n/a | the file descriptor must refer to a directory. |
---|
3601 | n/a | If this functionality is unavailable, using it raises NotImplementedError. |
---|
3602 | n/a | |
---|
3603 | n/a | The list is in arbitrary order. It does not include the special |
---|
3604 | n/a | entries '.' and '..' even if they are present in the directory. |
---|
3605 | n/a | |
---|
3606 | n/a | |
---|
3607 | n/a | [clinic start generated code]*/ |
---|
3608 | n/a | |
---|
3609 | n/a | static PyObject * |
---|
3610 | n/a | os_listdir_impl(PyObject *module, path_t *path) |
---|
3611 | n/a | /*[clinic end generated code: output=293045673fcd1a75 input=09e300416e3cd729]*/ |
---|
3612 | n/a | { |
---|
3613 | n/a | #if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR) |
---|
3614 | n/a | return _listdir_windows_no_opendir(path, NULL); |
---|
3615 | n/a | #else |
---|
3616 | n/a | return _posix_listdir(path, NULL); |
---|
3617 | n/a | #endif |
---|
3618 | n/a | } |
---|
3619 | n/a | |
---|
3620 | n/a | #ifdef MS_WINDOWS |
---|
3621 | n/a | /* A helper function for abspath on win32 */ |
---|
3622 | n/a | /*[clinic input] |
---|
3623 | n/a | os._getfullpathname |
---|
3624 | n/a | |
---|
3625 | n/a | path: path_t |
---|
3626 | n/a | / |
---|
3627 | n/a | |
---|
3628 | n/a | [clinic start generated code]*/ |
---|
3629 | n/a | |
---|
3630 | n/a | static PyObject * |
---|
3631 | n/a | os__getfullpathname_impl(PyObject *module, path_t *path) |
---|
3632 | n/a | /*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/ |
---|
3633 | n/a | { |
---|
3634 | n/a | wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf; |
---|
3635 | n/a | wchar_t *wtemp; |
---|
3636 | n/a | DWORD result; |
---|
3637 | n/a | PyObject *v; |
---|
3638 | n/a | |
---|
3639 | n/a | result = GetFullPathNameW(path->wide, |
---|
3640 | n/a | Py_ARRAY_LENGTH(woutbuf), |
---|
3641 | n/a | woutbuf, &wtemp); |
---|
3642 | n/a | if (result > Py_ARRAY_LENGTH(woutbuf)) { |
---|
3643 | n/a | woutbufp = PyMem_New(wchar_t, result); |
---|
3644 | n/a | if (!woutbufp) |
---|
3645 | n/a | return PyErr_NoMemory(); |
---|
3646 | n/a | result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp); |
---|
3647 | n/a | } |
---|
3648 | n/a | if (result) { |
---|
3649 | n/a | v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp)); |
---|
3650 | n/a | if (path->narrow) |
---|
3651 | n/a | Py_SETREF(v, PyUnicode_EncodeFSDefault(v)); |
---|
3652 | n/a | } else |
---|
3653 | n/a | v = win32_error_object("GetFullPathNameW", path->object); |
---|
3654 | n/a | if (woutbufp != woutbuf) |
---|
3655 | n/a | PyMem_Free(woutbufp); |
---|
3656 | n/a | return v; |
---|
3657 | n/a | } |
---|
3658 | n/a | |
---|
3659 | n/a | |
---|
3660 | n/a | /*[clinic input] |
---|
3661 | n/a | os._getfinalpathname |
---|
3662 | n/a | |
---|
3663 | n/a | path: unicode |
---|
3664 | n/a | / |
---|
3665 | n/a | |
---|
3666 | n/a | A helper function for samepath on windows. |
---|
3667 | n/a | [clinic start generated code]*/ |
---|
3668 | n/a | |
---|
3669 | n/a | static PyObject * |
---|
3670 | n/a | os__getfinalpathname_impl(PyObject *module, PyObject *path) |
---|
3671 | n/a | /*[clinic end generated code: output=9bd78d0e52782e75 input=71d5e89334891bf4]*/ |
---|
3672 | n/a | { |
---|
3673 | n/a | HANDLE hFile; |
---|
3674 | n/a | int buf_size; |
---|
3675 | n/a | wchar_t *target_path; |
---|
3676 | n/a | int result_length; |
---|
3677 | n/a | PyObject *result; |
---|
3678 | n/a | const wchar_t *path_wchar; |
---|
3679 | n/a | |
---|
3680 | n/a | path_wchar = PyUnicode_AsUnicode(path); |
---|
3681 | n/a | if (path_wchar == NULL) |
---|
3682 | n/a | return NULL; |
---|
3683 | n/a | |
---|
3684 | n/a | hFile = CreateFileW( |
---|
3685 | n/a | path_wchar, |
---|
3686 | n/a | 0, /* desired access */ |
---|
3687 | n/a | 0, /* share mode */ |
---|
3688 | n/a | NULL, /* security attributes */ |
---|
3689 | n/a | OPEN_EXISTING, |
---|
3690 | n/a | /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */ |
---|
3691 | n/a | FILE_FLAG_BACKUP_SEMANTICS, |
---|
3692 | n/a | NULL); |
---|
3693 | n/a | |
---|
3694 | n/a | if(hFile == INVALID_HANDLE_VALUE) |
---|
3695 | n/a | return win32_error_object("CreateFileW", path); |
---|
3696 | n/a | |
---|
3697 | n/a | /* We have a good handle to the target, use it to determine the |
---|
3698 | n/a | target path name. */ |
---|
3699 | n/a | buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT); |
---|
3700 | n/a | |
---|
3701 | n/a | if(!buf_size) |
---|
3702 | n/a | return win32_error_object("GetFinalPathNameByHandle", path); |
---|
3703 | n/a | |
---|
3704 | n/a | target_path = PyMem_New(wchar_t, buf_size+1); |
---|
3705 | n/a | if(!target_path) |
---|
3706 | n/a | return PyErr_NoMemory(); |
---|
3707 | n/a | |
---|
3708 | n/a | result_length = GetFinalPathNameByHandleW(hFile, target_path, |
---|
3709 | n/a | buf_size, VOLUME_NAME_DOS); |
---|
3710 | n/a | if(!result_length) |
---|
3711 | n/a | return win32_error_object("GetFinalPathNamyByHandle", path); |
---|
3712 | n/a | |
---|
3713 | n/a | if(!CloseHandle(hFile)) |
---|
3714 | n/a | return win32_error_object("CloseHandle", path); |
---|
3715 | n/a | |
---|
3716 | n/a | target_path[result_length] = 0; |
---|
3717 | n/a | result = PyUnicode_FromWideChar(target_path, result_length); |
---|
3718 | n/a | PyMem_Free(target_path); |
---|
3719 | n/a | return result; |
---|
3720 | n/a | } |
---|
3721 | n/a | |
---|
3722 | n/a | /*[clinic input] |
---|
3723 | n/a | os._isdir |
---|
3724 | n/a | |
---|
3725 | n/a | path: path_t |
---|
3726 | n/a | / |
---|
3727 | n/a | |
---|
3728 | n/a | Return true if the pathname refers to an existing directory. |
---|
3729 | n/a | [clinic start generated code]*/ |
---|
3730 | n/a | |
---|
3731 | n/a | static PyObject * |
---|
3732 | n/a | os__isdir_impl(PyObject *module, path_t *path) |
---|
3733 | n/a | /*[clinic end generated code: output=75f56f32720836cb input=5e0800149c0ad95f]*/ |
---|
3734 | n/a | { |
---|
3735 | n/a | DWORD attributes; |
---|
3736 | n/a | |
---|
3737 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
3738 | n/a | attributes = GetFileAttributesW(path->wide); |
---|
3739 | n/a | Py_END_ALLOW_THREADS |
---|
3740 | n/a | |
---|
3741 | n/a | if (attributes == INVALID_FILE_ATTRIBUTES) |
---|
3742 | n/a | Py_RETURN_FALSE; |
---|
3743 | n/a | |
---|
3744 | n/a | if (attributes & FILE_ATTRIBUTE_DIRECTORY) |
---|
3745 | n/a | Py_RETURN_TRUE; |
---|
3746 | n/a | else |
---|
3747 | n/a | Py_RETURN_FALSE; |
---|
3748 | n/a | } |
---|
3749 | n/a | |
---|
3750 | n/a | |
---|
3751 | n/a | /*[clinic input] |
---|
3752 | n/a | os._getvolumepathname |
---|
3753 | n/a | |
---|
3754 | n/a | path: unicode |
---|
3755 | n/a | |
---|
3756 | n/a | A helper function for ismount on Win32. |
---|
3757 | n/a | [clinic start generated code]*/ |
---|
3758 | n/a | |
---|
3759 | n/a | static PyObject * |
---|
3760 | n/a | os__getvolumepathname_impl(PyObject *module, PyObject *path) |
---|
3761 | n/a | /*[clinic end generated code: output=cbdcbd1059ceef4c input=7eacadc40acbda6b]*/ |
---|
3762 | n/a | { |
---|
3763 | n/a | PyObject *result; |
---|
3764 | n/a | const wchar_t *path_wchar; |
---|
3765 | n/a | wchar_t *mountpath=NULL; |
---|
3766 | n/a | size_t buflen; |
---|
3767 | n/a | BOOL ret; |
---|
3768 | n/a | |
---|
3769 | n/a | path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen); |
---|
3770 | n/a | if (path_wchar == NULL) |
---|
3771 | n/a | return NULL; |
---|
3772 | n/a | buflen += 1; |
---|
3773 | n/a | |
---|
3774 | n/a | /* Volume path should be shorter than entire path */ |
---|
3775 | n/a | buflen = Py_MAX(buflen, MAX_PATH); |
---|
3776 | n/a | |
---|
3777 | n/a | if (buflen > DWORD_MAX) { |
---|
3778 | n/a | PyErr_SetString(PyExc_OverflowError, "path too long"); |
---|
3779 | n/a | return NULL; |
---|
3780 | n/a | } |
---|
3781 | n/a | |
---|
3782 | n/a | mountpath = PyMem_New(wchar_t, buflen); |
---|
3783 | n/a | if (mountpath == NULL) |
---|
3784 | n/a | return PyErr_NoMemory(); |
---|
3785 | n/a | |
---|
3786 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
3787 | n/a | ret = GetVolumePathNameW(path_wchar, mountpath, |
---|
3788 | n/a | Py_SAFE_DOWNCAST(buflen, size_t, DWORD)); |
---|
3789 | n/a | Py_END_ALLOW_THREADS |
---|
3790 | n/a | |
---|
3791 | n/a | if (!ret) { |
---|
3792 | n/a | result = win32_error_object("_getvolumepathname", path); |
---|
3793 | n/a | goto exit; |
---|
3794 | n/a | } |
---|
3795 | n/a | result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath)); |
---|
3796 | n/a | |
---|
3797 | n/a | exit: |
---|
3798 | n/a | PyMem_Free(mountpath); |
---|
3799 | n/a | return result; |
---|
3800 | n/a | } |
---|
3801 | n/a | |
---|
3802 | n/a | #endif /* MS_WINDOWS */ |
---|
3803 | n/a | |
---|
3804 | n/a | |
---|
3805 | n/a | /*[clinic input] |
---|
3806 | n/a | os.mkdir |
---|
3807 | n/a | |
---|
3808 | n/a | path : path_t |
---|
3809 | n/a | |
---|
3810 | n/a | mode: int = 0o777 |
---|
3811 | n/a | |
---|
3812 | n/a | * |
---|
3813 | n/a | |
---|
3814 | n/a | dir_fd : dir_fd(requires='mkdirat') = None |
---|
3815 | n/a | |
---|
3816 | n/a | # "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\ |
---|
3817 | n/a | |
---|
3818 | n/a | Create a directory. |
---|
3819 | n/a | |
---|
3820 | n/a | If dir_fd is not None, it should be a file descriptor open to a directory, |
---|
3821 | n/a | and path should be relative; path will then be relative to that directory. |
---|
3822 | n/a | dir_fd may not be implemented on your platform. |
---|
3823 | n/a | If it is unavailable, using it will raise a NotImplementedError. |
---|
3824 | n/a | |
---|
3825 | n/a | The mode argument is ignored on Windows. |
---|
3826 | n/a | [clinic start generated code]*/ |
---|
3827 | n/a | |
---|
3828 | n/a | static PyObject * |
---|
3829 | n/a | os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd) |
---|
3830 | n/a | /*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/ |
---|
3831 | n/a | { |
---|
3832 | n/a | int result; |
---|
3833 | n/a | |
---|
3834 | n/a | #ifdef MS_WINDOWS |
---|
3835 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
3836 | n/a | result = CreateDirectoryW(path->wide, NULL); |
---|
3837 | n/a | Py_END_ALLOW_THREADS |
---|
3838 | n/a | |
---|
3839 | n/a | if (!result) |
---|
3840 | n/a | return path_error(path); |
---|
3841 | n/a | #else |
---|
3842 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
3843 | n/a | #if HAVE_MKDIRAT |
---|
3844 | n/a | if (dir_fd != DEFAULT_DIR_FD) |
---|
3845 | n/a | result = mkdirat(dir_fd, path->narrow, mode); |
---|
3846 | n/a | else |
---|
3847 | n/a | #endif |
---|
3848 | n/a | #if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__) |
---|
3849 | n/a | result = mkdir(path->narrow); |
---|
3850 | n/a | #else |
---|
3851 | n/a | result = mkdir(path->narrow, mode); |
---|
3852 | n/a | #endif |
---|
3853 | n/a | Py_END_ALLOW_THREADS |
---|
3854 | n/a | if (result < 0) |
---|
3855 | n/a | return path_error(path); |
---|
3856 | n/a | #endif /* MS_WINDOWS */ |
---|
3857 | n/a | Py_RETURN_NONE; |
---|
3858 | n/a | } |
---|
3859 | n/a | |
---|
3860 | n/a | |
---|
3861 | n/a | /* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */ |
---|
3862 | n/a | #if defined(HAVE_SYS_RESOURCE_H) |
---|
3863 | n/a | #include <sys/resource.h> |
---|
3864 | n/a | #endif |
---|
3865 | n/a | |
---|
3866 | n/a | |
---|
3867 | n/a | #ifdef HAVE_NICE |
---|
3868 | n/a | /*[clinic input] |
---|
3869 | n/a | os.nice |
---|
3870 | n/a | |
---|
3871 | n/a | increment: int |
---|
3872 | n/a | / |
---|
3873 | n/a | |
---|
3874 | n/a | Add increment to the priority of process and return the new priority. |
---|
3875 | n/a | [clinic start generated code]*/ |
---|
3876 | n/a | |
---|
3877 | n/a | static PyObject * |
---|
3878 | n/a | os_nice_impl(PyObject *module, int increment) |
---|
3879 | n/a | /*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/ |
---|
3880 | n/a | { |
---|
3881 | n/a | int value; |
---|
3882 | n/a | |
---|
3883 | n/a | /* There are two flavours of 'nice': one that returns the new |
---|
3884 | n/a | priority (as required by almost all standards out there) and the |
---|
3885 | n/a | Linux/FreeBSD/BSDI one, which returns '0' on success and advices |
---|
3886 | n/a | the use of getpriority() to get the new priority. |
---|
3887 | n/a | |
---|
3888 | n/a | If we are of the nice family that returns the new priority, we |
---|
3889 | n/a | need to clear errno before the call, and check if errno is filled |
---|
3890 | n/a | before calling posix_error() on a returnvalue of -1, because the |
---|
3891 | n/a | -1 may be the actual new priority! */ |
---|
3892 | n/a | |
---|
3893 | n/a | errno = 0; |
---|
3894 | n/a | value = nice(increment); |
---|
3895 | n/a | #if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY) |
---|
3896 | n/a | if (value == 0) |
---|
3897 | n/a | value = getpriority(PRIO_PROCESS, 0); |
---|
3898 | n/a | #endif |
---|
3899 | n/a | if (value == -1 && errno != 0) |
---|
3900 | n/a | /* either nice() or getpriority() returned an error */ |
---|
3901 | n/a | return posix_error(); |
---|
3902 | n/a | return PyLong_FromLong((long) value); |
---|
3903 | n/a | } |
---|
3904 | n/a | #endif /* HAVE_NICE */ |
---|
3905 | n/a | |
---|
3906 | n/a | |
---|
3907 | n/a | #ifdef HAVE_GETPRIORITY |
---|
3908 | n/a | /*[clinic input] |
---|
3909 | n/a | os.getpriority |
---|
3910 | n/a | |
---|
3911 | n/a | which: int |
---|
3912 | n/a | who: int |
---|
3913 | n/a | |
---|
3914 | n/a | Return program scheduling priority. |
---|
3915 | n/a | [clinic start generated code]*/ |
---|
3916 | n/a | |
---|
3917 | n/a | static PyObject * |
---|
3918 | n/a | os_getpriority_impl(PyObject *module, int which, int who) |
---|
3919 | n/a | /*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/ |
---|
3920 | n/a | { |
---|
3921 | n/a | int retval; |
---|
3922 | n/a | |
---|
3923 | n/a | errno = 0; |
---|
3924 | n/a | retval = getpriority(which, who); |
---|
3925 | n/a | if (errno != 0) |
---|
3926 | n/a | return posix_error(); |
---|
3927 | n/a | return PyLong_FromLong((long)retval); |
---|
3928 | n/a | } |
---|
3929 | n/a | #endif /* HAVE_GETPRIORITY */ |
---|
3930 | n/a | |
---|
3931 | n/a | |
---|
3932 | n/a | #ifdef HAVE_SETPRIORITY |
---|
3933 | n/a | /*[clinic input] |
---|
3934 | n/a | os.setpriority |
---|
3935 | n/a | |
---|
3936 | n/a | which: int |
---|
3937 | n/a | who: int |
---|
3938 | n/a | priority: int |
---|
3939 | n/a | |
---|
3940 | n/a | Set program scheduling priority. |
---|
3941 | n/a | [clinic start generated code]*/ |
---|
3942 | n/a | |
---|
3943 | n/a | static PyObject * |
---|
3944 | n/a | os_setpriority_impl(PyObject *module, int which, int who, int priority) |
---|
3945 | n/a | /*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/ |
---|
3946 | n/a | { |
---|
3947 | n/a | int retval; |
---|
3948 | n/a | |
---|
3949 | n/a | retval = setpriority(which, who, priority); |
---|
3950 | n/a | if (retval == -1) |
---|
3951 | n/a | return posix_error(); |
---|
3952 | n/a | Py_RETURN_NONE; |
---|
3953 | n/a | } |
---|
3954 | n/a | #endif /* HAVE_SETPRIORITY */ |
---|
3955 | n/a | |
---|
3956 | n/a | |
---|
3957 | n/a | static PyObject * |
---|
3958 | n/a | internal_rename(path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd, int is_replace) |
---|
3959 | n/a | { |
---|
3960 | n/a | const char *function_name = is_replace ? "replace" : "rename"; |
---|
3961 | n/a | int dir_fd_specified; |
---|
3962 | n/a | |
---|
3963 | n/a | #ifdef MS_WINDOWS |
---|
3964 | n/a | BOOL result; |
---|
3965 | n/a | int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0; |
---|
3966 | n/a | #else |
---|
3967 | n/a | int result; |
---|
3968 | n/a | #endif |
---|
3969 | n/a | |
---|
3970 | n/a | dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) || |
---|
3971 | n/a | (dst_dir_fd != DEFAULT_DIR_FD); |
---|
3972 | n/a | #ifndef HAVE_RENAMEAT |
---|
3973 | n/a | if (dir_fd_specified) { |
---|
3974 | n/a | argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd"); |
---|
3975 | n/a | return NULL; |
---|
3976 | n/a | } |
---|
3977 | n/a | #endif |
---|
3978 | n/a | |
---|
3979 | n/a | #ifdef MS_WINDOWS |
---|
3980 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
3981 | n/a | result = MoveFileExW(src->wide, dst->wide, flags); |
---|
3982 | n/a | Py_END_ALLOW_THREADS |
---|
3983 | n/a | |
---|
3984 | n/a | if (!result) |
---|
3985 | n/a | return path_error2(src, dst); |
---|
3986 | n/a | |
---|
3987 | n/a | #else |
---|
3988 | n/a | if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) { |
---|
3989 | n/a | PyErr_Format(PyExc_ValueError, |
---|
3990 | n/a | "%s: src and dst must be the same type", function_name); |
---|
3991 | n/a | return NULL; |
---|
3992 | n/a | } |
---|
3993 | n/a | |
---|
3994 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
3995 | n/a | #ifdef HAVE_RENAMEAT |
---|
3996 | n/a | if (dir_fd_specified) |
---|
3997 | n/a | result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow); |
---|
3998 | n/a | else |
---|
3999 | n/a | #endif |
---|
4000 | n/a | result = rename(src->narrow, dst->narrow); |
---|
4001 | n/a | Py_END_ALLOW_THREADS |
---|
4002 | n/a | |
---|
4003 | n/a | if (result) |
---|
4004 | n/a | return path_error2(src, dst); |
---|
4005 | n/a | #endif |
---|
4006 | n/a | Py_RETURN_NONE; |
---|
4007 | n/a | } |
---|
4008 | n/a | |
---|
4009 | n/a | |
---|
4010 | n/a | /*[clinic input] |
---|
4011 | n/a | os.rename |
---|
4012 | n/a | |
---|
4013 | n/a | src : path_t |
---|
4014 | n/a | dst : path_t |
---|
4015 | n/a | * |
---|
4016 | n/a | src_dir_fd : dir_fd = None |
---|
4017 | n/a | dst_dir_fd : dir_fd = None |
---|
4018 | n/a | |
---|
4019 | n/a | Rename a file or directory. |
---|
4020 | n/a | |
---|
4021 | n/a | If either src_dir_fd or dst_dir_fd is not None, it should be a file |
---|
4022 | n/a | descriptor open to a directory, and the respective path string (src or dst) |
---|
4023 | n/a | should be relative; the path will then be relative to that directory. |
---|
4024 | n/a | src_dir_fd and dst_dir_fd, may not be implemented on your platform. |
---|
4025 | n/a | If they are unavailable, using them will raise a NotImplementedError. |
---|
4026 | n/a | [clinic start generated code]*/ |
---|
4027 | n/a | |
---|
4028 | n/a | static PyObject * |
---|
4029 | n/a | os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd, |
---|
4030 | n/a | int dst_dir_fd) |
---|
4031 | n/a | /*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/ |
---|
4032 | n/a | { |
---|
4033 | n/a | return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0); |
---|
4034 | n/a | } |
---|
4035 | n/a | |
---|
4036 | n/a | |
---|
4037 | n/a | /*[clinic input] |
---|
4038 | n/a | os.replace = os.rename |
---|
4039 | n/a | |
---|
4040 | n/a | Rename a file or directory, overwriting the destination. |
---|
4041 | n/a | |
---|
4042 | n/a | If either src_dir_fd or dst_dir_fd is not None, it should be a file |
---|
4043 | n/a | descriptor open to a directory, and the respective path string (src or dst) |
---|
4044 | n/a | should be relative; the path will then be relative to that directory. |
---|
4045 | n/a | src_dir_fd and dst_dir_fd, may not be implemented on your platform. |
---|
4046 | n/a | If they are unavailable, using them will raise a NotImplementedError." |
---|
4047 | n/a | [clinic start generated code]*/ |
---|
4048 | n/a | |
---|
4049 | n/a | static PyObject * |
---|
4050 | n/a | os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd, |
---|
4051 | n/a | int dst_dir_fd) |
---|
4052 | n/a | /*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/ |
---|
4053 | n/a | { |
---|
4054 | n/a | return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1); |
---|
4055 | n/a | } |
---|
4056 | n/a | |
---|
4057 | n/a | |
---|
4058 | n/a | /*[clinic input] |
---|
4059 | n/a | os.rmdir |
---|
4060 | n/a | |
---|
4061 | n/a | path: path_t |
---|
4062 | n/a | * |
---|
4063 | n/a | dir_fd: dir_fd(requires='unlinkat') = None |
---|
4064 | n/a | |
---|
4065 | n/a | Remove a directory. |
---|
4066 | n/a | |
---|
4067 | n/a | If dir_fd is not None, it should be a file descriptor open to a directory, |
---|
4068 | n/a | and path should be relative; path will then be relative to that directory. |
---|
4069 | n/a | dir_fd may not be implemented on your platform. |
---|
4070 | n/a | If it is unavailable, using it will raise a NotImplementedError. |
---|
4071 | n/a | [clinic start generated code]*/ |
---|
4072 | n/a | |
---|
4073 | n/a | static PyObject * |
---|
4074 | n/a | os_rmdir_impl(PyObject *module, path_t *path, int dir_fd) |
---|
4075 | n/a | /*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/ |
---|
4076 | n/a | { |
---|
4077 | n/a | int result; |
---|
4078 | n/a | |
---|
4079 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
4080 | n/a | #ifdef MS_WINDOWS |
---|
4081 | n/a | /* Windows, success=1, UNIX, success=0 */ |
---|
4082 | n/a | result = !RemoveDirectoryW(path->wide); |
---|
4083 | n/a | #else |
---|
4084 | n/a | #ifdef HAVE_UNLINKAT |
---|
4085 | n/a | if (dir_fd != DEFAULT_DIR_FD) |
---|
4086 | n/a | result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR); |
---|
4087 | n/a | else |
---|
4088 | n/a | #endif |
---|
4089 | n/a | result = rmdir(path->narrow); |
---|
4090 | n/a | #endif |
---|
4091 | n/a | Py_END_ALLOW_THREADS |
---|
4092 | n/a | |
---|
4093 | n/a | if (result) |
---|
4094 | n/a | return path_error(path); |
---|
4095 | n/a | |
---|
4096 | n/a | Py_RETURN_NONE; |
---|
4097 | n/a | } |
---|
4098 | n/a | |
---|
4099 | n/a | |
---|
4100 | n/a | #ifdef HAVE_SYSTEM |
---|
4101 | n/a | #ifdef MS_WINDOWS |
---|
4102 | n/a | /*[clinic input] |
---|
4103 | n/a | os.system -> long |
---|
4104 | n/a | |
---|
4105 | n/a | command: Py_UNICODE |
---|
4106 | n/a | |
---|
4107 | n/a | Execute the command in a subshell. |
---|
4108 | n/a | [clinic start generated code]*/ |
---|
4109 | n/a | |
---|
4110 | n/a | static long |
---|
4111 | n/a | os_system_impl(PyObject *module, Py_UNICODE *command) |
---|
4112 | n/a | /*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/ |
---|
4113 | n/a | { |
---|
4114 | n/a | long result; |
---|
4115 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
4116 | n/a | _Py_BEGIN_SUPPRESS_IPH |
---|
4117 | n/a | result = _wsystem(command); |
---|
4118 | n/a | _Py_END_SUPPRESS_IPH |
---|
4119 | n/a | Py_END_ALLOW_THREADS |
---|
4120 | n/a | return result; |
---|
4121 | n/a | } |
---|
4122 | n/a | #else /* MS_WINDOWS */ |
---|
4123 | n/a | /*[clinic input] |
---|
4124 | n/a | os.system -> long |
---|
4125 | n/a | |
---|
4126 | n/a | command: FSConverter |
---|
4127 | n/a | |
---|
4128 | n/a | Execute the command in a subshell. |
---|
4129 | n/a | [clinic start generated code]*/ |
---|
4130 | n/a | |
---|
4131 | n/a | static long |
---|
4132 | n/a | os_system_impl(PyObject *module, PyObject *command) |
---|
4133 | n/a | /*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/ |
---|
4134 | n/a | { |
---|
4135 | n/a | long result; |
---|
4136 | n/a | const char *bytes = PyBytes_AsString(command); |
---|
4137 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
4138 | n/a | result = system(bytes); |
---|
4139 | n/a | Py_END_ALLOW_THREADS |
---|
4140 | n/a | return result; |
---|
4141 | n/a | } |
---|
4142 | n/a | #endif |
---|
4143 | n/a | #endif /* HAVE_SYSTEM */ |
---|
4144 | n/a | |
---|
4145 | n/a | |
---|
4146 | n/a | /*[clinic input] |
---|
4147 | n/a | os.umask |
---|
4148 | n/a | |
---|
4149 | n/a | mask: int |
---|
4150 | n/a | / |
---|
4151 | n/a | |
---|
4152 | n/a | Set the current numeric umask and return the previous umask. |
---|
4153 | n/a | [clinic start generated code]*/ |
---|
4154 | n/a | |
---|
4155 | n/a | static PyObject * |
---|
4156 | n/a | os_umask_impl(PyObject *module, int mask) |
---|
4157 | n/a | /*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/ |
---|
4158 | n/a | { |
---|
4159 | n/a | int i = (int)umask(mask); |
---|
4160 | n/a | if (i < 0) |
---|
4161 | n/a | return posix_error(); |
---|
4162 | n/a | return PyLong_FromLong((long)i); |
---|
4163 | n/a | } |
---|
4164 | n/a | |
---|
4165 | n/a | #ifdef MS_WINDOWS |
---|
4166 | n/a | |
---|
4167 | n/a | /* override the default DeleteFileW behavior so that directory |
---|
4168 | n/a | symlinks can be removed with this function, the same as with |
---|
4169 | n/a | Unix symlinks */ |
---|
4170 | n/a | BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName) |
---|
4171 | n/a | { |
---|
4172 | n/a | WIN32_FILE_ATTRIBUTE_DATA info; |
---|
4173 | n/a | WIN32_FIND_DATAW find_data; |
---|
4174 | n/a | HANDLE find_data_handle; |
---|
4175 | n/a | int is_directory = 0; |
---|
4176 | n/a | int is_link = 0; |
---|
4177 | n/a | |
---|
4178 | n/a | if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) { |
---|
4179 | n/a | is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; |
---|
4180 | n/a | |
---|
4181 | n/a | /* Get WIN32_FIND_DATA structure for the path to determine if |
---|
4182 | n/a | it is a symlink */ |
---|
4183 | n/a | if(is_directory && |
---|
4184 | n/a | info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { |
---|
4185 | n/a | find_data_handle = FindFirstFileW(lpFileName, &find_data); |
---|
4186 | n/a | |
---|
4187 | n/a | if(find_data_handle != INVALID_HANDLE_VALUE) { |
---|
4188 | n/a | /* IO_REPARSE_TAG_SYMLINK if it is a symlink and |
---|
4189 | n/a | IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */ |
---|
4190 | n/a | is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK || |
---|
4191 | n/a | find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT; |
---|
4192 | n/a | FindClose(find_data_handle); |
---|
4193 | n/a | } |
---|
4194 | n/a | } |
---|
4195 | n/a | } |
---|
4196 | n/a | |
---|
4197 | n/a | if (is_directory && is_link) |
---|
4198 | n/a | return RemoveDirectoryW(lpFileName); |
---|
4199 | n/a | |
---|
4200 | n/a | return DeleteFileW(lpFileName); |
---|
4201 | n/a | } |
---|
4202 | n/a | #endif /* MS_WINDOWS */ |
---|
4203 | n/a | |
---|
4204 | n/a | |
---|
4205 | n/a | /*[clinic input] |
---|
4206 | n/a | os.unlink |
---|
4207 | n/a | |
---|
4208 | n/a | path: path_t |
---|
4209 | n/a | * |
---|
4210 | n/a | dir_fd: dir_fd(requires='unlinkat')=None |
---|
4211 | n/a | |
---|
4212 | n/a | Remove a file (same as remove()). |
---|
4213 | n/a | |
---|
4214 | n/a | If dir_fd is not None, it should be a file descriptor open to a directory, |
---|
4215 | n/a | and path should be relative; path will then be relative to that directory. |
---|
4216 | n/a | dir_fd may not be implemented on your platform. |
---|
4217 | n/a | If it is unavailable, using it will raise a NotImplementedError. |
---|
4218 | n/a | |
---|
4219 | n/a | [clinic start generated code]*/ |
---|
4220 | n/a | |
---|
4221 | n/a | static PyObject * |
---|
4222 | n/a | os_unlink_impl(PyObject *module, path_t *path, int dir_fd) |
---|
4223 | n/a | /*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/ |
---|
4224 | n/a | { |
---|
4225 | n/a | int result; |
---|
4226 | n/a | |
---|
4227 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
4228 | n/a | _Py_BEGIN_SUPPRESS_IPH |
---|
4229 | n/a | #ifdef MS_WINDOWS |
---|
4230 | n/a | /* Windows, success=1, UNIX, success=0 */ |
---|
4231 | n/a | result = !Py_DeleteFileW(path->wide); |
---|
4232 | n/a | #else |
---|
4233 | n/a | #ifdef HAVE_UNLINKAT |
---|
4234 | n/a | if (dir_fd != DEFAULT_DIR_FD) |
---|
4235 | n/a | result = unlinkat(dir_fd, path->narrow, 0); |
---|
4236 | n/a | else |
---|
4237 | n/a | #endif /* HAVE_UNLINKAT */ |
---|
4238 | n/a | result = unlink(path->narrow); |
---|
4239 | n/a | #endif |
---|
4240 | n/a | _Py_END_SUPPRESS_IPH |
---|
4241 | n/a | Py_END_ALLOW_THREADS |
---|
4242 | n/a | |
---|
4243 | n/a | if (result) |
---|
4244 | n/a | return path_error(path); |
---|
4245 | n/a | |
---|
4246 | n/a | Py_RETURN_NONE; |
---|
4247 | n/a | } |
---|
4248 | n/a | |
---|
4249 | n/a | |
---|
4250 | n/a | /*[clinic input] |
---|
4251 | n/a | os.remove = os.unlink |
---|
4252 | n/a | |
---|
4253 | n/a | Remove a file (same as unlink()). |
---|
4254 | n/a | |
---|
4255 | n/a | If dir_fd is not None, it should be a file descriptor open to a directory, |
---|
4256 | n/a | and path should be relative; path will then be relative to that directory. |
---|
4257 | n/a | dir_fd may not be implemented on your platform. |
---|
4258 | n/a | If it is unavailable, using it will raise a NotImplementedError. |
---|
4259 | n/a | [clinic start generated code]*/ |
---|
4260 | n/a | |
---|
4261 | n/a | static PyObject * |
---|
4262 | n/a | os_remove_impl(PyObject *module, path_t *path, int dir_fd) |
---|
4263 | n/a | /*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/ |
---|
4264 | n/a | { |
---|
4265 | n/a | return os_unlink_impl(module, path, dir_fd); |
---|
4266 | n/a | } |
---|
4267 | n/a | |
---|
4268 | n/a | |
---|
4269 | n/a | static PyStructSequence_Field uname_result_fields[] = { |
---|
4270 | n/a | {"sysname", "operating system name"}, |
---|
4271 | n/a | {"nodename", "name of machine on network (implementation-defined)"}, |
---|
4272 | n/a | {"release", "operating system release"}, |
---|
4273 | n/a | {"version", "operating system version"}, |
---|
4274 | n/a | {"machine", "hardware identifier"}, |
---|
4275 | n/a | {NULL} |
---|
4276 | n/a | }; |
---|
4277 | n/a | |
---|
4278 | n/a | PyDoc_STRVAR(uname_result__doc__, |
---|
4279 | n/a | "uname_result: Result from os.uname().\n\n\ |
---|
4280 | n/a | This object may be accessed either as a tuple of\n\ |
---|
4281 | n/a | (sysname, nodename, release, version, machine),\n\ |
---|
4282 | n/a | or via the attributes sysname, nodename, release, version, and machine.\n\ |
---|
4283 | n/a | \n\ |
---|
4284 | n/a | See os.uname for more information."); |
---|
4285 | n/a | |
---|
4286 | n/a | static PyStructSequence_Desc uname_result_desc = { |
---|
4287 | n/a | "uname_result", /* name */ |
---|
4288 | n/a | uname_result__doc__, /* doc */ |
---|
4289 | n/a | uname_result_fields, |
---|
4290 | n/a | 5 |
---|
4291 | n/a | }; |
---|
4292 | n/a | |
---|
4293 | n/a | static PyTypeObject UnameResultType; |
---|
4294 | n/a | |
---|
4295 | n/a | |
---|
4296 | n/a | #ifdef HAVE_UNAME |
---|
4297 | n/a | /*[clinic input] |
---|
4298 | n/a | os.uname |
---|
4299 | n/a | |
---|
4300 | n/a | Return an object identifying the current operating system. |
---|
4301 | n/a | |
---|
4302 | n/a | The object behaves like a named tuple with the following fields: |
---|
4303 | n/a | (sysname, nodename, release, version, machine) |
---|
4304 | n/a | |
---|
4305 | n/a | [clinic start generated code]*/ |
---|
4306 | n/a | |
---|
4307 | n/a | static PyObject * |
---|
4308 | n/a | os_uname_impl(PyObject *module) |
---|
4309 | n/a | /*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/ |
---|
4310 | n/a | { |
---|
4311 | n/a | struct utsname u; |
---|
4312 | n/a | int res; |
---|
4313 | n/a | PyObject *value; |
---|
4314 | n/a | |
---|
4315 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
4316 | n/a | res = uname(&u); |
---|
4317 | n/a | Py_END_ALLOW_THREADS |
---|
4318 | n/a | if (res < 0) |
---|
4319 | n/a | return posix_error(); |
---|
4320 | n/a | |
---|
4321 | n/a | value = PyStructSequence_New(&UnameResultType); |
---|
4322 | n/a | if (value == NULL) |
---|
4323 | n/a | return NULL; |
---|
4324 | n/a | |
---|
4325 | n/a | #define SET(i, field) \ |
---|
4326 | n/a | { \ |
---|
4327 | n/a | PyObject *o = PyUnicode_DecodeFSDefault(field); \ |
---|
4328 | n/a | if (!o) { \ |
---|
4329 | n/a | Py_DECREF(value); \ |
---|
4330 | n/a | return NULL; \ |
---|
4331 | n/a | } \ |
---|
4332 | n/a | PyStructSequence_SET_ITEM(value, i, o); \ |
---|
4333 | n/a | } \ |
---|
4334 | n/a | |
---|
4335 | n/a | SET(0, u.sysname); |
---|
4336 | n/a | SET(1, u.nodename); |
---|
4337 | n/a | SET(2, u.release); |
---|
4338 | n/a | SET(3, u.version); |
---|
4339 | n/a | SET(4, u.machine); |
---|
4340 | n/a | |
---|
4341 | n/a | #undef SET |
---|
4342 | n/a | |
---|
4343 | n/a | return value; |
---|
4344 | n/a | } |
---|
4345 | n/a | #endif /* HAVE_UNAME */ |
---|
4346 | n/a | |
---|
4347 | n/a | |
---|
4348 | n/a | |
---|
4349 | n/a | typedef struct { |
---|
4350 | n/a | int now; |
---|
4351 | n/a | time_t atime_s; |
---|
4352 | n/a | long atime_ns; |
---|
4353 | n/a | time_t mtime_s; |
---|
4354 | n/a | long mtime_ns; |
---|
4355 | n/a | } utime_t; |
---|
4356 | n/a | |
---|
4357 | n/a | /* |
---|
4358 | n/a | * these macros assume that "ut" is a pointer to a utime_t |
---|
4359 | n/a | * they also intentionally leak the declaration of a pointer named "time" |
---|
4360 | n/a | */ |
---|
4361 | n/a | #define UTIME_TO_TIMESPEC \ |
---|
4362 | n/a | struct timespec ts[2]; \ |
---|
4363 | n/a | struct timespec *time; \ |
---|
4364 | n/a | if (ut->now) \ |
---|
4365 | n/a | time = NULL; \ |
---|
4366 | n/a | else { \ |
---|
4367 | n/a | ts[0].tv_sec = ut->atime_s; \ |
---|
4368 | n/a | ts[0].tv_nsec = ut->atime_ns; \ |
---|
4369 | n/a | ts[1].tv_sec = ut->mtime_s; \ |
---|
4370 | n/a | ts[1].tv_nsec = ut->mtime_ns; \ |
---|
4371 | n/a | time = ts; \ |
---|
4372 | n/a | } \ |
---|
4373 | n/a | |
---|
4374 | n/a | #define UTIME_TO_TIMEVAL \ |
---|
4375 | n/a | struct timeval tv[2]; \ |
---|
4376 | n/a | struct timeval *time; \ |
---|
4377 | n/a | if (ut->now) \ |
---|
4378 | n/a | time = NULL; \ |
---|
4379 | n/a | else { \ |
---|
4380 | n/a | tv[0].tv_sec = ut->atime_s; \ |
---|
4381 | n/a | tv[0].tv_usec = ut->atime_ns / 1000; \ |
---|
4382 | n/a | tv[1].tv_sec = ut->mtime_s; \ |
---|
4383 | n/a | tv[1].tv_usec = ut->mtime_ns / 1000; \ |
---|
4384 | n/a | time = tv; \ |
---|
4385 | n/a | } \ |
---|
4386 | n/a | |
---|
4387 | n/a | #define UTIME_TO_UTIMBUF \ |
---|
4388 | n/a | struct utimbuf u; \ |
---|
4389 | n/a | struct utimbuf *time; \ |
---|
4390 | n/a | if (ut->now) \ |
---|
4391 | n/a | time = NULL; \ |
---|
4392 | n/a | else { \ |
---|
4393 | n/a | u.actime = ut->atime_s; \ |
---|
4394 | n/a | u.modtime = ut->mtime_s; \ |
---|
4395 | n/a | time = &u; \ |
---|
4396 | n/a | } |
---|
4397 | n/a | |
---|
4398 | n/a | #define UTIME_TO_TIME_T \ |
---|
4399 | n/a | time_t timet[2]; \ |
---|
4400 | n/a | time_t *time; \ |
---|
4401 | n/a | if (ut->now) \ |
---|
4402 | n/a | time = NULL; \ |
---|
4403 | n/a | else { \ |
---|
4404 | n/a | timet[0] = ut->atime_s; \ |
---|
4405 | n/a | timet[1] = ut->mtime_s; \ |
---|
4406 | n/a | time = timet; \ |
---|
4407 | n/a | } \ |
---|
4408 | n/a | |
---|
4409 | n/a | |
---|
4410 | n/a | #if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT) |
---|
4411 | n/a | |
---|
4412 | n/a | static int |
---|
4413 | n/a | utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks) |
---|
4414 | n/a | { |
---|
4415 | n/a | #ifdef HAVE_UTIMENSAT |
---|
4416 | n/a | int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW; |
---|
4417 | n/a | UTIME_TO_TIMESPEC; |
---|
4418 | n/a | return utimensat(dir_fd, path, time, flags); |
---|
4419 | n/a | #elif defined(HAVE_FUTIMESAT) |
---|
4420 | n/a | UTIME_TO_TIMEVAL; |
---|
4421 | n/a | /* |
---|
4422 | n/a | * follow_symlinks will never be false here; |
---|
4423 | n/a | * we only allow !follow_symlinks and dir_fd together |
---|
4424 | n/a | * if we have utimensat() |
---|
4425 | n/a | */ |
---|
4426 | n/a | assert(follow_symlinks); |
---|
4427 | n/a | return futimesat(dir_fd, path, time); |
---|
4428 | n/a | #endif |
---|
4429 | n/a | } |
---|
4430 | n/a | |
---|
4431 | n/a | #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter |
---|
4432 | n/a | #else |
---|
4433 | n/a | #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable |
---|
4434 | n/a | #endif |
---|
4435 | n/a | |
---|
4436 | n/a | #if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS) |
---|
4437 | n/a | |
---|
4438 | n/a | static int |
---|
4439 | n/a | utime_fd(utime_t *ut, int fd) |
---|
4440 | n/a | { |
---|
4441 | n/a | #ifdef HAVE_FUTIMENS |
---|
4442 | n/a | UTIME_TO_TIMESPEC; |
---|
4443 | n/a | return futimens(fd, time); |
---|
4444 | n/a | #else |
---|
4445 | n/a | UTIME_TO_TIMEVAL; |
---|
4446 | n/a | return futimes(fd, time); |
---|
4447 | n/a | #endif |
---|
4448 | n/a | } |
---|
4449 | n/a | |
---|
4450 | n/a | #define PATH_UTIME_HAVE_FD 1 |
---|
4451 | n/a | #else |
---|
4452 | n/a | #define PATH_UTIME_HAVE_FD 0 |
---|
4453 | n/a | #endif |
---|
4454 | n/a | |
---|
4455 | n/a | #if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES) |
---|
4456 | n/a | # define UTIME_HAVE_NOFOLLOW_SYMLINKS |
---|
4457 | n/a | #endif |
---|
4458 | n/a | |
---|
4459 | n/a | #ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS |
---|
4460 | n/a | |
---|
4461 | n/a | static int |
---|
4462 | n/a | utime_nofollow_symlinks(utime_t *ut, const char *path) |
---|
4463 | n/a | { |
---|
4464 | n/a | #ifdef HAVE_UTIMENSAT |
---|
4465 | n/a | UTIME_TO_TIMESPEC; |
---|
4466 | n/a | return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW); |
---|
4467 | n/a | #else |
---|
4468 | n/a | UTIME_TO_TIMEVAL; |
---|
4469 | n/a | return lutimes(path, time); |
---|
4470 | n/a | #endif |
---|
4471 | n/a | } |
---|
4472 | n/a | |
---|
4473 | n/a | #endif |
---|
4474 | n/a | |
---|
4475 | n/a | #ifndef MS_WINDOWS |
---|
4476 | n/a | |
---|
4477 | n/a | static int |
---|
4478 | n/a | utime_default(utime_t *ut, const char *path) |
---|
4479 | n/a | { |
---|
4480 | n/a | #ifdef HAVE_UTIMENSAT |
---|
4481 | n/a | UTIME_TO_TIMESPEC; |
---|
4482 | n/a | return utimensat(DEFAULT_DIR_FD, path, time, 0); |
---|
4483 | n/a | #elif defined(HAVE_UTIMES) |
---|
4484 | n/a | UTIME_TO_TIMEVAL; |
---|
4485 | n/a | return utimes(path, time); |
---|
4486 | n/a | #elif defined(HAVE_UTIME_H) |
---|
4487 | n/a | UTIME_TO_UTIMBUF; |
---|
4488 | n/a | return utime(path, time); |
---|
4489 | n/a | #else |
---|
4490 | n/a | UTIME_TO_TIME_T; |
---|
4491 | n/a | return utime(path, time); |
---|
4492 | n/a | #endif |
---|
4493 | n/a | } |
---|
4494 | n/a | |
---|
4495 | n/a | #endif |
---|
4496 | n/a | |
---|
4497 | n/a | static int |
---|
4498 | n/a | split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns) |
---|
4499 | n/a | { |
---|
4500 | n/a | int result = 0; |
---|
4501 | n/a | PyObject *divmod; |
---|
4502 | n/a | divmod = PyNumber_Divmod(py_long, billion); |
---|
4503 | n/a | if (!divmod) |
---|
4504 | n/a | goto exit; |
---|
4505 | n/a | *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0)); |
---|
4506 | n/a | if ((*s == -1) && PyErr_Occurred()) |
---|
4507 | n/a | goto exit; |
---|
4508 | n/a | *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1)); |
---|
4509 | n/a | if ((*ns == -1) && PyErr_Occurred()) |
---|
4510 | n/a | goto exit; |
---|
4511 | n/a | |
---|
4512 | n/a | result = 1; |
---|
4513 | n/a | exit: |
---|
4514 | n/a | Py_XDECREF(divmod); |
---|
4515 | n/a | return result; |
---|
4516 | n/a | } |
---|
4517 | n/a | |
---|
4518 | n/a | |
---|
4519 | n/a | /*[clinic input] |
---|
4520 | n/a | os.utime |
---|
4521 | n/a | |
---|
4522 | n/a | path: path_t(allow_fd='PATH_UTIME_HAVE_FD') |
---|
4523 | n/a | times: object = NULL |
---|
4524 | n/a | * |
---|
4525 | n/a | ns: object = NULL |
---|
4526 | n/a | dir_fd: dir_fd(requires='futimensat') = None |
---|
4527 | n/a | follow_symlinks: bool=True |
---|
4528 | n/a | |
---|
4529 | n/a | # "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\ |
---|
4530 | n/a | |
---|
4531 | n/a | Set the access and modified time of path. |
---|
4532 | n/a | |
---|
4533 | n/a | path may always be specified as a string. |
---|
4534 | n/a | On some platforms, path may also be specified as an open file descriptor. |
---|
4535 | n/a | If this functionality is unavailable, using it raises an exception. |
---|
4536 | n/a | |
---|
4537 | n/a | If times is not None, it must be a tuple (atime, mtime); |
---|
4538 | n/a | atime and mtime should be expressed as float seconds since the epoch. |
---|
4539 | n/a | If ns is specified, it must be a tuple (atime_ns, mtime_ns); |
---|
4540 | n/a | atime_ns and mtime_ns should be expressed as integer nanoseconds |
---|
4541 | n/a | since the epoch. |
---|
4542 | n/a | If times is None and ns is unspecified, utime uses the current time. |
---|
4543 | n/a | Specifying tuples for both times and ns is an error. |
---|
4544 | n/a | |
---|
4545 | n/a | If dir_fd is not None, it should be a file descriptor open to a directory, |
---|
4546 | n/a | and path should be relative; path will then be relative to that directory. |
---|
4547 | n/a | If follow_symlinks is False, and the last element of the path is a symbolic |
---|
4548 | n/a | link, utime will modify the symbolic link itself instead of the file the |
---|
4549 | n/a | link points to. |
---|
4550 | n/a | It is an error to use dir_fd or follow_symlinks when specifying path |
---|
4551 | n/a | as an open file descriptor. |
---|
4552 | n/a | dir_fd and follow_symlinks may not be available on your platform. |
---|
4553 | n/a | If they are unavailable, using them will raise a NotImplementedError. |
---|
4554 | n/a | |
---|
4555 | n/a | [clinic start generated code]*/ |
---|
4556 | n/a | |
---|
4557 | n/a | static PyObject * |
---|
4558 | n/a | os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns, |
---|
4559 | n/a | int dir_fd, int follow_symlinks) |
---|
4560 | n/a | /*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/ |
---|
4561 | n/a | { |
---|
4562 | n/a | #ifdef MS_WINDOWS |
---|
4563 | n/a | HANDLE hFile; |
---|
4564 | n/a | FILETIME atime, mtime; |
---|
4565 | n/a | #else |
---|
4566 | n/a | int result; |
---|
4567 | n/a | #endif |
---|
4568 | n/a | |
---|
4569 | n/a | PyObject *return_value = NULL; |
---|
4570 | n/a | utime_t utime; |
---|
4571 | n/a | |
---|
4572 | n/a | memset(&utime, 0, sizeof(utime_t)); |
---|
4573 | n/a | |
---|
4574 | n/a | if (times && (times != Py_None) && ns) { |
---|
4575 | n/a | PyErr_SetString(PyExc_ValueError, |
---|
4576 | n/a | "utime: you may specify either 'times'" |
---|
4577 | n/a | " or 'ns' but not both"); |
---|
4578 | n/a | goto exit; |
---|
4579 | n/a | } |
---|
4580 | n/a | |
---|
4581 | n/a | if (times && (times != Py_None)) { |
---|
4582 | n/a | time_t a_sec, m_sec; |
---|
4583 | n/a | long a_nsec, m_nsec; |
---|
4584 | n/a | if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) { |
---|
4585 | n/a | PyErr_SetString(PyExc_TypeError, |
---|
4586 | n/a | "utime: 'times' must be either" |
---|
4587 | n/a | " a tuple of two ints or None"); |
---|
4588 | n/a | goto exit; |
---|
4589 | n/a | } |
---|
4590 | n/a | utime.now = 0; |
---|
4591 | n/a | if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0), |
---|
4592 | n/a | &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 || |
---|
4593 | n/a | _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1), |
---|
4594 | n/a | &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) { |
---|
4595 | n/a | goto exit; |
---|
4596 | n/a | } |
---|
4597 | n/a | utime.atime_s = a_sec; |
---|
4598 | n/a | utime.atime_ns = a_nsec; |
---|
4599 | n/a | utime.mtime_s = m_sec; |
---|
4600 | n/a | utime.mtime_ns = m_nsec; |
---|
4601 | n/a | } |
---|
4602 | n/a | else if (ns) { |
---|
4603 | n/a | if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) { |
---|
4604 | n/a | PyErr_SetString(PyExc_TypeError, |
---|
4605 | n/a | "utime: 'ns' must be a tuple of two ints"); |
---|
4606 | n/a | goto exit; |
---|
4607 | n/a | } |
---|
4608 | n/a | utime.now = 0; |
---|
4609 | n/a | if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0), |
---|
4610 | n/a | &utime.atime_s, &utime.atime_ns) || |
---|
4611 | n/a | !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1), |
---|
4612 | n/a | &utime.mtime_s, &utime.mtime_ns)) { |
---|
4613 | n/a | goto exit; |
---|
4614 | n/a | } |
---|
4615 | n/a | } |
---|
4616 | n/a | else { |
---|
4617 | n/a | /* times and ns are both None/unspecified. use "now". */ |
---|
4618 | n/a | utime.now = 1; |
---|
4619 | n/a | } |
---|
4620 | n/a | |
---|
4621 | n/a | #if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS) |
---|
4622 | n/a | if (follow_symlinks_specified("utime", follow_symlinks)) |
---|
4623 | n/a | goto exit; |
---|
4624 | n/a | #endif |
---|
4625 | n/a | |
---|
4626 | n/a | if (path_and_dir_fd_invalid("utime", path, dir_fd) || |
---|
4627 | n/a | dir_fd_and_fd_invalid("utime", dir_fd, path->fd) || |
---|
4628 | n/a | fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks)) |
---|
4629 | n/a | goto exit; |
---|
4630 | n/a | |
---|
4631 | n/a | #if !defined(HAVE_UTIMENSAT) |
---|
4632 | n/a | if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) { |
---|
4633 | n/a | PyErr_SetString(PyExc_ValueError, |
---|
4634 | n/a | "utime: cannot use dir_fd and follow_symlinks " |
---|
4635 | n/a | "together on this platform"); |
---|
4636 | n/a | goto exit; |
---|
4637 | n/a | } |
---|
4638 | n/a | #endif |
---|
4639 | n/a | |
---|
4640 | n/a | #ifdef MS_WINDOWS |
---|
4641 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
4642 | n/a | hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0, |
---|
4643 | n/a | NULL, OPEN_EXISTING, |
---|
4644 | n/a | FILE_FLAG_BACKUP_SEMANTICS, NULL); |
---|
4645 | n/a | Py_END_ALLOW_THREADS |
---|
4646 | n/a | if (hFile == INVALID_HANDLE_VALUE) { |
---|
4647 | n/a | path_error(path); |
---|
4648 | n/a | goto exit; |
---|
4649 | n/a | } |
---|
4650 | n/a | |
---|
4651 | n/a | if (utime.now) { |
---|
4652 | n/a | GetSystemTimeAsFileTime(&mtime); |
---|
4653 | n/a | atime = mtime; |
---|
4654 | n/a | } |
---|
4655 | n/a | else { |
---|
4656 | n/a | _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime); |
---|
4657 | n/a | _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime); |
---|
4658 | n/a | } |
---|
4659 | n/a | if (!SetFileTime(hFile, NULL, &atime, &mtime)) { |
---|
4660 | n/a | /* Avoid putting the file name into the error here, |
---|
4661 | n/a | as that may confuse the user into believing that |
---|
4662 | n/a | something is wrong with the file, when it also |
---|
4663 | n/a | could be the time stamp that gives a problem. */ |
---|
4664 | n/a | PyErr_SetFromWindowsErr(0); |
---|
4665 | n/a | goto exit; |
---|
4666 | n/a | } |
---|
4667 | n/a | #else /* MS_WINDOWS */ |
---|
4668 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
4669 | n/a | |
---|
4670 | n/a | #ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS |
---|
4671 | n/a | if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD)) |
---|
4672 | n/a | result = utime_nofollow_symlinks(&utime, path->narrow); |
---|
4673 | n/a | else |
---|
4674 | n/a | #endif |
---|
4675 | n/a | |
---|
4676 | n/a | #if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT) |
---|
4677 | n/a | if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks)) |
---|
4678 | n/a | result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks); |
---|
4679 | n/a | else |
---|
4680 | n/a | #endif |
---|
4681 | n/a | |
---|
4682 | n/a | #if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS) |
---|
4683 | n/a | if (path->fd != -1) |
---|
4684 | n/a | result = utime_fd(&utime, path->fd); |
---|
4685 | n/a | else |
---|
4686 | n/a | #endif |
---|
4687 | n/a | |
---|
4688 | n/a | result = utime_default(&utime, path->narrow); |
---|
4689 | n/a | |
---|
4690 | n/a | Py_END_ALLOW_THREADS |
---|
4691 | n/a | |
---|
4692 | n/a | if (result < 0) { |
---|
4693 | n/a | /* see previous comment about not putting filename in error here */ |
---|
4694 | n/a | return_value = posix_error(); |
---|
4695 | n/a | goto exit; |
---|
4696 | n/a | } |
---|
4697 | n/a | |
---|
4698 | n/a | #endif /* MS_WINDOWS */ |
---|
4699 | n/a | |
---|
4700 | n/a | Py_INCREF(Py_None); |
---|
4701 | n/a | return_value = Py_None; |
---|
4702 | n/a | |
---|
4703 | n/a | exit: |
---|
4704 | n/a | #ifdef MS_WINDOWS |
---|
4705 | n/a | if (hFile != INVALID_HANDLE_VALUE) |
---|
4706 | n/a | CloseHandle(hFile); |
---|
4707 | n/a | #endif |
---|
4708 | n/a | return return_value; |
---|
4709 | n/a | } |
---|
4710 | n/a | |
---|
4711 | n/a | /* Process operations */ |
---|
4712 | n/a | |
---|
4713 | n/a | |
---|
4714 | n/a | /*[clinic input] |
---|
4715 | n/a | os._exit |
---|
4716 | n/a | |
---|
4717 | n/a | status: int |
---|
4718 | n/a | |
---|
4719 | n/a | Exit to the system with specified status, without normal exit processing. |
---|
4720 | n/a | [clinic start generated code]*/ |
---|
4721 | n/a | |
---|
4722 | n/a | static PyObject * |
---|
4723 | n/a | os__exit_impl(PyObject *module, int status) |
---|
4724 | n/a | /*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/ |
---|
4725 | n/a | { |
---|
4726 | n/a | _exit(status); |
---|
4727 | n/a | return NULL; /* Make gcc -Wall happy */ |
---|
4728 | n/a | } |
---|
4729 | n/a | |
---|
4730 | n/a | #if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV) |
---|
4731 | n/a | #define EXECV_CHAR wchar_t |
---|
4732 | n/a | #else |
---|
4733 | n/a | #define EXECV_CHAR char |
---|
4734 | n/a | #endif |
---|
4735 | n/a | |
---|
4736 | n/a | #if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) |
---|
4737 | n/a | static void |
---|
4738 | n/a | free_string_array(EXECV_CHAR **array, Py_ssize_t count) |
---|
4739 | n/a | { |
---|
4740 | n/a | Py_ssize_t i; |
---|
4741 | n/a | for (i = 0; i < count; i++) |
---|
4742 | n/a | PyMem_Free(array[i]); |
---|
4743 | n/a | PyMem_DEL(array); |
---|
4744 | n/a | } |
---|
4745 | n/a | |
---|
4746 | n/a | static int |
---|
4747 | n/a | fsconvert_strdup(PyObject *o, EXECV_CHAR **out) |
---|
4748 | n/a | { |
---|
4749 | n/a | Py_ssize_t size; |
---|
4750 | n/a | PyObject *ub; |
---|
4751 | n/a | int result = 0; |
---|
4752 | n/a | #if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV) |
---|
4753 | n/a | if (!PyUnicode_FSDecoder(o, &ub)) |
---|
4754 | n/a | return 0; |
---|
4755 | n/a | *out = PyUnicode_AsWideCharString(ub, &size); |
---|
4756 | n/a | if (*out) |
---|
4757 | n/a | result = 1; |
---|
4758 | n/a | #else |
---|
4759 | n/a | if (!PyUnicode_FSConverter(o, &ub)) |
---|
4760 | n/a | return 0; |
---|
4761 | n/a | size = PyBytes_GET_SIZE(ub); |
---|
4762 | n/a | *out = PyMem_Malloc(size + 1); |
---|
4763 | n/a | if (*out) { |
---|
4764 | n/a | memcpy(*out, PyBytes_AS_STRING(ub), size + 1); |
---|
4765 | n/a | result = 1; |
---|
4766 | n/a | } else |
---|
4767 | n/a | PyErr_NoMemory(); |
---|
4768 | n/a | #endif |
---|
4769 | n/a | Py_DECREF(ub); |
---|
4770 | n/a | return result; |
---|
4771 | n/a | } |
---|
4772 | n/a | #endif |
---|
4773 | n/a | |
---|
4774 | n/a | #if defined(HAVE_EXECV) || defined (HAVE_FEXECVE) |
---|
4775 | n/a | static EXECV_CHAR** |
---|
4776 | n/a | parse_envlist(PyObject* env, Py_ssize_t *envc_ptr) |
---|
4777 | n/a | { |
---|
4778 | n/a | Py_ssize_t i, pos, envc; |
---|
4779 | n/a | PyObject *keys=NULL, *vals=NULL; |
---|
4780 | n/a | PyObject *key, *val, *key2, *val2, *keyval; |
---|
4781 | n/a | EXECV_CHAR **envlist; |
---|
4782 | n/a | |
---|
4783 | n/a | i = PyMapping_Size(env); |
---|
4784 | n/a | if (i < 0) |
---|
4785 | n/a | return NULL; |
---|
4786 | n/a | envlist = PyMem_NEW(EXECV_CHAR *, i + 1); |
---|
4787 | n/a | if (envlist == NULL) { |
---|
4788 | n/a | PyErr_NoMemory(); |
---|
4789 | n/a | return NULL; |
---|
4790 | n/a | } |
---|
4791 | n/a | envc = 0; |
---|
4792 | n/a | keys = PyMapping_Keys(env); |
---|
4793 | n/a | if (!keys) |
---|
4794 | n/a | goto error; |
---|
4795 | n/a | vals = PyMapping_Values(env); |
---|
4796 | n/a | if (!vals) |
---|
4797 | n/a | goto error; |
---|
4798 | n/a | if (!PyList_Check(keys) || !PyList_Check(vals)) { |
---|
4799 | n/a | PyErr_Format(PyExc_TypeError, |
---|
4800 | n/a | "env.keys() or env.values() is not a list"); |
---|
4801 | n/a | goto error; |
---|
4802 | n/a | } |
---|
4803 | n/a | |
---|
4804 | n/a | for (pos = 0; pos < i; pos++) { |
---|
4805 | n/a | key = PyList_GetItem(keys, pos); |
---|
4806 | n/a | val = PyList_GetItem(vals, pos); |
---|
4807 | n/a | if (!key || !val) |
---|
4808 | n/a | goto error; |
---|
4809 | n/a | |
---|
4810 | n/a | #if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV) |
---|
4811 | n/a | if (!PyUnicode_FSDecoder(key, &key2)) |
---|
4812 | n/a | goto error; |
---|
4813 | n/a | if (!PyUnicode_FSDecoder(val, &val2)) { |
---|
4814 | n/a | Py_DECREF(key2); |
---|
4815 | n/a | goto error; |
---|
4816 | n/a | } |
---|
4817 | n/a | keyval = PyUnicode_FromFormat("%U=%U", key2, val2); |
---|
4818 | n/a | #else |
---|
4819 | n/a | if (!PyUnicode_FSConverter(key, &key2)) |
---|
4820 | n/a | goto error; |
---|
4821 | n/a | if (!PyUnicode_FSConverter(val, &val2)) { |
---|
4822 | n/a | Py_DECREF(key2); |
---|
4823 | n/a | goto error; |
---|
4824 | n/a | } |
---|
4825 | n/a | keyval = PyBytes_FromFormat("%s=%s", PyBytes_AS_STRING(key2), |
---|
4826 | n/a | PyBytes_AS_STRING(val2)); |
---|
4827 | n/a | #endif |
---|
4828 | n/a | Py_DECREF(key2); |
---|
4829 | n/a | Py_DECREF(val2); |
---|
4830 | n/a | if (!keyval) |
---|
4831 | n/a | goto error; |
---|
4832 | n/a | |
---|
4833 | n/a | if (!fsconvert_strdup(keyval, &envlist[envc++])) { |
---|
4834 | n/a | Py_DECREF(keyval); |
---|
4835 | n/a | goto error; |
---|
4836 | n/a | } |
---|
4837 | n/a | |
---|
4838 | n/a | Py_DECREF(keyval); |
---|
4839 | n/a | } |
---|
4840 | n/a | Py_DECREF(vals); |
---|
4841 | n/a | Py_DECREF(keys); |
---|
4842 | n/a | |
---|
4843 | n/a | envlist[envc] = 0; |
---|
4844 | n/a | *envc_ptr = envc; |
---|
4845 | n/a | return envlist; |
---|
4846 | n/a | |
---|
4847 | n/a | error: |
---|
4848 | n/a | Py_XDECREF(keys); |
---|
4849 | n/a | Py_XDECREF(vals); |
---|
4850 | n/a | free_string_array(envlist, envc); |
---|
4851 | n/a | return NULL; |
---|
4852 | n/a | } |
---|
4853 | n/a | |
---|
4854 | n/a | static EXECV_CHAR** |
---|
4855 | n/a | parse_arglist(PyObject* argv, Py_ssize_t *argc) |
---|
4856 | n/a | { |
---|
4857 | n/a | int i; |
---|
4858 | n/a | EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1); |
---|
4859 | n/a | if (argvlist == NULL) { |
---|
4860 | n/a | PyErr_NoMemory(); |
---|
4861 | n/a | return NULL; |
---|
4862 | n/a | } |
---|
4863 | n/a | for (i = 0; i < *argc; i++) { |
---|
4864 | n/a | PyObject* item = PySequence_ITEM(argv, i); |
---|
4865 | n/a | if (item == NULL) |
---|
4866 | n/a | goto fail; |
---|
4867 | n/a | if (!fsconvert_strdup(item, &argvlist[i])) { |
---|
4868 | n/a | Py_DECREF(item); |
---|
4869 | n/a | goto fail; |
---|
4870 | n/a | } |
---|
4871 | n/a | Py_DECREF(item); |
---|
4872 | n/a | } |
---|
4873 | n/a | argvlist[*argc] = NULL; |
---|
4874 | n/a | return argvlist; |
---|
4875 | n/a | fail: |
---|
4876 | n/a | *argc = i; |
---|
4877 | n/a | free_string_array(argvlist, *argc); |
---|
4878 | n/a | return NULL; |
---|
4879 | n/a | } |
---|
4880 | n/a | |
---|
4881 | n/a | #endif |
---|
4882 | n/a | |
---|
4883 | n/a | |
---|
4884 | n/a | #ifdef HAVE_EXECV |
---|
4885 | n/a | /*[clinic input] |
---|
4886 | n/a | os.execv |
---|
4887 | n/a | |
---|
4888 | n/a | path: path_t |
---|
4889 | n/a | Path of executable file. |
---|
4890 | n/a | argv: object |
---|
4891 | n/a | Tuple or list of strings. |
---|
4892 | n/a | / |
---|
4893 | n/a | |
---|
4894 | n/a | Execute an executable path with arguments, replacing current process. |
---|
4895 | n/a | [clinic start generated code]*/ |
---|
4896 | n/a | |
---|
4897 | n/a | static PyObject * |
---|
4898 | n/a | os_execv_impl(PyObject *module, path_t *path, PyObject *argv) |
---|
4899 | n/a | /*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/ |
---|
4900 | n/a | { |
---|
4901 | n/a | EXECV_CHAR **argvlist; |
---|
4902 | n/a | Py_ssize_t argc; |
---|
4903 | n/a | |
---|
4904 | n/a | /* execv has two arguments: (path, argv), where |
---|
4905 | n/a | argv is a list or tuple of strings. */ |
---|
4906 | n/a | |
---|
4907 | n/a | if (!PyList_Check(argv) && !PyTuple_Check(argv)) { |
---|
4908 | n/a | PyErr_SetString(PyExc_TypeError, |
---|
4909 | n/a | "execv() arg 2 must be a tuple or list"); |
---|
4910 | n/a | return NULL; |
---|
4911 | n/a | } |
---|
4912 | n/a | argc = PySequence_Size(argv); |
---|
4913 | n/a | if (argc < 1) { |
---|
4914 | n/a | PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty"); |
---|
4915 | n/a | return NULL; |
---|
4916 | n/a | } |
---|
4917 | n/a | |
---|
4918 | n/a | argvlist = parse_arglist(argv, &argc); |
---|
4919 | n/a | if (argvlist == NULL) { |
---|
4920 | n/a | return NULL; |
---|
4921 | n/a | } |
---|
4922 | n/a | if (!argvlist[0][0]) { |
---|
4923 | n/a | PyErr_SetString(PyExc_ValueError, |
---|
4924 | n/a | "execv() arg 2 first element cannot be empty"); |
---|
4925 | n/a | free_string_array(argvlist, argc); |
---|
4926 | n/a | return NULL; |
---|
4927 | n/a | } |
---|
4928 | n/a | |
---|
4929 | n/a | _Py_BEGIN_SUPPRESS_IPH |
---|
4930 | n/a | #ifdef HAVE_WEXECV |
---|
4931 | n/a | _wexecv(path->wide, argvlist); |
---|
4932 | n/a | #else |
---|
4933 | n/a | execv(path->narrow, argvlist); |
---|
4934 | n/a | #endif |
---|
4935 | n/a | _Py_END_SUPPRESS_IPH |
---|
4936 | n/a | |
---|
4937 | n/a | /* If we get here it's definitely an error */ |
---|
4938 | n/a | |
---|
4939 | n/a | free_string_array(argvlist, argc); |
---|
4940 | n/a | return posix_error(); |
---|
4941 | n/a | } |
---|
4942 | n/a | |
---|
4943 | n/a | |
---|
4944 | n/a | /*[clinic input] |
---|
4945 | n/a | os.execve |
---|
4946 | n/a | |
---|
4947 | n/a | path: path_t(allow_fd='PATH_HAVE_FEXECVE') |
---|
4948 | n/a | Path of executable file. |
---|
4949 | n/a | argv: object |
---|
4950 | n/a | Tuple or list of strings. |
---|
4951 | n/a | env: object |
---|
4952 | n/a | Dictionary of strings mapping to strings. |
---|
4953 | n/a | |
---|
4954 | n/a | Execute an executable path with arguments, replacing current process. |
---|
4955 | n/a | [clinic start generated code]*/ |
---|
4956 | n/a | |
---|
4957 | n/a | static PyObject * |
---|
4958 | n/a | os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env) |
---|
4959 | n/a | /*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/ |
---|
4960 | n/a | { |
---|
4961 | n/a | EXECV_CHAR **argvlist = NULL; |
---|
4962 | n/a | EXECV_CHAR **envlist; |
---|
4963 | n/a | Py_ssize_t argc, envc; |
---|
4964 | n/a | |
---|
4965 | n/a | /* execve has three arguments: (path, argv, env), where |
---|
4966 | n/a | argv is a list or tuple of strings and env is a dictionary |
---|
4967 | n/a | like posix.environ. */ |
---|
4968 | n/a | |
---|
4969 | n/a | if (!PyList_Check(argv) && !PyTuple_Check(argv)) { |
---|
4970 | n/a | PyErr_SetString(PyExc_TypeError, |
---|
4971 | n/a | "execve: argv must be a tuple or list"); |
---|
4972 | n/a | goto fail; |
---|
4973 | n/a | } |
---|
4974 | n/a | argc = PySequence_Size(argv); |
---|
4975 | n/a | if (argc < 1) { |
---|
4976 | n/a | PyErr_SetString(PyExc_ValueError, "execve: argv must not be empty"); |
---|
4977 | n/a | return NULL; |
---|
4978 | n/a | } |
---|
4979 | n/a | |
---|
4980 | n/a | if (!PyMapping_Check(env)) { |
---|
4981 | n/a | PyErr_SetString(PyExc_TypeError, |
---|
4982 | n/a | "execve: environment must be a mapping object"); |
---|
4983 | n/a | goto fail; |
---|
4984 | n/a | } |
---|
4985 | n/a | |
---|
4986 | n/a | argvlist = parse_arglist(argv, &argc); |
---|
4987 | n/a | if (argvlist == NULL) { |
---|
4988 | n/a | goto fail; |
---|
4989 | n/a | } |
---|
4990 | n/a | if (!argvlist[0][0]) { |
---|
4991 | n/a | PyErr_SetString(PyExc_ValueError, |
---|
4992 | n/a | "execve: argv first element cannot be empty"); |
---|
4993 | n/a | goto fail; |
---|
4994 | n/a | } |
---|
4995 | n/a | |
---|
4996 | n/a | envlist = parse_envlist(env, &envc); |
---|
4997 | n/a | if (envlist == NULL) |
---|
4998 | n/a | goto fail; |
---|
4999 | n/a | |
---|
5000 | n/a | _Py_BEGIN_SUPPRESS_IPH |
---|
5001 | n/a | #ifdef HAVE_FEXECVE |
---|
5002 | n/a | if (path->fd > -1) |
---|
5003 | n/a | fexecve(path->fd, argvlist, envlist); |
---|
5004 | n/a | else |
---|
5005 | n/a | #endif |
---|
5006 | n/a | #ifdef HAVE_WEXECV |
---|
5007 | n/a | _wexecve(path->wide, argvlist, envlist); |
---|
5008 | n/a | #else |
---|
5009 | n/a | execve(path->narrow, argvlist, envlist); |
---|
5010 | n/a | #endif |
---|
5011 | n/a | _Py_END_SUPPRESS_IPH |
---|
5012 | n/a | |
---|
5013 | n/a | /* If we get here it's definitely an error */ |
---|
5014 | n/a | |
---|
5015 | n/a | path_error(path); |
---|
5016 | n/a | |
---|
5017 | n/a | free_string_array(envlist, envc); |
---|
5018 | n/a | fail: |
---|
5019 | n/a | if (argvlist) |
---|
5020 | n/a | free_string_array(argvlist, argc); |
---|
5021 | n/a | return NULL; |
---|
5022 | n/a | } |
---|
5023 | n/a | |
---|
5024 | n/a | #endif /* HAVE_EXECV */ |
---|
5025 | n/a | |
---|
5026 | n/a | |
---|
5027 | n/a | #if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV) |
---|
5028 | n/a | /*[clinic input] |
---|
5029 | n/a | os.spawnv |
---|
5030 | n/a | |
---|
5031 | n/a | mode: int |
---|
5032 | n/a | Mode of process creation. |
---|
5033 | n/a | path: path_t |
---|
5034 | n/a | Path of executable file. |
---|
5035 | n/a | argv: object |
---|
5036 | n/a | Tuple or list of strings. |
---|
5037 | n/a | / |
---|
5038 | n/a | |
---|
5039 | n/a | Execute the program specified by path in a new process. |
---|
5040 | n/a | [clinic start generated code]*/ |
---|
5041 | n/a | |
---|
5042 | n/a | static PyObject * |
---|
5043 | n/a | os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv) |
---|
5044 | n/a | /*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/ |
---|
5045 | n/a | { |
---|
5046 | n/a | EXECV_CHAR **argvlist; |
---|
5047 | n/a | int i; |
---|
5048 | n/a | Py_ssize_t argc; |
---|
5049 | n/a | intptr_t spawnval; |
---|
5050 | n/a | PyObject *(*getitem)(PyObject *, Py_ssize_t); |
---|
5051 | n/a | |
---|
5052 | n/a | /* spawnv has three arguments: (mode, path, argv), where |
---|
5053 | n/a | argv is a list or tuple of strings. */ |
---|
5054 | n/a | |
---|
5055 | n/a | if (PyList_Check(argv)) { |
---|
5056 | n/a | argc = PyList_Size(argv); |
---|
5057 | n/a | getitem = PyList_GetItem; |
---|
5058 | n/a | } |
---|
5059 | n/a | else if (PyTuple_Check(argv)) { |
---|
5060 | n/a | argc = PyTuple_Size(argv); |
---|
5061 | n/a | getitem = PyTuple_GetItem; |
---|
5062 | n/a | } |
---|
5063 | n/a | else { |
---|
5064 | n/a | PyErr_SetString(PyExc_TypeError, |
---|
5065 | n/a | "spawnv() arg 2 must be a tuple or list"); |
---|
5066 | n/a | return NULL; |
---|
5067 | n/a | } |
---|
5068 | n/a | if (argc == 0) { |
---|
5069 | n/a | PyErr_SetString(PyExc_ValueError, |
---|
5070 | n/a | "spawnv() arg 2 cannot be empty"); |
---|
5071 | n/a | return NULL; |
---|
5072 | n/a | } |
---|
5073 | n/a | |
---|
5074 | n/a | argvlist = PyMem_NEW(EXECV_CHAR *, argc+1); |
---|
5075 | n/a | if (argvlist == NULL) { |
---|
5076 | n/a | return PyErr_NoMemory(); |
---|
5077 | n/a | } |
---|
5078 | n/a | for (i = 0; i < argc; i++) { |
---|
5079 | n/a | if (!fsconvert_strdup((*getitem)(argv, i), |
---|
5080 | n/a | &argvlist[i])) { |
---|
5081 | n/a | free_string_array(argvlist, i); |
---|
5082 | n/a | PyErr_SetString( |
---|
5083 | n/a | PyExc_TypeError, |
---|
5084 | n/a | "spawnv() arg 2 must contain only strings"); |
---|
5085 | n/a | return NULL; |
---|
5086 | n/a | } |
---|
5087 | n/a | if (i == 0 && !argvlist[0][0]) { |
---|
5088 | n/a | free_string_array(argvlist, i); |
---|
5089 | n/a | PyErr_SetString( |
---|
5090 | n/a | PyExc_ValueError, |
---|
5091 | n/a | "spawnv() arg 2 first element cannot be empty"); |
---|
5092 | n/a | return NULL; |
---|
5093 | n/a | } |
---|
5094 | n/a | } |
---|
5095 | n/a | argvlist[argc] = NULL; |
---|
5096 | n/a | |
---|
5097 | n/a | if (mode == _OLD_P_OVERLAY) |
---|
5098 | n/a | mode = _P_OVERLAY; |
---|
5099 | n/a | |
---|
5100 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
5101 | n/a | _Py_BEGIN_SUPPRESS_IPH |
---|
5102 | n/a | #ifdef HAVE_WSPAWNV |
---|
5103 | n/a | spawnval = _wspawnv(mode, path->wide, argvlist); |
---|
5104 | n/a | #else |
---|
5105 | n/a | spawnval = _spawnv(mode, path->narrow, argvlist); |
---|
5106 | n/a | #endif |
---|
5107 | n/a | _Py_END_SUPPRESS_IPH |
---|
5108 | n/a | Py_END_ALLOW_THREADS |
---|
5109 | n/a | |
---|
5110 | n/a | free_string_array(argvlist, argc); |
---|
5111 | n/a | |
---|
5112 | n/a | if (spawnval == -1) |
---|
5113 | n/a | return posix_error(); |
---|
5114 | n/a | else |
---|
5115 | n/a | return Py_BuildValue(_Py_PARSE_INTPTR, spawnval); |
---|
5116 | n/a | } |
---|
5117 | n/a | |
---|
5118 | n/a | |
---|
5119 | n/a | /*[clinic input] |
---|
5120 | n/a | os.spawnve |
---|
5121 | n/a | |
---|
5122 | n/a | mode: int |
---|
5123 | n/a | Mode of process creation. |
---|
5124 | n/a | path: path_t |
---|
5125 | n/a | Path of executable file. |
---|
5126 | n/a | argv: object |
---|
5127 | n/a | Tuple or list of strings. |
---|
5128 | n/a | env: object |
---|
5129 | n/a | Dictionary of strings mapping to strings. |
---|
5130 | n/a | / |
---|
5131 | n/a | |
---|
5132 | n/a | Execute the program specified by path in a new process. |
---|
5133 | n/a | [clinic start generated code]*/ |
---|
5134 | n/a | |
---|
5135 | n/a | static PyObject * |
---|
5136 | n/a | os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv, |
---|
5137 | n/a | PyObject *env) |
---|
5138 | n/a | /*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/ |
---|
5139 | n/a | { |
---|
5140 | n/a | EXECV_CHAR **argvlist; |
---|
5141 | n/a | EXECV_CHAR **envlist; |
---|
5142 | n/a | PyObject *res = NULL; |
---|
5143 | n/a | Py_ssize_t argc, i, envc; |
---|
5144 | n/a | intptr_t spawnval; |
---|
5145 | n/a | PyObject *(*getitem)(PyObject *, Py_ssize_t); |
---|
5146 | n/a | Py_ssize_t lastarg = 0; |
---|
5147 | n/a | |
---|
5148 | n/a | /* spawnve has four arguments: (mode, path, argv, env), where |
---|
5149 | n/a | argv is a list or tuple of strings and env is a dictionary |
---|
5150 | n/a | like posix.environ. */ |
---|
5151 | n/a | |
---|
5152 | n/a | if (PyList_Check(argv)) { |
---|
5153 | n/a | argc = PyList_Size(argv); |
---|
5154 | n/a | getitem = PyList_GetItem; |
---|
5155 | n/a | } |
---|
5156 | n/a | else if (PyTuple_Check(argv)) { |
---|
5157 | n/a | argc = PyTuple_Size(argv); |
---|
5158 | n/a | getitem = PyTuple_GetItem; |
---|
5159 | n/a | } |
---|
5160 | n/a | else { |
---|
5161 | n/a | PyErr_SetString(PyExc_TypeError, |
---|
5162 | n/a | "spawnve() arg 2 must be a tuple or list"); |
---|
5163 | n/a | goto fail_0; |
---|
5164 | n/a | } |
---|
5165 | n/a | if (argc == 0) { |
---|
5166 | n/a | PyErr_SetString(PyExc_ValueError, |
---|
5167 | n/a | "spawnve() arg 2 cannot be empty"); |
---|
5168 | n/a | goto fail_0; |
---|
5169 | n/a | } |
---|
5170 | n/a | if (!PyMapping_Check(env)) { |
---|
5171 | n/a | PyErr_SetString(PyExc_TypeError, |
---|
5172 | n/a | "spawnve() arg 3 must be a mapping object"); |
---|
5173 | n/a | goto fail_0; |
---|
5174 | n/a | } |
---|
5175 | n/a | |
---|
5176 | n/a | argvlist = PyMem_NEW(EXECV_CHAR *, argc+1); |
---|
5177 | n/a | if (argvlist == NULL) { |
---|
5178 | n/a | PyErr_NoMemory(); |
---|
5179 | n/a | goto fail_0; |
---|
5180 | n/a | } |
---|
5181 | n/a | for (i = 0; i < argc; i++) { |
---|
5182 | n/a | if (!fsconvert_strdup((*getitem)(argv, i), |
---|
5183 | n/a | &argvlist[i])) |
---|
5184 | n/a | { |
---|
5185 | n/a | lastarg = i; |
---|
5186 | n/a | goto fail_1; |
---|
5187 | n/a | } |
---|
5188 | n/a | if (i == 0 && !argvlist[0][0]) { |
---|
5189 | n/a | lastarg = i; |
---|
5190 | n/a | PyErr_SetString( |
---|
5191 | n/a | PyExc_ValueError, |
---|
5192 | n/a | "spawnv() arg 2 first element cannot be empty"); |
---|
5193 | n/a | goto fail_1; |
---|
5194 | n/a | } |
---|
5195 | n/a | } |
---|
5196 | n/a | lastarg = argc; |
---|
5197 | n/a | argvlist[argc] = NULL; |
---|
5198 | n/a | |
---|
5199 | n/a | envlist = parse_envlist(env, &envc); |
---|
5200 | n/a | if (envlist == NULL) |
---|
5201 | n/a | goto fail_1; |
---|
5202 | n/a | |
---|
5203 | n/a | if (mode == _OLD_P_OVERLAY) |
---|
5204 | n/a | mode = _P_OVERLAY; |
---|
5205 | n/a | |
---|
5206 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
5207 | n/a | _Py_BEGIN_SUPPRESS_IPH |
---|
5208 | n/a | #ifdef HAVE_WSPAWNV |
---|
5209 | n/a | spawnval = _wspawnve(mode, path->wide, argvlist, envlist); |
---|
5210 | n/a | #else |
---|
5211 | n/a | spawnval = _spawnve(mode, path->narrow, argvlist, envlist); |
---|
5212 | n/a | #endif |
---|
5213 | n/a | _Py_END_SUPPRESS_IPH |
---|
5214 | n/a | Py_END_ALLOW_THREADS |
---|
5215 | n/a | |
---|
5216 | n/a | if (spawnval == -1) |
---|
5217 | n/a | (void) posix_error(); |
---|
5218 | n/a | else |
---|
5219 | n/a | res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval); |
---|
5220 | n/a | |
---|
5221 | n/a | while (--envc >= 0) |
---|
5222 | n/a | PyMem_DEL(envlist[envc]); |
---|
5223 | n/a | PyMem_DEL(envlist); |
---|
5224 | n/a | fail_1: |
---|
5225 | n/a | free_string_array(argvlist, lastarg); |
---|
5226 | n/a | fail_0: |
---|
5227 | n/a | return res; |
---|
5228 | n/a | } |
---|
5229 | n/a | |
---|
5230 | n/a | #endif /* HAVE_SPAWNV */ |
---|
5231 | n/a | |
---|
5232 | n/a | |
---|
5233 | n/a | #ifdef HAVE_FORK1 |
---|
5234 | n/a | /*[clinic input] |
---|
5235 | n/a | os.fork1 |
---|
5236 | n/a | |
---|
5237 | n/a | Fork a child process with a single multiplexed (i.e., not bound) thread. |
---|
5238 | n/a | |
---|
5239 | n/a | Return 0 to child process and PID of child to parent process. |
---|
5240 | n/a | [clinic start generated code]*/ |
---|
5241 | n/a | |
---|
5242 | n/a | static PyObject * |
---|
5243 | n/a | os_fork1_impl(PyObject *module) |
---|
5244 | n/a | /*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/ |
---|
5245 | n/a | { |
---|
5246 | n/a | pid_t pid; |
---|
5247 | n/a | int result = 0; |
---|
5248 | n/a | _PyImport_AcquireLock(); |
---|
5249 | n/a | pid = fork1(); |
---|
5250 | n/a | if (pid == 0) { |
---|
5251 | n/a | /* child: this clobbers and resets the import lock. */ |
---|
5252 | n/a | PyOS_AfterFork(); |
---|
5253 | n/a | } else { |
---|
5254 | n/a | /* parent: release the import lock. */ |
---|
5255 | n/a | result = _PyImport_ReleaseLock(); |
---|
5256 | n/a | } |
---|
5257 | n/a | if (pid == -1) |
---|
5258 | n/a | return posix_error(); |
---|
5259 | n/a | if (result < 0) { |
---|
5260 | n/a | /* Don't clobber the OSError if the fork failed. */ |
---|
5261 | n/a | PyErr_SetString(PyExc_RuntimeError, |
---|
5262 | n/a | "not holding the import lock"); |
---|
5263 | n/a | return NULL; |
---|
5264 | n/a | } |
---|
5265 | n/a | return PyLong_FromPid(pid); |
---|
5266 | n/a | } |
---|
5267 | n/a | #endif /* HAVE_FORK1 */ |
---|
5268 | n/a | |
---|
5269 | n/a | |
---|
5270 | n/a | #ifdef HAVE_FORK |
---|
5271 | n/a | /*[clinic input] |
---|
5272 | n/a | os.fork |
---|
5273 | n/a | |
---|
5274 | n/a | Fork a child process. |
---|
5275 | n/a | |
---|
5276 | n/a | Return 0 to child process and PID of child to parent process. |
---|
5277 | n/a | [clinic start generated code]*/ |
---|
5278 | n/a | |
---|
5279 | n/a | static PyObject * |
---|
5280 | n/a | os_fork_impl(PyObject *module) |
---|
5281 | n/a | /*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/ |
---|
5282 | n/a | { |
---|
5283 | n/a | pid_t pid; |
---|
5284 | n/a | int result = 0; |
---|
5285 | n/a | _PyImport_AcquireLock(); |
---|
5286 | n/a | pid = fork(); |
---|
5287 | n/a | if (pid == 0) { |
---|
5288 | n/a | /* child: this clobbers and resets the import lock. */ |
---|
5289 | n/a | PyOS_AfterFork(); |
---|
5290 | n/a | } else { |
---|
5291 | n/a | /* parent: release the import lock. */ |
---|
5292 | n/a | result = _PyImport_ReleaseLock(); |
---|
5293 | n/a | } |
---|
5294 | n/a | if (pid == -1) |
---|
5295 | n/a | return posix_error(); |
---|
5296 | n/a | if (result < 0) { |
---|
5297 | n/a | /* Don't clobber the OSError if the fork failed. */ |
---|
5298 | n/a | PyErr_SetString(PyExc_RuntimeError, |
---|
5299 | n/a | "not holding the import lock"); |
---|
5300 | n/a | return NULL; |
---|
5301 | n/a | } |
---|
5302 | n/a | return PyLong_FromPid(pid); |
---|
5303 | n/a | } |
---|
5304 | n/a | #endif /* HAVE_FORK */ |
---|
5305 | n/a | |
---|
5306 | n/a | |
---|
5307 | n/a | #ifdef HAVE_SCHED_H |
---|
5308 | n/a | #ifdef HAVE_SCHED_GET_PRIORITY_MAX |
---|
5309 | n/a | /*[clinic input] |
---|
5310 | n/a | os.sched_get_priority_max |
---|
5311 | n/a | |
---|
5312 | n/a | policy: int |
---|
5313 | n/a | |
---|
5314 | n/a | Get the maximum scheduling priority for policy. |
---|
5315 | n/a | [clinic start generated code]*/ |
---|
5316 | n/a | |
---|
5317 | n/a | static PyObject * |
---|
5318 | n/a | os_sched_get_priority_max_impl(PyObject *module, int policy) |
---|
5319 | n/a | /*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/ |
---|
5320 | n/a | { |
---|
5321 | n/a | int max; |
---|
5322 | n/a | |
---|
5323 | n/a | max = sched_get_priority_max(policy); |
---|
5324 | n/a | if (max < 0) |
---|
5325 | n/a | return posix_error(); |
---|
5326 | n/a | return PyLong_FromLong(max); |
---|
5327 | n/a | } |
---|
5328 | n/a | |
---|
5329 | n/a | |
---|
5330 | n/a | /*[clinic input] |
---|
5331 | n/a | os.sched_get_priority_min |
---|
5332 | n/a | |
---|
5333 | n/a | policy: int |
---|
5334 | n/a | |
---|
5335 | n/a | Get the minimum scheduling priority for policy. |
---|
5336 | n/a | [clinic start generated code]*/ |
---|
5337 | n/a | |
---|
5338 | n/a | static PyObject * |
---|
5339 | n/a | os_sched_get_priority_min_impl(PyObject *module, int policy) |
---|
5340 | n/a | /*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/ |
---|
5341 | n/a | { |
---|
5342 | n/a | int min = sched_get_priority_min(policy); |
---|
5343 | n/a | if (min < 0) |
---|
5344 | n/a | return posix_error(); |
---|
5345 | n/a | return PyLong_FromLong(min); |
---|
5346 | n/a | } |
---|
5347 | n/a | #endif /* HAVE_SCHED_GET_PRIORITY_MAX */ |
---|
5348 | n/a | |
---|
5349 | n/a | |
---|
5350 | n/a | #ifdef HAVE_SCHED_SETSCHEDULER |
---|
5351 | n/a | /*[clinic input] |
---|
5352 | n/a | os.sched_getscheduler |
---|
5353 | n/a | pid: pid_t |
---|
5354 | n/a | / |
---|
5355 | n/a | |
---|
5356 | n/a | Get the scheduling policy for the process identifiedy by pid. |
---|
5357 | n/a | |
---|
5358 | n/a | Passing 0 for pid returns the scheduling policy for the calling process. |
---|
5359 | n/a | [clinic start generated code]*/ |
---|
5360 | n/a | |
---|
5361 | n/a | static PyObject * |
---|
5362 | n/a | os_sched_getscheduler_impl(PyObject *module, pid_t pid) |
---|
5363 | n/a | /*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/ |
---|
5364 | n/a | { |
---|
5365 | n/a | int policy; |
---|
5366 | n/a | |
---|
5367 | n/a | policy = sched_getscheduler(pid); |
---|
5368 | n/a | if (policy < 0) |
---|
5369 | n/a | return posix_error(); |
---|
5370 | n/a | return PyLong_FromLong(policy); |
---|
5371 | n/a | } |
---|
5372 | n/a | #endif /* HAVE_SCHED_SETSCHEDULER */ |
---|
5373 | n/a | |
---|
5374 | n/a | |
---|
5375 | n/a | #if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) |
---|
5376 | n/a | /*[clinic input] |
---|
5377 | n/a | class os.sched_param "PyObject *" "&SchedParamType" |
---|
5378 | n/a | |
---|
5379 | n/a | @classmethod |
---|
5380 | n/a | os.sched_param.__new__ |
---|
5381 | n/a | |
---|
5382 | n/a | sched_priority: object |
---|
5383 | n/a | A scheduling parameter. |
---|
5384 | n/a | |
---|
5385 | n/a | Current has only one field: sched_priority"); |
---|
5386 | n/a | [clinic start generated code]*/ |
---|
5387 | n/a | |
---|
5388 | n/a | static PyObject * |
---|
5389 | n/a | os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority) |
---|
5390 | n/a | /*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/ |
---|
5391 | n/a | { |
---|
5392 | n/a | PyObject *res; |
---|
5393 | n/a | |
---|
5394 | n/a | res = PyStructSequence_New(type); |
---|
5395 | n/a | if (!res) |
---|
5396 | n/a | return NULL; |
---|
5397 | n/a | Py_INCREF(sched_priority); |
---|
5398 | n/a | PyStructSequence_SET_ITEM(res, 0, sched_priority); |
---|
5399 | n/a | return res; |
---|
5400 | n/a | } |
---|
5401 | n/a | |
---|
5402 | n/a | |
---|
5403 | n/a | PyDoc_VAR(os_sched_param__doc__); |
---|
5404 | n/a | |
---|
5405 | n/a | static PyStructSequence_Field sched_param_fields[] = { |
---|
5406 | n/a | {"sched_priority", "the scheduling priority"}, |
---|
5407 | n/a | {0} |
---|
5408 | n/a | }; |
---|
5409 | n/a | |
---|
5410 | n/a | static PyStructSequence_Desc sched_param_desc = { |
---|
5411 | n/a | "sched_param", /* name */ |
---|
5412 | n/a | os_sched_param__doc__, /* doc */ |
---|
5413 | n/a | sched_param_fields, |
---|
5414 | n/a | 1 |
---|
5415 | n/a | }; |
---|
5416 | n/a | |
---|
5417 | n/a | static int |
---|
5418 | n/a | convert_sched_param(PyObject *param, struct sched_param *res) |
---|
5419 | n/a | { |
---|
5420 | n/a | long priority; |
---|
5421 | n/a | |
---|
5422 | n/a | if (Py_TYPE(param) != &SchedParamType) { |
---|
5423 | n/a | PyErr_SetString(PyExc_TypeError, "must have a sched_param object"); |
---|
5424 | n/a | return 0; |
---|
5425 | n/a | } |
---|
5426 | n/a | priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0)); |
---|
5427 | n/a | if (priority == -1 && PyErr_Occurred()) |
---|
5428 | n/a | return 0; |
---|
5429 | n/a | if (priority > INT_MAX || priority < INT_MIN) { |
---|
5430 | n/a | PyErr_SetString(PyExc_OverflowError, "sched_priority out of range"); |
---|
5431 | n/a | return 0; |
---|
5432 | n/a | } |
---|
5433 | n/a | res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int); |
---|
5434 | n/a | return 1; |
---|
5435 | n/a | } |
---|
5436 | n/a | #endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */ |
---|
5437 | n/a | |
---|
5438 | n/a | |
---|
5439 | n/a | #ifdef HAVE_SCHED_SETSCHEDULER |
---|
5440 | n/a | /*[clinic input] |
---|
5441 | n/a | os.sched_setscheduler |
---|
5442 | n/a | |
---|
5443 | n/a | pid: pid_t |
---|
5444 | n/a | policy: int |
---|
5445 | n/a | param: sched_param |
---|
5446 | n/a | / |
---|
5447 | n/a | |
---|
5448 | n/a | Set the scheduling policy for the process identified by pid. |
---|
5449 | n/a | |
---|
5450 | n/a | If pid is 0, the calling process is changed. |
---|
5451 | n/a | param is an instance of sched_param. |
---|
5452 | n/a | [clinic start generated code]*/ |
---|
5453 | n/a | |
---|
5454 | n/a | static PyObject * |
---|
5455 | n/a | os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy, |
---|
5456 | n/a | struct sched_param *param) |
---|
5457 | n/a | /*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/ |
---|
5458 | n/a | { |
---|
5459 | n/a | /* |
---|
5460 | n/a | ** sched_setscheduler() returns 0 in Linux, but the previous |
---|
5461 | n/a | ** scheduling policy under Solaris/Illumos, and others. |
---|
5462 | n/a | ** On error, -1 is returned in all Operating Systems. |
---|
5463 | n/a | */ |
---|
5464 | n/a | if (sched_setscheduler(pid, policy, param) == -1) |
---|
5465 | n/a | return posix_error(); |
---|
5466 | n/a | Py_RETURN_NONE; |
---|
5467 | n/a | } |
---|
5468 | n/a | #endif /* HAVE_SCHED_SETSCHEDULER*/ |
---|
5469 | n/a | |
---|
5470 | n/a | |
---|
5471 | n/a | #ifdef HAVE_SCHED_SETPARAM |
---|
5472 | n/a | /*[clinic input] |
---|
5473 | n/a | os.sched_getparam |
---|
5474 | n/a | pid: pid_t |
---|
5475 | n/a | / |
---|
5476 | n/a | |
---|
5477 | n/a | Returns scheduling parameters for the process identified by pid. |
---|
5478 | n/a | |
---|
5479 | n/a | If pid is 0, returns parameters for the calling process. |
---|
5480 | n/a | Return value is an instance of sched_param. |
---|
5481 | n/a | [clinic start generated code]*/ |
---|
5482 | n/a | |
---|
5483 | n/a | static PyObject * |
---|
5484 | n/a | os_sched_getparam_impl(PyObject *module, pid_t pid) |
---|
5485 | n/a | /*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/ |
---|
5486 | n/a | { |
---|
5487 | n/a | struct sched_param param; |
---|
5488 | n/a | PyObject *result; |
---|
5489 | n/a | PyObject *priority; |
---|
5490 | n/a | |
---|
5491 | n/a | if (sched_getparam(pid, ¶m)) |
---|
5492 | n/a | return posix_error(); |
---|
5493 | n/a | result = PyStructSequence_New(&SchedParamType); |
---|
5494 | n/a | if (!result) |
---|
5495 | n/a | return NULL; |
---|
5496 | n/a | priority = PyLong_FromLong(param.sched_priority); |
---|
5497 | n/a | if (!priority) { |
---|
5498 | n/a | Py_DECREF(result); |
---|
5499 | n/a | return NULL; |
---|
5500 | n/a | } |
---|
5501 | n/a | PyStructSequence_SET_ITEM(result, 0, priority); |
---|
5502 | n/a | return result; |
---|
5503 | n/a | } |
---|
5504 | n/a | |
---|
5505 | n/a | |
---|
5506 | n/a | /*[clinic input] |
---|
5507 | n/a | os.sched_setparam |
---|
5508 | n/a | pid: pid_t |
---|
5509 | n/a | param: sched_param |
---|
5510 | n/a | / |
---|
5511 | n/a | |
---|
5512 | n/a | Set scheduling parameters for the process identified by pid. |
---|
5513 | n/a | |
---|
5514 | n/a | If pid is 0, sets parameters for the calling process. |
---|
5515 | n/a | param should be an instance of sched_param. |
---|
5516 | n/a | [clinic start generated code]*/ |
---|
5517 | n/a | |
---|
5518 | n/a | static PyObject * |
---|
5519 | n/a | os_sched_setparam_impl(PyObject *module, pid_t pid, |
---|
5520 | n/a | struct sched_param *param) |
---|
5521 | n/a | /*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/ |
---|
5522 | n/a | { |
---|
5523 | n/a | if (sched_setparam(pid, param)) |
---|
5524 | n/a | return posix_error(); |
---|
5525 | n/a | Py_RETURN_NONE; |
---|
5526 | n/a | } |
---|
5527 | n/a | #endif /* HAVE_SCHED_SETPARAM */ |
---|
5528 | n/a | |
---|
5529 | n/a | |
---|
5530 | n/a | #ifdef HAVE_SCHED_RR_GET_INTERVAL |
---|
5531 | n/a | /*[clinic input] |
---|
5532 | n/a | os.sched_rr_get_interval -> double |
---|
5533 | n/a | pid: pid_t |
---|
5534 | n/a | / |
---|
5535 | n/a | |
---|
5536 | n/a | Return the round-robin quantum for the process identified by pid, in seconds. |
---|
5537 | n/a | |
---|
5538 | n/a | Value returned is a float. |
---|
5539 | n/a | [clinic start generated code]*/ |
---|
5540 | n/a | |
---|
5541 | n/a | static double |
---|
5542 | n/a | os_sched_rr_get_interval_impl(PyObject *module, pid_t pid) |
---|
5543 | n/a | /*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/ |
---|
5544 | n/a | { |
---|
5545 | n/a | struct timespec interval; |
---|
5546 | n/a | if (sched_rr_get_interval(pid, &interval)) { |
---|
5547 | n/a | posix_error(); |
---|
5548 | n/a | return -1.0; |
---|
5549 | n/a | } |
---|
5550 | n/a | return (double)interval.tv_sec + 1e-9*interval.tv_nsec; |
---|
5551 | n/a | } |
---|
5552 | n/a | #endif /* HAVE_SCHED_RR_GET_INTERVAL */ |
---|
5553 | n/a | |
---|
5554 | n/a | |
---|
5555 | n/a | /*[clinic input] |
---|
5556 | n/a | os.sched_yield |
---|
5557 | n/a | |
---|
5558 | n/a | Voluntarily relinquish the CPU. |
---|
5559 | n/a | [clinic start generated code]*/ |
---|
5560 | n/a | |
---|
5561 | n/a | static PyObject * |
---|
5562 | n/a | os_sched_yield_impl(PyObject *module) |
---|
5563 | n/a | /*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/ |
---|
5564 | n/a | { |
---|
5565 | n/a | if (sched_yield()) |
---|
5566 | n/a | return posix_error(); |
---|
5567 | n/a | Py_RETURN_NONE; |
---|
5568 | n/a | } |
---|
5569 | n/a | |
---|
5570 | n/a | #ifdef HAVE_SCHED_SETAFFINITY |
---|
5571 | n/a | /* The minimum number of CPUs allocated in a cpu_set_t */ |
---|
5572 | n/a | static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT; |
---|
5573 | n/a | |
---|
5574 | n/a | /*[clinic input] |
---|
5575 | n/a | os.sched_setaffinity |
---|
5576 | n/a | pid: pid_t |
---|
5577 | n/a | mask : object |
---|
5578 | n/a | / |
---|
5579 | n/a | |
---|
5580 | n/a | Set the CPU affinity of the process identified by pid to mask. |
---|
5581 | n/a | |
---|
5582 | n/a | mask should be an iterable of integers identifying CPUs. |
---|
5583 | n/a | [clinic start generated code]*/ |
---|
5584 | n/a | |
---|
5585 | n/a | static PyObject * |
---|
5586 | n/a | os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask) |
---|
5587 | n/a | /*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/ |
---|
5588 | n/a | { |
---|
5589 | n/a | int ncpus; |
---|
5590 | n/a | size_t setsize; |
---|
5591 | n/a | cpu_set_t *cpu_set = NULL; |
---|
5592 | n/a | PyObject *iterator = NULL, *item; |
---|
5593 | n/a | |
---|
5594 | n/a | iterator = PyObject_GetIter(mask); |
---|
5595 | n/a | if (iterator == NULL) |
---|
5596 | n/a | return NULL; |
---|
5597 | n/a | |
---|
5598 | n/a | ncpus = NCPUS_START; |
---|
5599 | n/a | setsize = CPU_ALLOC_SIZE(ncpus); |
---|
5600 | n/a | cpu_set = CPU_ALLOC(ncpus); |
---|
5601 | n/a | if (cpu_set == NULL) { |
---|
5602 | n/a | PyErr_NoMemory(); |
---|
5603 | n/a | goto error; |
---|
5604 | n/a | } |
---|
5605 | n/a | CPU_ZERO_S(setsize, cpu_set); |
---|
5606 | n/a | |
---|
5607 | n/a | while ((item = PyIter_Next(iterator))) { |
---|
5608 | n/a | long cpu; |
---|
5609 | n/a | if (!PyLong_Check(item)) { |
---|
5610 | n/a | PyErr_Format(PyExc_TypeError, |
---|
5611 | n/a | "expected an iterator of ints, " |
---|
5612 | n/a | "but iterator yielded %R", |
---|
5613 | n/a | Py_TYPE(item)); |
---|
5614 | n/a | Py_DECREF(item); |
---|
5615 | n/a | goto error; |
---|
5616 | n/a | } |
---|
5617 | n/a | cpu = PyLong_AsLong(item); |
---|
5618 | n/a | Py_DECREF(item); |
---|
5619 | n/a | if (cpu < 0) { |
---|
5620 | n/a | if (!PyErr_Occurred()) |
---|
5621 | n/a | PyErr_SetString(PyExc_ValueError, "negative CPU number"); |
---|
5622 | n/a | goto error; |
---|
5623 | n/a | } |
---|
5624 | n/a | if (cpu > INT_MAX - 1) { |
---|
5625 | n/a | PyErr_SetString(PyExc_OverflowError, "CPU number too large"); |
---|
5626 | n/a | goto error; |
---|
5627 | n/a | } |
---|
5628 | n/a | if (cpu >= ncpus) { |
---|
5629 | n/a | /* Grow CPU mask to fit the CPU number */ |
---|
5630 | n/a | int newncpus = ncpus; |
---|
5631 | n/a | cpu_set_t *newmask; |
---|
5632 | n/a | size_t newsetsize; |
---|
5633 | n/a | while (newncpus <= cpu) { |
---|
5634 | n/a | if (newncpus > INT_MAX / 2) |
---|
5635 | n/a | newncpus = cpu + 1; |
---|
5636 | n/a | else |
---|
5637 | n/a | newncpus = newncpus * 2; |
---|
5638 | n/a | } |
---|
5639 | n/a | newmask = CPU_ALLOC(newncpus); |
---|
5640 | n/a | if (newmask == NULL) { |
---|
5641 | n/a | PyErr_NoMemory(); |
---|
5642 | n/a | goto error; |
---|
5643 | n/a | } |
---|
5644 | n/a | newsetsize = CPU_ALLOC_SIZE(newncpus); |
---|
5645 | n/a | CPU_ZERO_S(newsetsize, newmask); |
---|
5646 | n/a | memcpy(newmask, cpu_set, setsize); |
---|
5647 | n/a | CPU_FREE(cpu_set); |
---|
5648 | n/a | setsize = newsetsize; |
---|
5649 | n/a | cpu_set = newmask; |
---|
5650 | n/a | ncpus = newncpus; |
---|
5651 | n/a | } |
---|
5652 | n/a | CPU_SET_S(cpu, setsize, cpu_set); |
---|
5653 | n/a | } |
---|
5654 | n/a | Py_CLEAR(iterator); |
---|
5655 | n/a | |
---|
5656 | n/a | if (sched_setaffinity(pid, setsize, cpu_set)) { |
---|
5657 | n/a | posix_error(); |
---|
5658 | n/a | goto error; |
---|
5659 | n/a | } |
---|
5660 | n/a | CPU_FREE(cpu_set); |
---|
5661 | n/a | Py_RETURN_NONE; |
---|
5662 | n/a | |
---|
5663 | n/a | error: |
---|
5664 | n/a | if (cpu_set) |
---|
5665 | n/a | CPU_FREE(cpu_set); |
---|
5666 | n/a | Py_XDECREF(iterator); |
---|
5667 | n/a | return NULL; |
---|
5668 | n/a | } |
---|
5669 | n/a | |
---|
5670 | n/a | |
---|
5671 | n/a | /*[clinic input] |
---|
5672 | n/a | os.sched_getaffinity |
---|
5673 | n/a | pid: pid_t |
---|
5674 | n/a | / |
---|
5675 | n/a | |
---|
5676 | n/a | Return the affinity of the process identified by pid (or the current process if zero). |
---|
5677 | n/a | |
---|
5678 | n/a | The affinity is returned as a set of CPU identifiers. |
---|
5679 | n/a | [clinic start generated code]*/ |
---|
5680 | n/a | |
---|
5681 | n/a | static PyObject * |
---|
5682 | n/a | os_sched_getaffinity_impl(PyObject *module, pid_t pid) |
---|
5683 | n/a | /*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/ |
---|
5684 | n/a | { |
---|
5685 | n/a | int cpu, ncpus, count; |
---|
5686 | n/a | size_t setsize; |
---|
5687 | n/a | cpu_set_t *mask = NULL; |
---|
5688 | n/a | PyObject *res = NULL; |
---|
5689 | n/a | |
---|
5690 | n/a | ncpus = NCPUS_START; |
---|
5691 | n/a | while (1) { |
---|
5692 | n/a | setsize = CPU_ALLOC_SIZE(ncpus); |
---|
5693 | n/a | mask = CPU_ALLOC(ncpus); |
---|
5694 | n/a | if (mask == NULL) |
---|
5695 | n/a | return PyErr_NoMemory(); |
---|
5696 | n/a | if (sched_getaffinity(pid, setsize, mask) == 0) |
---|
5697 | n/a | break; |
---|
5698 | n/a | CPU_FREE(mask); |
---|
5699 | n/a | if (errno != EINVAL) |
---|
5700 | n/a | return posix_error(); |
---|
5701 | n/a | if (ncpus > INT_MAX / 2) { |
---|
5702 | n/a | PyErr_SetString(PyExc_OverflowError, "could not allocate " |
---|
5703 | n/a | "a large enough CPU set"); |
---|
5704 | n/a | return NULL; |
---|
5705 | n/a | } |
---|
5706 | n/a | ncpus = ncpus * 2; |
---|
5707 | n/a | } |
---|
5708 | n/a | |
---|
5709 | n/a | res = PySet_New(NULL); |
---|
5710 | n/a | if (res == NULL) |
---|
5711 | n/a | goto error; |
---|
5712 | n/a | for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) { |
---|
5713 | n/a | if (CPU_ISSET_S(cpu, setsize, mask)) { |
---|
5714 | n/a | PyObject *cpu_num = PyLong_FromLong(cpu); |
---|
5715 | n/a | --count; |
---|
5716 | n/a | if (cpu_num == NULL) |
---|
5717 | n/a | goto error; |
---|
5718 | n/a | if (PySet_Add(res, cpu_num)) { |
---|
5719 | n/a | Py_DECREF(cpu_num); |
---|
5720 | n/a | goto error; |
---|
5721 | n/a | } |
---|
5722 | n/a | Py_DECREF(cpu_num); |
---|
5723 | n/a | } |
---|
5724 | n/a | } |
---|
5725 | n/a | CPU_FREE(mask); |
---|
5726 | n/a | return res; |
---|
5727 | n/a | |
---|
5728 | n/a | error: |
---|
5729 | n/a | if (mask) |
---|
5730 | n/a | CPU_FREE(mask); |
---|
5731 | n/a | Py_XDECREF(res); |
---|
5732 | n/a | return NULL; |
---|
5733 | n/a | } |
---|
5734 | n/a | |
---|
5735 | n/a | #endif /* HAVE_SCHED_SETAFFINITY */ |
---|
5736 | n/a | |
---|
5737 | n/a | #endif /* HAVE_SCHED_H */ |
---|
5738 | n/a | |
---|
5739 | n/a | |
---|
5740 | n/a | /* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */ |
---|
5741 | n/a | /* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */ |
---|
5742 | n/a | #if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX) |
---|
5743 | n/a | #define DEV_PTY_FILE "/dev/ptc" |
---|
5744 | n/a | #define HAVE_DEV_PTMX |
---|
5745 | n/a | #else |
---|
5746 | n/a | #define DEV_PTY_FILE "/dev/ptmx" |
---|
5747 | n/a | #endif |
---|
5748 | n/a | |
---|
5749 | n/a | #if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) |
---|
5750 | n/a | #ifdef HAVE_PTY_H |
---|
5751 | n/a | #include <pty.h> |
---|
5752 | n/a | #else |
---|
5753 | n/a | #ifdef HAVE_LIBUTIL_H |
---|
5754 | n/a | #include <libutil.h> |
---|
5755 | n/a | #else |
---|
5756 | n/a | #ifdef HAVE_UTIL_H |
---|
5757 | n/a | #include <util.h> |
---|
5758 | n/a | #endif /* HAVE_UTIL_H */ |
---|
5759 | n/a | #endif /* HAVE_LIBUTIL_H */ |
---|
5760 | n/a | #endif /* HAVE_PTY_H */ |
---|
5761 | n/a | #ifdef HAVE_STROPTS_H |
---|
5762 | n/a | #include <stropts.h> |
---|
5763 | n/a | #endif |
---|
5764 | n/a | #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */ |
---|
5765 | n/a | |
---|
5766 | n/a | |
---|
5767 | n/a | #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) |
---|
5768 | n/a | /*[clinic input] |
---|
5769 | n/a | os.openpty |
---|
5770 | n/a | |
---|
5771 | n/a | Open a pseudo-terminal. |
---|
5772 | n/a | |
---|
5773 | n/a | Return a tuple of (master_fd, slave_fd) containing open file descriptors |
---|
5774 | n/a | for both the master and slave ends. |
---|
5775 | n/a | [clinic start generated code]*/ |
---|
5776 | n/a | |
---|
5777 | n/a | static PyObject * |
---|
5778 | n/a | os_openpty_impl(PyObject *module) |
---|
5779 | n/a | /*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/ |
---|
5780 | n/a | { |
---|
5781 | n/a | int master_fd = -1, slave_fd = -1; |
---|
5782 | n/a | #ifndef HAVE_OPENPTY |
---|
5783 | n/a | char * slave_name; |
---|
5784 | n/a | #endif |
---|
5785 | n/a | #if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY) |
---|
5786 | n/a | PyOS_sighandler_t sig_saved; |
---|
5787 | n/a | #ifdef sun |
---|
5788 | n/a | extern char *ptsname(int fildes); |
---|
5789 | n/a | #endif |
---|
5790 | n/a | #endif |
---|
5791 | n/a | |
---|
5792 | n/a | #ifdef HAVE_OPENPTY |
---|
5793 | n/a | if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0) |
---|
5794 | n/a | goto posix_error; |
---|
5795 | n/a | |
---|
5796 | n/a | if (_Py_set_inheritable(master_fd, 0, NULL) < 0) |
---|
5797 | n/a | goto error; |
---|
5798 | n/a | if (_Py_set_inheritable(slave_fd, 0, NULL) < 0) |
---|
5799 | n/a | goto error; |
---|
5800 | n/a | |
---|
5801 | n/a | #elif defined(HAVE__GETPTY) |
---|
5802 | n/a | slave_name = _getpty(&master_fd, O_RDWR, 0666, 0); |
---|
5803 | n/a | if (slave_name == NULL) |
---|
5804 | n/a | goto posix_error; |
---|
5805 | n/a | if (_Py_set_inheritable(master_fd, 0, NULL) < 0) |
---|
5806 | n/a | goto error; |
---|
5807 | n/a | |
---|
5808 | n/a | slave_fd = _Py_open(slave_name, O_RDWR); |
---|
5809 | n/a | if (slave_fd < 0) |
---|
5810 | n/a | goto error; |
---|
5811 | n/a | |
---|
5812 | n/a | #else |
---|
5813 | n/a | master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */ |
---|
5814 | n/a | if (master_fd < 0) |
---|
5815 | n/a | goto posix_error; |
---|
5816 | n/a | |
---|
5817 | n/a | sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL); |
---|
5818 | n/a | |
---|
5819 | n/a | /* change permission of slave */ |
---|
5820 | n/a | if (grantpt(master_fd) < 0) { |
---|
5821 | n/a | PyOS_setsig(SIGCHLD, sig_saved); |
---|
5822 | n/a | goto posix_error; |
---|
5823 | n/a | } |
---|
5824 | n/a | |
---|
5825 | n/a | /* unlock slave */ |
---|
5826 | n/a | if (unlockpt(master_fd) < 0) { |
---|
5827 | n/a | PyOS_setsig(SIGCHLD, sig_saved); |
---|
5828 | n/a | goto posix_error; |
---|
5829 | n/a | } |
---|
5830 | n/a | |
---|
5831 | n/a | PyOS_setsig(SIGCHLD, sig_saved); |
---|
5832 | n/a | |
---|
5833 | n/a | slave_name = ptsname(master_fd); /* get name of slave */ |
---|
5834 | n/a | if (slave_name == NULL) |
---|
5835 | n/a | goto posix_error; |
---|
5836 | n/a | |
---|
5837 | n/a | slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */ |
---|
5838 | n/a | if (slave_fd == -1) |
---|
5839 | n/a | goto error; |
---|
5840 | n/a | |
---|
5841 | n/a | if (_Py_set_inheritable(master_fd, 0, NULL) < 0) |
---|
5842 | n/a | goto posix_error; |
---|
5843 | n/a | |
---|
5844 | n/a | #if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC) |
---|
5845 | n/a | ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */ |
---|
5846 | n/a | ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */ |
---|
5847 | n/a | #ifndef __hpux |
---|
5848 | n/a | ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */ |
---|
5849 | n/a | #endif /* __hpux */ |
---|
5850 | n/a | #endif /* HAVE_CYGWIN */ |
---|
5851 | n/a | #endif /* HAVE_OPENPTY */ |
---|
5852 | n/a | |
---|
5853 | n/a | return Py_BuildValue("(ii)", master_fd, slave_fd); |
---|
5854 | n/a | |
---|
5855 | n/a | posix_error: |
---|
5856 | n/a | posix_error(); |
---|
5857 | n/a | error: |
---|
5858 | n/a | if (master_fd != -1) |
---|
5859 | n/a | close(master_fd); |
---|
5860 | n/a | if (slave_fd != -1) |
---|
5861 | n/a | close(slave_fd); |
---|
5862 | n/a | return NULL; |
---|
5863 | n/a | } |
---|
5864 | n/a | #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */ |
---|
5865 | n/a | |
---|
5866 | n/a | |
---|
5867 | n/a | #ifdef HAVE_FORKPTY |
---|
5868 | n/a | /*[clinic input] |
---|
5869 | n/a | os.forkpty |
---|
5870 | n/a | |
---|
5871 | n/a | Fork a new process with a new pseudo-terminal as controlling tty. |
---|
5872 | n/a | |
---|
5873 | n/a | Returns a tuple of (pid, master_fd). |
---|
5874 | n/a | Like fork(), return pid of 0 to the child process, |
---|
5875 | n/a | and pid of child to the parent process. |
---|
5876 | n/a | To both, return fd of newly opened pseudo-terminal. |
---|
5877 | n/a | [clinic start generated code]*/ |
---|
5878 | n/a | |
---|
5879 | n/a | static PyObject * |
---|
5880 | n/a | os_forkpty_impl(PyObject *module) |
---|
5881 | n/a | /*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/ |
---|
5882 | n/a | { |
---|
5883 | n/a | int master_fd = -1, result = 0; |
---|
5884 | n/a | pid_t pid; |
---|
5885 | n/a | |
---|
5886 | n/a | _PyImport_AcquireLock(); |
---|
5887 | n/a | pid = forkpty(&master_fd, NULL, NULL, NULL); |
---|
5888 | n/a | if (pid == 0) { |
---|
5889 | n/a | /* child: this clobbers and resets the import lock. */ |
---|
5890 | n/a | PyOS_AfterFork(); |
---|
5891 | n/a | } else { |
---|
5892 | n/a | /* parent: release the import lock. */ |
---|
5893 | n/a | result = _PyImport_ReleaseLock(); |
---|
5894 | n/a | } |
---|
5895 | n/a | if (pid == -1) |
---|
5896 | n/a | return posix_error(); |
---|
5897 | n/a | if (result < 0) { |
---|
5898 | n/a | /* Don't clobber the OSError if the fork failed. */ |
---|
5899 | n/a | PyErr_SetString(PyExc_RuntimeError, |
---|
5900 | n/a | "not holding the import lock"); |
---|
5901 | n/a | return NULL; |
---|
5902 | n/a | } |
---|
5903 | n/a | return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd); |
---|
5904 | n/a | } |
---|
5905 | n/a | #endif /* HAVE_FORKPTY */ |
---|
5906 | n/a | |
---|
5907 | n/a | |
---|
5908 | n/a | #ifdef HAVE_GETEGID |
---|
5909 | n/a | /*[clinic input] |
---|
5910 | n/a | os.getegid |
---|
5911 | n/a | |
---|
5912 | n/a | Return the current process's effective group id. |
---|
5913 | n/a | [clinic start generated code]*/ |
---|
5914 | n/a | |
---|
5915 | n/a | static PyObject * |
---|
5916 | n/a | os_getegid_impl(PyObject *module) |
---|
5917 | n/a | /*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/ |
---|
5918 | n/a | { |
---|
5919 | n/a | return _PyLong_FromGid(getegid()); |
---|
5920 | n/a | } |
---|
5921 | n/a | #endif /* HAVE_GETEGID */ |
---|
5922 | n/a | |
---|
5923 | n/a | |
---|
5924 | n/a | #ifdef HAVE_GETEUID |
---|
5925 | n/a | /*[clinic input] |
---|
5926 | n/a | os.geteuid |
---|
5927 | n/a | |
---|
5928 | n/a | Return the current process's effective user id. |
---|
5929 | n/a | [clinic start generated code]*/ |
---|
5930 | n/a | |
---|
5931 | n/a | static PyObject * |
---|
5932 | n/a | os_geteuid_impl(PyObject *module) |
---|
5933 | n/a | /*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/ |
---|
5934 | n/a | { |
---|
5935 | n/a | return _PyLong_FromUid(geteuid()); |
---|
5936 | n/a | } |
---|
5937 | n/a | #endif /* HAVE_GETEUID */ |
---|
5938 | n/a | |
---|
5939 | n/a | |
---|
5940 | n/a | #ifdef HAVE_GETGID |
---|
5941 | n/a | /*[clinic input] |
---|
5942 | n/a | os.getgid |
---|
5943 | n/a | |
---|
5944 | n/a | Return the current process's group id. |
---|
5945 | n/a | [clinic start generated code]*/ |
---|
5946 | n/a | |
---|
5947 | n/a | static PyObject * |
---|
5948 | n/a | os_getgid_impl(PyObject *module) |
---|
5949 | n/a | /*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/ |
---|
5950 | n/a | { |
---|
5951 | n/a | return _PyLong_FromGid(getgid()); |
---|
5952 | n/a | } |
---|
5953 | n/a | #endif /* HAVE_GETGID */ |
---|
5954 | n/a | |
---|
5955 | n/a | |
---|
5956 | n/a | #ifdef HAVE_GETPID |
---|
5957 | n/a | /*[clinic input] |
---|
5958 | n/a | os.getpid |
---|
5959 | n/a | |
---|
5960 | n/a | Return the current process id. |
---|
5961 | n/a | [clinic start generated code]*/ |
---|
5962 | n/a | |
---|
5963 | n/a | static PyObject * |
---|
5964 | n/a | os_getpid_impl(PyObject *module) |
---|
5965 | n/a | /*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/ |
---|
5966 | n/a | { |
---|
5967 | n/a | return PyLong_FromPid(getpid()); |
---|
5968 | n/a | } |
---|
5969 | n/a | #endif /* HAVE_GETPID */ |
---|
5970 | n/a | |
---|
5971 | n/a | #ifdef HAVE_GETGROUPLIST |
---|
5972 | n/a | |
---|
5973 | n/a | /* AC 3.5: funny apple logic below */ |
---|
5974 | n/a | PyDoc_STRVAR(posix_getgrouplist__doc__, |
---|
5975 | n/a | "getgrouplist(user, group) -> list of groups to which a user belongs\n\n\ |
---|
5976 | n/a | Returns a list of groups to which a user belongs.\n\n\ |
---|
5977 | n/a | user: username to lookup\n\ |
---|
5978 | n/a | group: base group id of the user"); |
---|
5979 | n/a | |
---|
5980 | n/a | static PyObject * |
---|
5981 | n/a | posix_getgrouplist(PyObject *self, PyObject *args) |
---|
5982 | n/a | { |
---|
5983 | n/a | #ifdef NGROUPS_MAX |
---|
5984 | n/a | #define MAX_GROUPS NGROUPS_MAX |
---|
5985 | n/a | #else |
---|
5986 | n/a | /* defined to be 16 on Solaris7, so this should be a small number */ |
---|
5987 | n/a | #define MAX_GROUPS 64 |
---|
5988 | n/a | #endif |
---|
5989 | n/a | |
---|
5990 | n/a | const char *user; |
---|
5991 | n/a | int i, ngroups; |
---|
5992 | n/a | PyObject *list; |
---|
5993 | n/a | #ifdef __APPLE__ |
---|
5994 | n/a | int *groups, basegid; |
---|
5995 | n/a | #else |
---|
5996 | n/a | gid_t *groups, basegid; |
---|
5997 | n/a | #endif |
---|
5998 | n/a | ngroups = MAX_GROUPS; |
---|
5999 | n/a | |
---|
6000 | n/a | #ifdef __APPLE__ |
---|
6001 | n/a | if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid)) |
---|
6002 | n/a | return NULL; |
---|
6003 | n/a | #else |
---|
6004 | n/a | if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user, |
---|
6005 | n/a | _Py_Gid_Converter, &basegid)) |
---|
6006 | n/a | return NULL; |
---|
6007 | n/a | #endif |
---|
6008 | n/a | |
---|
6009 | n/a | #ifdef __APPLE__ |
---|
6010 | n/a | groups = PyMem_New(int, ngroups); |
---|
6011 | n/a | #else |
---|
6012 | n/a | groups = PyMem_New(gid_t, ngroups); |
---|
6013 | n/a | #endif |
---|
6014 | n/a | if (groups == NULL) |
---|
6015 | n/a | return PyErr_NoMemory(); |
---|
6016 | n/a | |
---|
6017 | n/a | if (getgrouplist(user, basegid, groups, &ngroups) == -1) { |
---|
6018 | n/a | PyMem_Del(groups); |
---|
6019 | n/a | return posix_error(); |
---|
6020 | n/a | } |
---|
6021 | n/a | |
---|
6022 | n/a | list = PyList_New(ngroups); |
---|
6023 | n/a | if (list == NULL) { |
---|
6024 | n/a | PyMem_Del(groups); |
---|
6025 | n/a | return NULL; |
---|
6026 | n/a | } |
---|
6027 | n/a | |
---|
6028 | n/a | for (i = 0; i < ngroups; i++) { |
---|
6029 | n/a | #ifdef __APPLE__ |
---|
6030 | n/a | PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]); |
---|
6031 | n/a | #else |
---|
6032 | n/a | PyObject *o = _PyLong_FromGid(groups[i]); |
---|
6033 | n/a | #endif |
---|
6034 | n/a | if (o == NULL) { |
---|
6035 | n/a | Py_DECREF(list); |
---|
6036 | n/a | PyMem_Del(groups); |
---|
6037 | n/a | return NULL; |
---|
6038 | n/a | } |
---|
6039 | n/a | PyList_SET_ITEM(list, i, o); |
---|
6040 | n/a | } |
---|
6041 | n/a | |
---|
6042 | n/a | PyMem_Del(groups); |
---|
6043 | n/a | |
---|
6044 | n/a | return list; |
---|
6045 | n/a | } |
---|
6046 | n/a | #endif /* HAVE_GETGROUPLIST */ |
---|
6047 | n/a | |
---|
6048 | n/a | |
---|
6049 | n/a | #ifdef HAVE_GETGROUPS |
---|
6050 | n/a | /*[clinic input] |
---|
6051 | n/a | os.getgroups |
---|
6052 | n/a | |
---|
6053 | n/a | Return list of supplemental group IDs for the process. |
---|
6054 | n/a | [clinic start generated code]*/ |
---|
6055 | n/a | |
---|
6056 | n/a | static PyObject * |
---|
6057 | n/a | os_getgroups_impl(PyObject *module) |
---|
6058 | n/a | /*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/ |
---|
6059 | n/a | { |
---|
6060 | n/a | PyObject *result = NULL; |
---|
6061 | n/a | |
---|
6062 | n/a | #ifdef NGROUPS_MAX |
---|
6063 | n/a | #define MAX_GROUPS NGROUPS_MAX |
---|
6064 | n/a | #else |
---|
6065 | n/a | /* defined to be 16 on Solaris7, so this should be a small number */ |
---|
6066 | n/a | #define MAX_GROUPS 64 |
---|
6067 | n/a | #endif |
---|
6068 | n/a | gid_t grouplist[MAX_GROUPS]; |
---|
6069 | n/a | |
---|
6070 | n/a | /* On MacOSX getgroups(2) can return more than MAX_GROUPS results |
---|
6071 | n/a | * This is a helper variable to store the intermediate result when |
---|
6072 | n/a | * that happens. |
---|
6073 | n/a | * |
---|
6074 | n/a | * To keep the code readable the OSX behaviour is unconditional, |
---|
6075 | n/a | * according to the POSIX spec this should be safe on all unix-y |
---|
6076 | n/a | * systems. |
---|
6077 | n/a | */ |
---|
6078 | n/a | gid_t* alt_grouplist = grouplist; |
---|
6079 | n/a | int n; |
---|
6080 | n/a | |
---|
6081 | n/a | #ifdef __APPLE__ |
---|
6082 | n/a | /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if |
---|
6083 | n/a | * there are more groups than can fit in grouplist. Therefore, on OS X |
---|
6084 | n/a | * always first call getgroups with length 0 to get the actual number |
---|
6085 | n/a | * of groups. |
---|
6086 | n/a | */ |
---|
6087 | n/a | n = getgroups(0, NULL); |
---|
6088 | n/a | if (n < 0) { |
---|
6089 | n/a | return posix_error(); |
---|
6090 | n/a | } else if (n <= MAX_GROUPS) { |
---|
6091 | n/a | /* groups will fit in existing array */ |
---|
6092 | n/a | alt_grouplist = grouplist; |
---|
6093 | n/a | } else { |
---|
6094 | n/a | alt_grouplist = PyMem_New(gid_t, n); |
---|
6095 | n/a | if (alt_grouplist == NULL) { |
---|
6096 | n/a | errno = EINVAL; |
---|
6097 | n/a | return posix_error(); |
---|
6098 | n/a | } |
---|
6099 | n/a | } |
---|
6100 | n/a | |
---|
6101 | n/a | n = getgroups(n, alt_grouplist); |
---|
6102 | n/a | if (n == -1) { |
---|
6103 | n/a | if (alt_grouplist != grouplist) { |
---|
6104 | n/a | PyMem_Free(alt_grouplist); |
---|
6105 | n/a | } |
---|
6106 | n/a | return posix_error(); |
---|
6107 | n/a | } |
---|
6108 | n/a | #else |
---|
6109 | n/a | n = getgroups(MAX_GROUPS, grouplist); |
---|
6110 | n/a | if (n < 0) { |
---|
6111 | n/a | if (errno == EINVAL) { |
---|
6112 | n/a | n = getgroups(0, NULL); |
---|
6113 | n/a | if (n == -1) { |
---|
6114 | n/a | return posix_error(); |
---|
6115 | n/a | } |
---|
6116 | n/a | if (n == 0) { |
---|
6117 | n/a | /* Avoid malloc(0) */ |
---|
6118 | n/a | alt_grouplist = grouplist; |
---|
6119 | n/a | } else { |
---|
6120 | n/a | alt_grouplist = PyMem_New(gid_t, n); |
---|
6121 | n/a | if (alt_grouplist == NULL) { |
---|
6122 | n/a | errno = EINVAL; |
---|
6123 | n/a | return posix_error(); |
---|
6124 | n/a | } |
---|
6125 | n/a | n = getgroups(n, alt_grouplist); |
---|
6126 | n/a | if (n == -1) { |
---|
6127 | n/a | PyMem_Free(alt_grouplist); |
---|
6128 | n/a | return posix_error(); |
---|
6129 | n/a | } |
---|
6130 | n/a | } |
---|
6131 | n/a | } else { |
---|
6132 | n/a | return posix_error(); |
---|
6133 | n/a | } |
---|
6134 | n/a | } |
---|
6135 | n/a | #endif |
---|
6136 | n/a | |
---|
6137 | n/a | result = PyList_New(n); |
---|
6138 | n/a | if (result != NULL) { |
---|
6139 | n/a | int i; |
---|
6140 | n/a | for (i = 0; i < n; ++i) { |
---|
6141 | n/a | PyObject *o = _PyLong_FromGid(alt_grouplist[i]); |
---|
6142 | n/a | if (o == NULL) { |
---|
6143 | n/a | Py_DECREF(result); |
---|
6144 | n/a | result = NULL; |
---|
6145 | n/a | break; |
---|
6146 | n/a | } |
---|
6147 | n/a | PyList_SET_ITEM(result, i, o); |
---|
6148 | n/a | } |
---|
6149 | n/a | } |
---|
6150 | n/a | |
---|
6151 | n/a | if (alt_grouplist != grouplist) { |
---|
6152 | n/a | PyMem_Free(alt_grouplist); |
---|
6153 | n/a | } |
---|
6154 | n/a | |
---|
6155 | n/a | return result; |
---|
6156 | n/a | } |
---|
6157 | n/a | #endif /* HAVE_GETGROUPS */ |
---|
6158 | n/a | |
---|
6159 | n/a | #ifdef HAVE_INITGROUPS |
---|
6160 | n/a | PyDoc_STRVAR(posix_initgroups__doc__, |
---|
6161 | n/a | "initgroups(username, gid) -> None\n\n\ |
---|
6162 | n/a | Call the system initgroups() to initialize the group access list with all of\n\ |
---|
6163 | n/a | the groups of which the specified username is a member, plus the specified\n\ |
---|
6164 | n/a | group id."); |
---|
6165 | n/a | |
---|
6166 | n/a | /* AC 3.5: funny apple logic */ |
---|
6167 | n/a | static PyObject * |
---|
6168 | n/a | posix_initgroups(PyObject *self, PyObject *args) |
---|
6169 | n/a | { |
---|
6170 | n/a | PyObject *oname; |
---|
6171 | n/a | const char *username; |
---|
6172 | n/a | int res; |
---|
6173 | n/a | #ifdef __APPLE__ |
---|
6174 | n/a | int gid; |
---|
6175 | n/a | #else |
---|
6176 | n/a | gid_t gid; |
---|
6177 | n/a | #endif |
---|
6178 | n/a | |
---|
6179 | n/a | #ifdef __APPLE__ |
---|
6180 | n/a | if (!PyArg_ParseTuple(args, "O&i:initgroups", |
---|
6181 | n/a | PyUnicode_FSConverter, &oname, |
---|
6182 | n/a | &gid)) |
---|
6183 | n/a | #else |
---|
6184 | n/a | if (!PyArg_ParseTuple(args, "O&O&:initgroups", |
---|
6185 | n/a | PyUnicode_FSConverter, &oname, |
---|
6186 | n/a | _Py_Gid_Converter, &gid)) |
---|
6187 | n/a | #endif |
---|
6188 | n/a | return NULL; |
---|
6189 | n/a | username = PyBytes_AS_STRING(oname); |
---|
6190 | n/a | |
---|
6191 | n/a | res = initgroups(username, gid); |
---|
6192 | n/a | Py_DECREF(oname); |
---|
6193 | n/a | if (res == -1) |
---|
6194 | n/a | return PyErr_SetFromErrno(PyExc_OSError); |
---|
6195 | n/a | |
---|
6196 | n/a | Py_RETURN_NONE; |
---|
6197 | n/a | } |
---|
6198 | n/a | #endif /* HAVE_INITGROUPS */ |
---|
6199 | n/a | |
---|
6200 | n/a | |
---|
6201 | n/a | #ifdef HAVE_GETPGID |
---|
6202 | n/a | /*[clinic input] |
---|
6203 | n/a | os.getpgid |
---|
6204 | n/a | |
---|
6205 | n/a | pid: pid_t |
---|
6206 | n/a | |
---|
6207 | n/a | Call the system call getpgid(), and return the result. |
---|
6208 | n/a | [clinic start generated code]*/ |
---|
6209 | n/a | |
---|
6210 | n/a | static PyObject * |
---|
6211 | n/a | os_getpgid_impl(PyObject *module, pid_t pid) |
---|
6212 | n/a | /*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/ |
---|
6213 | n/a | { |
---|
6214 | n/a | pid_t pgid = getpgid(pid); |
---|
6215 | n/a | if (pgid < 0) |
---|
6216 | n/a | return posix_error(); |
---|
6217 | n/a | return PyLong_FromPid(pgid); |
---|
6218 | n/a | } |
---|
6219 | n/a | #endif /* HAVE_GETPGID */ |
---|
6220 | n/a | |
---|
6221 | n/a | |
---|
6222 | n/a | #ifdef HAVE_GETPGRP |
---|
6223 | n/a | /*[clinic input] |
---|
6224 | n/a | os.getpgrp |
---|
6225 | n/a | |
---|
6226 | n/a | Return the current process group id. |
---|
6227 | n/a | [clinic start generated code]*/ |
---|
6228 | n/a | |
---|
6229 | n/a | static PyObject * |
---|
6230 | n/a | os_getpgrp_impl(PyObject *module) |
---|
6231 | n/a | /*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/ |
---|
6232 | n/a | { |
---|
6233 | n/a | #ifdef GETPGRP_HAVE_ARG |
---|
6234 | n/a | return PyLong_FromPid(getpgrp(0)); |
---|
6235 | n/a | #else /* GETPGRP_HAVE_ARG */ |
---|
6236 | n/a | return PyLong_FromPid(getpgrp()); |
---|
6237 | n/a | #endif /* GETPGRP_HAVE_ARG */ |
---|
6238 | n/a | } |
---|
6239 | n/a | #endif /* HAVE_GETPGRP */ |
---|
6240 | n/a | |
---|
6241 | n/a | |
---|
6242 | n/a | #ifdef HAVE_SETPGRP |
---|
6243 | n/a | /*[clinic input] |
---|
6244 | n/a | os.setpgrp |
---|
6245 | n/a | |
---|
6246 | n/a | Make the current process the leader of its process group. |
---|
6247 | n/a | [clinic start generated code]*/ |
---|
6248 | n/a | |
---|
6249 | n/a | static PyObject * |
---|
6250 | n/a | os_setpgrp_impl(PyObject *module) |
---|
6251 | n/a | /*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/ |
---|
6252 | n/a | { |
---|
6253 | n/a | #ifdef SETPGRP_HAVE_ARG |
---|
6254 | n/a | if (setpgrp(0, 0) < 0) |
---|
6255 | n/a | #else /* SETPGRP_HAVE_ARG */ |
---|
6256 | n/a | if (setpgrp() < 0) |
---|
6257 | n/a | #endif /* SETPGRP_HAVE_ARG */ |
---|
6258 | n/a | return posix_error(); |
---|
6259 | n/a | Py_RETURN_NONE; |
---|
6260 | n/a | } |
---|
6261 | n/a | #endif /* HAVE_SETPGRP */ |
---|
6262 | n/a | |
---|
6263 | n/a | #ifdef HAVE_GETPPID |
---|
6264 | n/a | |
---|
6265 | n/a | #ifdef MS_WINDOWS |
---|
6266 | n/a | #include <tlhelp32.h> |
---|
6267 | n/a | |
---|
6268 | n/a | static PyObject* |
---|
6269 | n/a | win32_getppid() |
---|
6270 | n/a | { |
---|
6271 | n/a | HANDLE snapshot; |
---|
6272 | n/a | pid_t mypid; |
---|
6273 | n/a | PyObject* result = NULL; |
---|
6274 | n/a | BOOL have_record; |
---|
6275 | n/a | PROCESSENTRY32 pe; |
---|
6276 | n/a | |
---|
6277 | n/a | mypid = getpid(); /* This function never fails */ |
---|
6278 | n/a | |
---|
6279 | n/a | snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); |
---|
6280 | n/a | if (snapshot == INVALID_HANDLE_VALUE) |
---|
6281 | n/a | return PyErr_SetFromWindowsErr(GetLastError()); |
---|
6282 | n/a | |
---|
6283 | n/a | pe.dwSize = sizeof(pe); |
---|
6284 | n/a | have_record = Process32First(snapshot, &pe); |
---|
6285 | n/a | while (have_record) { |
---|
6286 | n/a | if (mypid == (pid_t)pe.th32ProcessID) { |
---|
6287 | n/a | /* We could cache the ulong value in a static variable. */ |
---|
6288 | n/a | result = PyLong_FromPid((pid_t)pe.th32ParentProcessID); |
---|
6289 | n/a | break; |
---|
6290 | n/a | } |
---|
6291 | n/a | |
---|
6292 | n/a | have_record = Process32Next(snapshot, &pe); |
---|
6293 | n/a | } |
---|
6294 | n/a | |
---|
6295 | n/a | /* If our loop exits and our pid was not found (result will be NULL) |
---|
6296 | n/a | * then GetLastError will return ERROR_NO_MORE_FILES. This is an |
---|
6297 | n/a | * error anyway, so let's raise it. */ |
---|
6298 | n/a | if (!result) |
---|
6299 | n/a | result = PyErr_SetFromWindowsErr(GetLastError()); |
---|
6300 | n/a | |
---|
6301 | n/a | CloseHandle(snapshot); |
---|
6302 | n/a | |
---|
6303 | n/a | return result; |
---|
6304 | n/a | } |
---|
6305 | n/a | #endif /*MS_WINDOWS*/ |
---|
6306 | n/a | |
---|
6307 | n/a | |
---|
6308 | n/a | /*[clinic input] |
---|
6309 | n/a | os.getppid |
---|
6310 | n/a | |
---|
6311 | n/a | Return the parent's process id. |
---|
6312 | n/a | |
---|
6313 | n/a | If the parent process has already exited, Windows machines will still |
---|
6314 | n/a | return its id; others systems will return the id of the 'init' process (1). |
---|
6315 | n/a | [clinic start generated code]*/ |
---|
6316 | n/a | |
---|
6317 | n/a | static PyObject * |
---|
6318 | n/a | os_getppid_impl(PyObject *module) |
---|
6319 | n/a | /*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/ |
---|
6320 | n/a | { |
---|
6321 | n/a | #ifdef MS_WINDOWS |
---|
6322 | n/a | return win32_getppid(); |
---|
6323 | n/a | #else |
---|
6324 | n/a | return PyLong_FromPid(getppid()); |
---|
6325 | n/a | #endif |
---|
6326 | n/a | } |
---|
6327 | n/a | #endif /* HAVE_GETPPID */ |
---|
6328 | n/a | |
---|
6329 | n/a | |
---|
6330 | n/a | #ifdef HAVE_GETLOGIN |
---|
6331 | n/a | /*[clinic input] |
---|
6332 | n/a | os.getlogin |
---|
6333 | n/a | |
---|
6334 | n/a | Return the actual login name. |
---|
6335 | n/a | [clinic start generated code]*/ |
---|
6336 | n/a | |
---|
6337 | n/a | static PyObject * |
---|
6338 | n/a | os_getlogin_impl(PyObject *module) |
---|
6339 | n/a | /*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/ |
---|
6340 | n/a | { |
---|
6341 | n/a | PyObject *result = NULL; |
---|
6342 | n/a | #ifdef MS_WINDOWS |
---|
6343 | n/a | wchar_t user_name[UNLEN + 1]; |
---|
6344 | n/a | DWORD num_chars = Py_ARRAY_LENGTH(user_name); |
---|
6345 | n/a | |
---|
6346 | n/a | if (GetUserNameW(user_name, &num_chars)) { |
---|
6347 | n/a | /* num_chars is the number of unicode chars plus null terminator */ |
---|
6348 | n/a | result = PyUnicode_FromWideChar(user_name, num_chars - 1); |
---|
6349 | n/a | } |
---|
6350 | n/a | else |
---|
6351 | n/a | result = PyErr_SetFromWindowsErr(GetLastError()); |
---|
6352 | n/a | #else |
---|
6353 | n/a | char *name; |
---|
6354 | n/a | int old_errno = errno; |
---|
6355 | n/a | |
---|
6356 | n/a | errno = 0; |
---|
6357 | n/a | name = getlogin(); |
---|
6358 | n/a | if (name == NULL) { |
---|
6359 | n/a | if (errno) |
---|
6360 | n/a | posix_error(); |
---|
6361 | n/a | else |
---|
6362 | n/a | PyErr_SetString(PyExc_OSError, "unable to determine login name"); |
---|
6363 | n/a | } |
---|
6364 | n/a | else |
---|
6365 | n/a | result = PyUnicode_DecodeFSDefault(name); |
---|
6366 | n/a | errno = old_errno; |
---|
6367 | n/a | #endif |
---|
6368 | n/a | return result; |
---|
6369 | n/a | } |
---|
6370 | n/a | #endif /* HAVE_GETLOGIN */ |
---|
6371 | n/a | |
---|
6372 | n/a | |
---|
6373 | n/a | #ifdef HAVE_GETUID |
---|
6374 | n/a | /*[clinic input] |
---|
6375 | n/a | os.getuid |
---|
6376 | n/a | |
---|
6377 | n/a | Return the current process's user id. |
---|
6378 | n/a | [clinic start generated code]*/ |
---|
6379 | n/a | |
---|
6380 | n/a | static PyObject * |
---|
6381 | n/a | os_getuid_impl(PyObject *module) |
---|
6382 | n/a | /*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/ |
---|
6383 | n/a | { |
---|
6384 | n/a | return _PyLong_FromUid(getuid()); |
---|
6385 | n/a | } |
---|
6386 | n/a | #endif /* HAVE_GETUID */ |
---|
6387 | n/a | |
---|
6388 | n/a | |
---|
6389 | n/a | #ifdef MS_WINDOWS |
---|
6390 | n/a | #define HAVE_KILL |
---|
6391 | n/a | #endif /* MS_WINDOWS */ |
---|
6392 | n/a | |
---|
6393 | n/a | #ifdef HAVE_KILL |
---|
6394 | n/a | /*[clinic input] |
---|
6395 | n/a | os.kill |
---|
6396 | n/a | |
---|
6397 | n/a | pid: pid_t |
---|
6398 | n/a | signal: Py_ssize_t |
---|
6399 | n/a | / |
---|
6400 | n/a | |
---|
6401 | n/a | Kill a process with a signal. |
---|
6402 | n/a | [clinic start generated code]*/ |
---|
6403 | n/a | |
---|
6404 | n/a | static PyObject * |
---|
6405 | n/a | os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal) |
---|
6406 | n/a | /*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/ |
---|
6407 | n/a | #ifndef MS_WINDOWS |
---|
6408 | n/a | { |
---|
6409 | n/a | if (kill(pid, (int)signal) == -1) |
---|
6410 | n/a | return posix_error(); |
---|
6411 | n/a | Py_RETURN_NONE; |
---|
6412 | n/a | } |
---|
6413 | n/a | #else /* !MS_WINDOWS */ |
---|
6414 | n/a | { |
---|
6415 | n/a | PyObject *result; |
---|
6416 | n/a | DWORD sig = (DWORD)signal; |
---|
6417 | n/a | DWORD err; |
---|
6418 | n/a | HANDLE handle; |
---|
6419 | n/a | |
---|
6420 | n/a | /* Console processes which share a common console can be sent CTRL+C or |
---|
6421 | n/a | CTRL+BREAK events, provided they handle said events. */ |
---|
6422 | n/a | if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) { |
---|
6423 | n/a | if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) { |
---|
6424 | n/a | err = GetLastError(); |
---|
6425 | n/a | PyErr_SetFromWindowsErr(err); |
---|
6426 | n/a | } |
---|
6427 | n/a | else |
---|
6428 | n/a | Py_RETURN_NONE; |
---|
6429 | n/a | } |
---|
6430 | n/a | |
---|
6431 | n/a | /* If the signal is outside of what GenerateConsoleCtrlEvent can use, |
---|
6432 | n/a | attempt to open and terminate the process. */ |
---|
6433 | n/a | handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid); |
---|
6434 | n/a | if (handle == NULL) { |
---|
6435 | n/a | err = GetLastError(); |
---|
6436 | n/a | return PyErr_SetFromWindowsErr(err); |
---|
6437 | n/a | } |
---|
6438 | n/a | |
---|
6439 | n/a | if (TerminateProcess(handle, sig) == 0) { |
---|
6440 | n/a | err = GetLastError(); |
---|
6441 | n/a | result = PyErr_SetFromWindowsErr(err); |
---|
6442 | n/a | } else { |
---|
6443 | n/a | Py_INCREF(Py_None); |
---|
6444 | n/a | result = Py_None; |
---|
6445 | n/a | } |
---|
6446 | n/a | |
---|
6447 | n/a | CloseHandle(handle); |
---|
6448 | n/a | return result; |
---|
6449 | n/a | } |
---|
6450 | n/a | #endif /* !MS_WINDOWS */ |
---|
6451 | n/a | #endif /* HAVE_KILL */ |
---|
6452 | n/a | |
---|
6453 | n/a | |
---|
6454 | n/a | #ifdef HAVE_KILLPG |
---|
6455 | n/a | /*[clinic input] |
---|
6456 | n/a | os.killpg |
---|
6457 | n/a | |
---|
6458 | n/a | pgid: pid_t |
---|
6459 | n/a | signal: int |
---|
6460 | n/a | / |
---|
6461 | n/a | |
---|
6462 | n/a | Kill a process group with a signal. |
---|
6463 | n/a | [clinic start generated code]*/ |
---|
6464 | n/a | |
---|
6465 | n/a | static PyObject * |
---|
6466 | n/a | os_killpg_impl(PyObject *module, pid_t pgid, int signal) |
---|
6467 | n/a | /*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/ |
---|
6468 | n/a | { |
---|
6469 | n/a | /* XXX some man pages make the `pgid` parameter an int, others |
---|
6470 | n/a | a pid_t. Since getpgrp() returns a pid_t, we assume killpg should |
---|
6471 | n/a | take the same type. Moreover, pid_t is always at least as wide as |
---|
6472 | n/a | int (else compilation of this module fails), which is safe. */ |
---|
6473 | n/a | if (killpg(pgid, signal) == -1) |
---|
6474 | n/a | return posix_error(); |
---|
6475 | n/a | Py_RETURN_NONE; |
---|
6476 | n/a | } |
---|
6477 | n/a | #endif /* HAVE_KILLPG */ |
---|
6478 | n/a | |
---|
6479 | n/a | |
---|
6480 | n/a | #ifdef HAVE_PLOCK |
---|
6481 | n/a | #ifdef HAVE_SYS_LOCK_H |
---|
6482 | n/a | #include <sys/lock.h> |
---|
6483 | n/a | #endif |
---|
6484 | n/a | |
---|
6485 | n/a | /*[clinic input] |
---|
6486 | n/a | os.plock |
---|
6487 | n/a | op: int |
---|
6488 | n/a | / |
---|
6489 | n/a | |
---|
6490 | n/a | Lock program segments into memory."); |
---|
6491 | n/a | [clinic start generated code]*/ |
---|
6492 | n/a | |
---|
6493 | n/a | static PyObject * |
---|
6494 | n/a | os_plock_impl(PyObject *module, int op) |
---|
6495 | n/a | /*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/ |
---|
6496 | n/a | { |
---|
6497 | n/a | if (plock(op) == -1) |
---|
6498 | n/a | return posix_error(); |
---|
6499 | n/a | Py_RETURN_NONE; |
---|
6500 | n/a | } |
---|
6501 | n/a | #endif /* HAVE_PLOCK */ |
---|
6502 | n/a | |
---|
6503 | n/a | |
---|
6504 | n/a | #ifdef HAVE_SETUID |
---|
6505 | n/a | /*[clinic input] |
---|
6506 | n/a | os.setuid |
---|
6507 | n/a | |
---|
6508 | n/a | uid: uid_t |
---|
6509 | n/a | / |
---|
6510 | n/a | |
---|
6511 | n/a | Set the current process's user id. |
---|
6512 | n/a | [clinic start generated code]*/ |
---|
6513 | n/a | |
---|
6514 | n/a | static PyObject * |
---|
6515 | n/a | os_setuid_impl(PyObject *module, uid_t uid) |
---|
6516 | n/a | /*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/ |
---|
6517 | n/a | { |
---|
6518 | n/a | if (setuid(uid) < 0) |
---|
6519 | n/a | return posix_error(); |
---|
6520 | n/a | Py_RETURN_NONE; |
---|
6521 | n/a | } |
---|
6522 | n/a | #endif /* HAVE_SETUID */ |
---|
6523 | n/a | |
---|
6524 | n/a | |
---|
6525 | n/a | #ifdef HAVE_SETEUID |
---|
6526 | n/a | /*[clinic input] |
---|
6527 | n/a | os.seteuid |
---|
6528 | n/a | |
---|
6529 | n/a | euid: uid_t |
---|
6530 | n/a | / |
---|
6531 | n/a | |
---|
6532 | n/a | Set the current process's effective user id. |
---|
6533 | n/a | [clinic start generated code]*/ |
---|
6534 | n/a | |
---|
6535 | n/a | static PyObject * |
---|
6536 | n/a | os_seteuid_impl(PyObject *module, uid_t euid) |
---|
6537 | n/a | /*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/ |
---|
6538 | n/a | { |
---|
6539 | n/a | if (seteuid(euid) < 0) |
---|
6540 | n/a | return posix_error(); |
---|
6541 | n/a | Py_RETURN_NONE; |
---|
6542 | n/a | } |
---|
6543 | n/a | #endif /* HAVE_SETEUID */ |
---|
6544 | n/a | |
---|
6545 | n/a | |
---|
6546 | n/a | #ifdef HAVE_SETEGID |
---|
6547 | n/a | /*[clinic input] |
---|
6548 | n/a | os.setegid |
---|
6549 | n/a | |
---|
6550 | n/a | egid: gid_t |
---|
6551 | n/a | / |
---|
6552 | n/a | |
---|
6553 | n/a | Set the current process's effective group id. |
---|
6554 | n/a | [clinic start generated code]*/ |
---|
6555 | n/a | |
---|
6556 | n/a | static PyObject * |
---|
6557 | n/a | os_setegid_impl(PyObject *module, gid_t egid) |
---|
6558 | n/a | /*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/ |
---|
6559 | n/a | { |
---|
6560 | n/a | if (setegid(egid) < 0) |
---|
6561 | n/a | return posix_error(); |
---|
6562 | n/a | Py_RETURN_NONE; |
---|
6563 | n/a | } |
---|
6564 | n/a | #endif /* HAVE_SETEGID */ |
---|
6565 | n/a | |
---|
6566 | n/a | |
---|
6567 | n/a | #ifdef HAVE_SETREUID |
---|
6568 | n/a | /*[clinic input] |
---|
6569 | n/a | os.setreuid |
---|
6570 | n/a | |
---|
6571 | n/a | ruid: uid_t |
---|
6572 | n/a | euid: uid_t |
---|
6573 | n/a | / |
---|
6574 | n/a | |
---|
6575 | n/a | Set the current process's real and effective user ids. |
---|
6576 | n/a | [clinic start generated code]*/ |
---|
6577 | n/a | |
---|
6578 | n/a | static PyObject * |
---|
6579 | n/a | os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid) |
---|
6580 | n/a | /*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/ |
---|
6581 | n/a | { |
---|
6582 | n/a | if (setreuid(ruid, euid) < 0) { |
---|
6583 | n/a | return posix_error(); |
---|
6584 | n/a | } else { |
---|
6585 | n/a | Py_RETURN_NONE; |
---|
6586 | n/a | } |
---|
6587 | n/a | } |
---|
6588 | n/a | #endif /* HAVE_SETREUID */ |
---|
6589 | n/a | |
---|
6590 | n/a | |
---|
6591 | n/a | #ifdef HAVE_SETREGID |
---|
6592 | n/a | /*[clinic input] |
---|
6593 | n/a | os.setregid |
---|
6594 | n/a | |
---|
6595 | n/a | rgid: gid_t |
---|
6596 | n/a | egid: gid_t |
---|
6597 | n/a | / |
---|
6598 | n/a | |
---|
6599 | n/a | Set the current process's real and effective group ids. |
---|
6600 | n/a | [clinic start generated code]*/ |
---|
6601 | n/a | |
---|
6602 | n/a | static PyObject * |
---|
6603 | n/a | os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid) |
---|
6604 | n/a | /*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/ |
---|
6605 | n/a | { |
---|
6606 | n/a | if (setregid(rgid, egid) < 0) |
---|
6607 | n/a | return posix_error(); |
---|
6608 | n/a | Py_RETURN_NONE; |
---|
6609 | n/a | } |
---|
6610 | n/a | #endif /* HAVE_SETREGID */ |
---|
6611 | n/a | |
---|
6612 | n/a | |
---|
6613 | n/a | #ifdef HAVE_SETGID |
---|
6614 | n/a | /*[clinic input] |
---|
6615 | n/a | os.setgid |
---|
6616 | n/a | gid: gid_t |
---|
6617 | n/a | / |
---|
6618 | n/a | |
---|
6619 | n/a | Set the current process's group id. |
---|
6620 | n/a | [clinic start generated code]*/ |
---|
6621 | n/a | |
---|
6622 | n/a | static PyObject * |
---|
6623 | n/a | os_setgid_impl(PyObject *module, gid_t gid) |
---|
6624 | n/a | /*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/ |
---|
6625 | n/a | { |
---|
6626 | n/a | if (setgid(gid) < 0) |
---|
6627 | n/a | return posix_error(); |
---|
6628 | n/a | Py_RETURN_NONE; |
---|
6629 | n/a | } |
---|
6630 | n/a | #endif /* HAVE_SETGID */ |
---|
6631 | n/a | |
---|
6632 | n/a | |
---|
6633 | n/a | #ifdef HAVE_SETGROUPS |
---|
6634 | n/a | /*[clinic input] |
---|
6635 | n/a | os.setgroups |
---|
6636 | n/a | |
---|
6637 | n/a | groups: object |
---|
6638 | n/a | / |
---|
6639 | n/a | |
---|
6640 | n/a | Set the groups of the current process to list. |
---|
6641 | n/a | [clinic start generated code]*/ |
---|
6642 | n/a | |
---|
6643 | n/a | static PyObject * |
---|
6644 | n/a | os_setgroups(PyObject *module, PyObject *groups) |
---|
6645 | n/a | /*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/ |
---|
6646 | n/a | { |
---|
6647 | n/a | int i, len; |
---|
6648 | n/a | gid_t grouplist[MAX_GROUPS]; |
---|
6649 | n/a | |
---|
6650 | n/a | if (!PySequence_Check(groups)) { |
---|
6651 | n/a | PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence"); |
---|
6652 | n/a | return NULL; |
---|
6653 | n/a | } |
---|
6654 | n/a | len = PySequence_Size(groups); |
---|
6655 | n/a | if (len > MAX_GROUPS) { |
---|
6656 | n/a | PyErr_SetString(PyExc_ValueError, "too many groups"); |
---|
6657 | n/a | return NULL; |
---|
6658 | n/a | } |
---|
6659 | n/a | for(i = 0; i < len; i++) { |
---|
6660 | n/a | PyObject *elem; |
---|
6661 | n/a | elem = PySequence_GetItem(groups, i); |
---|
6662 | n/a | if (!elem) |
---|
6663 | n/a | return NULL; |
---|
6664 | n/a | if (!PyLong_Check(elem)) { |
---|
6665 | n/a | PyErr_SetString(PyExc_TypeError, |
---|
6666 | n/a | "groups must be integers"); |
---|
6667 | n/a | Py_DECREF(elem); |
---|
6668 | n/a | return NULL; |
---|
6669 | n/a | } else { |
---|
6670 | n/a | if (!_Py_Gid_Converter(elem, &grouplist[i])) { |
---|
6671 | n/a | Py_DECREF(elem); |
---|
6672 | n/a | return NULL; |
---|
6673 | n/a | } |
---|
6674 | n/a | } |
---|
6675 | n/a | Py_DECREF(elem); |
---|
6676 | n/a | } |
---|
6677 | n/a | |
---|
6678 | n/a | if (setgroups(len, grouplist) < 0) |
---|
6679 | n/a | return posix_error(); |
---|
6680 | n/a | Py_RETURN_NONE; |
---|
6681 | n/a | } |
---|
6682 | n/a | #endif /* HAVE_SETGROUPS */ |
---|
6683 | n/a | |
---|
6684 | n/a | #if defined(HAVE_WAIT3) || defined(HAVE_WAIT4) |
---|
6685 | n/a | static PyObject * |
---|
6686 | n/a | wait_helper(pid_t pid, int status, struct rusage *ru) |
---|
6687 | n/a | { |
---|
6688 | n/a | PyObject *result; |
---|
6689 | n/a | static PyObject *struct_rusage; |
---|
6690 | n/a | _Py_IDENTIFIER(struct_rusage); |
---|
6691 | n/a | |
---|
6692 | n/a | if (pid == -1) |
---|
6693 | n/a | return posix_error(); |
---|
6694 | n/a | |
---|
6695 | n/a | if (struct_rusage == NULL) { |
---|
6696 | n/a | PyObject *m = PyImport_ImportModuleNoBlock("resource"); |
---|
6697 | n/a | if (m == NULL) |
---|
6698 | n/a | return NULL; |
---|
6699 | n/a | struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage); |
---|
6700 | n/a | Py_DECREF(m); |
---|
6701 | n/a | if (struct_rusage == NULL) |
---|
6702 | n/a | return NULL; |
---|
6703 | n/a | } |
---|
6704 | n/a | |
---|
6705 | n/a | /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */ |
---|
6706 | n/a | result = PyStructSequence_New((PyTypeObject*) struct_rusage); |
---|
6707 | n/a | if (!result) |
---|
6708 | n/a | return NULL; |
---|
6709 | n/a | |
---|
6710 | n/a | #ifndef doubletime |
---|
6711 | n/a | #define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001) |
---|
6712 | n/a | #endif |
---|
6713 | n/a | |
---|
6714 | n/a | PyStructSequence_SET_ITEM(result, 0, |
---|
6715 | n/a | PyFloat_FromDouble(doubletime(ru->ru_utime))); |
---|
6716 | n/a | PyStructSequence_SET_ITEM(result, 1, |
---|
6717 | n/a | PyFloat_FromDouble(doubletime(ru->ru_stime))); |
---|
6718 | n/a | #define SET_INT(result, index, value)\ |
---|
6719 | n/a | PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value)) |
---|
6720 | n/a | SET_INT(result, 2, ru->ru_maxrss); |
---|
6721 | n/a | SET_INT(result, 3, ru->ru_ixrss); |
---|
6722 | n/a | SET_INT(result, 4, ru->ru_idrss); |
---|
6723 | n/a | SET_INT(result, 5, ru->ru_isrss); |
---|
6724 | n/a | SET_INT(result, 6, ru->ru_minflt); |
---|
6725 | n/a | SET_INT(result, 7, ru->ru_majflt); |
---|
6726 | n/a | SET_INT(result, 8, ru->ru_nswap); |
---|
6727 | n/a | SET_INT(result, 9, ru->ru_inblock); |
---|
6728 | n/a | SET_INT(result, 10, ru->ru_oublock); |
---|
6729 | n/a | SET_INT(result, 11, ru->ru_msgsnd); |
---|
6730 | n/a | SET_INT(result, 12, ru->ru_msgrcv); |
---|
6731 | n/a | SET_INT(result, 13, ru->ru_nsignals); |
---|
6732 | n/a | SET_INT(result, 14, ru->ru_nvcsw); |
---|
6733 | n/a | SET_INT(result, 15, ru->ru_nivcsw); |
---|
6734 | n/a | #undef SET_INT |
---|
6735 | n/a | |
---|
6736 | n/a | if (PyErr_Occurred()) { |
---|
6737 | n/a | Py_DECREF(result); |
---|
6738 | n/a | return NULL; |
---|
6739 | n/a | } |
---|
6740 | n/a | |
---|
6741 | n/a | return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result); |
---|
6742 | n/a | } |
---|
6743 | n/a | #endif /* HAVE_WAIT3 || HAVE_WAIT4 */ |
---|
6744 | n/a | |
---|
6745 | n/a | |
---|
6746 | n/a | #ifdef HAVE_WAIT3 |
---|
6747 | n/a | /*[clinic input] |
---|
6748 | n/a | os.wait3 |
---|
6749 | n/a | |
---|
6750 | n/a | options: int |
---|
6751 | n/a | Wait for completion of a child process. |
---|
6752 | n/a | |
---|
6753 | n/a | Returns a tuple of information about the child process: |
---|
6754 | n/a | (pid, status, rusage) |
---|
6755 | n/a | [clinic start generated code]*/ |
---|
6756 | n/a | |
---|
6757 | n/a | static PyObject * |
---|
6758 | n/a | os_wait3_impl(PyObject *module, int options) |
---|
6759 | n/a | /*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/ |
---|
6760 | n/a | { |
---|
6761 | n/a | pid_t pid; |
---|
6762 | n/a | struct rusage ru; |
---|
6763 | n/a | int async_err = 0; |
---|
6764 | n/a | WAIT_TYPE status; |
---|
6765 | n/a | WAIT_STATUS_INT(status) = 0; |
---|
6766 | n/a | |
---|
6767 | n/a | do { |
---|
6768 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
6769 | n/a | pid = wait3(&status, options, &ru); |
---|
6770 | n/a | Py_END_ALLOW_THREADS |
---|
6771 | n/a | } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); |
---|
6772 | n/a | if (pid < 0) |
---|
6773 | n/a | return (!async_err) ? posix_error() : NULL; |
---|
6774 | n/a | |
---|
6775 | n/a | return wait_helper(pid, WAIT_STATUS_INT(status), &ru); |
---|
6776 | n/a | } |
---|
6777 | n/a | #endif /* HAVE_WAIT3 */ |
---|
6778 | n/a | |
---|
6779 | n/a | |
---|
6780 | n/a | #ifdef HAVE_WAIT4 |
---|
6781 | n/a | /*[clinic input] |
---|
6782 | n/a | |
---|
6783 | n/a | os.wait4 |
---|
6784 | n/a | |
---|
6785 | n/a | pid: pid_t |
---|
6786 | n/a | options: int |
---|
6787 | n/a | |
---|
6788 | n/a | Wait for completion of a specific child process. |
---|
6789 | n/a | |
---|
6790 | n/a | Returns a tuple of information about the child process: |
---|
6791 | n/a | (pid, status, rusage) |
---|
6792 | n/a | [clinic start generated code]*/ |
---|
6793 | n/a | |
---|
6794 | n/a | static PyObject * |
---|
6795 | n/a | os_wait4_impl(PyObject *module, pid_t pid, int options) |
---|
6796 | n/a | /*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/ |
---|
6797 | n/a | { |
---|
6798 | n/a | pid_t res; |
---|
6799 | n/a | struct rusage ru; |
---|
6800 | n/a | int async_err = 0; |
---|
6801 | n/a | WAIT_TYPE status; |
---|
6802 | n/a | WAIT_STATUS_INT(status) = 0; |
---|
6803 | n/a | |
---|
6804 | n/a | do { |
---|
6805 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
6806 | n/a | res = wait4(pid, &status, options, &ru); |
---|
6807 | n/a | Py_END_ALLOW_THREADS |
---|
6808 | n/a | } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); |
---|
6809 | n/a | if (res < 0) |
---|
6810 | n/a | return (!async_err) ? posix_error() : NULL; |
---|
6811 | n/a | |
---|
6812 | n/a | return wait_helper(res, WAIT_STATUS_INT(status), &ru); |
---|
6813 | n/a | } |
---|
6814 | n/a | #endif /* HAVE_WAIT4 */ |
---|
6815 | n/a | |
---|
6816 | n/a | |
---|
6817 | n/a | #if defined(HAVE_WAITID) && !defined(__APPLE__) |
---|
6818 | n/a | /*[clinic input] |
---|
6819 | n/a | os.waitid |
---|
6820 | n/a | |
---|
6821 | n/a | idtype: idtype_t |
---|
6822 | n/a | Must be one of be P_PID, P_PGID or P_ALL. |
---|
6823 | n/a | id: id_t |
---|
6824 | n/a | The id to wait on. |
---|
6825 | n/a | options: int |
---|
6826 | n/a | Constructed from the ORing of one or more of WEXITED, WSTOPPED |
---|
6827 | n/a | or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT. |
---|
6828 | n/a | / |
---|
6829 | n/a | |
---|
6830 | n/a | Returns the result of waiting for a process or processes. |
---|
6831 | n/a | |
---|
6832 | n/a | Returns either waitid_result or None if WNOHANG is specified and there are |
---|
6833 | n/a | no children in a waitable state. |
---|
6834 | n/a | [clinic start generated code]*/ |
---|
6835 | n/a | |
---|
6836 | n/a | static PyObject * |
---|
6837 | n/a | os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options) |
---|
6838 | n/a | /*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/ |
---|
6839 | n/a | { |
---|
6840 | n/a | PyObject *result; |
---|
6841 | n/a | int res; |
---|
6842 | n/a | int async_err = 0; |
---|
6843 | n/a | siginfo_t si; |
---|
6844 | n/a | si.si_pid = 0; |
---|
6845 | n/a | |
---|
6846 | n/a | do { |
---|
6847 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
6848 | n/a | res = waitid(idtype, id, &si, options); |
---|
6849 | n/a | Py_END_ALLOW_THREADS |
---|
6850 | n/a | } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); |
---|
6851 | n/a | if (res < 0) |
---|
6852 | n/a | return (!async_err) ? posix_error() : NULL; |
---|
6853 | n/a | |
---|
6854 | n/a | if (si.si_pid == 0) |
---|
6855 | n/a | Py_RETURN_NONE; |
---|
6856 | n/a | |
---|
6857 | n/a | result = PyStructSequence_New(&WaitidResultType); |
---|
6858 | n/a | if (!result) |
---|
6859 | n/a | return NULL; |
---|
6860 | n/a | |
---|
6861 | n/a | PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid)); |
---|
6862 | n/a | PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid)); |
---|
6863 | n/a | PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo))); |
---|
6864 | n/a | PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status))); |
---|
6865 | n/a | PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code))); |
---|
6866 | n/a | if (PyErr_Occurred()) { |
---|
6867 | n/a | Py_DECREF(result); |
---|
6868 | n/a | return NULL; |
---|
6869 | n/a | } |
---|
6870 | n/a | |
---|
6871 | n/a | return result; |
---|
6872 | n/a | } |
---|
6873 | n/a | #endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */ |
---|
6874 | n/a | |
---|
6875 | n/a | |
---|
6876 | n/a | #if defined(HAVE_WAITPID) |
---|
6877 | n/a | /*[clinic input] |
---|
6878 | n/a | os.waitpid |
---|
6879 | n/a | pid: pid_t |
---|
6880 | n/a | options: int |
---|
6881 | n/a | / |
---|
6882 | n/a | |
---|
6883 | n/a | Wait for completion of a given child process. |
---|
6884 | n/a | |
---|
6885 | n/a | Returns a tuple of information regarding the child process: |
---|
6886 | n/a | (pid, status) |
---|
6887 | n/a | |
---|
6888 | n/a | The options argument is ignored on Windows. |
---|
6889 | n/a | [clinic start generated code]*/ |
---|
6890 | n/a | |
---|
6891 | n/a | static PyObject * |
---|
6892 | n/a | os_waitpid_impl(PyObject *module, pid_t pid, int options) |
---|
6893 | n/a | /*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/ |
---|
6894 | n/a | { |
---|
6895 | n/a | pid_t res; |
---|
6896 | n/a | int async_err = 0; |
---|
6897 | n/a | WAIT_TYPE status; |
---|
6898 | n/a | WAIT_STATUS_INT(status) = 0; |
---|
6899 | n/a | |
---|
6900 | n/a | do { |
---|
6901 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
6902 | n/a | res = waitpid(pid, &status, options); |
---|
6903 | n/a | Py_END_ALLOW_THREADS |
---|
6904 | n/a | } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); |
---|
6905 | n/a | if (res < 0) |
---|
6906 | n/a | return (!async_err) ? posix_error() : NULL; |
---|
6907 | n/a | |
---|
6908 | n/a | return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status)); |
---|
6909 | n/a | } |
---|
6910 | n/a | #elif defined(HAVE_CWAIT) |
---|
6911 | n/a | /* MS C has a variant of waitpid() that's usable for most purposes. */ |
---|
6912 | n/a | /*[clinic input] |
---|
6913 | n/a | os.waitpid |
---|
6914 | n/a | pid: intptr_t |
---|
6915 | n/a | options: int |
---|
6916 | n/a | / |
---|
6917 | n/a | |
---|
6918 | n/a | Wait for completion of a given process. |
---|
6919 | n/a | |
---|
6920 | n/a | Returns a tuple of information regarding the process: |
---|
6921 | n/a | (pid, status << 8) |
---|
6922 | n/a | |
---|
6923 | n/a | The options argument is ignored on Windows. |
---|
6924 | n/a | [clinic start generated code]*/ |
---|
6925 | n/a | |
---|
6926 | n/a | static PyObject * |
---|
6927 | n/a | os_waitpid_impl(PyObject *module, intptr_t pid, int options) |
---|
6928 | n/a | /*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/ |
---|
6929 | n/a | { |
---|
6930 | n/a | int status; |
---|
6931 | n/a | intptr_t res; |
---|
6932 | n/a | int async_err = 0; |
---|
6933 | n/a | |
---|
6934 | n/a | do { |
---|
6935 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
6936 | n/a | _Py_BEGIN_SUPPRESS_IPH |
---|
6937 | n/a | res = _cwait(&status, pid, options); |
---|
6938 | n/a | _Py_END_SUPPRESS_IPH |
---|
6939 | n/a | Py_END_ALLOW_THREADS |
---|
6940 | n/a | } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); |
---|
6941 | n/a | if (res < 0) |
---|
6942 | n/a | return (!async_err) ? posix_error() : NULL; |
---|
6943 | n/a | |
---|
6944 | n/a | /* shift the status left a byte so this is more like the POSIX waitpid */ |
---|
6945 | n/a | return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8); |
---|
6946 | n/a | } |
---|
6947 | n/a | #endif |
---|
6948 | n/a | |
---|
6949 | n/a | |
---|
6950 | n/a | #ifdef HAVE_WAIT |
---|
6951 | n/a | /*[clinic input] |
---|
6952 | n/a | os.wait |
---|
6953 | n/a | |
---|
6954 | n/a | Wait for completion of a child process. |
---|
6955 | n/a | |
---|
6956 | n/a | Returns a tuple of information about the child process: |
---|
6957 | n/a | (pid, status) |
---|
6958 | n/a | [clinic start generated code]*/ |
---|
6959 | n/a | |
---|
6960 | n/a | static PyObject * |
---|
6961 | n/a | os_wait_impl(PyObject *module) |
---|
6962 | n/a | /*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/ |
---|
6963 | n/a | { |
---|
6964 | n/a | pid_t pid; |
---|
6965 | n/a | int async_err = 0; |
---|
6966 | n/a | WAIT_TYPE status; |
---|
6967 | n/a | WAIT_STATUS_INT(status) = 0; |
---|
6968 | n/a | |
---|
6969 | n/a | do { |
---|
6970 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
6971 | n/a | pid = wait(&status); |
---|
6972 | n/a | Py_END_ALLOW_THREADS |
---|
6973 | n/a | } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); |
---|
6974 | n/a | if (pid < 0) |
---|
6975 | n/a | return (!async_err) ? posix_error() : NULL; |
---|
6976 | n/a | |
---|
6977 | n/a | return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status)); |
---|
6978 | n/a | } |
---|
6979 | n/a | #endif /* HAVE_WAIT */ |
---|
6980 | n/a | |
---|
6981 | n/a | |
---|
6982 | n/a | #if defined(HAVE_READLINK) || defined(MS_WINDOWS) |
---|
6983 | n/a | PyDoc_STRVAR(readlink__doc__, |
---|
6984 | n/a | "readlink(path, *, dir_fd=None) -> path\n\n\ |
---|
6985 | n/a | Return a string representing the path to which the symbolic link points.\n\ |
---|
6986 | n/a | \n\ |
---|
6987 | n/a | If dir_fd is not None, it should be a file descriptor open to a directory,\n\ |
---|
6988 | n/a | and path should be relative; path will then be relative to that directory.\n\ |
---|
6989 | n/a | dir_fd may not be implemented on your platform.\n\ |
---|
6990 | n/a | If it is unavailable, using it will raise a NotImplementedError."); |
---|
6991 | n/a | #endif |
---|
6992 | n/a | |
---|
6993 | n/a | #ifdef HAVE_READLINK |
---|
6994 | n/a | |
---|
6995 | n/a | /* AC 3.5: merge win32 and not together */ |
---|
6996 | n/a | static PyObject * |
---|
6997 | n/a | posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs) |
---|
6998 | n/a | { |
---|
6999 | n/a | path_t path; |
---|
7000 | n/a | int dir_fd = DEFAULT_DIR_FD; |
---|
7001 | n/a | char buffer[MAXPATHLEN+1]; |
---|
7002 | n/a | ssize_t length; |
---|
7003 | n/a | PyObject *return_value = NULL; |
---|
7004 | n/a | static char *keywords[] = {"path", "dir_fd", NULL}; |
---|
7005 | n/a | |
---|
7006 | n/a | memset(&path, 0, sizeof(path)); |
---|
7007 | n/a | path.function_name = "readlink"; |
---|
7008 | n/a | if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords, |
---|
7009 | n/a | path_converter, &path, |
---|
7010 | n/a | READLINKAT_DIR_FD_CONVERTER, &dir_fd)) |
---|
7011 | n/a | return NULL; |
---|
7012 | n/a | |
---|
7013 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
7014 | n/a | #ifdef HAVE_READLINKAT |
---|
7015 | n/a | if (dir_fd != DEFAULT_DIR_FD) |
---|
7016 | n/a | length = readlinkat(dir_fd, path.narrow, buffer, MAXPATHLEN); |
---|
7017 | n/a | else |
---|
7018 | n/a | #endif |
---|
7019 | n/a | length = readlink(path.narrow, buffer, MAXPATHLEN); |
---|
7020 | n/a | Py_END_ALLOW_THREADS |
---|
7021 | n/a | |
---|
7022 | n/a | if (length < 0) { |
---|
7023 | n/a | return_value = path_error(&path); |
---|
7024 | n/a | goto exit; |
---|
7025 | n/a | } |
---|
7026 | n/a | buffer[length] = '\0'; |
---|
7027 | n/a | |
---|
7028 | n/a | if (PyUnicode_Check(path.object)) |
---|
7029 | n/a | return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length); |
---|
7030 | n/a | else |
---|
7031 | n/a | return_value = PyBytes_FromStringAndSize(buffer, length); |
---|
7032 | n/a | exit: |
---|
7033 | n/a | path_cleanup(&path); |
---|
7034 | n/a | return return_value; |
---|
7035 | n/a | } |
---|
7036 | n/a | |
---|
7037 | n/a | #endif /* HAVE_READLINK */ |
---|
7038 | n/a | |
---|
7039 | n/a | #if !defined(HAVE_READLINK) && defined(MS_WINDOWS) |
---|
7040 | n/a | |
---|
7041 | n/a | static PyObject * |
---|
7042 | n/a | win_readlink(PyObject *self, PyObject *args, PyObject *kwargs) |
---|
7043 | n/a | { |
---|
7044 | n/a | const wchar_t *path; |
---|
7045 | n/a | DWORD n_bytes_returned; |
---|
7046 | n/a | DWORD io_result; |
---|
7047 | n/a | PyObject *po, *result; |
---|
7048 | n/a | int dir_fd; |
---|
7049 | n/a | HANDLE reparse_point_handle; |
---|
7050 | n/a | |
---|
7051 | n/a | char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; |
---|
7052 | n/a | _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer; |
---|
7053 | n/a | const wchar_t *print_name; |
---|
7054 | n/a | |
---|
7055 | n/a | static char *keywords[] = {"path", "dir_fd", NULL}; |
---|
7056 | n/a | |
---|
7057 | n/a | if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords, |
---|
7058 | n/a | &po, |
---|
7059 | n/a | dir_fd_unavailable, &dir_fd |
---|
7060 | n/a | )) |
---|
7061 | n/a | return NULL; |
---|
7062 | n/a | |
---|
7063 | n/a | path = PyUnicode_AsUnicode(po); |
---|
7064 | n/a | if (path == NULL) |
---|
7065 | n/a | return NULL; |
---|
7066 | n/a | |
---|
7067 | n/a | /* First get a handle to the reparse point */ |
---|
7068 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
7069 | n/a | reparse_point_handle = CreateFileW( |
---|
7070 | n/a | path, |
---|
7071 | n/a | 0, |
---|
7072 | n/a | 0, |
---|
7073 | n/a | 0, |
---|
7074 | n/a | OPEN_EXISTING, |
---|
7075 | n/a | FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, |
---|
7076 | n/a | 0); |
---|
7077 | n/a | Py_END_ALLOW_THREADS |
---|
7078 | n/a | |
---|
7079 | n/a | if (reparse_point_handle==INVALID_HANDLE_VALUE) |
---|
7080 | n/a | return win32_error_object("readlink", po); |
---|
7081 | n/a | |
---|
7082 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
7083 | n/a | /* New call DeviceIoControl to read the reparse point */ |
---|
7084 | n/a | io_result = DeviceIoControl( |
---|
7085 | n/a | reparse_point_handle, |
---|
7086 | n/a | FSCTL_GET_REPARSE_POINT, |
---|
7087 | n/a | 0, 0, /* in buffer */ |
---|
7088 | n/a | target_buffer, sizeof(target_buffer), |
---|
7089 | n/a | &n_bytes_returned, |
---|
7090 | n/a | 0 /* we're not using OVERLAPPED_IO */ |
---|
7091 | n/a | ); |
---|
7092 | n/a | CloseHandle(reparse_point_handle); |
---|
7093 | n/a | Py_END_ALLOW_THREADS |
---|
7094 | n/a | |
---|
7095 | n/a | if (io_result==0) |
---|
7096 | n/a | return win32_error_object("readlink", po); |
---|
7097 | n/a | |
---|
7098 | n/a | if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK) |
---|
7099 | n/a | { |
---|
7100 | n/a | PyErr_SetString(PyExc_ValueError, |
---|
7101 | n/a | "not a symbolic link"); |
---|
7102 | n/a | return NULL; |
---|
7103 | n/a | } |
---|
7104 | n/a | print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer + |
---|
7105 | n/a | rdb->SymbolicLinkReparseBuffer.PrintNameOffset; |
---|
7106 | n/a | |
---|
7107 | n/a | result = PyUnicode_FromWideChar(print_name, |
---|
7108 | n/a | rdb->SymbolicLinkReparseBuffer.PrintNameLength/2); |
---|
7109 | n/a | return result; |
---|
7110 | n/a | } |
---|
7111 | n/a | |
---|
7112 | n/a | #endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */ |
---|
7113 | n/a | |
---|
7114 | n/a | |
---|
7115 | n/a | |
---|
7116 | n/a | #ifdef HAVE_SYMLINK |
---|
7117 | n/a | |
---|
7118 | n/a | #if defined(MS_WINDOWS) |
---|
7119 | n/a | |
---|
7120 | n/a | /* Grab CreateSymbolicLinkW dynamically from kernel32 */ |
---|
7121 | n/a | static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL; |
---|
7122 | n/a | |
---|
7123 | n/a | static int |
---|
7124 | n/a | check_CreateSymbolicLink(void) |
---|
7125 | n/a | { |
---|
7126 | n/a | HINSTANCE hKernel32; |
---|
7127 | n/a | /* only recheck */ |
---|
7128 | n/a | if (Py_CreateSymbolicLinkW) |
---|
7129 | n/a | return 1; |
---|
7130 | n/a | hKernel32 = GetModuleHandleW(L"KERNEL32"); |
---|
7131 | n/a | *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32, |
---|
7132 | n/a | "CreateSymbolicLinkW"); |
---|
7133 | n/a | return Py_CreateSymbolicLinkW != NULL; |
---|
7134 | n/a | } |
---|
7135 | n/a | |
---|
7136 | n/a | /* Remove the last portion of the path */ |
---|
7137 | n/a | static void |
---|
7138 | n/a | _dirnameW(WCHAR *path) |
---|
7139 | n/a | { |
---|
7140 | n/a | WCHAR *ptr; |
---|
7141 | n/a | |
---|
7142 | n/a | /* walk the path from the end until a backslash is encountered */ |
---|
7143 | n/a | for(ptr = path + wcslen(path); ptr != path; ptr--) { |
---|
7144 | n/a | if (*ptr == L'\\' || *ptr == L'/') |
---|
7145 | n/a | break; |
---|
7146 | n/a | } |
---|
7147 | n/a | *ptr = 0; |
---|
7148 | n/a | } |
---|
7149 | n/a | |
---|
7150 | n/a | /* Is this path absolute? */ |
---|
7151 | n/a | static int |
---|
7152 | n/a | _is_absW(const WCHAR *path) |
---|
7153 | n/a | { |
---|
7154 | n/a | return path[0] == L'\\' || path[0] == L'/' || path[1] == L':'; |
---|
7155 | n/a | |
---|
7156 | n/a | } |
---|
7157 | n/a | |
---|
7158 | n/a | /* join root and rest with a backslash */ |
---|
7159 | n/a | static void |
---|
7160 | n/a | _joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest) |
---|
7161 | n/a | { |
---|
7162 | n/a | size_t root_len; |
---|
7163 | n/a | |
---|
7164 | n/a | if (_is_absW(rest)) { |
---|
7165 | n/a | wcscpy(dest_path, rest); |
---|
7166 | n/a | return; |
---|
7167 | n/a | } |
---|
7168 | n/a | |
---|
7169 | n/a | root_len = wcslen(root); |
---|
7170 | n/a | |
---|
7171 | n/a | wcscpy(dest_path, root); |
---|
7172 | n/a | if(root_len) { |
---|
7173 | n/a | dest_path[root_len] = L'\\'; |
---|
7174 | n/a | root_len++; |
---|
7175 | n/a | } |
---|
7176 | n/a | wcscpy(dest_path+root_len, rest); |
---|
7177 | n/a | } |
---|
7178 | n/a | |
---|
7179 | n/a | /* Return True if the path at src relative to dest is a directory */ |
---|
7180 | n/a | static int |
---|
7181 | n/a | _check_dirW(LPCWSTR src, LPCWSTR dest) |
---|
7182 | n/a | { |
---|
7183 | n/a | WIN32_FILE_ATTRIBUTE_DATA src_info; |
---|
7184 | n/a | WCHAR dest_parent[MAX_PATH]; |
---|
7185 | n/a | WCHAR src_resolved[MAX_PATH] = L""; |
---|
7186 | n/a | |
---|
7187 | n/a | /* dest_parent = os.path.dirname(dest) */ |
---|
7188 | n/a | wcscpy(dest_parent, dest); |
---|
7189 | n/a | _dirnameW(dest_parent); |
---|
7190 | n/a | /* src_resolved = os.path.join(dest_parent, src) */ |
---|
7191 | n/a | _joinW(src_resolved, dest_parent, src); |
---|
7192 | n/a | return ( |
---|
7193 | n/a | GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info) |
---|
7194 | n/a | && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY |
---|
7195 | n/a | ); |
---|
7196 | n/a | } |
---|
7197 | n/a | #endif |
---|
7198 | n/a | |
---|
7199 | n/a | |
---|
7200 | n/a | /*[clinic input] |
---|
7201 | n/a | os.symlink |
---|
7202 | n/a | src: path_t |
---|
7203 | n/a | dst: path_t |
---|
7204 | n/a | target_is_directory: bool = False |
---|
7205 | n/a | * |
---|
7206 | n/a | dir_fd: dir_fd(requires='symlinkat')=None |
---|
7207 | n/a | |
---|
7208 | n/a | # "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\ |
---|
7209 | n/a | |
---|
7210 | n/a | Create a symbolic link pointing to src named dst. |
---|
7211 | n/a | |
---|
7212 | n/a | target_is_directory is required on Windows if the target is to be |
---|
7213 | n/a | interpreted as a directory. (On Windows, symlink requires |
---|
7214 | n/a | Windows 6.0 or greater, and raises a NotImplementedError otherwise.) |
---|
7215 | n/a | target_is_directory is ignored on non-Windows platforms. |
---|
7216 | n/a | |
---|
7217 | n/a | If dir_fd is not None, it should be a file descriptor open to a directory, |
---|
7218 | n/a | and path should be relative; path will then be relative to that directory. |
---|
7219 | n/a | dir_fd may not be implemented on your platform. |
---|
7220 | n/a | If it is unavailable, using it will raise a NotImplementedError. |
---|
7221 | n/a | |
---|
7222 | n/a | [clinic start generated code]*/ |
---|
7223 | n/a | |
---|
7224 | n/a | static PyObject * |
---|
7225 | n/a | os_symlink_impl(PyObject *module, path_t *src, path_t *dst, |
---|
7226 | n/a | int target_is_directory, int dir_fd) |
---|
7227 | n/a | /*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/ |
---|
7228 | n/a | { |
---|
7229 | n/a | #ifdef MS_WINDOWS |
---|
7230 | n/a | DWORD result; |
---|
7231 | n/a | #else |
---|
7232 | n/a | int result; |
---|
7233 | n/a | #endif |
---|
7234 | n/a | |
---|
7235 | n/a | #ifdef MS_WINDOWS |
---|
7236 | n/a | if (!check_CreateSymbolicLink()) { |
---|
7237 | n/a | PyErr_SetString(PyExc_NotImplementedError, |
---|
7238 | n/a | "CreateSymbolicLink functions not found"); |
---|
7239 | n/a | return NULL; |
---|
7240 | n/a | } |
---|
7241 | n/a | if (!win32_can_symlink) { |
---|
7242 | n/a | PyErr_SetString(PyExc_OSError, "symbolic link privilege not held"); |
---|
7243 | n/a | return NULL; |
---|
7244 | n/a | } |
---|
7245 | n/a | #endif |
---|
7246 | n/a | |
---|
7247 | n/a | if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) { |
---|
7248 | n/a | PyErr_SetString(PyExc_ValueError, |
---|
7249 | n/a | "symlink: src and dst must be the same type"); |
---|
7250 | n/a | return NULL; |
---|
7251 | n/a | } |
---|
7252 | n/a | |
---|
7253 | n/a | #ifdef MS_WINDOWS |
---|
7254 | n/a | |
---|
7255 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
7256 | n/a | /* if src is a directory, ensure target_is_directory==1 */ |
---|
7257 | n/a | target_is_directory |= _check_dirW(src->wide, dst->wide); |
---|
7258 | n/a | result = Py_CreateSymbolicLinkW(dst->wide, src->wide, |
---|
7259 | n/a | target_is_directory); |
---|
7260 | n/a | Py_END_ALLOW_THREADS |
---|
7261 | n/a | |
---|
7262 | n/a | if (!result) |
---|
7263 | n/a | return path_error2(src, dst); |
---|
7264 | n/a | |
---|
7265 | n/a | #else |
---|
7266 | n/a | |
---|
7267 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
7268 | n/a | #if HAVE_SYMLINKAT |
---|
7269 | n/a | if (dir_fd != DEFAULT_DIR_FD) |
---|
7270 | n/a | result = symlinkat(src->narrow, dir_fd, dst->narrow); |
---|
7271 | n/a | else |
---|
7272 | n/a | #endif |
---|
7273 | n/a | result = symlink(src->narrow, dst->narrow); |
---|
7274 | n/a | Py_END_ALLOW_THREADS |
---|
7275 | n/a | |
---|
7276 | n/a | if (result) |
---|
7277 | n/a | return path_error2(src, dst); |
---|
7278 | n/a | #endif |
---|
7279 | n/a | |
---|
7280 | n/a | Py_RETURN_NONE; |
---|
7281 | n/a | } |
---|
7282 | n/a | #endif /* HAVE_SYMLINK */ |
---|
7283 | n/a | |
---|
7284 | n/a | |
---|
7285 | n/a | |
---|
7286 | n/a | |
---|
7287 | n/a | static PyStructSequence_Field times_result_fields[] = { |
---|
7288 | n/a | {"user", "user time"}, |
---|
7289 | n/a | {"system", "system time"}, |
---|
7290 | n/a | {"children_user", "user time of children"}, |
---|
7291 | n/a | {"children_system", "system time of children"}, |
---|
7292 | n/a | {"elapsed", "elapsed time since an arbitrary point in the past"}, |
---|
7293 | n/a | {NULL} |
---|
7294 | n/a | }; |
---|
7295 | n/a | |
---|
7296 | n/a | PyDoc_STRVAR(times_result__doc__, |
---|
7297 | n/a | "times_result: Result from os.times().\n\n\ |
---|
7298 | n/a | This object may be accessed either as a tuple of\n\ |
---|
7299 | n/a | (user, system, children_user, children_system, elapsed),\n\ |
---|
7300 | n/a | or via the attributes user, system, children_user, children_system,\n\ |
---|
7301 | n/a | and elapsed.\n\ |
---|
7302 | n/a | \n\ |
---|
7303 | n/a | See os.times for more information."); |
---|
7304 | n/a | |
---|
7305 | n/a | static PyStructSequence_Desc times_result_desc = { |
---|
7306 | n/a | "times_result", /* name */ |
---|
7307 | n/a | times_result__doc__, /* doc */ |
---|
7308 | n/a | times_result_fields, |
---|
7309 | n/a | 5 |
---|
7310 | n/a | }; |
---|
7311 | n/a | |
---|
7312 | n/a | static PyTypeObject TimesResultType; |
---|
7313 | n/a | |
---|
7314 | n/a | #ifdef MS_WINDOWS |
---|
7315 | n/a | #define HAVE_TIMES /* mandatory, for the method table */ |
---|
7316 | n/a | #endif |
---|
7317 | n/a | |
---|
7318 | n/a | #ifdef HAVE_TIMES |
---|
7319 | n/a | |
---|
7320 | n/a | static PyObject * |
---|
7321 | n/a | build_times_result(double user, double system, |
---|
7322 | n/a | double children_user, double children_system, |
---|
7323 | n/a | double elapsed) |
---|
7324 | n/a | { |
---|
7325 | n/a | PyObject *value = PyStructSequence_New(&TimesResultType); |
---|
7326 | n/a | if (value == NULL) |
---|
7327 | n/a | return NULL; |
---|
7328 | n/a | |
---|
7329 | n/a | #define SET(i, field) \ |
---|
7330 | n/a | { \ |
---|
7331 | n/a | PyObject *o = PyFloat_FromDouble(field); \ |
---|
7332 | n/a | if (!o) { \ |
---|
7333 | n/a | Py_DECREF(value); \ |
---|
7334 | n/a | return NULL; \ |
---|
7335 | n/a | } \ |
---|
7336 | n/a | PyStructSequence_SET_ITEM(value, i, o); \ |
---|
7337 | n/a | } \ |
---|
7338 | n/a | |
---|
7339 | n/a | SET(0, user); |
---|
7340 | n/a | SET(1, system); |
---|
7341 | n/a | SET(2, children_user); |
---|
7342 | n/a | SET(3, children_system); |
---|
7343 | n/a | SET(4, elapsed); |
---|
7344 | n/a | |
---|
7345 | n/a | #undef SET |
---|
7346 | n/a | |
---|
7347 | n/a | return value; |
---|
7348 | n/a | } |
---|
7349 | n/a | |
---|
7350 | n/a | |
---|
7351 | n/a | #ifndef MS_WINDOWS |
---|
7352 | n/a | #define NEED_TICKS_PER_SECOND |
---|
7353 | n/a | static long ticks_per_second = -1; |
---|
7354 | n/a | #endif /* MS_WINDOWS */ |
---|
7355 | n/a | |
---|
7356 | n/a | /*[clinic input] |
---|
7357 | n/a | os.times |
---|
7358 | n/a | |
---|
7359 | n/a | Return a collection containing process timing information. |
---|
7360 | n/a | |
---|
7361 | n/a | The object returned behaves like a named tuple with these fields: |
---|
7362 | n/a | (utime, stime, cutime, cstime, elapsed_time) |
---|
7363 | n/a | All fields are floating point numbers. |
---|
7364 | n/a | [clinic start generated code]*/ |
---|
7365 | n/a | |
---|
7366 | n/a | static PyObject * |
---|
7367 | n/a | os_times_impl(PyObject *module) |
---|
7368 | n/a | /*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/ |
---|
7369 | n/a | #ifdef MS_WINDOWS |
---|
7370 | n/a | { |
---|
7371 | n/a | FILETIME create, exit, kernel, user; |
---|
7372 | n/a | HANDLE hProc; |
---|
7373 | n/a | hProc = GetCurrentProcess(); |
---|
7374 | n/a | GetProcessTimes(hProc, &create, &exit, &kernel, &user); |
---|
7375 | n/a | /* The fields of a FILETIME structure are the hi and lo part |
---|
7376 | n/a | of a 64-bit value expressed in 100 nanosecond units. |
---|
7377 | n/a | 1e7 is one second in such units; 1e-7 the inverse. |
---|
7378 | n/a | 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7. |
---|
7379 | n/a | */ |
---|
7380 | n/a | return build_times_result( |
---|
7381 | n/a | (double)(user.dwHighDateTime*429.4967296 + |
---|
7382 | n/a | user.dwLowDateTime*1e-7), |
---|
7383 | n/a | (double)(kernel.dwHighDateTime*429.4967296 + |
---|
7384 | n/a | kernel.dwLowDateTime*1e-7), |
---|
7385 | n/a | (double)0, |
---|
7386 | n/a | (double)0, |
---|
7387 | n/a | (double)0); |
---|
7388 | n/a | } |
---|
7389 | n/a | #else /* MS_WINDOWS */ |
---|
7390 | n/a | { |
---|
7391 | n/a | |
---|
7392 | n/a | |
---|
7393 | n/a | struct tms t; |
---|
7394 | n/a | clock_t c; |
---|
7395 | n/a | errno = 0; |
---|
7396 | n/a | c = times(&t); |
---|
7397 | n/a | if (c == (clock_t) -1) |
---|
7398 | n/a | return posix_error(); |
---|
7399 | n/a | return build_times_result( |
---|
7400 | n/a | (double)t.tms_utime / ticks_per_second, |
---|
7401 | n/a | (double)t.tms_stime / ticks_per_second, |
---|
7402 | n/a | (double)t.tms_cutime / ticks_per_second, |
---|
7403 | n/a | (double)t.tms_cstime / ticks_per_second, |
---|
7404 | n/a | (double)c / ticks_per_second); |
---|
7405 | n/a | } |
---|
7406 | n/a | #endif /* MS_WINDOWS */ |
---|
7407 | n/a | #endif /* HAVE_TIMES */ |
---|
7408 | n/a | |
---|
7409 | n/a | |
---|
7410 | n/a | #ifdef HAVE_GETSID |
---|
7411 | n/a | /*[clinic input] |
---|
7412 | n/a | os.getsid |
---|
7413 | n/a | |
---|
7414 | n/a | pid: pid_t |
---|
7415 | n/a | / |
---|
7416 | n/a | |
---|
7417 | n/a | Call the system call getsid(pid) and return the result. |
---|
7418 | n/a | [clinic start generated code]*/ |
---|
7419 | n/a | |
---|
7420 | n/a | static PyObject * |
---|
7421 | n/a | os_getsid_impl(PyObject *module, pid_t pid) |
---|
7422 | n/a | /*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/ |
---|
7423 | n/a | { |
---|
7424 | n/a | int sid; |
---|
7425 | n/a | sid = getsid(pid); |
---|
7426 | n/a | if (sid < 0) |
---|
7427 | n/a | return posix_error(); |
---|
7428 | n/a | return PyLong_FromLong((long)sid); |
---|
7429 | n/a | } |
---|
7430 | n/a | #endif /* HAVE_GETSID */ |
---|
7431 | n/a | |
---|
7432 | n/a | |
---|
7433 | n/a | #ifdef HAVE_SETSID |
---|
7434 | n/a | /*[clinic input] |
---|
7435 | n/a | os.setsid |
---|
7436 | n/a | |
---|
7437 | n/a | Call the system call setsid(). |
---|
7438 | n/a | [clinic start generated code]*/ |
---|
7439 | n/a | |
---|
7440 | n/a | static PyObject * |
---|
7441 | n/a | os_setsid_impl(PyObject *module) |
---|
7442 | n/a | /*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/ |
---|
7443 | n/a | { |
---|
7444 | n/a | if (setsid() < 0) |
---|
7445 | n/a | return posix_error(); |
---|
7446 | n/a | Py_RETURN_NONE; |
---|
7447 | n/a | } |
---|
7448 | n/a | #endif /* HAVE_SETSID */ |
---|
7449 | n/a | |
---|
7450 | n/a | |
---|
7451 | n/a | #ifdef HAVE_SETPGID |
---|
7452 | n/a | /*[clinic input] |
---|
7453 | n/a | os.setpgid |
---|
7454 | n/a | |
---|
7455 | n/a | pid: pid_t |
---|
7456 | n/a | pgrp: pid_t |
---|
7457 | n/a | / |
---|
7458 | n/a | |
---|
7459 | n/a | Call the system call setpgid(pid, pgrp). |
---|
7460 | n/a | [clinic start generated code]*/ |
---|
7461 | n/a | |
---|
7462 | n/a | static PyObject * |
---|
7463 | n/a | os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp) |
---|
7464 | n/a | /*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/ |
---|
7465 | n/a | { |
---|
7466 | n/a | if (setpgid(pid, pgrp) < 0) |
---|
7467 | n/a | return posix_error(); |
---|
7468 | n/a | Py_RETURN_NONE; |
---|
7469 | n/a | } |
---|
7470 | n/a | #endif /* HAVE_SETPGID */ |
---|
7471 | n/a | |
---|
7472 | n/a | |
---|
7473 | n/a | #ifdef HAVE_TCGETPGRP |
---|
7474 | n/a | /*[clinic input] |
---|
7475 | n/a | os.tcgetpgrp |
---|
7476 | n/a | |
---|
7477 | n/a | fd: int |
---|
7478 | n/a | / |
---|
7479 | n/a | |
---|
7480 | n/a | Return the process group associated with the terminal specified by fd. |
---|
7481 | n/a | [clinic start generated code]*/ |
---|
7482 | n/a | |
---|
7483 | n/a | static PyObject * |
---|
7484 | n/a | os_tcgetpgrp_impl(PyObject *module, int fd) |
---|
7485 | n/a | /*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/ |
---|
7486 | n/a | { |
---|
7487 | n/a | pid_t pgid = tcgetpgrp(fd); |
---|
7488 | n/a | if (pgid < 0) |
---|
7489 | n/a | return posix_error(); |
---|
7490 | n/a | return PyLong_FromPid(pgid); |
---|
7491 | n/a | } |
---|
7492 | n/a | #endif /* HAVE_TCGETPGRP */ |
---|
7493 | n/a | |
---|
7494 | n/a | |
---|
7495 | n/a | #ifdef HAVE_TCSETPGRP |
---|
7496 | n/a | /*[clinic input] |
---|
7497 | n/a | os.tcsetpgrp |
---|
7498 | n/a | |
---|
7499 | n/a | fd: int |
---|
7500 | n/a | pgid: pid_t |
---|
7501 | n/a | / |
---|
7502 | n/a | |
---|
7503 | n/a | Set the process group associated with the terminal specified by fd. |
---|
7504 | n/a | [clinic start generated code]*/ |
---|
7505 | n/a | |
---|
7506 | n/a | static PyObject * |
---|
7507 | n/a | os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid) |
---|
7508 | n/a | /*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/ |
---|
7509 | n/a | { |
---|
7510 | n/a | if (tcsetpgrp(fd, pgid) < 0) |
---|
7511 | n/a | return posix_error(); |
---|
7512 | n/a | Py_RETURN_NONE; |
---|
7513 | n/a | } |
---|
7514 | n/a | #endif /* HAVE_TCSETPGRP */ |
---|
7515 | n/a | |
---|
7516 | n/a | /* Functions acting on file descriptors */ |
---|
7517 | n/a | |
---|
7518 | n/a | #ifdef O_CLOEXEC |
---|
7519 | n/a | extern int _Py_open_cloexec_works; |
---|
7520 | n/a | #endif |
---|
7521 | n/a | |
---|
7522 | n/a | |
---|
7523 | n/a | /*[clinic input] |
---|
7524 | n/a | os.open -> int |
---|
7525 | n/a | path: path_t |
---|
7526 | n/a | flags: int |
---|
7527 | n/a | mode: int = 0o777 |
---|
7528 | n/a | * |
---|
7529 | n/a | dir_fd: dir_fd(requires='openat') = None |
---|
7530 | n/a | |
---|
7531 | n/a | # "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\ |
---|
7532 | n/a | |
---|
7533 | n/a | Open a file for low level IO. Returns a file descriptor (integer). |
---|
7534 | n/a | |
---|
7535 | n/a | If dir_fd is not None, it should be a file descriptor open to a directory, |
---|
7536 | n/a | and path should be relative; path will then be relative to that directory. |
---|
7537 | n/a | dir_fd may not be implemented on your platform. |
---|
7538 | n/a | If it is unavailable, using it will raise a NotImplementedError. |
---|
7539 | n/a | [clinic start generated code]*/ |
---|
7540 | n/a | |
---|
7541 | n/a | static int |
---|
7542 | n/a | os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd) |
---|
7543 | n/a | /*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/ |
---|
7544 | n/a | { |
---|
7545 | n/a | int fd; |
---|
7546 | n/a | int async_err = 0; |
---|
7547 | n/a | |
---|
7548 | n/a | #ifdef O_CLOEXEC |
---|
7549 | n/a | int *atomic_flag_works = &_Py_open_cloexec_works; |
---|
7550 | n/a | #elif !defined(MS_WINDOWS) |
---|
7551 | n/a | int *atomic_flag_works = NULL; |
---|
7552 | n/a | #endif |
---|
7553 | n/a | |
---|
7554 | n/a | #ifdef MS_WINDOWS |
---|
7555 | n/a | flags |= O_NOINHERIT; |
---|
7556 | n/a | #elif defined(O_CLOEXEC) |
---|
7557 | n/a | flags |= O_CLOEXEC; |
---|
7558 | n/a | #endif |
---|
7559 | n/a | |
---|
7560 | n/a | _Py_BEGIN_SUPPRESS_IPH |
---|
7561 | n/a | do { |
---|
7562 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
7563 | n/a | #ifdef MS_WINDOWS |
---|
7564 | n/a | fd = _wopen(path->wide, flags, mode); |
---|
7565 | n/a | #else |
---|
7566 | n/a | #ifdef HAVE_OPENAT |
---|
7567 | n/a | if (dir_fd != DEFAULT_DIR_FD) |
---|
7568 | n/a | fd = openat(dir_fd, path->narrow, flags, mode); |
---|
7569 | n/a | else |
---|
7570 | n/a | #endif /* HAVE_OPENAT */ |
---|
7571 | n/a | fd = open(path->narrow, flags, mode); |
---|
7572 | n/a | #endif /* !MS_WINDOWS */ |
---|
7573 | n/a | Py_END_ALLOW_THREADS |
---|
7574 | n/a | } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); |
---|
7575 | n/a | _Py_END_SUPPRESS_IPH |
---|
7576 | n/a | |
---|
7577 | n/a | if (fd < 0) { |
---|
7578 | n/a | if (!async_err) |
---|
7579 | n/a | PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object); |
---|
7580 | n/a | return -1; |
---|
7581 | n/a | } |
---|
7582 | n/a | |
---|
7583 | n/a | #ifndef MS_WINDOWS |
---|
7584 | n/a | if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) { |
---|
7585 | n/a | close(fd); |
---|
7586 | n/a | return -1; |
---|
7587 | n/a | } |
---|
7588 | n/a | #endif |
---|
7589 | n/a | |
---|
7590 | n/a | return fd; |
---|
7591 | n/a | } |
---|
7592 | n/a | |
---|
7593 | n/a | |
---|
7594 | n/a | /*[clinic input] |
---|
7595 | n/a | os.close |
---|
7596 | n/a | |
---|
7597 | n/a | fd: int |
---|
7598 | n/a | |
---|
7599 | n/a | Close a file descriptor. |
---|
7600 | n/a | [clinic start generated code]*/ |
---|
7601 | n/a | |
---|
7602 | n/a | static PyObject * |
---|
7603 | n/a | os_close_impl(PyObject *module, int fd) |
---|
7604 | n/a | /*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/ |
---|
7605 | n/a | { |
---|
7606 | n/a | int res; |
---|
7607 | n/a | /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/ |
---|
7608 | n/a | * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html |
---|
7609 | n/a | * for more details. |
---|
7610 | n/a | */ |
---|
7611 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
7612 | n/a | _Py_BEGIN_SUPPRESS_IPH |
---|
7613 | n/a | res = close(fd); |
---|
7614 | n/a | _Py_END_SUPPRESS_IPH |
---|
7615 | n/a | Py_END_ALLOW_THREADS |
---|
7616 | n/a | if (res < 0) |
---|
7617 | n/a | return posix_error(); |
---|
7618 | n/a | Py_RETURN_NONE; |
---|
7619 | n/a | } |
---|
7620 | n/a | |
---|
7621 | n/a | |
---|
7622 | n/a | /*[clinic input] |
---|
7623 | n/a | os.closerange |
---|
7624 | n/a | |
---|
7625 | n/a | fd_low: int |
---|
7626 | n/a | fd_high: int |
---|
7627 | n/a | / |
---|
7628 | n/a | |
---|
7629 | n/a | Closes all file descriptors in [fd_low, fd_high), ignoring errors. |
---|
7630 | n/a | [clinic start generated code]*/ |
---|
7631 | n/a | |
---|
7632 | n/a | static PyObject * |
---|
7633 | n/a | os_closerange_impl(PyObject *module, int fd_low, int fd_high) |
---|
7634 | n/a | /*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/ |
---|
7635 | n/a | { |
---|
7636 | n/a | int i; |
---|
7637 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
7638 | n/a | _Py_BEGIN_SUPPRESS_IPH |
---|
7639 | n/a | for (i = Py_MAX(fd_low, 0); i < fd_high; i++) |
---|
7640 | n/a | close(i); |
---|
7641 | n/a | _Py_END_SUPPRESS_IPH |
---|
7642 | n/a | Py_END_ALLOW_THREADS |
---|
7643 | n/a | Py_RETURN_NONE; |
---|
7644 | n/a | } |
---|
7645 | n/a | |
---|
7646 | n/a | |
---|
7647 | n/a | /*[clinic input] |
---|
7648 | n/a | os.dup -> int |
---|
7649 | n/a | |
---|
7650 | n/a | fd: int |
---|
7651 | n/a | / |
---|
7652 | n/a | |
---|
7653 | n/a | Return a duplicate of a file descriptor. |
---|
7654 | n/a | [clinic start generated code]*/ |
---|
7655 | n/a | |
---|
7656 | n/a | static int |
---|
7657 | n/a | os_dup_impl(PyObject *module, int fd) |
---|
7658 | n/a | /*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/ |
---|
7659 | n/a | { |
---|
7660 | n/a | return _Py_dup(fd); |
---|
7661 | n/a | } |
---|
7662 | n/a | |
---|
7663 | n/a | |
---|
7664 | n/a | /*[clinic input] |
---|
7665 | n/a | os.dup2 |
---|
7666 | n/a | fd: int |
---|
7667 | n/a | fd2: int |
---|
7668 | n/a | inheritable: bool=True |
---|
7669 | n/a | |
---|
7670 | n/a | Duplicate file descriptor. |
---|
7671 | n/a | [clinic start generated code]*/ |
---|
7672 | n/a | |
---|
7673 | n/a | static PyObject * |
---|
7674 | n/a | os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable) |
---|
7675 | n/a | /*[clinic end generated code: output=db832a2d872ccc5f input=76e96f511be0352f]*/ |
---|
7676 | n/a | { |
---|
7677 | n/a | int res; |
---|
7678 | n/a | #if defined(HAVE_DUP3) && \ |
---|
7679 | n/a | !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)) |
---|
7680 | n/a | /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */ |
---|
7681 | n/a | int dup3_works = -1; |
---|
7682 | n/a | #endif |
---|
7683 | n/a | |
---|
7684 | n/a | if (fd < 0 || fd2 < 0) |
---|
7685 | n/a | return posix_error(); |
---|
7686 | n/a | |
---|
7687 | n/a | /* dup2() can fail with EINTR if the target FD is already open, because it |
---|
7688 | n/a | * then has to be closed. See os_close_impl() for why we don't handle EINTR |
---|
7689 | n/a | * upon close(), and therefore below. |
---|
7690 | n/a | */ |
---|
7691 | n/a | #ifdef MS_WINDOWS |
---|
7692 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
7693 | n/a | _Py_BEGIN_SUPPRESS_IPH |
---|
7694 | n/a | res = dup2(fd, fd2); |
---|
7695 | n/a | _Py_END_SUPPRESS_IPH |
---|
7696 | n/a | Py_END_ALLOW_THREADS |
---|
7697 | n/a | if (res < 0) |
---|
7698 | n/a | return posix_error(); |
---|
7699 | n/a | |
---|
7700 | n/a | /* Character files like console cannot be make non-inheritable */ |
---|
7701 | n/a | if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) { |
---|
7702 | n/a | close(fd2); |
---|
7703 | n/a | return NULL; |
---|
7704 | n/a | } |
---|
7705 | n/a | |
---|
7706 | n/a | #elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC) |
---|
7707 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
7708 | n/a | if (!inheritable) |
---|
7709 | n/a | res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2); |
---|
7710 | n/a | else |
---|
7711 | n/a | res = dup2(fd, fd2); |
---|
7712 | n/a | Py_END_ALLOW_THREADS |
---|
7713 | n/a | if (res < 0) |
---|
7714 | n/a | return posix_error(); |
---|
7715 | n/a | |
---|
7716 | n/a | #else |
---|
7717 | n/a | |
---|
7718 | n/a | #ifdef HAVE_DUP3 |
---|
7719 | n/a | if (!inheritable && dup3_works != 0) { |
---|
7720 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
7721 | n/a | res = dup3(fd, fd2, O_CLOEXEC); |
---|
7722 | n/a | Py_END_ALLOW_THREADS |
---|
7723 | n/a | if (res < 0) { |
---|
7724 | n/a | if (dup3_works == -1) |
---|
7725 | n/a | dup3_works = (errno != ENOSYS); |
---|
7726 | n/a | if (dup3_works) |
---|
7727 | n/a | return posix_error(); |
---|
7728 | n/a | } |
---|
7729 | n/a | } |
---|
7730 | n/a | |
---|
7731 | n/a | if (inheritable || dup3_works == 0) |
---|
7732 | n/a | { |
---|
7733 | n/a | #endif |
---|
7734 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
7735 | n/a | res = dup2(fd, fd2); |
---|
7736 | n/a | Py_END_ALLOW_THREADS |
---|
7737 | n/a | if (res < 0) |
---|
7738 | n/a | return posix_error(); |
---|
7739 | n/a | |
---|
7740 | n/a | if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) { |
---|
7741 | n/a | close(fd2); |
---|
7742 | n/a | return NULL; |
---|
7743 | n/a | } |
---|
7744 | n/a | #ifdef HAVE_DUP3 |
---|
7745 | n/a | } |
---|
7746 | n/a | #endif |
---|
7747 | n/a | |
---|
7748 | n/a | #endif |
---|
7749 | n/a | |
---|
7750 | n/a | Py_RETURN_NONE; |
---|
7751 | n/a | } |
---|
7752 | n/a | |
---|
7753 | n/a | |
---|
7754 | n/a | #ifdef HAVE_LOCKF |
---|
7755 | n/a | /*[clinic input] |
---|
7756 | n/a | os.lockf |
---|
7757 | n/a | |
---|
7758 | n/a | fd: int |
---|
7759 | n/a | An open file descriptor. |
---|
7760 | n/a | command: int |
---|
7761 | n/a | One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST. |
---|
7762 | n/a | length: Py_off_t |
---|
7763 | n/a | The number of bytes to lock, starting at the current position. |
---|
7764 | n/a | / |
---|
7765 | n/a | |
---|
7766 | n/a | Apply, test or remove a POSIX lock on an open file descriptor. |
---|
7767 | n/a | |
---|
7768 | n/a | [clinic start generated code]*/ |
---|
7769 | n/a | |
---|
7770 | n/a | static PyObject * |
---|
7771 | n/a | os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length) |
---|
7772 | n/a | /*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/ |
---|
7773 | n/a | { |
---|
7774 | n/a | int res; |
---|
7775 | n/a | |
---|
7776 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
7777 | n/a | res = lockf(fd, command, length); |
---|
7778 | n/a | Py_END_ALLOW_THREADS |
---|
7779 | n/a | |
---|
7780 | n/a | if (res < 0) |
---|
7781 | n/a | return posix_error(); |
---|
7782 | n/a | |
---|
7783 | n/a | Py_RETURN_NONE; |
---|
7784 | n/a | } |
---|
7785 | n/a | #endif /* HAVE_LOCKF */ |
---|
7786 | n/a | |
---|
7787 | n/a | |
---|
7788 | n/a | /*[clinic input] |
---|
7789 | n/a | os.lseek -> Py_off_t |
---|
7790 | n/a | |
---|
7791 | n/a | fd: int |
---|
7792 | n/a | position: Py_off_t |
---|
7793 | n/a | how: int |
---|
7794 | n/a | / |
---|
7795 | n/a | |
---|
7796 | n/a | Set the position of a file descriptor. Return the new position. |
---|
7797 | n/a | |
---|
7798 | n/a | Return the new cursor position in number of bytes |
---|
7799 | n/a | relative to the beginning of the file. |
---|
7800 | n/a | [clinic start generated code]*/ |
---|
7801 | n/a | |
---|
7802 | n/a | static Py_off_t |
---|
7803 | n/a | os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how) |
---|
7804 | n/a | /*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/ |
---|
7805 | n/a | { |
---|
7806 | n/a | Py_off_t result; |
---|
7807 | n/a | |
---|
7808 | n/a | #ifdef SEEK_SET |
---|
7809 | n/a | /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */ |
---|
7810 | n/a | switch (how) { |
---|
7811 | n/a | case 0: how = SEEK_SET; break; |
---|
7812 | n/a | case 1: how = SEEK_CUR; break; |
---|
7813 | n/a | case 2: how = SEEK_END; break; |
---|
7814 | n/a | } |
---|
7815 | n/a | #endif /* SEEK_END */ |
---|
7816 | n/a | |
---|
7817 | n/a | if (PyErr_Occurred()) |
---|
7818 | n/a | return -1; |
---|
7819 | n/a | |
---|
7820 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
7821 | n/a | _Py_BEGIN_SUPPRESS_IPH |
---|
7822 | n/a | #ifdef MS_WINDOWS |
---|
7823 | n/a | result = _lseeki64(fd, position, how); |
---|
7824 | n/a | #else |
---|
7825 | n/a | result = lseek(fd, position, how); |
---|
7826 | n/a | #endif |
---|
7827 | n/a | _Py_END_SUPPRESS_IPH |
---|
7828 | n/a | Py_END_ALLOW_THREADS |
---|
7829 | n/a | if (result < 0) |
---|
7830 | n/a | posix_error(); |
---|
7831 | n/a | |
---|
7832 | n/a | return result; |
---|
7833 | n/a | } |
---|
7834 | n/a | |
---|
7835 | n/a | |
---|
7836 | n/a | /*[clinic input] |
---|
7837 | n/a | os.read |
---|
7838 | n/a | fd: int |
---|
7839 | n/a | length: Py_ssize_t |
---|
7840 | n/a | / |
---|
7841 | n/a | |
---|
7842 | n/a | Read from a file descriptor. Returns a bytes object. |
---|
7843 | n/a | [clinic start generated code]*/ |
---|
7844 | n/a | |
---|
7845 | n/a | static PyObject * |
---|
7846 | n/a | os_read_impl(PyObject *module, int fd, Py_ssize_t length) |
---|
7847 | n/a | /*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/ |
---|
7848 | n/a | { |
---|
7849 | n/a | Py_ssize_t n; |
---|
7850 | n/a | PyObject *buffer; |
---|
7851 | n/a | |
---|
7852 | n/a | if (length < 0) { |
---|
7853 | n/a | errno = EINVAL; |
---|
7854 | n/a | return posix_error(); |
---|
7855 | n/a | } |
---|
7856 | n/a | |
---|
7857 | n/a | #ifdef MS_WINDOWS |
---|
7858 | n/a | /* On Windows, the count parameter of read() is an int */ |
---|
7859 | n/a | if (length > INT_MAX) |
---|
7860 | n/a | length = INT_MAX; |
---|
7861 | n/a | #endif |
---|
7862 | n/a | |
---|
7863 | n/a | buffer = PyBytes_FromStringAndSize((char *)NULL, length); |
---|
7864 | n/a | if (buffer == NULL) |
---|
7865 | n/a | return NULL; |
---|
7866 | n/a | |
---|
7867 | n/a | n = _Py_read(fd, PyBytes_AS_STRING(buffer), length); |
---|
7868 | n/a | if (n == -1) { |
---|
7869 | n/a | Py_DECREF(buffer); |
---|
7870 | n/a | return NULL; |
---|
7871 | n/a | } |
---|
7872 | n/a | |
---|
7873 | n/a | if (n != length) |
---|
7874 | n/a | _PyBytes_Resize(&buffer, n); |
---|
7875 | n/a | |
---|
7876 | n/a | return buffer; |
---|
7877 | n/a | } |
---|
7878 | n/a | |
---|
7879 | n/a | #if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \ |
---|
7880 | n/a | || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV) |
---|
7881 | n/a | static Py_ssize_t |
---|
7882 | n/a | iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type) |
---|
7883 | n/a | { |
---|
7884 | n/a | int i, j; |
---|
7885 | n/a | Py_ssize_t blen, total = 0; |
---|
7886 | n/a | |
---|
7887 | n/a | *iov = PyMem_New(struct iovec, cnt); |
---|
7888 | n/a | if (*iov == NULL) { |
---|
7889 | n/a | PyErr_NoMemory(); |
---|
7890 | n/a | return -1; |
---|
7891 | n/a | } |
---|
7892 | n/a | |
---|
7893 | n/a | *buf = PyMem_New(Py_buffer, cnt); |
---|
7894 | n/a | if (*buf == NULL) { |
---|
7895 | n/a | PyMem_Del(*iov); |
---|
7896 | n/a | PyErr_NoMemory(); |
---|
7897 | n/a | return -1; |
---|
7898 | n/a | } |
---|
7899 | n/a | |
---|
7900 | n/a | for (i = 0; i < cnt; i++) { |
---|
7901 | n/a | PyObject *item = PySequence_GetItem(seq, i); |
---|
7902 | n/a | if (item == NULL) |
---|
7903 | n/a | goto fail; |
---|
7904 | n/a | if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) { |
---|
7905 | n/a | Py_DECREF(item); |
---|
7906 | n/a | goto fail; |
---|
7907 | n/a | } |
---|
7908 | n/a | Py_DECREF(item); |
---|
7909 | n/a | (*iov)[i].iov_base = (*buf)[i].buf; |
---|
7910 | n/a | blen = (*buf)[i].len; |
---|
7911 | n/a | (*iov)[i].iov_len = blen; |
---|
7912 | n/a | total += blen; |
---|
7913 | n/a | } |
---|
7914 | n/a | return total; |
---|
7915 | n/a | |
---|
7916 | n/a | fail: |
---|
7917 | n/a | PyMem_Del(*iov); |
---|
7918 | n/a | for (j = 0; j < i; j++) { |
---|
7919 | n/a | PyBuffer_Release(&(*buf)[j]); |
---|
7920 | n/a | } |
---|
7921 | n/a | PyMem_Del(*buf); |
---|
7922 | n/a | return -1; |
---|
7923 | n/a | } |
---|
7924 | n/a | |
---|
7925 | n/a | static void |
---|
7926 | n/a | iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt) |
---|
7927 | n/a | { |
---|
7928 | n/a | int i; |
---|
7929 | n/a | PyMem_Del(iov); |
---|
7930 | n/a | for (i = 0; i < cnt; i++) { |
---|
7931 | n/a | PyBuffer_Release(&buf[i]); |
---|
7932 | n/a | } |
---|
7933 | n/a | PyMem_Del(buf); |
---|
7934 | n/a | } |
---|
7935 | n/a | #endif |
---|
7936 | n/a | |
---|
7937 | n/a | |
---|
7938 | n/a | #ifdef HAVE_READV |
---|
7939 | n/a | /*[clinic input] |
---|
7940 | n/a | os.readv -> Py_ssize_t |
---|
7941 | n/a | |
---|
7942 | n/a | fd: int |
---|
7943 | n/a | buffers: object |
---|
7944 | n/a | / |
---|
7945 | n/a | |
---|
7946 | n/a | Read from a file descriptor fd into an iterable of buffers. |
---|
7947 | n/a | |
---|
7948 | n/a | The buffers should be mutable buffers accepting bytes. |
---|
7949 | n/a | readv will transfer data into each buffer until it is full |
---|
7950 | n/a | and then move on to the next buffer in the sequence to hold |
---|
7951 | n/a | the rest of the data. |
---|
7952 | n/a | |
---|
7953 | n/a | readv returns the total number of bytes read, |
---|
7954 | n/a | which may be less than the total capacity of all the buffers. |
---|
7955 | n/a | [clinic start generated code]*/ |
---|
7956 | n/a | |
---|
7957 | n/a | static Py_ssize_t |
---|
7958 | n/a | os_readv_impl(PyObject *module, int fd, PyObject *buffers) |
---|
7959 | n/a | /*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/ |
---|
7960 | n/a | { |
---|
7961 | n/a | int cnt; |
---|
7962 | n/a | Py_ssize_t n; |
---|
7963 | n/a | int async_err = 0; |
---|
7964 | n/a | struct iovec *iov; |
---|
7965 | n/a | Py_buffer *buf; |
---|
7966 | n/a | |
---|
7967 | n/a | if (!PySequence_Check(buffers)) { |
---|
7968 | n/a | PyErr_SetString(PyExc_TypeError, |
---|
7969 | n/a | "readv() arg 2 must be a sequence"); |
---|
7970 | n/a | return -1; |
---|
7971 | n/a | } |
---|
7972 | n/a | |
---|
7973 | n/a | cnt = PySequence_Size(buffers); |
---|
7974 | n/a | |
---|
7975 | n/a | if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) |
---|
7976 | n/a | return -1; |
---|
7977 | n/a | |
---|
7978 | n/a | do { |
---|
7979 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
7980 | n/a | n = readv(fd, iov, cnt); |
---|
7981 | n/a | Py_END_ALLOW_THREADS |
---|
7982 | n/a | } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); |
---|
7983 | n/a | |
---|
7984 | n/a | iov_cleanup(iov, buf, cnt); |
---|
7985 | n/a | if (n < 0) { |
---|
7986 | n/a | if (!async_err) |
---|
7987 | n/a | posix_error(); |
---|
7988 | n/a | return -1; |
---|
7989 | n/a | } |
---|
7990 | n/a | |
---|
7991 | n/a | return n; |
---|
7992 | n/a | } |
---|
7993 | n/a | #endif /* HAVE_READV */ |
---|
7994 | n/a | |
---|
7995 | n/a | |
---|
7996 | n/a | #ifdef HAVE_PREAD |
---|
7997 | n/a | /*[clinic input] |
---|
7998 | n/a | # TODO length should be size_t! but Python doesn't support parsing size_t yet. |
---|
7999 | n/a | os.pread |
---|
8000 | n/a | |
---|
8001 | n/a | fd: int |
---|
8002 | n/a | length: int |
---|
8003 | n/a | offset: Py_off_t |
---|
8004 | n/a | / |
---|
8005 | n/a | |
---|
8006 | n/a | Read a number of bytes from a file descriptor starting at a particular offset. |
---|
8007 | n/a | |
---|
8008 | n/a | Read length bytes from file descriptor fd, starting at offset bytes from |
---|
8009 | n/a | the beginning of the file. The file offset remains unchanged. |
---|
8010 | n/a | [clinic start generated code]*/ |
---|
8011 | n/a | |
---|
8012 | n/a | static PyObject * |
---|
8013 | n/a | os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset) |
---|
8014 | n/a | /*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/ |
---|
8015 | n/a | { |
---|
8016 | n/a | Py_ssize_t n; |
---|
8017 | n/a | int async_err = 0; |
---|
8018 | n/a | PyObject *buffer; |
---|
8019 | n/a | |
---|
8020 | n/a | if (length < 0) { |
---|
8021 | n/a | errno = EINVAL; |
---|
8022 | n/a | return posix_error(); |
---|
8023 | n/a | } |
---|
8024 | n/a | buffer = PyBytes_FromStringAndSize((char *)NULL, length); |
---|
8025 | n/a | if (buffer == NULL) |
---|
8026 | n/a | return NULL; |
---|
8027 | n/a | |
---|
8028 | n/a | do { |
---|
8029 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
8030 | n/a | _Py_BEGIN_SUPPRESS_IPH |
---|
8031 | n/a | n = pread(fd, PyBytes_AS_STRING(buffer), length, offset); |
---|
8032 | n/a | _Py_END_SUPPRESS_IPH |
---|
8033 | n/a | Py_END_ALLOW_THREADS |
---|
8034 | n/a | } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); |
---|
8035 | n/a | |
---|
8036 | n/a | if (n < 0) { |
---|
8037 | n/a | Py_DECREF(buffer); |
---|
8038 | n/a | return (!async_err) ? posix_error() : NULL; |
---|
8039 | n/a | } |
---|
8040 | n/a | if (n != length) |
---|
8041 | n/a | _PyBytes_Resize(&buffer, n); |
---|
8042 | n/a | return buffer; |
---|
8043 | n/a | } |
---|
8044 | n/a | #endif /* HAVE_PREAD */ |
---|
8045 | n/a | |
---|
8046 | n/a | |
---|
8047 | n/a | /*[clinic input] |
---|
8048 | n/a | os.write -> Py_ssize_t |
---|
8049 | n/a | |
---|
8050 | n/a | fd: int |
---|
8051 | n/a | data: Py_buffer |
---|
8052 | n/a | / |
---|
8053 | n/a | |
---|
8054 | n/a | Write a bytes object to a file descriptor. |
---|
8055 | n/a | [clinic start generated code]*/ |
---|
8056 | n/a | |
---|
8057 | n/a | static Py_ssize_t |
---|
8058 | n/a | os_write_impl(PyObject *module, int fd, Py_buffer *data) |
---|
8059 | n/a | /*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/ |
---|
8060 | n/a | { |
---|
8061 | n/a | return _Py_write(fd, data->buf, data->len); |
---|
8062 | n/a | } |
---|
8063 | n/a | |
---|
8064 | n/a | #ifdef HAVE_SENDFILE |
---|
8065 | n/a | PyDoc_STRVAR(posix_sendfile__doc__, |
---|
8066 | n/a | "sendfile(out, in, offset, count) -> byteswritten\n\ |
---|
8067 | n/a | sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\ |
---|
8068 | n/a | -> byteswritten\n\ |
---|
8069 | n/a | Copy count bytes from file descriptor in to file descriptor out."); |
---|
8070 | n/a | |
---|
8071 | n/a | /* AC 3.5: don't bother converting, has optional group*/ |
---|
8072 | n/a | static PyObject * |
---|
8073 | n/a | posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict) |
---|
8074 | n/a | { |
---|
8075 | n/a | int in, out; |
---|
8076 | n/a | Py_ssize_t ret; |
---|
8077 | n/a | int async_err = 0; |
---|
8078 | n/a | off_t offset; |
---|
8079 | n/a | |
---|
8080 | n/a | #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__) |
---|
8081 | n/a | #ifndef __APPLE__ |
---|
8082 | n/a | Py_ssize_t len; |
---|
8083 | n/a | #endif |
---|
8084 | n/a | PyObject *headers = NULL, *trailers = NULL; |
---|
8085 | n/a | Py_buffer *hbuf, *tbuf; |
---|
8086 | n/a | off_t sbytes; |
---|
8087 | n/a | struct sf_hdtr sf; |
---|
8088 | n/a | int flags = 0; |
---|
8089 | n/a | /* Beware that "in" clashes with Python's own "in" operator keyword */ |
---|
8090 | n/a | static char *keywords[] = {"out", "in", |
---|
8091 | n/a | "offset", "count", |
---|
8092 | n/a | "headers", "trailers", "flags", NULL}; |
---|
8093 | n/a | |
---|
8094 | n/a | sf.headers = NULL; |
---|
8095 | n/a | sf.trailers = NULL; |
---|
8096 | n/a | |
---|
8097 | n/a | #ifdef __APPLE__ |
---|
8098 | n/a | if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile", |
---|
8099 | n/a | keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes, |
---|
8100 | n/a | #else |
---|
8101 | n/a | if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile", |
---|
8102 | n/a | keywords, &out, &in, Py_off_t_converter, &offset, &len, |
---|
8103 | n/a | #endif |
---|
8104 | n/a | &headers, &trailers, &flags)) |
---|
8105 | n/a | return NULL; |
---|
8106 | n/a | if (headers != NULL) { |
---|
8107 | n/a | if (!PySequence_Check(headers)) { |
---|
8108 | n/a | PyErr_SetString(PyExc_TypeError, |
---|
8109 | n/a | "sendfile() headers must be a sequence"); |
---|
8110 | n/a | return NULL; |
---|
8111 | n/a | } else { |
---|
8112 | n/a | Py_ssize_t i = 0; /* Avoid uninitialized warning */ |
---|
8113 | n/a | sf.hdr_cnt = PySequence_Size(headers); |
---|
8114 | n/a | if (sf.hdr_cnt > 0 && |
---|
8115 | n/a | (i = iov_setup(&(sf.headers), &hbuf, |
---|
8116 | n/a | headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0) |
---|
8117 | n/a | return NULL; |
---|
8118 | n/a | #ifdef __APPLE__ |
---|
8119 | n/a | sbytes += i; |
---|
8120 | n/a | #endif |
---|
8121 | n/a | } |
---|
8122 | n/a | } |
---|
8123 | n/a | if (trailers != NULL) { |
---|
8124 | n/a | if (!PySequence_Check(trailers)) { |
---|
8125 | n/a | PyErr_SetString(PyExc_TypeError, |
---|
8126 | n/a | "sendfile() trailers must be a sequence"); |
---|
8127 | n/a | return NULL; |
---|
8128 | n/a | } else { |
---|
8129 | n/a | Py_ssize_t i = 0; /* Avoid uninitialized warning */ |
---|
8130 | n/a | sf.trl_cnt = PySequence_Size(trailers); |
---|
8131 | n/a | if (sf.trl_cnt > 0 && |
---|
8132 | n/a | (i = iov_setup(&(sf.trailers), &tbuf, |
---|
8133 | n/a | trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0) |
---|
8134 | n/a | return NULL; |
---|
8135 | n/a | #ifdef __APPLE__ |
---|
8136 | n/a | sbytes += i; |
---|
8137 | n/a | #endif |
---|
8138 | n/a | } |
---|
8139 | n/a | } |
---|
8140 | n/a | |
---|
8141 | n/a | _Py_BEGIN_SUPPRESS_IPH |
---|
8142 | n/a | do { |
---|
8143 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
8144 | n/a | #ifdef __APPLE__ |
---|
8145 | n/a | ret = sendfile(in, out, offset, &sbytes, &sf, flags); |
---|
8146 | n/a | #else |
---|
8147 | n/a | ret = sendfile(in, out, offset, len, &sf, &sbytes, flags); |
---|
8148 | n/a | #endif |
---|
8149 | n/a | Py_END_ALLOW_THREADS |
---|
8150 | n/a | } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); |
---|
8151 | n/a | _Py_END_SUPPRESS_IPH |
---|
8152 | n/a | |
---|
8153 | n/a | if (sf.headers != NULL) |
---|
8154 | n/a | iov_cleanup(sf.headers, hbuf, sf.hdr_cnt); |
---|
8155 | n/a | if (sf.trailers != NULL) |
---|
8156 | n/a | iov_cleanup(sf.trailers, tbuf, sf.trl_cnt); |
---|
8157 | n/a | |
---|
8158 | n/a | if (ret < 0) { |
---|
8159 | n/a | if ((errno == EAGAIN) || (errno == EBUSY)) { |
---|
8160 | n/a | if (sbytes != 0) { |
---|
8161 | n/a | // some data has been sent |
---|
8162 | n/a | goto done; |
---|
8163 | n/a | } |
---|
8164 | n/a | else { |
---|
8165 | n/a | // no data has been sent; upper application is supposed |
---|
8166 | n/a | // to retry on EAGAIN or EBUSY |
---|
8167 | n/a | return posix_error(); |
---|
8168 | n/a | } |
---|
8169 | n/a | } |
---|
8170 | n/a | return (!async_err) ? posix_error() : NULL; |
---|
8171 | n/a | } |
---|
8172 | n/a | goto done; |
---|
8173 | n/a | |
---|
8174 | n/a | done: |
---|
8175 | n/a | #if !defined(HAVE_LARGEFILE_SUPPORT) |
---|
8176 | n/a | return Py_BuildValue("l", sbytes); |
---|
8177 | n/a | #else |
---|
8178 | n/a | return Py_BuildValue("L", sbytes); |
---|
8179 | n/a | #endif |
---|
8180 | n/a | |
---|
8181 | n/a | #else |
---|
8182 | n/a | Py_ssize_t count; |
---|
8183 | n/a | PyObject *offobj; |
---|
8184 | n/a | static char *keywords[] = {"out", "in", |
---|
8185 | n/a | "offset", "count", NULL}; |
---|
8186 | n/a | if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile", |
---|
8187 | n/a | keywords, &out, &in, &offobj, &count)) |
---|
8188 | n/a | return NULL; |
---|
8189 | n/a | #ifdef __linux__ |
---|
8190 | n/a | if (offobj == Py_None) { |
---|
8191 | n/a | do { |
---|
8192 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
8193 | n/a | ret = sendfile(out, in, NULL, count); |
---|
8194 | n/a | Py_END_ALLOW_THREADS |
---|
8195 | n/a | } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); |
---|
8196 | n/a | if (ret < 0) |
---|
8197 | n/a | return (!async_err) ? posix_error() : NULL; |
---|
8198 | n/a | return Py_BuildValue("n", ret); |
---|
8199 | n/a | } |
---|
8200 | n/a | #endif |
---|
8201 | n/a | if (!Py_off_t_converter(offobj, &offset)) |
---|
8202 | n/a | return NULL; |
---|
8203 | n/a | |
---|
8204 | n/a | do { |
---|
8205 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
8206 | n/a | ret = sendfile(out, in, &offset, count); |
---|
8207 | n/a | Py_END_ALLOW_THREADS |
---|
8208 | n/a | } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); |
---|
8209 | n/a | if (ret < 0) |
---|
8210 | n/a | return (!async_err) ? posix_error() : NULL; |
---|
8211 | n/a | return Py_BuildValue("n", ret); |
---|
8212 | n/a | #endif |
---|
8213 | n/a | } |
---|
8214 | n/a | #endif /* HAVE_SENDFILE */ |
---|
8215 | n/a | |
---|
8216 | n/a | |
---|
8217 | n/a | /*[clinic input] |
---|
8218 | n/a | os.fstat |
---|
8219 | n/a | |
---|
8220 | n/a | fd : int |
---|
8221 | n/a | |
---|
8222 | n/a | Perform a stat system call on the given file descriptor. |
---|
8223 | n/a | |
---|
8224 | n/a | Like stat(), but for an open file descriptor. |
---|
8225 | n/a | Equivalent to os.stat(fd). |
---|
8226 | n/a | [clinic start generated code]*/ |
---|
8227 | n/a | |
---|
8228 | n/a | static PyObject * |
---|
8229 | n/a | os_fstat_impl(PyObject *module, int fd) |
---|
8230 | n/a | /*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/ |
---|
8231 | n/a | { |
---|
8232 | n/a | STRUCT_STAT st; |
---|
8233 | n/a | int res; |
---|
8234 | n/a | int async_err = 0; |
---|
8235 | n/a | |
---|
8236 | n/a | do { |
---|
8237 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
8238 | n/a | res = FSTAT(fd, &st); |
---|
8239 | n/a | Py_END_ALLOW_THREADS |
---|
8240 | n/a | } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); |
---|
8241 | n/a | if (res != 0) { |
---|
8242 | n/a | #ifdef MS_WINDOWS |
---|
8243 | n/a | return PyErr_SetFromWindowsErr(0); |
---|
8244 | n/a | #else |
---|
8245 | n/a | return (!async_err) ? posix_error() : NULL; |
---|
8246 | n/a | #endif |
---|
8247 | n/a | } |
---|
8248 | n/a | |
---|
8249 | n/a | return _pystat_fromstructstat(&st); |
---|
8250 | n/a | } |
---|
8251 | n/a | |
---|
8252 | n/a | |
---|
8253 | n/a | /*[clinic input] |
---|
8254 | n/a | os.isatty -> bool |
---|
8255 | n/a | fd: int |
---|
8256 | n/a | / |
---|
8257 | n/a | |
---|
8258 | n/a | Return True if the fd is connected to a terminal. |
---|
8259 | n/a | |
---|
8260 | n/a | Return True if the file descriptor is an open file descriptor |
---|
8261 | n/a | connected to the slave end of a terminal. |
---|
8262 | n/a | [clinic start generated code]*/ |
---|
8263 | n/a | |
---|
8264 | n/a | static int |
---|
8265 | n/a | os_isatty_impl(PyObject *module, int fd) |
---|
8266 | n/a | /*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/ |
---|
8267 | n/a | { |
---|
8268 | n/a | int return_value; |
---|
8269 | n/a | _Py_BEGIN_SUPPRESS_IPH |
---|
8270 | n/a | return_value = isatty(fd); |
---|
8271 | n/a | _Py_END_SUPPRESS_IPH |
---|
8272 | n/a | return return_value; |
---|
8273 | n/a | } |
---|
8274 | n/a | |
---|
8275 | n/a | |
---|
8276 | n/a | #ifdef HAVE_PIPE |
---|
8277 | n/a | /*[clinic input] |
---|
8278 | n/a | os.pipe |
---|
8279 | n/a | |
---|
8280 | n/a | Create a pipe. |
---|
8281 | n/a | |
---|
8282 | n/a | Returns a tuple of two file descriptors: |
---|
8283 | n/a | (read_fd, write_fd) |
---|
8284 | n/a | [clinic start generated code]*/ |
---|
8285 | n/a | |
---|
8286 | n/a | static PyObject * |
---|
8287 | n/a | os_pipe_impl(PyObject *module) |
---|
8288 | n/a | /*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/ |
---|
8289 | n/a | { |
---|
8290 | n/a | int fds[2]; |
---|
8291 | n/a | #ifdef MS_WINDOWS |
---|
8292 | n/a | HANDLE read, write; |
---|
8293 | n/a | SECURITY_ATTRIBUTES attr; |
---|
8294 | n/a | BOOL ok; |
---|
8295 | n/a | #else |
---|
8296 | n/a | int res; |
---|
8297 | n/a | #endif |
---|
8298 | n/a | |
---|
8299 | n/a | #ifdef MS_WINDOWS |
---|
8300 | n/a | attr.nLength = sizeof(attr); |
---|
8301 | n/a | attr.lpSecurityDescriptor = NULL; |
---|
8302 | n/a | attr.bInheritHandle = FALSE; |
---|
8303 | n/a | |
---|
8304 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
8305 | n/a | _Py_BEGIN_SUPPRESS_IPH |
---|
8306 | n/a | ok = CreatePipe(&read, &write, &attr, 0); |
---|
8307 | n/a | if (ok) { |
---|
8308 | n/a | fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY); |
---|
8309 | n/a | fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY); |
---|
8310 | n/a | if (fds[0] == -1 || fds[1] == -1) { |
---|
8311 | n/a | CloseHandle(read); |
---|
8312 | n/a | CloseHandle(write); |
---|
8313 | n/a | ok = 0; |
---|
8314 | n/a | } |
---|
8315 | n/a | } |
---|
8316 | n/a | _Py_END_SUPPRESS_IPH |
---|
8317 | n/a | Py_END_ALLOW_THREADS |
---|
8318 | n/a | |
---|
8319 | n/a | if (!ok) |
---|
8320 | n/a | return PyErr_SetFromWindowsErr(0); |
---|
8321 | n/a | #else |
---|
8322 | n/a | |
---|
8323 | n/a | #ifdef HAVE_PIPE2 |
---|
8324 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
8325 | n/a | res = pipe2(fds, O_CLOEXEC); |
---|
8326 | n/a | Py_END_ALLOW_THREADS |
---|
8327 | n/a | |
---|
8328 | n/a | if (res != 0 && errno == ENOSYS) |
---|
8329 | n/a | { |
---|
8330 | n/a | #endif |
---|
8331 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
8332 | n/a | res = pipe(fds); |
---|
8333 | n/a | Py_END_ALLOW_THREADS |
---|
8334 | n/a | |
---|
8335 | n/a | if (res == 0) { |
---|
8336 | n/a | if (_Py_set_inheritable(fds[0], 0, NULL) < 0) { |
---|
8337 | n/a | close(fds[0]); |
---|
8338 | n/a | close(fds[1]); |
---|
8339 | n/a | return NULL; |
---|
8340 | n/a | } |
---|
8341 | n/a | if (_Py_set_inheritable(fds[1], 0, NULL) < 0) { |
---|
8342 | n/a | close(fds[0]); |
---|
8343 | n/a | close(fds[1]); |
---|
8344 | n/a | return NULL; |
---|
8345 | n/a | } |
---|
8346 | n/a | } |
---|
8347 | n/a | #ifdef HAVE_PIPE2 |
---|
8348 | n/a | } |
---|
8349 | n/a | #endif |
---|
8350 | n/a | |
---|
8351 | n/a | if (res != 0) |
---|
8352 | n/a | return PyErr_SetFromErrno(PyExc_OSError); |
---|
8353 | n/a | #endif /* !MS_WINDOWS */ |
---|
8354 | n/a | return Py_BuildValue("(ii)", fds[0], fds[1]); |
---|
8355 | n/a | } |
---|
8356 | n/a | #endif /* HAVE_PIPE */ |
---|
8357 | n/a | |
---|
8358 | n/a | |
---|
8359 | n/a | #ifdef HAVE_PIPE2 |
---|
8360 | n/a | /*[clinic input] |
---|
8361 | n/a | os.pipe2 |
---|
8362 | n/a | |
---|
8363 | n/a | flags: int |
---|
8364 | n/a | / |
---|
8365 | n/a | |
---|
8366 | n/a | Create a pipe with flags set atomically. |
---|
8367 | n/a | |
---|
8368 | n/a | Returns a tuple of two file descriptors: |
---|
8369 | n/a | (read_fd, write_fd) |
---|
8370 | n/a | |
---|
8371 | n/a | flags can be constructed by ORing together one or more of these values: |
---|
8372 | n/a | O_NONBLOCK, O_CLOEXEC. |
---|
8373 | n/a | [clinic start generated code]*/ |
---|
8374 | n/a | |
---|
8375 | n/a | static PyObject * |
---|
8376 | n/a | os_pipe2_impl(PyObject *module, int flags) |
---|
8377 | n/a | /*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/ |
---|
8378 | n/a | { |
---|
8379 | n/a | int fds[2]; |
---|
8380 | n/a | int res; |
---|
8381 | n/a | |
---|
8382 | n/a | res = pipe2(fds, flags); |
---|
8383 | n/a | if (res != 0) |
---|
8384 | n/a | return posix_error(); |
---|
8385 | n/a | return Py_BuildValue("(ii)", fds[0], fds[1]); |
---|
8386 | n/a | } |
---|
8387 | n/a | #endif /* HAVE_PIPE2 */ |
---|
8388 | n/a | |
---|
8389 | n/a | |
---|
8390 | n/a | #ifdef HAVE_WRITEV |
---|
8391 | n/a | /*[clinic input] |
---|
8392 | n/a | os.writev -> Py_ssize_t |
---|
8393 | n/a | fd: int |
---|
8394 | n/a | buffers: object |
---|
8395 | n/a | / |
---|
8396 | n/a | |
---|
8397 | n/a | Iterate over buffers, and write the contents of each to a file descriptor. |
---|
8398 | n/a | |
---|
8399 | n/a | Returns the total number of bytes written. |
---|
8400 | n/a | buffers must be a sequence of bytes-like objects. |
---|
8401 | n/a | [clinic start generated code]*/ |
---|
8402 | n/a | |
---|
8403 | n/a | static Py_ssize_t |
---|
8404 | n/a | os_writev_impl(PyObject *module, int fd, PyObject *buffers) |
---|
8405 | n/a | /*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/ |
---|
8406 | n/a | { |
---|
8407 | n/a | int cnt; |
---|
8408 | n/a | Py_ssize_t result; |
---|
8409 | n/a | int async_err = 0; |
---|
8410 | n/a | struct iovec *iov; |
---|
8411 | n/a | Py_buffer *buf; |
---|
8412 | n/a | |
---|
8413 | n/a | if (!PySequence_Check(buffers)) { |
---|
8414 | n/a | PyErr_SetString(PyExc_TypeError, |
---|
8415 | n/a | "writev() arg 2 must be a sequence"); |
---|
8416 | n/a | return -1; |
---|
8417 | n/a | } |
---|
8418 | n/a | cnt = PySequence_Size(buffers); |
---|
8419 | n/a | |
---|
8420 | n/a | if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) { |
---|
8421 | n/a | return -1; |
---|
8422 | n/a | } |
---|
8423 | n/a | |
---|
8424 | n/a | do { |
---|
8425 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
8426 | n/a | result = writev(fd, iov, cnt); |
---|
8427 | n/a | Py_END_ALLOW_THREADS |
---|
8428 | n/a | } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); |
---|
8429 | n/a | |
---|
8430 | n/a | iov_cleanup(iov, buf, cnt); |
---|
8431 | n/a | if (result < 0 && !async_err) |
---|
8432 | n/a | posix_error(); |
---|
8433 | n/a | |
---|
8434 | n/a | return result; |
---|
8435 | n/a | } |
---|
8436 | n/a | #endif /* HAVE_WRITEV */ |
---|
8437 | n/a | |
---|
8438 | n/a | |
---|
8439 | n/a | #ifdef HAVE_PWRITE |
---|
8440 | n/a | /*[clinic input] |
---|
8441 | n/a | os.pwrite -> Py_ssize_t |
---|
8442 | n/a | |
---|
8443 | n/a | fd: int |
---|
8444 | n/a | buffer: Py_buffer |
---|
8445 | n/a | offset: Py_off_t |
---|
8446 | n/a | / |
---|
8447 | n/a | |
---|
8448 | n/a | Write bytes to a file descriptor starting at a particular offset. |
---|
8449 | n/a | |
---|
8450 | n/a | Write buffer to fd, starting at offset bytes from the beginning of |
---|
8451 | n/a | the file. Returns the number of bytes writte. Does not change the |
---|
8452 | n/a | current file offset. |
---|
8453 | n/a | [clinic start generated code]*/ |
---|
8454 | n/a | |
---|
8455 | n/a | static Py_ssize_t |
---|
8456 | n/a | os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset) |
---|
8457 | n/a | /*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/ |
---|
8458 | n/a | { |
---|
8459 | n/a | Py_ssize_t size; |
---|
8460 | n/a | int async_err = 0; |
---|
8461 | n/a | |
---|
8462 | n/a | do { |
---|
8463 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
8464 | n/a | _Py_BEGIN_SUPPRESS_IPH |
---|
8465 | n/a | size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset); |
---|
8466 | n/a | _Py_END_SUPPRESS_IPH |
---|
8467 | n/a | Py_END_ALLOW_THREADS |
---|
8468 | n/a | } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); |
---|
8469 | n/a | |
---|
8470 | n/a | if (size < 0 && !async_err) |
---|
8471 | n/a | posix_error(); |
---|
8472 | n/a | return size; |
---|
8473 | n/a | } |
---|
8474 | n/a | #endif /* HAVE_PWRITE */ |
---|
8475 | n/a | |
---|
8476 | n/a | |
---|
8477 | n/a | #ifdef HAVE_MKFIFO |
---|
8478 | n/a | /*[clinic input] |
---|
8479 | n/a | os.mkfifo |
---|
8480 | n/a | |
---|
8481 | n/a | path: path_t |
---|
8482 | n/a | mode: int=0o666 |
---|
8483 | n/a | * |
---|
8484 | n/a | dir_fd: dir_fd(requires='mkfifoat')=None |
---|
8485 | n/a | |
---|
8486 | n/a | Create a "fifo" (a POSIX named pipe). |
---|
8487 | n/a | |
---|
8488 | n/a | If dir_fd is not None, it should be a file descriptor open to a directory, |
---|
8489 | n/a | and path should be relative; path will then be relative to that directory. |
---|
8490 | n/a | dir_fd may not be implemented on your platform. |
---|
8491 | n/a | If it is unavailable, using it will raise a NotImplementedError. |
---|
8492 | n/a | [clinic start generated code]*/ |
---|
8493 | n/a | |
---|
8494 | n/a | static PyObject * |
---|
8495 | n/a | os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd) |
---|
8496 | n/a | /*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/ |
---|
8497 | n/a | { |
---|
8498 | n/a | int result; |
---|
8499 | n/a | int async_err = 0; |
---|
8500 | n/a | |
---|
8501 | n/a | do { |
---|
8502 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
8503 | n/a | #ifdef HAVE_MKFIFOAT |
---|
8504 | n/a | if (dir_fd != DEFAULT_DIR_FD) |
---|
8505 | n/a | result = mkfifoat(dir_fd, path->narrow, mode); |
---|
8506 | n/a | else |
---|
8507 | n/a | #endif |
---|
8508 | n/a | result = mkfifo(path->narrow, mode); |
---|
8509 | n/a | Py_END_ALLOW_THREADS |
---|
8510 | n/a | } while (result != 0 && errno == EINTR && |
---|
8511 | n/a | !(async_err = PyErr_CheckSignals())); |
---|
8512 | n/a | if (result != 0) |
---|
8513 | n/a | return (!async_err) ? posix_error() : NULL; |
---|
8514 | n/a | |
---|
8515 | n/a | Py_RETURN_NONE; |
---|
8516 | n/a | } |
---|
8517 | n/a | #endif /* HAVE_MKFIFO */ |
---|
8518 | n/a | |
---|
8519 | n/a | |
---|
8520 | n/a | #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) |
---|
8521 | n/a | /*[clinic input] |
---|
8522 | n/a | os.mknod |
---|
8523 | n/a | |
---|
8524 | n/a | path: path_t |
---|
8525 | n/a | mode: int=0o600 |
---|
8526 | n/a | device: dev_t=0 |
---|
8527 | n/a | * |
---|
8528 | n/a | dir_fd: dir_fd(requires='mknodat')=None |
---|
8529 | n/a | |
---|
8530 | n/a | Create a node in the file system. |
---|
8531 | n/a | |
---|
8532 | n/a | Create a node in the file system (file, device special file or named pipe) |
---|
8533 | n/a | at path. mode specifies both the permissions to use and the |
---|
8534 | n/a | type of node to be created, being combined (bitwise OR) with one of |
---|
8535 | n/a | S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode, |
---|
8536 | n/a | device defines the newly created device special file (probably using |
---|
8537 | n/a | os.makedev()). Otherwise device is ignored. |
---|
8538 | n/a | |
---|
8539 | n/a | If dir_fd is not None, it should be a file descriptor open to a directory, |
---|
8540 | n/a | and path should be relative; path will then be relative to that directory. |
---|
8541 | n/a | dir_fd may not be implemented on your platform. |
---|
8542 | n/a | If it is unavailable, using it will raise a NotImplementedError. |
---|
8543 | n/a | [clinic start generated code]*/ |
---|
8544 | n/a | |
---|
8545 | n/a | static PyObject * |
---|
8546 | n/a | os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device, |
---|
8547 | n/a | int dir_fd) |
---|
8548 | n/a | /*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/ |
---|
8549 | n/a | { |
---|
8550 | n/a | int result; |
---|
8551 | n/a | int async_err = 0; |
---|
8552 | n/a | |
---|
8553 | n/a | do { |
---|
8554 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
8555 | n/a | #ifdef HAVE_MKNODAT |
---|
8556 | n/a | if (dir_fd != DEFAULT_DIR_FD) |
---|
8557 | n/a | result = mknodat(dir_fd, path->narrow, mode, device); |
---|
8558 | n/a | else |
---|
8559 | n/a | #endif |
---|
8560 | n/a | result = mknod(path->narrow, mode, device); |
---|
8561 | n/a | Py_END_ALLOW_THREADS |
---|
8562 | n/a | } while (result != 0 && errno == EINTR && |
---|
8563 | n/a | !(async_err = PyErr_CheckSignals())); |
---|
8564 | n/a | if (result != 0) |
---|
8565 | n/a | return (!async_err) ? posix_error() : NULL; |
---|
8566 | n/a | |
---|
8567 | n/a | Py_RETURN_NONE; |
---|
8568 | n/a | } |
---|
8569 | n/a | #endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */ |
---|
8570 | n/a | |
---|
8571 | n/a | |
---|
8572 | n/a | #ifdef HAVE_DEVICE_MACROS |
---|
8573 | n/a | /*[clinic input] |
---|
8574 | n/a | os.major -> unsigned_int |
---|
8575 | n/a | |
---|
8576 | n/a | device: dev_t |
---|
8577 | n/a | / |
---|
8578 | n/a | |
---|
8579 | n/a | Extracts a device major number from a raw device number. |
---|
8580 | n/a | [clinic start generated code]*/ |
---|
8581 | n/a | |
---|
8582 | n/a | static unsigned int |
---|
8583 | n/a | os_major_impl(PyObject *module, dev_t device) |
---|
8584 | n/a | /*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/ |
---|
8585 | n/a | { |
---|
8586 | n/a | return major(device); |
---|
8587 | n/a | } |
---|
8588 | n/a | |
---|
8589 | n/a | |
---|
8590 | n/a | /*[clinic input] |
---|
8591 | n/a | os.minor -> unsigned_int |
---|
8592 | n/a | |
---|
8593 | n/a | device: dev_t |
---|
8594 | n/a | / |
---|
8595 | n/a | |
---|
8596 | n/a | Extracts a device minor number from a raw device number. |
---|
8597 | n/a | [clinic start generated code]*/ |
---|
8598 | n/a | |
---|
8599 | n/a | static unsigned int |
---|
8600 | n/a | os_minor_impl(PyObject *module, dev_t device) |
---|
8601 | n/a | /*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/ |
---|
8602 | n/a | { |
---|
8603 | n/a | return minor(device); |
---|
8604 | n/a | } |
---|
8605 | n/a | |
---|
8606 | n/a | |
---|
8607 | n/a | /*[clinic input] |
---|
8608 | n/a | os.makedev -> dev_t |
---|
8609 | n/a | |
---|
8610 | n/a | major: int |
---|
8611 | n/a | minor: int |
---|
8612 | n/a | / |
---|
8613 | n/a | |
---|
8614 | n/a | Composes a raw device number from the major and minor device numbers. |
---|
8615 | n/a | [clinic start generated code]*/ |
---|
8616 | n/a | |
---|
8617 | n/a | static dev_t |
---|
8618 | n/a | os_makedev_impl(PyObject *module, int major, int minor) |
---|
8619 | n/a | /*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/ |
---|
8620 | n/a | { |
---|
8621 | n/a | return makedev(major, minor); |
---|
8622 | n/a | } |
---|
8623 | n/a | #endif /* HAVE_DEVICE_MACROS */ |
---|
8624 | n/a | |
---|
8625 | n/a | |
---|
8626 | n/a | #if defined HAVE_FTRUNCATE || defined MS_WINDOWS |
---|
8627 | n/a | /*[clinic input] |
---|
8628 | n/a | os.ftruncate |
---|
8629 | n/a | |
---|
8630 | n/a | fd: int |
---|
8631 | n/a | length: Py_off_t |
---|
8632 | n/a | / |
---|
8633 | n/a | |
---|
8634 | n/a | Truncate a file, specified by file descriptor, to a specific length. |
---|
8635 | n/a | [clinic start generated code]*/ |
---|
8636 | n/a | |
---|
8637 | n/a | static PyObject * |
---|
8638 | n/a | os_ftruncate_impl(PyObject *module, int fd, Py_off_t length) |
---|
8639 | n/a | /*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/ |
---|
8640 | n/a | { |
---|
8641 | n/a | int result; |
---|
8642 | n/a | int async_err = 0; |
---|
8643 | n/a | |
---|
8644 | n/a | do { |
---|
8645 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
8646 | n/a | _Py_BEGIN_SUPPRESS_IPH |
---|
8647 | n/a | #ifdef MS_WINDOWS |
---|
8648 | n/a | result = _chsize_s(fd, length); |
---|
8649 | n/a | #else |
---|
8650 | n/a | result = ftruncate(fd, length); |
---|
8651 | n/a | #endif |
---|
8652 | n/a | _Py_END_SUPPRESS_IPH |
---|
8653 | n/a | Py_END_ALLOW_THREADS |
---|
8654 | n/a | } while (result != 0 && errno == EINTR && |
---|
8655 | n/a | !(async_err = PyErr_CheckSignals())); |
---|
8656 | n/a | if (result != 0) |
---|
8657 | n/a | return (!async_err) ? posix_error() : NULL; |
---|
8658 | n/a | Py_RETURN_NONE; |
---|
8659 | n/a | } |
---|
8660 | n/a | #endif /* HAVE_FTRUNCATE || MS_WINDOWS */ |
---|
8661 | n/a | |
---|
8662 | n/a | |
---|
8663 | n/a | #if defined HAVE_TRUNCATE || defined MS_WINDOWS |
---|
8664 | n/a | /*[clinic input] |
---|
8665 | n/a | os.truncate |
---|
8666 | n/a | path: path_t(allow_fd='PATH_HAVE_FTRUNCATE') |
---|
8667 | n/a | length: Py_off_t |
---|
8668 | n/a | |
---|
8669 | n/a | Truncate a file, specified by path, to a specific length. |
---|
8670 | n/a | |
---|
8671 | n/a | On some platforms, path may also be specified as an open file descriptor. |
---|
8672 | n/a | If this functionality is unavailable, using it raises an exception. |
---|
8673 | n/a | [clinic start generated code]*/ |
---|
8674 | n/a | |
---|
8675 | n/a | static PyObject * |
---|
8676 | n/a | os_truncate_impl(PyObject *module, path_t *path, Py_off_t length) |
---|
8677 | n/a | /*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/ |
---|
8678 | n/a | { |
---|
8679 | n/a | int result; |
---|
8680 | n/a | #ifdef MS_WINDOWS |
---|
8681 | n/a | int fd; |
---|
8682 | n/a | #endif |
---|
8683 | n/a | |
---|
8684 | n/a | if (path->fd != -1) |
---|
8685 | n/a | return os_ftruncate_impl(module, path->fd, length); |
---|
8686 | n/a | |
---|
8687 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
8688 | n/a | _Py_BEGIN_SUPPRESS_IPH |
---|
8689 | n/a | #ifdef MS_WINDOWS |
---|
8690 | n/a | fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT); |
---|
8691 | n/a | if (fd < 0) |
---|
8692 | n/a | result = -1; |
---|
8693 | n/a | else { |
---|
8694 | n/a | result = _chsize_s(fd, length); |
---|
8695 | n/a | close(fd); |
---|
8696 | n/a | if (result < 0) |
---|
8697 | n/a | errno = result; |
---|
8698 | n/a | } |
---|
8699 | n/a | #else |
---|
8700 | n/a | result = truncate(path->narrow, length); |
---|
8701 | n/a | #endif |
---|
8702 | n/a | _Py_END_SUPPRESS_IPH |
---|
8703 | n/a | Py_END_ALLOW_THREADS |
---|
8704 | n/a | if (result < 0) |
---|
8705 | n/a | return path_error(path); |
---|
8706 | n/a | |
---|
8707 | n/a | Py_RETURN_NONE; |
---|
8708 | n/a | } |
---|
8709 | n/a | #endif /* HAVE_TRUNCATE || MS_WINDOWS */ |
---|
8710 | n/a | |
---|
8711 | n/a | |
---|
8712 | n/a | /* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise() |
---|
8713 | n/a | and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is |
---|
8714 | n/a | defined, which is the case in Python on AIX. AIX bug report: |
---|
8715 | n/a | http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */ |
---|
8716 | n/a | #if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__) |
---|
8717 | n/a | # define POSIX_FADVISE_AIX_BUG |
---|
8718 | n/a | #endif |
---|
8719 | n/a | |
---|
8720 | n/a | |
---|
8721 | n/a | #if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG) |
---|
8722 | n/a | /*[clinic input] |
---|
8723 | n/a | os.posix_fallocate |
---|
8724 | n/a | |
---|
8725 | n/a | fd: int |
---|
8726 | n/a | offset: Py_off_t |
---|
8727 | n/a | length: Py_off_t |
---|
8728 | n/a | / |
---|
8729 | n/a | |
---|
8730 | n/a | Ensure a file has allocated at least a particular number of bytes on disk. |
---|
8731 | n/a | |
---|
8732 | n/a | Ensure that the file specified by fd encompasses a range of bytes |
---|
8733 | n/a | starting at offset bytes from the beginning and continuing for length bytes. |
---|
8734 | n/a | [clinic start generated code]*/ |
---|
8735 | n/a | |
---|
8736 | n/a | static PyObject * |
---|
8737 | n/a | os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset, |
---|
8738 | n/a | Py_off_t length) |
---|
8739 | n/a | /*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/ |
---|
8740 | n/a | { |
---|
8741 | n/a | int result; |
---|
8742 | n/a | int async_err = 0; |
---|
8743 | n/a | |
---|
8744 | n/a | do { |
---|
8745 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
8746 | n/a | result = posix_fallocate(fd, offset, length); |
---|
8747 | n/a | Py_END_ALLOW_THREADS |
---|
8748 | n/a | } while (result != 0 && errno == EINTR && |
---|
8749 | n/a | !(async_err = PyErr_CheckSignals())); |
---|
8750 | n/a | if (result != 0) |
---|
8751 | n/a | return (!async_err) ? posix_error() : NULL; |
---|
8752 | n/a | Py_RETURN_NONE; |
---|
8753 | n/a | } |
---|
8754 | n/a | #endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */ |
---|
8755 | n/a | |
---|
8756 | n/a | |
---|
8757 | n/a | #if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG) |
---|
8758 | n/a | /*[clinic input] |
---|
8759 | n/a | os.posix_fadvise |
---|
8760 | n/a | |
---|
8761 | n/a | fd: int |
---|
8762 | n/a | offset: Py_off_t |
---|
8763 | n/a | length: Py_off_t |
---|
8764 | n/a | advice: int |
---|
8765 | n/a | / |
---|
8766 | n/a | |
---|
8767 | n/a | Announce an intention to access data in a specific pattern. |
---|
8768 | n/a | |
---|
8769 | n/a | Announce an intention to access data in a specific pattern, thus allowing |
---|
8770 | n/a | the kernel to make optimizations. |
---|
8771 | n/a | The advice applies to the region of the file specified by fd starting at |
---|
8772 | n/a | offset and continuing for length bytes. |
---|
8773 | n/a | advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL, |
---|
8774 | n/a | POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or |
---|
8775 | n/a | POSIX_FADV_DONTNEED. |
---|
8776 | n/a | [clinic start generated code]*/ |
---|
8777 | n/a | |
---|
8778 | n/a | static PyObject * |
---|
8779 | n/a | os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset, |
---|
8780 | n/a | Py_off_t length, int advice) |
---|
8781 | n/a | /*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/ |
---|
8782 | n/a | { |
---|
8783 | n/a | int result; |
---|
8784 | n/a | int async_err = 0; |
---|
8785 | n/a | |
---|
8786 | n/a | do { |
---|
8787 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
8788 | n/a | result = posix_fadvise(fd, offset, length, advice); |
---|
8789 | n/a | Py_END_ALLOW_THREADS |
---|
8790 | n/a | } while (result != 0 && errno == EINTR && |
---|
8791 | n/a | !(async_err = PyErr_CheckSignals())); |
---|
8792 | n/a | if (result != 0) |
---|
8793 | n/a | return (!async_err) ? posix_error() : NULL; |
---|
8794 | n/a | Py_RETURN_NONE; |
---|
8795 | n/a | } |
---|
8796 | n/a | #endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */ |
---|
8797 | n/a | |
---|
8798 | n/a | #ifdef HAVE_PUTENV |
---|
8799 | n/a | |
---|
8800 | n/a | /* Save putenv() parameters as values here, so we can collect them when they |
---|
8801 | n/a | * get re-set with another call for the same key. */ |
---|
8802 | n/a | static PyObject *posix_putenv_garbage; |
---|
8803 | n/a | |
---|
8804 | n/a | static void |
---|
8805 | n/a | posix_putenv_garbage_setitem(PyObject *name, PyObject *value) |
---|
8806 | n/a | { |
---|
8807 | n/a | /* Install the first arg and newstr in posix_putenv_garbage; |
---|
8808 | n/a | * this will cause previous value to be collected. This has to |
---|
8809 | n/a | * happen after the real putenv() call because the old value |
---|
8810 | n/a | * was still accessible until then. */ |
---|
8811 | n/a | if (PyDict_SetItem(posix_putenv_garbage, name, value)) |
---|
8812 | n/a | /* really not much we can do; just leak */ |
---|
8813 | n/a | PyErr_Clear(); |
---|
8814 | n/a | else |
---|
8815 | n/a | Py_DECREF(value); |
---|
8816 | n/a | } |
---|
8817 | n/a | |
---|
8818 | n/a | |
---|
8819 | n/a | #ifdef MS_WINDOWS |
---|
8820 | n/a | /*[clinic input] |
---|
8821 | n/a | os.putenv |
---|
8822 | n/a | |
---|
8823 | n/a | name: unicode |
---|
8824 | n/a | value: unicode |
---|
8825 | n/a | / |
---|
8826 | n/a | |
---|
8827 | n/a | Change or add an environment variable. |
---|
8828 | n/a | [clinic start generated code]*/ |
---|
8829 | n/a | |
---|
8830 | n/a | static PyObject * |
---|
8831 | n/a | os_putenv_impl(PyObject *module, PyObject *name, PyObject *value) |
---|
8832 | n/a | /*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/ |
---|
8833 | n/a | { |
---|
8834 | n/a | const wchar_t *env; |
---|
8835 | n/a | |
---|
8836 | n/a | PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value); |
---|
8837 | n/a | if (unicode == NULL) { |
---|
8838 | n/a | PyErr_NoMemory(); |
---|
8839 | n/a | return NULL; |
---|
8840 | n/a | } |
---|
8841 | n/a | if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) { |
---|
8842 | n/a | PyErr_Format(PyExc_ValueError, |
---|
8843 | n/a | "the environment variable is longer than %u characters", |
---|
8844 | n/a | _MAX_ENV); |
---|
8845 | n/a | goto error; |
---|
8846 | n/a | } |
---|
8847 | n/a | |
---|
8848 | n/a | env = PyUnicode_AsUnicode(unicode); |
---|
8849 | n/a | if (env == NULL) |
---|
8850 | n/a | goto error; |
---|
8851 | n/a | if (_wputenv(env)) { |
---|
8852 | n/a | posix_error(); |
---|
8853 | n/a | goto error; |
---|
8854 | n/a | } |
---|
8855 | n/a | |
---|
8856 | n/a | posix_putenv_garbage_setitem(name, unicode); |
---|
8857 | n/a | Py_RETURN_NONE; |
---|
8858 | n/a | |
---|
8859 | n/a | error: |
---|
8860 | n/a | Py_DECREF(unicode); |
---|
8861 | n/a | return NULL; |
---|
8862 | n/a | } |
---|
8863 | n/a | #else /* MS_WINDOWS */ |
---|
8864 | n/a | /*[clinic input] |
---|
8865 | n/a | os.putenv |
---|
8866 | n/a | |
---|
8867 | n/a | name: FSConverter |
---|
8868 | n/a | value: FSConverter |
---|
8869 | n/a | / |
---|
8870 | n/a | |
---|
8871 | n/a | Change or add an environment variable. |
---|
8872 | n/a | [clinic start generated code]*/ |
---|
8873 | n/a | |
---|
8874 | n/a | static PyObject * |
---|
8875 | n/a | os_putenv_impl(PyObject *module, PyObject *name, PyObject *value) |
---|
8876 | n/a | /*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/ |
---|
8877 | n/a | { |
---|
8878 | n/a | PyObject *bytes = NULL; |
---|
8879 | n/a | char *env; |
---|
8880 | n/a | const char *name_string = PyBytes_AsString(name); |
---|
8881 | n/a | const char *value_string = PyBytes_AsString(value); |
---|
8882 | n/a | |
---|
8883 | n/a | bytes = PyBytes_FromFormat("%s=%s", name_string, value_string); |
---|
8884 | n/a | if (bytes == NULL) { |
---|
8885 | n/a | PyErr_NoMemory(); |
---|
8886 | n/a | return NULL; |
---|
8887 | n/a | } |
---|
8888 | n/a | |
---|
8889 | n/a | env = PyBytes_AS_STRING(bytes); |
---|
8890 | n/a | if (putenv(env)) { |
---|
8891 | n/a | Py_DECREF(bytes); |
---|
8892 | n/a | return posix_error(); |
---|
8893 | n/a | } |
---|
8894 | n/a | |
---|
8895 | n/a | posix_putenv_garbage_setitem(name, bytes); |
---|
8896 | n/a | Py_RETURN_NONE; |
---|
8897 | n/a | } |
---|
8898 | n/a | #endif /* MS_WINDOWS */ |
---|
8899 | n/a | #endif /* HAVE_PUTENV */ |
---|
8900 | n/a | |
---|
8901 | n/a | |
---|
8902 | n/a | #ifdef HAVE_UNSETENV |
---|
8903 | n/a | /*[clinic input] |
---|
8904 | n/a | os.unsetenv |
---|
8905 | n/a | name: FSConverter |
---|
8906 | n/a | / |
---|
8907 | n/a | |
---|
8908 | n/a | Delete an environment variable. |
---|
8909 | n/a | [clinic start generated code]*/ |
---|
8910 | n/a | |
---|
8911 | n/a | static PyObject * |
---|
8912 | n/a | os_unsetenv_impl(PyObject *module, PyObject *name) |
---|
8913 | n/a | /*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/ |
---|
8914 | n/a | { |
---|
8915 | n/a | #ifndef HAVE_BROKEN_UNSETENV |
---|
8916 | n/a | int err; |
---|
8917 | n/a | #endif |
---|
8918 | n/a | |
---|
8919 | n/a | #ifdef HAVE_BROKEN_UNSETENV |
---|
8920 | n/a | unsetenv(PyBytes_AS_STRING(name)); |
---|
8921 | n/a | #else |
---|
8922 | n/a | err = unsetenv(PyBytes_AS_STRING(name)); |
---|
8923 | n/a | if (err) |
---|
8924 | n/a | return posix_error(); |
---|
8925 | n/a | #endif |
---|
8926 | n/a | |
---|
8927 | n/a | /* Remove the key from posix_putenv_garbage; |
---|
8928 | n/a | * this will cause it to be collected. This has to |
---|
8929 | n/a | * happen after the real unsetenv() call because the |
---|
8930 | n/a | * old value was still accessible until then. |
---|
8931 | n/a | */ |
---|
8932 | n/a | if (PyDict_DelItem(posix_putenv_garbage, name)) { |
---|
8933 | n/a | /* really not much we can do; just leak */ |
---|
8934 | n/a | PyErr_Clear(); |
---|
8935 | n/a | } |
---|
8936 | n/a | Py_RETURN_NONE; |
---|
8937 | n/a | } |
---|
8938 | n/a | #endif /* HAVE_UNSETENV */ |
---|
8939 | n/a | |
---|
8940 | n/a | |
---|
8941 | n/a | /*[clinic input] |
---|
8942 | n/a | os.strerror |
---|
8943 | n/a | |
---|
8944 | n/a | code: int |
---|
8945 | n/a | / |
---|
8946 | n/a | |
---|
8947 | n/a | Translate an error code to a message string. |
---|
8948 | n/a | [clinic start generated code]*/ |
---|
8949 | n/a | |
---|
8950 | n/a | static PyObject * |
---|
8951 | n/a | os_strerror_impl(PyObject *module, int code) |
---|
8952 | n/a | /*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/ |
---|
8953 | n/a | { |
---|
8954 | n/a | char *message = strerror(code); |
---|
8955 | n/a | if (message == NULL) { |
---|
8956 | n/a | PyErr_SetString(PyExc_ValueError, |
---|
8957 | n/a | "strerror() argument out of range"); |
---|
8958 | n/a | return NULL; |
---|
8959 | n/a | } |
---|
8960 | n/a | return PyUnicode_DecodeLocale(message, "surrogateescape"); |
---|
8961 | n/a | } |
---|
8962 | n/a | |
---|
8963 | n/a | |
---|
8964 | n/a | #ifdef HAVE_SYS_WAIT_H |
---|
8965 | n/a | #ifdef WCOREDUMP |
---|
8966 | n/a | /*[clinic input] |
---|
8967 | n/a | os.WCOREDUMP -> bool |
---|
8968 | n/a | |
---|
8969 | n/a | status: int |
---|
8970 | n/a | / |
---|
8971 | n/a | |
---|
8972 | n/a | Return True if the process returning status was dumped to a core file. |
---|
8973 | n/a | [clinic start generated code]*/ |
---|
8974 | n/a | |
---|
8975 | n/a | static int |
---|
8976 | n/a | os_WCOREDUMP_impl(PyObject *module, int status) |
---|
8977 | n/a | /*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/ |
---|
8978 | n/a | { |
---|
8979 | n/a | WAIT_TYPE wait_status; |
---|
8980 | n/a | WAIT_STATUS_INT(wait_status) = status; |
---|
8981 | n/a | return WCOREDUMP(wait_status); |
---|
8982 | n/a | } |
---|
8983 | n/a | #endif /* WCOREDUMP */ |
---|
8984 | n/a | |
---|
8985 | n/a | |
---|
8986 | n/a | #ifdef WIFCONTINUED |
---|
8987 | n/a | /*[clinic input] |
---|
8988 | n/a | os.WIFCONTINUED -> bool |
---|
8989 | n/a | |
---|
8990 | n/a | status: int |
---|
8991 | n/a | |
---|
8992 | n/a | Return True if a particular process was continued from a job control stop. |
---|
8993 | n/a | |
---|
8994 | n/a | Return True if the process returning status was continued from a |
---|
8995 | n/a | job control stop. |
---|
8996 | n/a | [clinic start generated code]*/ |
---|
8997 | n/a | |
---|
8998 | n/a | static int |
---|
8999 | n/a | os_WIFCONTINUED_impl(PyObject *module, int status) |
---|
9000 | n/a | /*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/ |
---|
9001 | n/a | { |
---|
9002 | n/a | WAIT_TYPE wait_status; |
---|
9003 | n/a | WAIT_STATUS_INT(wait_status) = status; |
---|
9004 | n/a | return WIFCONTINUED(wait_status); |
---|
9005 | n/a | } |
---|
9006 | n/a | #endif /* WIFCONTINUED */ |
---|
9007 | n/a | |
---|
9008 | n/a | |
---|
9009 | n/a | #ifdef WIFSTOPPED |
---|
9010 | n/a | /*[clinic input] |
---|
9011 | n/a | os.WIFSTOPPED -> bool |
---|
9012 | n/a | |
---|
9013 | n/a | status: int |
---|
9014 | n/a | |
---|
9015 | n/a | Return True if the process returning status was stopped. |
---|
9016 | n/a | [clinic start generated code]*/ |
---|
9017 | n/a | |
---|
9018 | n/a | static int |
---|
9019 | n/a | os_WIFSTOPPED_impl(PyObject *module, int status) |
---|
9020 | n/a | /*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/ |
---|
9021 | n/a | { |
---|
9022 | n/a | WAIT_TYPE wait_status; |
---|
9023 | n/a | WAIT_STATUS_INT(wait_status) = status; |
---|
9024 | n/a | return WIFSTOPPED(wait_status); |
---|
9025 | n/a | } |
---|
9026 | n/a | #endif /* WIFSTOPPED */ |
---|
9027 | n/a | |
---|
9028 | n/a | |
---|
9029 | n/a | #ifdef WIFSIGNALED |
---|
9030 | n/a | /*[clinic input] |
---|
9031 | n/a | os.WIFSIGNALED -> bool |
---|
9032 | n/a | |
---|
9033 | n/a | status: int |
---|
9034 | n/a | |
---|
9035 | n/a | Return True if the process returning status was terminated by a signal. |
---|
9036 | n/a | [clinic start generated code]*/ |
---|
9037 | n/a | |
---|
9038 | n/a | static int |
---|
9039 | n/a | os_WIFSIGNALED_impl(PyObject *module, int status) |
---|
9040 | n/a | /*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/ |
---|
9041 | n/a | { |
---|
9042 | n/a | WAIT_TYPE wait_status; |
---|
9043 | n/a | WAIT_STATUS_INT(wait_status) = status; |
---|
9044 | n/a | return WIFSIGNALED(wait_status); |
---|
9045 | n/a | } |
---|
9046 | n/a | #endif /* WIFSIGNALED */ |
---|
9047 | n/a | |
---|
9048 | n/a | |
---|
9049 | n/a | #ifdef WIFEXITED |
---|
9050 | n/a | /*[clinic input] |
---|
9051 | n/a | os.WIFEXITED -> bool |
---|
9052 | n/a | |
---|
9053 | n/a | status: int |
---|
9054 | n/a | |
---|
9055 | n/a | Return True if the process returning status exited via the exit() system call. |
---|
9056 | n/a | [clinic start generated code]*/ |
---|
9057 | n/a | |
---|
9058 | n/a | static int |
---|
9059 | n/a | os_WIFEXITED_impl(PyObject *module, int status) |
---|
9060 | n/a | /*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/ |
---|
9061 | n/a | { |
---|
9062 | n/a | WAIT_TYPE wait_status; |
---|
9063 | n/a | WAIT_STATUS_INT(wait_status) = status; |
---|
9064 | n/a | return WIFEXITED(wait_status); |
---|
9065 | n/a | } |
---|
9066 | n/a | #endif /* WIFEXITED */ |
---|
9067 | n/a | |
---|
9068 | n/a | |
---|
9069 | n/a | #ifdef WEXITSTATUS |
---|
9070 | n/a | /*[clinic input] |
---|
9071 | n/a | os.WEXITSTATUS -> int |
---|
9072 | n/a | |
---|
9073 | n/a | status: int |
---|
9074 | n/a | |
---|
9075 | n/a | Return the process return code from status. |
---|
9076 | n/a | [clinic start generated code]*/ |
---|
9077 | n/a | |
---|
9078 | n/a | static int |
---|
9079 | n/a | os_WEXITSTATUS_impl(PyObject *module, int status) |
---|
9080 | n/a | /*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/ |
---|
9081 | n/a | { |
---|
9082 | n/a | WAIT_TYPE wait_status; |
---|
9083 | n/a | WAIT_STATUS_INT(wait_status) = status; |
---|
9084 | n/a | return WEXITSTATUS(wait_status); |
---|
9085 | n/a | } |
---|
9086 | n/a | #endif /* WEXITSTATUS */ |
---|
9087 | n/a | |
---|
9088 | n/a | |
---|
9089 | n/a | #ifdef WTERMSIG |
---|
9090 | n/a | /*[clinic input] |
---|
9091 | n/a | os.WTERMSIG -> int |
---|
9092 | n/a | |
---|
9093 | n/a | status: int |
---|
9094 | n/a | |
---|
9095 | n/a | Return the signal that terminated the process that provided the status value. |
---|
9096 | n/a | [clinic start generated code]*/ |
---|
9097 | n/a | |
---|
9098 | n/a | static int |
---|
9099 | n/a | os_WTERMSIG_impl(PyObject *module, int status) |
---|
9100 | n/a | /*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/ |
---|
9101 | n/a | { |
---|
9102 | n/a | WAIT_TYPE wait_status; |
---|
9103 | n/a | WAIT_STATUS_INT(wait_status) = status; |
---|
9104 | n/a | return WTERMSIG(wait_status); |
---|
9105 | n/a | } |
---|
9106 | n/a | #endif /* WTERMSIG */ |
---|
9107 | n/a | |
---|
9108 | n/a | |
---|
9109 | n/a | #ifdef WSTOPSIG |
---|
9110 | n/a | /*[clinic input] |
---|
9111 | n/a | os.WSTOPSIG -> int |
---|
9112 | n/a | |
---|
9113 | n/a | status: int |
---|
9114 | n/a | |
---|
9115 | n/a | Return the signal that stopped the process that provided the status value. |
---|
9116 | n/a | [clinic start generated code]*/ |
---|
9117 | n/a | |
---|
9118 | n/a | static int |
---|
9119 | n/a | os_WSTOPSIG_impl(PyObject *module, int status) |
---|
9120 | n/a | /*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/ |
---|
9121 | n/a | { |
---|
9122 | n/a | WAIT_TYPE wait_status; |
---|
9123 | n/a | WAIT_STATUS_INT(wait_status) = status; |
---|
9124 | n/a | return WSTOPSIG(wait_status); |
---|
9125 | n/a | } |
---|
9126 | n/a | #endif /* WSTOPSIG */ |
---|
9127 | n/a | #endif /* HAVE_SYS_WAIT_H */ |
---|
9128 | n/a | |
---|
9129 | n/a | |
---|
9130 | n/a | #if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) |
---|
9131 | n/a | #ifdef _SCO_DS |
---|
9132 | n/a | /* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the |
---|
9133 | n/a | needed definitions in sys/statvfs.h */ |
---|
9134 | n/a | #define _SVID3 |
---|
9135 | n/a | #endif |
---|
9136 | n/a | #include <sys/statvfs.h> |
---|
9137 | n/a | |
---|
9138 | n/a | static PyObject* |
---|
9139 | n/a | _pystatvfs_fromstructstatvfs(struct statvfs st) { |
---|
9140 | n/a | PyObject *v = PyStructSequence_New(&StatVFSResultType); |
---|
9141 | n/a | if (v == NULL) |
---|
9142 | n/a | return NULL; |
---|
9143 | n/a | |
---|
9144 | n/a | #if !defined(HAVE_LARGEFILE_SUPPORT) |
---|
9145 | n/a | PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize)); |
---|
9146 | n/a | PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize)); |
---|
9147 | n/a | PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks)); |
---|
9148 | n/a | PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree)); |
---|
9149 | n/a | PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail)); |
---|
9150 | n/a | PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files)); |
---|
9151 | n/a | PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree)); |
---|
9152 | n/a | PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail)); |
---|
9153 | n/a | PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag)); |
---|
9154 | n/a | PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax)); |
---|
9155 | n/a | #else |
---|
9156 | n/a | PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize)); |
---|
9157 | n/a | PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize)); |
---|
9158 | n/a | PyStructSequence_SET_ITEM(v, 2, |
---|
9159 | n/a | PyLong_FromLongLong((long long) st.f_blocks)); |
---|
9160 | n/a | PyStructSequence_SET_ITEM(v, 3, |
---|
9161 | n/a | PyLong_FromLongLong((long long) st.f_bfree)); |
---|
9162 | n/a | PyStructSequence_SET_ITEM(v, 4, |
---|
9163 | n/a | PyLong_FromLongLong((long long) st.f_bavail)); |
---|
9164 | n/a | PyStructSequence_SET_ITEM(v, 5, |
---|
9165 | n/a | PyLong_FromLongLong((long long) st.f_files)); |
---|
9166 | n/a | PyStructSequence_SET_ITEM(v, 6, |
---|
9167 | n/a | PyLong_FromLongLong((long long) st.f_ffree)); |
---|
9168 | n/a | PyStructSequence_SET_ITEM(v, 7, |
---|
9169 | n/a | PyLong_FromLongLong((long long) st.f_favail)); |
---|
9170 | n/a | PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag)); |
---|
9171 | n/a | PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax)); |
---|
9172 | n/a | #endif |
---|
9173 | n/a | if (PyErr_Occurred()) { |
---|
9174 | n/a | Py_DECREF(v); |
---|
9175 | n/a | return NULL; |
---|
9176 | n/a | } |
---|
9177 | n/a | |
---|
9178 | n/a | return v; |
---|
9179 | n/a | } |
---|
9180 | n/a | |
---|
9181 | n/a | |
---|
9182 | n/a | /*[clinic input] |
---|
9183 | n/a | os.fstatvfs |
---|
9184 | n/a | fd: int |
---|
9185 | n/a | / |
---|
9186 | n/a | |
---|
9187 | n/a | Perform an fstatvfs system call on the given fd. |
---|
9188 | n/a | |
---|
9189 | n/a | Equivalent to statvfs(fd). |
---|
9190 | n/a | [clinic start generated code]*/ |
---|
9191 | n/a | |
---|
9192 | n/a | static PyObject * |
---|
9193 | n/a | os_fstatvfs_impl(PyObject *module, int fd) |
---|
9194 | n/a | /*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/ |
---|
9195 | n/a | { |
---|
9196 | n/a | int result; |
---|
9197 | n/a | int async_err = 0; |
---|
9198 | n/a | struct statvfs st; |
---|
9199 | n/a | |
---|
9200 | n/a | do { |
---|
9201 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
9202 | n/a | result = fstatvfs(fd, &st); |
---|
9203 | n/a | Py_END_ALLOW_THREADS |
---|
9204 | n/a | } while (result != 0 && errno == EINTR && |
---|
9205 | n/a | !(async_err = PyErr_CheckSignals())); |
---|
9206 | n/a | if (result != 0) |
---|
9207 | n/a | return (!async_err) ? posix_error() : NULL; |
---|
9208 | n/a | |
---|
9209 | n/a | return _pystatvfs_fromstructstatvfs(st); |
---|
9210 | n/a | } |
---|
9211 | n/a | #endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */ |
---|
9212 | n/a | |
---|
9213 | n/a | |
---|
9214 | n/a | #if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) |
---|
9215 | n/a | #include <sys/statvfs.h> |
---|
9216 | n/a | /*[clinic input] |
---|
9217 | n/a | os.statvfs |
---|
9218 | n/a | |
---|
9219 | n/a | path: path_t(allow_fd='PATH_HAVE_FSTATVFS') |
---|
9220 | n/a | |
---|
9221 | n/a | Perform a statvfs system call on the given path. |
---|
9222 | n/a | |
---|
9223 | n/a | path may always be specified as a string. |
---|
9224 | n/a | On some platforms, path may also be specified as an open file descriptor. |
---|
9225 | n/a | If this functionality is unavailable, using it raises an exception. |
---|
9226 | n/a | [clinic start generated code]*/ |
---|
9227 | n/a | |
---|
9228 | n/a | static PyObject * |
---|
9229 | n/a | os_statvfs_impl(PyObject *module, path_t *path) |
---|
9230 | n/a | /*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/ |
---|
9231 | n/a | { |
---|
9232 | n/a | int result; |
---|
9233 | n/a | struct statvfs st; |
---|
9234 | n/a | |
---|
9235 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
9236 | n/a | #ifdef HAVE_FSTATVFS |
---|
9237 | n/a | if (path->fd != -1) { |
---|
9238 | n/a | #ifdef __APPLE__ |
---|
9239 | n/a | /* handle weak-linking on Mac OS X 10.3 */ |
---|
9240 | n/a | if (fstatvfs == NULL) { |
---|
9241 | n/a | fd_specified("statvfs", path->fd); |
---|
9242 | n/a | return NULL; |
---|
9243 | n/a | } |
---|
9244 | n/a | #endif |
---|
9245 | n/a | result = fstatvfs(path->fd, &st); |
---|
9246 | n/a | } |
---|
9247 | n/a | else |
---|
9248 | n/a | #endif |
---|
9249 | n/a | result = statvfs(path->narrow, &st); |
---|
9250 | n/a | Py_END_ALLOW_THREADS |
---|
9251 | n/a | |
---|
9252 | n/a | if (result) { |
---|
9253 | n/a | return path_error(path); |
---|
9254 | n/a | } |
---|
9255 | n/a | |
---|
9256 | n/a | return _pystatvfs_fromstructstatvfs(st); |
---|
9257 | n/a | } |
---|
9258 | n/a | #endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */ |
---|
9259 | n/a | |
---|
9260 | n/a | |
---|
9261 | n/a | #ifdef MS_WINDOWS |
---|
9262 | n/a | /*[clinic input] |
---|
9263 | n/a | os._getdiskusage |
---|
9264 | n/a | |
---|
9265 | n/a | path: Py_UNICODE |
---|
9266 | n/a | |
---|
9267 | n/a | Return disk usage statistics about the given path as a (total, free) tuple. |
---|
9268 | n/a | [clinic start generated code]*/ |
---|
9269 | n/a | |
---|
9270 | n/a | static PyObject * |
---|
9271 | n/a | os__getdiskusage_impl(PyObject *module, Py_UNICODE *path) |
---|
9272 | n/a | /*[clinic end generated code: output=76d6adcd86b1db0b input=6458133aed893c78]*/ |
---|
9273 | n/a | { |
---|
9274 | n/a | BOOL retval; |
---|
9275 | n/a | ULARGE_INTEGER _, total, free; |
---|
9276 | n/a | |
---|
9277 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
9278 | n/a | retval = GetDiskFreeSpaceExW(path, &_, &total, &free); |
---|
9279 | n/a | Py_END_ALLOW_THREADS |
---|
9280 | n/a | if (retval == 0) |
---|
9281 | n/a | return PyErr_SetFromWindowsErr(0); |
---|
9282 | n/a | |
---|
9283 | n/a | return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart); |
---|
9284 | n/a | } |
---|
9285 | n/a | #endif /* MS_WINDOWS */ |
---|
9286 | n/a | |
---|
9287 | n/a | |
---|
9288 | n/a | /* This is used for fpathconf(), pathconf(), confstr() and sysconf(). |
---|
9289 | n/a | * It maps strings representing configuration variable names to |
---|
9290 | n/a | * integer values, allowing those functions to be called with the |
---|
9291 | n/a | * magic names instead of polluting the module's namespace with tons of |
---|
9292 | n/a | * rarely-used constants. There are three separate tables that use |
---|
9293 | n/a | * these definitions. |
---|
9294 | n/a | * |
---|
9295 | n/a | * This code is always included, even if none of the interfaces that |
---|
9296 | n/a | * need it are included. The #if hackery needed to avoid it would be |
---|
9297 | n/a | * sufficiently pervasive that it's not worth the loss of readability. |
---|
9298 | n/a | */ |
---|
9299 | n/a | struct constdef { |
---|
9300 | n/a | const char *name; |
---|
9301 | n/a | int value; |
---|
9302 | n/a | }; |
---|
9303 | n/a | |
---|
9304 | n/a | static int |
---|
9305 | n/a | conv_confname(PyObject *arg, int *valuep, struct constdef *table, |
---|
9306 | n/a | size_t tablesize) |
---|
9307 | n/a | { |
---|
9308 | n/a | if (PyLong_Check(arg)) { |
---|
9309 | n/a | int value = _PyLong_AsInt(arg); |
---|
9310 | n/a | if (value == -1 && PyErr_Occurred()) |
---|
9311 | n/a | return 0; |
---|
9312 | n/a | *valuep = value; |
---|
9313 | n/a | return 1; |
---|
9314 | n/a | } |
---|
9315 | n/a | else { |
---|
9316 | n/a | /* look up the value in the table using a binary search */ |
---|
9317 | n/a | size_t lo = 0; |
---|
9318 | n/a | size_t mid; |
---|
9319 | n/a | size_t hi = tablesize; |
---|
9320 | n/a | int cmp; |
---|
9321 | n/a | const char *confname; |
---|
9322 | n/a | if (!PyUnicode_Check(arg)) { |
---|
9323 | n/a | PyErr_SetString(PyExc_TypeError, |
---|
9324 | n/a | "configuration names must be strings or integers"); |
---|
9325 | n/a | return 0; |
---|
9326 | n/a | } |
---|
9327 | n/a | confname = PyUnicode_AsUTF8(arg); |
---|
9328 | n/a | if (confname == NULL) |
---|
9329 | n/a | return 0; |
---|
9330 | n/a | while (lo < hi) { |
---|
9331 | n/a | mid = (lo + hi) / 2; |
---|
9332 | n/a | cmp = strcmp(confname, table[mid].name); |
---|
9333 | n/a | if (cmp < 0) |
---|
9334 | n/a | hi = mid; |
---|
9335 | n/a | else if (cmp > 0) |
---|
9336 | n/a | lo = mid + 1; |
---|
9337 | n/a | else { |
---|
9338 | n/a | *valuep = table[mid].value; |
---|
9339 | n/a | return 1; |
---|
9340 | n/a | } |
---|
9341 | n/a | } |
---|
9342 | n/a | PyErr_SetString(PyExc_ValueError, "unrecognized configuration name"); |
---|
9343 | n/a | return 0; |
---|
9344 | n/a | } |
---|
9345 | n/a | } |
---|
9346 | n/a | |
---|
9347 | n/a | |
---|
9348 | n/a | #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF) |
---|
9349 | n/a | static struct constdef posix_constants_pathconf[] = { |
---|
9350 | n/a | #ifdef _PC_ABI_AIO_XFER_MAX |
---|
9351 | n/a | {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX}, |
---|
9352 | n/a | #endif |
---|
9353 | n/a | #ifdef _PC_ABI_ASYNC_IO |
---|
9354 | n/a | {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO}, |
---|
9355 | n/a | #endif |
---|
9356 | n/a | #ifdef _PC_ASYNC_IO |
---|
9357 | n/a | {"PC_ASYNC_IO", _PC_ASYNC_IO}, |
---|
9358 | n/a | #endif |
---|
9359 | n/a | #ifdef _PC_CHOWN_RESTRICTED |
---|
9360 | n/a | {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED}, |
---|
9361 | n/a | #endif |
---|
9362 | n/a | #ifdef _PC_FILESIZEBITS |
---|
9363 | n/a | {"PC_FILESIZEBITS", _PC_FILESIZEBITS}, |
---|
9364 | n/a | #endif |
---|
9365 | n/a | #ifdef _PC_LAST |
---|
9366 | n/a | {"PC_LAST", _PC_LAST}, |
---|
9367 | n/a | #endif |
---|
9368 | n/a | #ifdef _PC_LINK_MAX |
---|
9369 | n/a | {"PC_LINK_MAX", _PC_LINK_MAX}, |
---|
9370 | n/a | #endif |
---|
9371 | n/a | #ifdef _PC_MAX_CANON |
---|
9372 | n/a | {"PC_MAX_CANON", _PC_MAX_CANON}, |
---|
9373 | n/a | #endif |
---|
9374 | n/a | #ifdef _PC_MAX_INPUT |
---|
9375 | n/a | {"PC_MAX_INPUT", _PC_MAX_INPUT}, |
---|
9376 | n/a | #endif |
---|
9377 | n/a | #ifdef _PC_NAME_MAX |
---|
9378 | n/a | {"PC_NAME_MAX", _PC_NAME_MAX}, |
---|
9379 | n/a | #endif |
---|
9380 | n/a | #ifdef _PC_NO_TRUNC |
---|
9381 | n/a | {"PC_NO_TRUNC", _PC_NO_TRUNC}, |
---|
9382 | n/a | #endif |
---|
9383 | n/a | #ifdef _PC_PATH_MAX |
---|
9384 | n/a | {"PC_PATH_MAX", _PC_PATH_MAX}, |
---|
9385 | n/a | #endif |
---|
9386 | n/a | #ifdef _PC_PIPE_BUF |
---|
9387 | n/a | {"PC_PIPE_BUF", _PC_PIPE_BUF}, |
---|
9388 | n/a | #endif |
---|
9389 | n/a | #ifdef _PC_PRIO_IO |
---|
9390 | n/a | {"PC_PRIO_IO", _PC_PRIO_IO}, |
---|
9391 | n/a | #endif |
---|
9392 | n/a | #ifdef _PC_SOCK_MAXBUF |
---|
9393 | n/a | {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF}, |
---|
9394 | n/a | #endif |
---|
9395 | n/a | #ifdef _PC_SYNC_IO |
---|
9396 | n/a | {"PC_SYNC_IO", _PC_SYNC_IO}, |
---|
9397 | n/a | #endif |
---|
9398 | n/a | #ifdef _PC_VDISABLE |
---|
9399 | n/a | {"PC_VDISABLE", _PC_VDISABLE}, |
---|
9400 | n/a | #endif |
---|
9401 | n/a | #ifdef _PC_ACL_ENABLED |
---|
9402 | n/a | {"PC_ACL_ENABLED", _PC_ACL_ENABLED}, |
---|
9403 | n/a | #endif |
---|
9404 | n/a | #ifdef _PC_MIN_HOLE_SIZE |
---|
9405 | n/a | {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE}, |
---|
9406 | n/a | #endif |
---|
9407 | n/a | #ifdef _PC_ALLOC_SIZE_MIN |
---|
9408 | n/a | {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN}, |
---|
9409 | n/a | #endif |
---|
9410 | n/a | #ifdef _PC_REC_INCR_XFER_SIZE |
---|
9411 | n/a | {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE}, |
---|
9412 | n/a | #endif |
---|
9413 | n/a | #ifdef _PC_REC_MAX_XFER_SIZE |
---|
9414 | n/a | {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE}, |
---|
9415 | n/a | #endif |
---|
9416 | n/a | #ifdef _PC_REC_MIN_XFER_SIZE |
---|
9417 | n/a | {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE}, |
---|
9418 | n/a | #endif |
---|
9419 | n/a | #ifdef _PC_REC_XFER_ALIGN |
---|
9420 | n/a | {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN}, |
---|
9421 | n/a | #endif |
---|
9422 | n/a | #ifdef _PC_SYMLINK_MAX |
---|
9423 | n/a | {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX}, |
---|
9424 | n/a | #endif |
---|
9425 | n/a | #ifdef _PC_XATTR_ENABLED |
---|
9426 | n/a | {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED}, |
---|
9427 | n/a | #endif |
---|
9428 | n/a | #ifdef _PC_XATTR_EXISTS |
---|
9429 | n/a | {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS}, |
---|
9430 | n/a | #endif |
---|
9431 | n/a | #ifdef _PC_TIMESTAMP_RESOLUTION |
---|
9432 | n/a | {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION}, |
---|
9433 | n/a | #endif |
---|
9434 | n/a | }; |
---|
9435 | n/a | |
---|
9436 | n/a | static int |
---|
9437 | n/a | conv_path_confname(PyObject *arg, int *valuep) |
---|
9438 | n/a | { |
---|
9439 | n/a | return conv_confname(arg, valuep, posix_constants_pathconf, |
---|
9440 | n/a | sizeof(posix_constants_pathconf) |
---|
9441 | n/a | / sizeof(struct constdef)); |
---|
9442 | n/a | } |
---|
9443 | n/a | #endif |
---|
9444 | n/a | |
---|
9445 | n/a | |
---|
9446 | n/a | #ifdef HAVE_FPATHCONF |
---|
9447 | n/a | /*[clinic input] |
---|
9448 | n/a | os.fpathconf -> long |
---|
9449 | n/a | |
---|
9450 | n/a | fd: int |
---|
9451 | n/a | name: path_confname |
---|
9452 | n/a | / |
---|
9453 | n/a | |
---|
9454 | n/a | Return the configuration limit name for the file descriptor fd. |
---|
9455 | n/a | |
---|
9456 | n/a | If there is no limit, return -1. |
---|
9457 | n/a | [clinic start generated code]*/ |
---|
9458 | n/a | |
---|
9459 | n/a | static long |
---|
9460 | n/a | os_fpathconf_impl(PyObject *module, int fd, int name) |
---|
9461 | n/a | /*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/ |
---|
9462 | n/a | { |
---|
9463 | n/a | long limit; |
---|
9464 | n/a | |
---|
9465 | n/a | errno = 0; |
---|
9466 | n/a | limit = fpathconf(fd, name); |
---|
9467 | n/a | if (limit == -1 && errno != 0) |
---|
9468 | n/a | posix_error(); |
---|
9469 | n/a | |
---|
9470 | n/a | return limit; |
---|
9471 | n/a | } |
---|
9472 | n/a | #endif /* HAVE_FPATHCONF */ |
---|
9473 | n/a | |
---|
9474 | n/a | |
---|
9475 | n/a | #ifdef HAVE_PATHCONF |
---|
9476 | n/a | /*[clinic input] |
---|
9477 | n/a | os.pathconf -> long |
---|
9478 | n/a | path: path_t(allow_fd='PATH_HAVE_FPATHCONF') |
---|
9479 | n/a | name: path_confname |
---|
9480 | n/a | |
---|
9481 | n/a | Return the configuration limit name for the file or directory path. |
---|
9482 | n/a | |
---|
9483 | n/a | If there is no limit, return -1. |
---|
9484 | n/a | On some platforms, path may also be specified as an open file descriptor. |
---|
9485 | n/a | If this functionality is unavailable, using it raises an exception. |
---|
9486 | n/a | [clinic start generated code]*/ |
---|
9487 | n/a | |
---|
9488 | n/a | static long |
---|
9489 | n/a | os_pathconf_impl(PyObject *module, path_t *path, int name) |
---|
9490 | n/a | /*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/ |
---|
9491 | n/a | { |
---|
9492 | n/a | long limit; |
---|
9493 | n/a | |
---|
9494 | n/a | errno = 0; |
---|
9495 | n/a | #ifdef HAVE_FPATHCONF |
---|
9496 | n/a | if (path->fd != -1) |
---|
9497 | n/a | limit = fpathconf(path->fd, name); |
---|
9498 | n/a | else |
---|
9499 | n/a | #endif |
---|
9500 | n/a | limit = pathconf(path->narrow, name); |
---|
9501 | n/a | if (limit == -1 && errno != 0) { |
---|
9502 | n/a | if (errno == EINVAL) |
---|
9503 | n/a | /* could be a path or name problem */ |
---|
9504 | n/a | posix_error(); |
---|
9505 | n/a | else |
---|
9506 | n/a | path_error(path); |
---|
9507 | n/a | } |
---|
9508 | n/a | |
---|
9509 | n/a | return limit; |
---|
9510 | n/a | } |
---|
9511 | n/a | #endif /* HAVE_PATHCONF */ |
---|
9512 | n/a | |
---|
9513 | n/a | #ifdef HAVE_CONFSTR |
---|
9514 | n/a | static struct constdef posix_constants_confstr[] = { |
---|
9515 | n/a | #ifdef _CS_ARCHITECTURE |
---|
9516 | n/a | {"CS_ARCHITECTURE", _CS_ARCHITECTURE}, |
---|
9517 | n/a | #endif |
---|
9518 | n/a | #ifdef _CS_GNU_LIBC_VERSION |
---|
9519 | n/a | {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION}, |
---|
9520 | n/a | #endif |
---|
9521 | n/a | #ifdef _CS_GNU_LIBPTHREAD_VERSION |
---|
9522 | n/a | {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION}, |
---|
9523 | n/a | #endif |
---|
9524 | n/a | #ifdef _CS_HOSTNAME |
---|
9525 | n/a | {"CS_HOSTNAME", _CS_HOSTNAME}, |
---|
9526 | n/a | #endif |
---|
9527 | n/a | #ifdef _CS_HW_PROVIDER |
---|
9528 | n/a | {"CS_HW_PROVIDER", _CS_HW_PROVIDER}, |
---|
9529 | n/a | #endif |
---|
9530 | n/a | #ifdef _CS_HW_SERIAL |
---|
9531 | n/a | {"CS_HW_SERIAL", _CS_HW_SERIAL}, |
---|
9532 | n/a | #endif |
---|
9533 | n/a | #ifdef _CS_INITTAB_NAME |
---|
9534 | n/a | {"CS_INITTAB_NAME", _CS_INITTAB_NAME}, |
---|
9535 | n/a | #endif |
---|
9536 | n/a | #ifdef _CS_LFS64_CFLAGS |
---|
9537 | n/a | {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS}, |
---|
9538 | n/a | #endif |
---|
9539 | n/a | #ifdef _CS_LFS64_LDFLAGS |
---|
9540 | n/a | {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS}, |
---|
9541 | n/a | #endif |
---|
9542 | n/a | #ifdef _CS_LFS64_LIBS |
---|
9543 | n/a | {"CS_LFS64_LIBS", _CS_LFS64_LIBS}, |
---|
9544 | n/a | #endif |
---|
9545 | n/a | #ifdef _CS_LFS64_LINTFLAGS |
---|
9546 | n/a | {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS}, |
---|
9547 | n/a | #endif |
---|
9548 | n/a | #ifdef _CS_LFS_CFLAGS |
---|
9549 | n/a | {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS}, |
---|
9550 | n/a | #endif |
---|
9551 | n/a | #ifdef _CS_LFS_LDFLAGS |
---|
9552 | n/a | {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS}, |
---|
9553 | n/a | #endif |
---|
9554 | n/a | #ifdef _CS_LFS_LIBS |
---|
9555 | n/a | {"CS_LFS_LIBS", _CS_LFS_LIBS}, |
---|
9556 | n/a | #endif |
---|
9557 | n/a | #ifdef _CS_LFS_LINTFLAGS |
---|
9558 | n/a | {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS}, |
---|
9559 | n/a | #endif |
---|
9560 | n/a | #ifdef _CS_MACHINE |
---|
9561 | n/a | {"CS_MACHINE", _CS_MACHINE}, |
---|
9562 | n/a | #endif |
---|
9563 | n/a | #ifdef _CS_PATH |
---|
9564 | n/a | {"CS_PATH", _CS_PATH}, |
---|
9565 | n/a | #endif |
---|
9566 | n/a | #ifdef _CS_RELEASE |
---|
9567 | n/a | {"CS_RELEASE", _CS_RELEASE}, |
---|
9568 | n/a | #endif |
---|
9569 | n/a | #ifdef _CS_SRPC_DOMAIN |
---|
9570 | n/a | {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN}, |
---|
9571 | n/a | #endif |
---|
9572 | n/a | #ifdef _CS_SYSNAME |
---|
9573 | n/a | {"CS_SYSNAME", _CS_SYSNAME}, |
---|
9574 | n/a | #endif |
---|
9575 | n/a | #ifdef _CS_VERSION |
---|
9576 | n/a | {"CS_VERSION", _CS_VERSION}, |
---|
9577 | n/a | #endif |
---|
9578 | n/a | #ifdef _CS_XBS5_ILP32_OFF32_CFLAGS |
---|
9579 | n/a | {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS}, |
---|
9580 | n/a | #endif |
---|
9581 | n/a | #ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS |
---|
9582 | n/a | {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS}, |
---|
9583 | n/a | #endif |
---|
9584 | n/a | #ifdef _CS_XBS5_ILP32_OFF32_LIBS |
---|
9585 | n/a | {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS}, |
---|
9586 | n/a | #endif |
---|
9587 | n/a | #ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS |
---|
9588 | n/a | {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS}, |
---|
9589 | n/a | #endif |
---|
9590 | n/a | #ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS |
---|
9591 | n/a | {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS}, |
---|
9592 | n/a | #endif |
---|
9593 | n/a | #ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS |
---|
9594 | n/a | {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS}, |
---|
9595 | n/a | #endif |
---|
9596 | n/a | #ifdef _CS_XBS5_ILP32_OFFBIG_LIBS |
---|
9597 | n/a | {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS}, |
---|
9598 | n/a | #endif |
---|
9599 | n/a | #ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS |
---|
9600 | n/a | {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS}, |
---|
9601 | n/a | #endif |
---|
9602 | n/a | #ifdef _CS_XBS5_LP64_OFF64_CFLAGS |
---|
9603 | n/a | {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS}, |
---|
9604 | n/a | #endif |
---|
9605 | n/a | #ifdef _CS_XBS5_LP64_OFF64_LDFLAGS |
---|
9606 | n/a | {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS}, |
---|
9607 | n/a | #endif |
---|
9608 | n/a | #ifdef _CS_XBS5_LP64_OFF64_LIBS |
---|
9609 | n/a | {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS}, |
---|
9610 | n/a | #endif |
---|
9611 | n/a | #ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS |
---|
9612 | n/a | {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS}, |
---|
9613 | n/a | #endif |
---|
9614 | n/a | #ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS |
---|
9615 | n/a | {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS}, |
---|
9616 | n/a | #endif |
---|
9617 | n/a | #ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS |
---|
9618 | n/a | {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS}, |
---|
9619 | n/a | #endif |
---|
9620 | n/a | #ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS |
---|
9621 | n/a | {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS}, |
---|
9622 | n/a | #endif |
---|
9623 | n/a | #ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS |
---|
9624 | n/a | {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS}, |
---|
9625 | n/a | #endif |
---|
9626 | n/a | #ifdef _MIPS_CS_AVAIL_PROCESSORS |
---|
9627 | n/a | {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS}, |
---|
9628 | n/a | #endif |
---|
9629 | n/a | #ifdef _MIPS_CS_BASE |
---|
9630 | n/a | {"MIPS_CS_BASE", _MIPS_CS_BASE}, |
---|
9631 | n/a | #endif |
---|
9632 | n/a | #ifdef _MIPS_CS_HOSTID |
---|
9633 | n/a | {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID}, |
---|
9634 | n/a | #endif |
---|
9635 | n/a | #ifdef _MIPS_CS_HW_NAME |
---|
9636 | n/a | {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME}, |
---|
9637 | n/a | #endif |
---|
9638 | n/a | #ifdef _MIPS_CS_NUM_PROCESSORS |
---|
9639 | n/a | {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS}, |
---|
9640 | n/a | #endif |
---|
9641 | n/a | #ifdef _MIPS_CS_OSREL_MAJ |
---|
9642 | n/a | {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ}, |
---|
9643 | n/a | #endif |
---|
9644 | n/a | #ifdef _MIPS_CS_OSREL_MIN |
---|
9645 | n/a | {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN}, |
---|
9646 | n/a | #endif |
---|
9647 | n/a | #ifdef _MIPS_CS_OSREL_PATCH |
---|
9648 | n/a | {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH}, |
---|
9649 | n/a | #endif |
---|
9650 | n/a | #ifdef _MIPS_CS_OS_NAME |
---|
9651 | n/a | {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME}, |
---|
9652 | n/a | #endif |
---|
9653 | n/a | #ifdef _MIPS_CS_OS_PROVIDER |
---|
9654 | n/a | {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER}, |
---|
9655 | n/a | #endif |
---|
9656 | n/a | #ifdef _MIPS_CS_PROCESSORS |
---|
9657 | n/a | {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS}, |
---|
9658 | n/a | #endif |
---|
9659 | n/a | #ifdef _MIPS_CS_SERIAL |
---|
9660 | n/a | {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL}, |
---|
9661 | n/a | #endif |
---|
9662 | n/a | #ifdef _MIPS_CS_VENDOR |
---|
9663 | n/a | {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR}, |
---|
9664 | n/a | #endif |
---|
9665 | n/a | }; |
---|
9666 | n/a | |
---|
9667 | n/a | static int |
---|
9668 | n/a | conv_confstr_confname(PyObject *arg, int *valuep) |
---|
9669 | n/a | { |
---|
9670 | n/a | return conv_confname(arg, valuep, posix_constants_confstr, |
---|
9671 | n/a | sizeof(posix_constants_confstr) |
---|
9672 | n/a | / sizeof(struct constdef)); |
---|
9673 | n/a | } |
---|
9674 | n/a | |
---|
9675 | n/a | |
---|
9676 | n/a | /*[clinic input] |
---|
9677 | n/a | os.confstr |
---|
9678 | n/a | |
---|
9679 | n/a | name: confstr_confname |
---|
9680 | n/a | / |
---|
9681 | n/a | |
---|
9682 | n/a | Return a string-valued system configuration variable. |
---|
9683 | n/a | [clinic start generated code]*/ |
---|
9684 | n/a | |
---|
9685 | n/a | static PyObject * |
---|
9686 | n/a | os_confstr_impl(PyObject *module, int name) |
---|
9687 | n/a | /*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/ |
---|
9688 | n/a | { |
---|
9689 | n/a | PyObject *result = NULL; |
---|
9690 | n/a | char buffer[255]; |
---|
9691 | n/a | size_t len; |
---|
9692 | n/a | |
---|
9693 | n/a | errno = 0; |
---|
9694 | n/a | len = confstr(name, buffer, sizeof(buffer)); |
---|
9695 | n/a | if (len == 0) { |
---|
9696 | n/a | if (errno) { |
---|
9697 | n/a | posix_error(); |
---|
9698 | n/a | return NULL; |
---|
9699 | n/a | } |
---|
9700 | n/a | else { |
---|
9701 | n/a | Py_RETURN_NONE; |
---|
9702 | n/a | } |
---|
9703 | n/a | } |
---|
9704 | n/a | |
---|
9705 | n/a | if (len >= sizeof(buffer)) { |
---|
9706 | n/a | size_t len2; |
---|
9707 | n/a | char *buf = PyMem_Malloc(len); |
---|
9708 | n/a | if (buf == NULL) |
---|
9709 | n/a | return PyErr_NoMemory(); |
---|
9710 | n/a | len2 = confstr(name, buf, len); |
---|
9711 | n/a | assert(len == len2); |
---|
9712 | n/a | result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1); |
---|
9713 | n/a | PyMem_Free(buf); |
---|
9714 | n/a | } |
---|
9715 | n/a | else |
---|
9716 | n/a | result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1); |
---|
9717 | n/a | return result; |
---|
9718 | n/a | } |
---|
9719 | n/a | #endif /* HAVE_CONFSTR */ |
---|
9720 | n/a | |
---|
9721 | n/a | |
---|
9722 | n/a | #ifdef HAVE_SYSCONF |
---|
9723 | n/a | static struct constdef posix_constants_sysconf[] = { |
---|
9724 | n/a | #ifdef _SC_2_CHAR_TERM |
---|
9725 | n/a | {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM}, |
---|
9726 | n/a | #endif |
---|
9727 | n/a | #ifdef _SC_2_C_BIND |
---|
9728 | n/a | {"SC_2_C_BIND", _SC_2_C_BIND}, |
---|
9729 | n/a | #endif |
---|
9730 | n/a | #ifdef _SC_2_C_DEV |
---|
9731 | n/a | {"SC_2_C_DEV", _SC_2_C_DEV}, |
---|
9732 | n/a | #endif |
---|
9733 | n/a | #ifdef _SC_2_C_VERSION |
---|
9734 | n/a | {"SC_2_C_VERSION", _SC_2_C_VERSION}, |
---|
9735 | n/a | #endif |
---|
9736 | n/a | #ifdef _SC_2_FORT_DEV |
---|
9737 | n/a | {"SC_2_FORT_DEV", _SC_2_FORT_DEV}, |
---|
9738 | n/a | #endif |
---|
9739 | n/a | #ifdef _SC_2_FORT_RUN |
---|
9740 | n/a | {"SC_2_FORT_RUN", _SC_2_FORT_RUN}, |
---|
9741 | n/a | #endif |
---|
9742 | n/a | #ifdef _SC_2_LOCALEDEF |
---|
9743 | n/a | {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF}, |
---|
9744 | n/a | #endif |
---|
9745 | n/a | #ifdef _SC_2_SW_DEV |
---|
9746 | n/a | {"SC_2_SW_DEV", _SC_2_SW_DEV}, |
---|
9747 | n/a | #endif |
---|
9748 | n/a | #ifdef _SC_2_UPE |
---|
9749 | n/a | {"SC_2_UPE", _SC_2_UPE}, |
---|
9750 | n/a | #endif |
---|
9751 | n/a | #ifdef _SC_2_VERSION |
---|
9752 | n/a | {"SC_2_VERSION", _SC_2_VERSION}, |
---|
9753 | n/a | #endif |
---|
9754 | n/a | #ifdef _SC_ABI_ASYNCHRONOUS_IO |
---|
9755 | n/a | {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO}, |
---|
9756 | n/a | #endif |
---|
9757 | n/a | #ifdef _SC_ACL |
---|
9758 | n/a | {"SC_ACL", _SC_ACL}, |
---|
9759 | n/a | #endif |
---|
9760 | n/a | #ifdef _SC_AIO_LISTIO_MAX |
---|
9761 | n/a | {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX}, |
---|
9762 | n/a | #endif |
---|
9763 | n/a | #ifdef _SC_AIO_MAX |
---|
9764 | n/a | {"SC_AIO_MAX", _SC_AIO_MAX}, |
---|
9765 | n/a | #endif |
---|
9766 | n/a | #ifdef _SC_AIO_PRIO_DELTA_MAX |
---|
9767 | n/a | {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX}, |
---|
9768 | n/a | #endif |
---|
9769 | n/a | #ifdef _SC_ARG_MAX |
---|
9770 | n/a | {"SC_ARG_MAX", _SC_ARG_MAX}, |
---|
9771 | n/a | #endif |
---|
9772 | n/a | #ifdef _SC_ASYNCHRONOUS_IO |
---|
9773 | n/a | {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO}, |
---|
9774 | n/a | #endif |
---|
9775 | n/a | #ifdef _SC_ATEXIT_MAX |
---|
9776 | n/a | {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX}, |
---|
9777 | n/a | #endif |
---|
9778 | n/a | #ifdef _SC_AUDIT |
---|
9779 | n/a | {"SC_AUDIT", _SC_AUDIT}, |
---|
9780 | n/a | #endif |
---|
9781 | n/a | #ifdef _SC_AVPHYS_PAGES |
---|
9782 | n/a | {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES}, |
---|
9783 | n/a | #endif |
---|
9784 | n/a | #ifdef _SC_BC_BASE_MAX |
---|
9785 | n/a | {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX}, |
---|
9786 | n/a | #endif |
---|
9787 | n/a | #ifdef _SC_BC_DIM_MAX |
---|
9788 | n/a | {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX}, |
---|
9789 | n/a | #endif |
---|
9790 | n/a | #ifdef _SC_BC_SCALE_MAX |
---|
9791 | n/a | {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX}, |
---|
9792 | n/a | #endif |
---|
9793 | n/a | #ifdef _SC_BC_STRING_MAX |
---|
9794 | n/a | {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX}, |
---|
9795 | n/a | #endif |
---|
9796 | n/a | #ifdef _SC_CAP |
---|
9797 | n/a | {"SC_CAP", _SC_CAP}, |
---|
9798 | n/a | #endif |
---|
9799 | n/a | #ifdef _SC_CHARCLASS_NAME_MAX |
---|
9800 | n/a | {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX}, |
---|
9801 | n/a | #endif |
---|
9802 | n/a | #ifdef _SC_CHAR_BIT |
---|
9803 | n/a | {"SC_CHAR_BIT", _SC_CHAR_BIT}, |
---|
9804 | n/a | #endif |
---|
9805 | n/a | #ifdef _SC_CHAR_MAX |
---|
9806 | n/a | {"SC_CHAR_MAX", _SC_CHAR_MAX}, |
---|
9807 | n/a | #endif |
---|
9808 | n/a | #ifdef _SC_CHAR_MIN |
---|
9809 | n/a | {"SC_CHAR_MIN", _SC_CHAR_MIN}, |
---|
9810 | n/a | #endif |
---|
9811 | n/a | #ifdef _SC_CHILD_MAX |
---|
9812 | n/a | {"SC_CHILD_MAX", _SC_CHILD_MAX}, |
---|
9813 | n/a | #endif |
---|
9814 | n/a | #ifdef _SC_CLK_TCK |
---|
9815 | n/a | {"SC_CLK_TCK", _SC_CLK_TCK}, |
---|
9816 | n/a | #endif |
---|
9817 | n/a | #ifdef _SC_COHER_BLKSZ |
---|
9818 | n/a | {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ}, |
---|
9819 | n/a | #endif |
---|
9820 | n/a | #ifdef _SC_COLL_WEIGHTS_MAX |
---|
9821 | n/a | {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX}, |
---|
9822 | n/a | #endif |
---|
9823 | n/a | #ifdef _SC_DCACHE_ASSOC |
---|
9824 | n/a | {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC}, |
---|
9825 | n/a | #endif |
---|
9826 | n/a | #ifdef _SC_DCACHE_BLKSZ |
---|
9827 | n/a | {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ}, |
---|
9828 | n/a | #endif |
---|
9829 | n/a | #ifdef _SC_DCACHE_LINESZ |
---|
9830 | n/a | {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ}, |
---|
9831 | n/a | #endif |
---|
9832 | n/a | #ifdef _SC_DCACHE_SZ |
---|
9833 | n/a | {"SC_DCACHE_SZ", _SC_DCACHE_SZ}, |
---|
9834 | n/a | #endif |
---|
9835 | n/a | #ifdef _SC_DCACHE_TBLKSZ |
---|
9836 | n/a | {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ}, |
---|
9837 | n/a | #endif |
---|
9838 | n/a | #ifdef _SC_DELAYTIMER_MAX |
---|
9839 | n/a | {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX}, |
---|
9840 | n/a | #endif |
---|
9841 | n/a | #ifdef _SC_EQUIV_CLASS_MAX |
---|
9842 | n/a | {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX}, |
---|
9843 | n/a | #endif |
---|
9844 | n/a | #ifdef _SC_EXPR_NEST_MAX |
---|
9845 | n/a | {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX}, |
---|
9846 | n/a | #endif |
---|
9847 | n/a | #ifdef _SC_FSYNC |
---|
9848 | n/a | {"SC_FSYNC", _SC_FSYNC}, |
---|
9849 | n/a | #endif |
---|
9850 | n/a | #ifdef _SC_GETGR_R_SIZE_MAX |
---|
9851 | n/a | {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX}, |
---|
9852 | n/a | #endif |
---|
9853 | n/a | #ifdef _SC_GETPW_R_SIZE_MAX |
---|
9854 | n/a | {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX}, |
---|
9855 | n/a | #endif |
---|
9856 | n/a | #ifdef _SC_ICACHE_ASSOC |
---|
9857 | n/a | {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC}, |
---|
9858 | n/a | #endif |
---|
9859 | n/a | #ifdef _SC_ICACHE_BLKSZ |
---|
9860 | n/a | {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ}, |
---|
9861 | n/a | #endif |
---|
9862 | n/a | #ifdef _SC_ICACHE_LINESZ |
---|
9863 | n/a | {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ}, |
---|
9864 | n/a | #endif |
---|
9865 | n/a | #ifdef _SC_ICACHE_SZ |
---|
9866 | n/a | {"SC_ICACHE_SZ", _SC_ICACHE_SZ}, |
---|
9867 | n/a | #endif |
---|
9868 | n/a | #ifdef _SC_INF |
---|
9869 | n/a | {"SC_INF", _SC_INF}, |
---|
9870 | n/a | #endif |
---|
9871 | n/a | #ifdef _SC_INT_MAX |
---|
9872 | n/a | {"SC_INT_MAX", _SC_INT_MAX}, |
---|
9873 | n/a | #endif |
---|
9874 | n/a | #ifdef _SC_INT_MIN |
---|
9875 | n/a | {"SC_INT_MIN", _SC_INT_MIN}, |
---|
9876 | n/a | #endif |
---|
9877 | n/a | #ifdef _SC_IOV_MAX |
---|
9878 | n/a | {"SC_IOV_MAX", _SC_IOV_MAX}, |
---|
9879 | n/a | #endif |
---|
9880 | n/a | #ifdef _SC_IP_SECOPTS |
---|
9881 | n/a | {"SC_IP_SECOPTS", _SC_IP_SECOPTS}, |
---|
9882 | n/a | #endif |
---|
9883 | n/a | #ifdef _SC_JOB_CONTROL |
---|
9884 | n/a | {"SC_JOB_CONTROL", _SC_JOB_CONTROL}, |
---|
9885 | n/a | #endif |
---|
9886 | n/a | #ifdef _SC_KERN_POINTERS |
---|
9887 | n/a | {"SC_KERN_POINTERS", _SC_KERN_POINTERS}, |
---|
9888 | n/a | #endif |
---|
9889 | n/a | #ifdef _SC_KERN_SIM |
---|
9890 | n/a | {"SC_KERN_SIM", _SC_KERN_SIM}, |
---|
9891 | n/a | #endif |
---|
9892 | n/a | #ifdef _SC_LINE_MAX |
---|
9893 | n/a | {"SC_LINE_MAX", _SC_LINE_MAX}, |
---|
9894 | n/a | #endif |
---|
9895 | n/a | #ifdef _SC_LOGIN_NAME_MAX |
---|
9896 | n/a | {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX}, |
---|
9897 | n/a | #endif |
---|
9898 | n/a | #ifdef _SC_LOGNAME_MAX |
---|
9899 | n/a | {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX}, |
---|
9900 | n/a | #endif |
---|
9901 | n/a | #ifdef _SC_LONG_BIT |
---|
9902 | n/a | {"SC_LONG_BIT", _SC_LONG_BIT}, |
---|
9903 | n/a | #endif |
---|
9904 | n/a | #ifdef _SC_MAC |
---|
9905 | n/a | {"SC_MAC", _SC_MAC}, |
---|
9906 | n/a | #endif |
---|
9907 | n/a | #ifdef _SC_MAPPED_FILES |
---|
9908 | n/a | {"SC_MAPPED_FILES", _SC_MAPPED_FILES}, |
---|
9909 | n/a | #endif |
---|
9910 | n/a | #ifdef _SC_MAXPID |
---|
9911 | n/a | {"SC_MAXPID", _SC_MAXPID}, |
---|
9912 | n/a | #endif |
---|
9913 | n/a | #ifdef _SC_MB_LEN_MAX |
---|
9914 | n/a | {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX}, |
---|
9915 | n/a | #endif |
---|
9916 | n/a | #ifdef _SC_MEMLOCK |
---|
9917 | n/a | {"SC_MEMLOCK", _SC_MEMLOCK}, |
---|
9918 | n/a | #endif |
---|
9919 | n/a | #ifdef _SC_MEMLOCK_RANGE |
---|
9920 | n/a | {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE}, |
---|
9921 | n/a | #endif |
---|
9922 | n/a | #ifdef _SC_MEMORY_PROTECTION |
---|
9923 | n/a | {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION}, |
---|
9924 | n/a | #endif |
---|
9925 | n/a | #ifdef _SC_MESSAGE_PASSING |
---|
9926 | n/a | {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING}, |
---|
9927 | n/a | #endif |
---|
9928 | n/a | #ifdef _SC_MMAP_FIXED_ALIGNMENT |
---|
9929 | n/a | {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT}, |
---|
9930 | n/a | #endif |
---|
9931 | n/a | #ifdef _SC_MQ_OPEN_MAX |
---|
9932 | n/a | {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX}, |
---|
9933 | n/a | #endif |
---|
9934 | n/a | #ifdef _SC_MQ_PRIO_MAX |
---|
9935 | n/a | {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX}, |
---|
9936 | n/a | #endif |
---|
9937 | n/a | #ifdef _SC_NACLS_MAX |
---|
9938 | n/a | {"SC_NACLS_MAX", _SC_NACLS_MAX}, |
---|
9939 | n/a | #endif |
---|
9940 | n/a | #ifdef _SC_NGROUPS_MAX |
---|
9941 | n/a | {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX}, |
---|
9942 | n/a | #endif |
---|
9943 | n/a | #ifdef _SC_NL_ARGMAX |
---|
9944 | n/a | {"SC_NL_ARGMAX", _SC_NL_ARGMAX}, |
---|
9945 | n/a | #endif |
---|
9946 | n/a | #ifdef _SC_NL_LANGMAX |
---|
9947 | n/a | {"SC_NL_LANGMAX", _SC_NL_LANGMAX}, |
---|
9948 | n/a | #endif |
---|
9949 | n/a | #ifdef _SC_NL_MSGMAX |
---|
9950 | n/a | {"SC_NL_MSGMAX", _SC_NL_MSGMAX}, |
---|
9951 | n/a | #endif |
---|
9952 | n/a | #ifdef _SC_NL_NMAX |
---|
9953 | n/a | {"SC_NL_NMAX", _SC_NL_NMAX}, |
---|
9954 | n/a | #endif |
---|
9955 | n/a | #ifdef _SC_NL_SETMAX |
---|
9956 | n/a | {"SC_NL_SETMAX", _SC_NL_SETMAX}, |
---|
9957 | n/a | #endif |
---|
9958 | n/a | #ifdef _SC_NL_TEXTMAX |
---|
9959 | n/a | {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX}, |
---|
9960 | n/a | #endif |
---|
9961 | n/a | #ifdef _SC_NPROCESSORS_CONF |
---|
9962 | n/a | {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF}, |
---|
9963 | n/a | #endif |
---|
9964 | n/a | #ifdef _SC_NPROCESSORS_ONLN |
---|
9965 | n/a | {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN}, |
---|
9966 | n/a | #endif |
---|
9967 | n/a | #ifdef _SC_NPROC_CONF |
---|
9968 | n/a | {"SC_NPROC_CONF", _SC_NPROC_CONF}, |
---|
9969 | n/a | #endif |
---|
9970 | n/a | #ifdef _SC_NPROC_ONLN |
---|
9971 | n/a | {"SC_NPROC_ONLN", _SC_NPROC_ONLN}, |
---|
9972 | n/a | #endif |
---|
9973 | n/a | #ifdef _SC_NZERO |
---|
9974 | n/a | {"SC_NZERO", _SC_NZERO}, |
---|
9975 | n/a | #endif |
---|
9976 | n/a | #ifdef _SC_OPEN_MAX |
---|
9977 | n/a | {"SC_OPEN_MAX", _SC_OPEN_MAX}, |
---|
9978 | n/a | #endif |
---|
9979 | n/a | #ifdef _SC_PAGESIZE |
---|
9980 | n/a | {"SC_PAGESIZE", _SC_PAGESIZE}, |
---|
9981 | n/a | #endif |
---|
9982 | n/a | #ifdef _SC_PAGE_SIZE |
---|
9983 | n/a | {"SC_PAGE_SIZE", _SC_PAGE_SIZE}, |
---|
9984 | n/a | #endif |
---|
9985 | n/a | #ifdef _SC_PASS_MAX |
---|
9986 | n/a | {"SC_PASS_MAX", _SC_PASS_MAX}, |
---|
9987 | n/a | #endif |
---|
9988 | n/a | #ifdef _SC_PHYS_PAGES |
---|
9989 | n/a | {"SC_PHYS_PAGES", _SC_PHYS_PAGES}, |
---|
9990 | n/a | #endif |
---|
9991 | n/a | #ifdef _SC_PII |
---|
9992 | n/a | {"SC_PII", _SC_PII}, |
---|
9993 | n/a | #endif |
---|
9994 | n/a | #ifdef _SC_PII_INTERNET |
---|
9995 | n/a | {"SC_PII_INTERNET", _SC_PII_INTERNET}, |
---|
9996 | n/a | #endif |
---|
9997 | n/a | #ifdef _SC_PII_INTERNET_DGRAM |
---|
9998 | n/a | {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM}, |
---|
9999 | n/a | #endif |
---|
10000 | n/a | #ifdef _SC_PII_INTERNET_STREAM |
---|
10001 | n/a | {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM}, |
---|
10002 | n/a | #endif |
---|
10003 | n/a | #ifdef _SC_PII_OSI |
---|
10004 | n/a | {"SC_PII_OSI", _SC_PII_OSI}, |
---|
10005 | n/a | #endif |
---|
10006 | n/a | #ifdef _SC_PII_OSI_CLTS |
---|
10007 | n/a | {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS}, |
---|
10008 | n/a | #endif |
---|
10009 | n/a | #ifdef _SC_PII_OSI_COTS |
---|
10010 | n/a | {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS}, |
---|
10011 | n/a | #endif |
---|
10012 | n/a | #ifdef _SC_PII_OSI_M |
---|
10013 | n/a | {"SC_PII_OSI_M", _SC_PII_OSI_M}, |
---|
10014 | n/a | #endif |
---|
10015 | n/a | #ifdef _SC_PII_SOCKET |
---|
10016 | n/a | {"SC_PII_SOCKET", _SC_PII_SOCKET}, |
---|
10017 | n/a | #endif |
---|
10018 | n/a | #ifdef _SC_PII_XTI |
---|
10019 | n/a | {"SC_PII_XTI", _SC_PII_XTI}, |
---|
10020 | n/a | #endif |
---|
10021 | n/a | #ifdef _SC_POLL |
---|
10022 | n/a | {"SC_POLL", _SC_POLL}, |
---|
10023 | n/a | #endif |
---|
10024 | n/a | #ifdef _SC_PRIORITIZED_IO |
---|
10025 | n/a | {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO}, |
---|
10026 | n/a | #endif |
---|
10027 | n/a | #ifdef _SC_PRIORITY_SCHEDULING |
---|
10028 | n/a | {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING}, |
---|
10029 | n/a | #endif |
---|
10030 | n/a | #ifdef _SC_REALTIME_SIGNALS |
---|
10031 | n/a | {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS}, |
---|
10032 | n/a | #endif |
---|
10033 | n/a | #ifdef _SC_RE_DUP_MAX |
---|
10034 | n/a | {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX}, |
---|
10035 | n/a | #endif |
---|
10036 | n/a | #ifdef _SC_RTSIG_MAX |
---|
10037 | n/a | {"SC_RTSIG_MAX", _SC_RTSIG_MAX}, |
---|
10038 | n/a | #endif |
---|
10039 | n/a | #ifdef _SC_SAVED_IDS |
---|
10040 | n/a | {"SC_SAVED_IDS", _SC_SAVED_IDS}, |
---|
10041 | n/a | #endif |
---|
10042 | n/a | #ifdef _SC_SCHAR_MAX |
---|
10043 | n/a | {"SC_SCHAR_MAX", _SC_SCHAR_MAX}, |
---|
10044 | n/a | #endif |
---|
10045 | n/a | #ifdef _SC_SCHAR_MIN |
---|
10046 | n/a | {"SC_SCHAR_MIN", _SC_SCHAR_MIN}, |
---|
10047 | n/a | #endif |
---|
10048 | n/a | #ifdef _SC_SELECT |
---|
10049 | n/a | {"SC_SELECT", _SC_SELECT}, |
---|
10050 | n/a | #endif |
---|
10051 | n/a | #ifdef _SC_SEMAPHORES |
---|
10052 | n/a | {"SC_SEMAPHORES", _SC_SEMAPHORES}, |
---|
10053 | n/a | #endif |
---|
10054 | n/a | #ifdef _SC_SEM_NSEMS_MAX |
---|
10055 | n/a | {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX}, |
---|
10056 | n/a | #endif |
---|
10057 | n/a | #ifdef _SC_SEM_VALUE_MAX |
---|
10058 | n/a | {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX}, |
---|
10059 | n/a | #endif |
---|
10060 | n/a | #ifdef _SC_SHARED_MEMORY_OBJECTS |
---|
10061 | n/a | {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS}, |
---|
10062 | n/a | #endif |
---|
10063 | n/a | #ifdef _SC_SHRT_MAX |
---|
10064 | n/a | {"SC_SHRT_MAX", _SC_SHRT_MAX}, |
---|
10065 | n/a | #endif |
---|
10066 | n/a | #ifdef _SC_SHRT_MIN |
---|
10067 | n/a | {"SC_SHRT_MIN", _SC_SHRT_MIN}, |
---|
10068 | n/a | #endif |
---|
10069 | n/a | #ifdef _SC_SIGQUEUE_MAX |
---|
10070 | n/a | {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX}, |
---|
10071 | n/a | #endif |
---|
10072 | n/a | #ifdef _SC_SIGRT_MAX |
---|
10073 | n/a | {"SC_SIGRT_MAX", _SC_SIGRT_MAX}, |
---|
10074 | n/a | #endif |
---|
10075 | n/a | #ifdef _SC_SIGRT_MIN |
---|
10076 | n/a | {"SC_SIGRT_MIN", _SC_SIGRT_MIN}, |
---|
10077 | n/a | #endif |
---|
10078 | n/a | #ifdef _SC_SOFTPOWER |
---|
10079 | n/a | {"SC_SOFTPOWER", _SC_SOFTPOWER}, |
---|
10080 | n/a | #endif |
---|
10081 | n/a | #ifdef _SC_SPLIT_CACHE |
---|
10082 | n/a | {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE}, |
---|
10083 | n/a | #endif |
---|
10084 | n/a | #ifdef _SC_SSIZE_MAX |
---|
10085 | n/a | {"SC_SSIZE_MAX", _SC_SSIZE_MAX}, |
---|
10086 | n/a | #endif |
---|
10087 | n/a | #ifdef _SC_STACK_PROT |
---|
10088 | n/a | {"SC_STACK_PROT", _SC_STACK_PROT}, |
---|
10089 | n/a | #endif |
---|
10090 | n/a | #ifdef _SC_STREAM_MAX |
---|
10091 | n/a | {"SC_STREAM_MAX", _SC_STREAM_MAX}, |
---|
10092 | n/a | #endif |
---|
10093 | n/a | #ifdef _SC_SYNCHRONIZED_IO |
---|
10094 | n/a | {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO}, |
---|
10095 | n/a | #endif |
---|
10096 | n/a | #ifdef _SC_THREADS |
---|
10097 | n/a | {"SC_THREADS", _SC_THREADS}, |
---|
10098 | n/a | #endif |
---|
10099 | n/a | #ifdef _SC_THREAD_ATTR_STACKADDR |
---|
10100 | n/a | {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR}, |
---|
10101 | n/a | #endif |
---|
10102 | n/a | #ifdef _SC_THREAD_ATTR_STACKSIZE |
---|
10103 | n/a | {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE}, |
---|
10104 | n/a | #endif |
---|
10105 | n/a | #ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS |
---|
10106 | n/a | {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS}, |
---|
10107 | n/a | #endif |
---|
10108 | n/a | #ifdef _SC_THREAD_KEYS_MAX |
---|
10109 | n/a | {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX}, |
---|
10110 | n/a | #endif |
---|
10111 | n/a | #ifdef _SC_THREAD_PRIORITY_SCHEDULING |
---|
10112 | n/a | {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING}, |
---|
10113 | n/a | #endif |
---|
10114 | n/a | #ifdef _SC_THREAD_PRIO_INHERIT |
---|
10115 | n/a | {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT}, |
---|
10116 | n/a | #endif |
---|
10117 | n/a | #ifdef _SC_THREAD_PRIO_PROTECT |
---|
10118 | n/a | {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT}, |
---|
10119 | n/a | #endif |
---|
10120 | n/a | #ifdef _SC_THREAD_PROCESS_SHARED |
---|
10121 | n/a | {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED}, |
---|
10122 | n/a | #endif |
---|
10123 | n/a | #ifdef _SC_THREAD_SAFE_FUNCTIONS |
---|
10124 | n/a | {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS}, |
---|
10125 | n/a | #endif |
---|
10126 | n/a | #ifdef _SC_THREAD_STACK_MIN |
---|
10127 | n/a | {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN}, |
---|
10128 | n/a | #endif |
---|
10129 | n/a | #ifdef _SC_THREAD_THREADS_MAX |
---|
10130 | n/a | {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX}, |
---|
10131 | n/a | #endif |
---|
10132 | n/a | #ifdef _SC_TIMERS |
---|
10133 | n/a | {"SC_TIMERS", _SC_TIMERS}, |
---|
10134 | n/a | #endif |
---|
10135 | n/a | #ifdef _SC_TIMER_MAX |
---|
10136 | n/a | {"SC_TIMER_MAX", _SC_TIMER_MAX}, |
---|
10137 | n/a | #endif |
---|
10138 | n/a | #ifdef _SC_TTY_NAME_MAX |
---|
10139 | n/a | {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX}, |
---|
10140 | n/a | #endif |
---|
10141 | n/a | #ifdef _SC_TZNAME_MAX |
---|
10142 | n/a | {"SC_TZNAME_MAX", _SC_TZNAME_MAX}, |
---|
10143 | n/a | #endif |
---|
10144 | n/a | #ifdef _SC_T_IOV_MAX |
---|
10145 | n/a | {"SC_T_IOV_MAX", _SC_T_IOV_MAX}, |
---|
10146 | n/a | #endif |
---|
10147 | n/a | #ifdef _SC_UCHAR_MAX |
---|
10148 | n/a | {"SC_UCHAR_MAX", _SC_UCHAR_MAX}, |
---|
10149 | n/a | #endif |
---|
10150 | n/a | #ifdef _SC_UINT_MAX |
---|
10151 | n/a | {"SC_UINT_MAX", _SC_UINT_MAX}, |
---|
10152 | n/a | #endif |
---|
10153 | n/a | #ifdef _SC_UIO_MAXIOV |
---|
10154 | n/a | {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV}, |
---|
10155 | n/a | #endif |
---|
10156 | n/a | #ifdef _SC_ULONG_MAX |
---|
10157 | n/a | {"SC_ULONG_MAX", _SC_ULONG_MAX}, |
---|
10158 | n/a | #endif |
---|
10159 | n/a | #ifdef _SC_USHRT_MAX |
---|
10160 | n/a | {"SC_USHRT_MAX", _SC_USHRT_MAX}, |
---|
10161 | n/a | #endif |
---|
10162 | n/a | #ifdef _SC_VERSION |
---|
10163 | n/a | {"SC_VERSION", _SC_VERSION}, |
---|
10164 | n/a | #endif |
---|
10165 | n/a | #ifdef _SC_WORD_BIT |
---|
10166 | n/a | {"SC_WORD_BIT", _SC_WORD_BIT}, |
---|
10167 | n/a | #endif |
---|
10168 | n/a | #ifdef _SC_XBS5_ILP32_OFF32 |
---|
10169 | n/a | {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32}, |
---|
10170 | n/a | #endif |
---|
10171 | n/a | #ifdef _SC_XBS5_ILP32_OFFBIG |
---|
10172 | n/a | {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG}, |
---|
10173 | n/a | #endif |
---|
10174 | n/a | #ifdef _SC_XBS5_LP64_OFF64 |
---|
10175 | n/a | {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64}, |
---|
10176 | n/a | #endif |
---|
10177 | n/a | #ifdef _SC_XBS5_LPBIG_OFFBIG |
---|
10178 | n/a | {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG}, |
---|
10179 | n/a | #endif |
---|
10180 | n/a | #ifdef _SC_XOPEN_CRYPT |
---|
10181 | n/a | {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT}, |
---|
10182 | n/a | #endif |
---|
10183 | n/a | #ifdef _SC_XOPEN_ENH_I18N |
---|
10184 | n/a | {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N}, |
---|
10185 | n/a | #endif |
---|
10186 | n/a | #ifdef _SC_XOPEN_LEGACY |
---|
10187 | n/a | {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY}, |
---|
10188 | n/a | #endif |
---|
10189 | n/a | #ifdef _SC_XOPEN_REALTIME |
---|
10190 | n/a | {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME}, |
---|
10191 | n/a | #endif |
---|
10192 | n/a | #ifdef _SC_XOPEN_REALTIME_THREADS |
---|
10193 | n/a | {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS}, |
---|
10194 | n/a | #endif |
---|
10195 | n/a | #ifdef _SC_XOPEN_SHM |
---|
10196 | n/a | {"SC_XOPEN_SHM", _SC_XOPEN_SHM}, |
---|
10197 | n/a | #endif |
---|
10198 | n/a | #ifdef _SC_XOPEN_UNIX |
---|
10199 | n/a | {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX}, |
---|
10200 | n/a | #endif |
---|
10201 | n/a | #ifdef _SC_XOPEN_VERSION |
---|
10202 | n/a | {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION}, |
---|
10203 | n/a | #endif |
---|
10204 | n/a | #ifdef _SC_XOPEN_XCU_VERSION |
---|
10205 | n/a | {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION}, |
---|
10206 | n/a | #endif |
---|
10207 | n/a | #ifdef _SC_XOPEN_XPG2 |
---|
10208 | n/a | {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2}, |
---|
10209 | n/a | #endif |
---|
10210 | n/a | #ifdef _SC_XOPEN_XPG3 |
---|
10211 | n/a | {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3}, |
---|
10212 | n/a | #endif |
---|
10213 | n/a | #ifdef _SC_XOPEN_XPG4 |
---|
10214 | n/a | {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4}, |
---|
10215 | n/a | #endif |
---|
10216 | n/a | }; |
---|
10217 | n/a | |
---|
10218 | n/a | static int |
---|
10219 | n/a | conv_sysconf_confname(PyObject *arg, int *valuep) |
---|
10220 | n/a | { |
---|
10221 | n/a | return conv_confname(arg, valuep, posix_constants_sysconf, |
---|
10222 | n/a | sizeof(posix_constants_sysconf) |
---|
10223 | n/a | / sizeof(struct constdef)); |
---|
10224 | n/a | } |
---|
10225 | n/a | |
---|
10226 | n/a | |
---|
10227 | n/a | /*[clinic input] |
---|
10228 | n/a | os.sysconf -> long |
---|
10229 | n/a | name: sysconf_confname |
---|
10230 | n/a | / |
---|
10231 | n/a | |
---|
10232 | n/a | Return an integer-valued system configuration variable. |
---|
10233 | n/a | [clinic start generated code]*/ |
---|
10234 | n/a | |
---|
10235 | n/a | static long |
---|
10236 | n/a | os_sysconf_impl(PyObject *module, int name) |
---|
10237 | n/a | /*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/ |
---|
10238 | n/a | { |
---|
10239 | n/a | long value; |
---|
10240 | n/a | |
---|
10241 | n/a | errno = 0; |
---|
10242 | n/a | value = sysconf(name); |
---|
10243 | n/a | if (value == -1 && errno != 0) |
---|
10244 | n/a | posix_error(); |
---|
10245 | n/a | return value; |
---|
10246 | n/a | } |
---|
10247 | n/a | #endif /* HAVE_SYSCONF */ |
---|
10248 | n/a | |
---|
10249 | n/a | |
---|
10250 | n/a | /* This code is used to ensure that the tables of configuration value names |
---|
10251 | n/a | * are in sorted order as required by conv_confname(), and also to build |
---|
10252 | n/a | * the exported dictionaries that are used to publish information about the |
---|
10253 | n/a | * names available on the host platform. |
---|
10254 | n/a | * |
---|
10255 | n/a | * Sorting the table at runtime ensures that the table is properly ordered |
---|
10256 | n/a | * when used, even for platforms we're not able to test on. It also makes |
---|
10257 | n/a | * it easier to add additional entries to the tables. |
---|
10258 | n/a | */ |
---|
10259 | n/a | |
---|
10260 | n/a | static int |
---|
10261 | n/a | cmp_constdefs(const void *v1, const void *v2) |
---|
10262 | n/a | { |
---|
10263 | n/a | const struct constdef *c1 = |
---|
10264 | n/a | (const struct constdef *) v1; |
---|
10265 | n/a | const struct constdef *c2 = |
---|
10266 | n/a | (const struct constdef *) v2; |
---|
10267 | n/a | |
---|
10268 | n/a | return strcmp(c1->name, c2->name); |
---|
10269 | n/a | } |
---|
10270 | n/a | |
---|
10271 | n/a | static int |
---|
10272 | n/a | setup_confname_table(struct constdef *table, size_t tablesize, |
---|
10273 | n/a | const char *tablename, PyObject *module) |
---|
10274 | n/a | { |
---|
10275 | n/a | PyObject *d = NULL; |
---|
10276 | n/a | size_t i; |
---|
10277 | n/a | |
---|
10278 | n/a | qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs); |
---|
10279 | n/a | d = PyDict_New(); |
---|
10280 | n/a | if (d == NULL) |
---|
10281 | n/a | return -1; |
---|
10282 | n/a | |
---|
10283 | n/a | for (i=0; i < tablesize; ++i) { |
---|
10284 | n/a | PyObject *o = PyLong_FromLong(table[i].value); |
---|
10285 | n/a | if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) { |
---|
10286 | n/a | Py_XDECREF(o); |
---|
10287 | n/a | Py_DECREF(d); |
---|
10288 | n/a | return -1; |
---|
10289 | n/a | } |
---|
10290 | n/a | Py_DECREF(o); |
---|
10291 | n/a | } |
---|
10292 | n/a | return PyModule_AddObject(module, tablename, d); |
---|
10293 | n/a | } |
---|
10294 | n/a | |
---|
10295 | n/a | /* Return -1 on failure, 0 on success. */ |
---|
10296 | n/a | static int |
---|
10297 | n/a | setup_confname_tables(PyObject *module) |
---|
10298 | n/a | { |
---|
10299 | n/a | #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF) |
---|
10300 | n/a | if (setup_confname_table(posix_constants_pathconf, |
---|
10301 | n/a | sizeof(posix_constants_pathconf) |
---|
10302 | n/a | / sizeof(struct constdef), |
---|
10303 | n/a | "pathconf_names", module)) |
---|
10304 | n/a | return -1; |
---|
10305 | n/a | #endif |
---|
10306 | n/a | #ifdef HAVE_CONFSTR |
---|
10307 | n/a | if (setup_confname_table(posix_constants_confstr, |
---|
10308 | n/a | sizeof(posix_constants_confstr) |
---|
10309 | n/a | / sizeof(struct constdef), |
---|
10310 | n/a | "confstr_names", module)) |
---|
10311 | n/a | return -1; |
---|
10312 | n/a | #endif |
---|
10313 | n/a | #ifdef HAVE_SYSCONF |
---|
10314 | n/a | if (setup_confname_table(posix_constants_sysconf, |
---|
10315 | n/a | sizeof(posix_constants_sysconf) |
---|
10316 | n/a | / sizeof(struct constdef), |
---|
10317 | n/a | "sysconf_names", module)) |
---|
10318 | n/a | return -1; |
---|
10319 | n/a | #endif |
---|
10320 | n/a | return 0; |
---|
10321 | n/a | } |
---|
10322 | n/a | |
---|
10323 | n/a | |
---|
10324 | n/a | /*[clinic input] |
---|
10325 | n/a | os.abort |
---|
10326 | n/a | |
---|
10327 | n/a | Abort the interpreter immediately. |
---|
10328 | n/a | |
---|
10329 | n/a | This function 'dumps core' or otherwise fails in the hardest way possible |
---|
10330 | n/a | on the hosting operating system. This function never returns. |
---|
10331 | n/a | [clinic start generated code]*/ |
---|
10332 | n/a | |
---|
10333 | n/a | static PyObject * |
---|
10334 | n/a | os_abort_impl(PyObject *module) |
---|
10335 | n/a | /*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/ |
---|
10336 | n/a | { |
---|
10337 | n/a | abort(); |
---|
10338 | n/a | /*NOTREACHED*/ |
---|
10339 | n/a | #ifndef __clang__ |
---|
10340 | n/a | /* Issue #28152: abort() is declared with __attribute__((__noreturn__)). |
---|
10341 | n/a | GCC emits a warning without "return NULL;" (compiler bug?), but Clang |
---|
10342 | n/a | is smarter and emits a warning on the return. */ |
---|
10343 | n/a | Py_FatalError("abort() called from Python code didn't abort!"); |
---|
10344 | n/a | return NULL; |
---|
10345 | n/a | #endif |
---|
10346 | n/a | } |
---|
10347 | n/a | |
---|
10348 | n/a | #ifdef MS_WINDOWS |
---|
10349 | n/a | /* Grab ShellExecute dynamically from shell32 */ |
---|
10350 | n/a | static int has_ShellExecute = -1; |
---|
10351 | n/a | static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR, |
---|
10352 | n/a | LPCWSTR, INT); |
---|
10353 | n/a | static int |
---|
10354 | n/a | check_ShellExecute() |
---|
10355 | n/a | { |
---|
10356 | n/a | HINSTANCE hShell32; |
---|
10357 | n/a | |
---|
10358 | n/a | /* only recheck */ |
---|
10359 | n/a | if (-1 == has_ShellExecute) { |
---|
10360 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
10361 | n/a | hShell32 = LoadLibraryW(L"SHELL32"); |
---|
10362 | n/a | Py_END_ALLOW_THREADS |
---|
10363 | n/a | if (hShell32) { |
---|
10364 | n/a | *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32, |
---|
10365 | n/a | "ShellExecuteW"); |
---|
10366 | n/a | has_ShellExecute = Py_ShellExecuteW != NULL; |
---|
10367 | n/a | } else { |
---|
10368 | n/a | has_ShellExecute = 0; |
---|
10369 | n/a | } |
---|
10370 | n/a | } |
---|
10371 | n/a | return has_ShellExecute; |
---|
10372 | n/a | } |
---|
10373 | n/a | |
---|
10374 | n/a | |
---|
10375 | n/a | /*[clinic input] |
---|
10376 | n/a | os.startfile |
---|
10377 | n/a | filepath: path_t |
---|
10378 | n/a | operation: Py_UNICODE = NULL |
---|
10379 | n/a | |
---|
10380 | n/a | startfile(filepath [, operation]) |
---|
10381 | n/a | |
---|
10382 | n/a | Start a file with its associated application. |
---|
10383 | n/a | |
---|
10384 | n/a | When "operation" is not specified or "open", this acts like |
---|
10385 | n/a | double-clicking the file in Explorer, or giving the file name as an |
---|
10386 | n/a | argument to the DOS "start" command: the file is opened with whatever |
---|
10387 | n/a | application (if any) its extension is associated. |
---|
10388 | n/a | When another "operation" is given, it specifies what should be done with |
---|
10389 | n/a | the file. A typical operation is "print". |
---|
10390 | n/a | |
---|
10391 | n/a | startfile returns as soon as the associated application is launched. |
---|
10392 | n/a | There is no option to wait for the application to close, and no way |
---|
10393 | n/a | to retrieve the application's exit status. |
---|
10394 | n/a | |
---|
10395 | n/a | The filepath is relative to the current directory. If you want to use |
---|
10396 | n/a | an absolute path, make sure the first character is not a slash ("/"); |
---|
10397 | n/a | the underlying Win32 ShellExecute function doesn't work if it is. |
---|
10398 | n/a | [clinic start generated code]*/ |
---|
10399 | n/a | |
---|
10400 | n/a | static PyObject * |
---|
10401 | n/a | os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation) |
---|
10402 | n/a | /*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/ |
---|
10403 | n/a | { |
---|
10404 | n/a | HINSTANCE rc; |
---|
10405 | n/a | |
---|
10406 | n/a | if(!check_ShellExecute()) { |
---|
10407 | n/a | /* If the OS doesn't have ShellExecute, return a |
---|
10408 | n/a | NotImplementedError. */ |
---|
10409 | n/a | return PyErr_Format(PyExc_NotImplementedError, |
---|
10410 | n/a | "startfile not available on this platform"); |
---|
10411 | n/a | } |
---|
10412 | n/a | |
---|
10413 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
10414 | n/a | rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide, |
---|
10415 | n/a | NULL, NULL, SW_SHOWNORMAL); |
---|
10416 | n/a | Py_END_ALLOW_THREADS |
---|
10417 | n/a | |
---|
10418 | n/a | if (rc <= (HINSTANCE)32) { |
---|
10419 | n/a | win32_error_object("startfile", filepath->object); |
---|
10420 | n/a | return NULL; |
---|
10421 | n/a | } |
---|
10422 | n/a | Py_RETURN_NONE; |
---|
10423 | n/a | } |
---|
10424 | n/a | #endif /* MS_WINDOWS */ |
---|
10425 | n/a | |
---|
10426 | n/a | |
---|
10427 | n/a | #ifdef HAVE_GETLOADAVG |
---|
10428 | n/a | /*[clinic input] |
---|
10429 | n/a | os.getloadavg |
---|
10430 | n/a | |
---|
10431 | n/a | Return average recent system load information. |
---|
10432 | n/a | |
---|
10433 | n/a | Return the number of processes in the system run queue averaged over |
---|
10434 | n/a | the last 1, 5, and 15 minutes as a tuple of three floats. |
---|
10435 | n/a | Raises OSError if the load average was unobtainable. |
---|
10436 | n/a | [clinic start generated code]*/ |
---|
10437 | n/a | |
---|
10438 | n/a | static PyObject * |
---|
10439 | n/a | os_getloadavg_impl(PyObject *module) |
---|
10440 | n/a | /*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/ |
---|
10441 | n/a | { |
---|
10442 | n/a | double loadavg[3]; |
---|
10443 | n/a | if (getloadavg(loadavg, 3)!=3) { |
---|
10444 | n/a | PyErr_SetString(PyExc_OSError, "Load averages are unobtainable"); |
---|
10445 | n/a | return NULL; |
---|
10446 | n/a | } else |
---|
10447 | n/a | return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]); |
---|
10448 | n/a | } |
---|
10449 | n/a | #endif /* HAVE_GETLOADAVG */ |
---|
10450 | n/a | |
---|
10451 | n/a | |
---|
10452 | n/a | /*[clinic input] |
---|
10453 | n/a | os.device_encoding |
---|
10454 | n/a | fd: int |
---|
10455 | n/a | |
---|
10456 | n/a | Return a string describing the encoding of a terminal's file descriptor. |
---|
10457 | n/a | |
---|
10458 | n/a | The file descriptor must be attached to a terminal. |
---|
10459 | n/a | If the device is not a terminal, return None. |
---|
10460 | n/a | [clinic start generated code]*/ |
---|
10461 | n/a | |
---|
10462 | n/a | static PyObject * |
---|
10463 | n/a | os_device_encoding_impl(PyObject *module, int fd) |
---|
10464 | n/a | /*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/ |
---|
10465 | n/a | { |
---|
10466 | n/a | return _Py_device_encoding(fd); |
---|
10467 | n/a | } |
---|
10468 | n/a | |
---|
10469 | n/a | |
---|
10470 | n/a | #ifdef HAVE_SETRESUID |
---|
10471 | n/a | /*[clinic input] |
---|
10472 | n/a | os.setresuid |
---|
10473 | n/a | |
---|
10474 | n/a | ruid: uid_t |
---|
10475 | n/a | euid: uid_t |
---|
10476 | n/a | suid: uid_t |
---|
10477 | n/a | / |
---|
10478 | n/a | |
---|
10479 | n/a | Set the current process's real, effective, and saved user ids. |
---|
10480 | n/a | [clinic start generated code]*/ |
---|
10481 | n/a | |
---|
10482 | n/a | static PyObject * |
---|
10483 | n/a | os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid) |
---|
10484 | n/a | /*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/ |
---|
10485 | n/a | { |
---|
10486 | n/a | if (setresuid(ruid, euid, suid) < 0) |
---|
10487 | n/a | return posix_error(); |
---|
10488 | n/a | Py_RETURN_NONE; |
---|
10489 | n/a | } |
---|
10490 | n/a | #endif /* HAVE_SETRESUID */ |
---|
10491 | n/a | |
---|
10492 | n/a | |
---|
10493 | n/a | #ifdef HAVE_SETRESGID |
---|
10494 | n/a | /*[clinic input] |
---|
10495 | n/a | os.setresgid |
---|
10496 | n/a | |
---|
10497 | n/a | rgid: gid_t |
---|
10498 | n/a | egid: gid_t |
---|
10499 | n/a | sgid: gid_t |
---|
10500 | n/a | / |
---|
10501 | n/a | |
---|
10502 | n/a | Set the current process's real, effective, and saved group ids. |
---|
10503 | n/a | [clinic start generated code]*/ |
---|
10504 | n/a | |
---|
10505 | n/a | static PyObject * |
---|
10506 | n/a | os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid) |
---|
10507 | n/a | /*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/ |
---|
10508 | n/a | { |
---|
10509 | n/a | if (setresgid(rgid, egid, sgid) < 0) |
---|
10510 | n/a | return posix_error(); |
---|
10511 | n/a | Py_RETURN_NONE; |
---|
10512 | n/a | } |
---|
10513 | n/a | #endif /* HAVE_SETRESGID */ |
---|
10514 | n/a | |
---|
10515 | n/a | |
---|
10516 | n/a | #ifdef HAVE_GETRESUID |
---|
10517 | n/a | /*[clinic input] |
---|
10518 | n/a | os.getresuid |
---|
10519 | n/a | |
---|
10520 | n/a | Return a tuple of the current process's real, effective, and saved user ids. |
---|
10521 | n/a | [clinic start generated code]*/ |
---|
10522 | n/a | |
---|
10523 | n/a | static PyObject * |
---|
10524 | n/a | os_getresuid_impl(PyObject *module) |
---|
10525 | n/a | /*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/ |
---|
10526 | n/a | { |
---|
10527 | n/a | uid_t ruid, euid, suid; |
---|
10528 | n/a | if (getresuid(&ruid, &euid, &suid) < 0) |
---|
10529 | n/a | return posix_error(); |
---|
10530 | n/a | return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid), |
---|
10531 | n/a | _PyLong_FromUid(euid), |
---|
10532 | n/a | _PyLong_FromUid(suid)); |
---|
10533 | n/a | } |
---|
10534 | n/a | #endif /* HAVE_GETRESUID */ |
---|
10535 | n/a | |
---|
10536 | n/a | |
---|
10537 | n/a | #ifdef HAVE_GETRESGID |
---|
10538 | n/a | /*[clinic input] |
---|
10539 | n/a | os.getresgid |
---|
10540 | n/a | |
---|
10541 | n/a | Return a tuple of the current process's real, effective, and saved group ids. |
---|
10542 | n/a | [clinic start generated code]*/ |
---|
10543 | n/a | |
---|
10544 | n/a | static PyObject * |
---|
10545 | n/a | os_getresgid_impl(PyObject *module) |
---|
10546 | n/a | /*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/ |
---|
10547 | n/a | { |
---|
10548 | n/a | gid_t rgid, egid, sgid; |
---|
10549 | n/a | if (getresgid(&rgid, &egid, &sgid) < 0) |
---|
10550 | n/a | return posix_error(); |
---|
10551 | n/a | return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid), |
---|
10552 | n/a | _PyLong_FromGid(egid), |
---|
10553 | n/a | _PyLong_FromGid(sgid)); |
---|
10554 | n/a | } |
---|
10555 | n/a | #endif /* HAVE_GETRESGID */ |
---|
10556 | n/a | |
---|
10557 | n/a | |
---|
10558 | n/a | #ifdef USE_XATTRS |
---|
10559 | n/a | /*[clinic input] |
---|
10560 | n/a | os.getxattr |
---|
10561 | n/a | |
---|
10562 | n/a | path: path_t(allow_fd=True) |
---|
10563 | n/a | attribute: path_t |
---|
10564 | n/a | * |
---|
10565 | n/a | follow_symlinks: bool = True |
---|
10566 | n/a | |
---|
10567 | n/a | Return the value of extended attribute attribute on path. |
---|
10568 | n/a | |
---|
10569 | n/a | path may be either a string or an open file descriptor. |
---|
10570 | n/a | If follow_symlinks is False, and the last element of the path is a symbolic |
---|
10571 | n/a | link, getxattr will examine the symbolic link itself instead of the file |
---|
10572 | n/a | the link points to. |
---|
10573 | n/a | |
---|
10574 | n/a | [clinic start generated code]*/ |
---|
10575 | n/a | |
---|
10576 | n/a | static PyObject * |
---|
10577 | n/a | os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute, |
---|
10578 | n/a | int follow_symlinks) |
---|
10579 | n/a | /*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/ |
---|
10580 | n/a | { |
---|
10581 | n/a | Py_ssize_t i; |
---|
10582 | n/a | PyObject *buffer = NULL; |
---|
10583 | n/a | |
---|
10584 | n/a | if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks)) |
---|
10585 | n/a | return NULL; |
---|
10586 | n/a | |
---|
10587 | n/a | for (i = 0; ; i++) { |
---|
10588 | n/a | void *ptr; |
---|
10589 | n/a | ssize_t result; |
---|
10590 | n/a | static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0}; |
---|
10591 | n/a | Py_ssize_t buffer_size = buffer_sizes[i]; |
---|
10592 | n/a | if (!buffer_size) { |
---|
10593 | n/a | path_error(path); |
---|
10594 | n/a | return NULL; |
---|
10595 | n/a | } |
---|
10596 | n/a | buffer = PyBytes_FromStringAndSize(NULL, buffer_size); |
---|
10597 | n/a | if (!buffer) |
---|
10598 | n/a | return NULL; |
---|
10599 | n/a | ptr = PyBytes_AS_STRING(buffer); |
---|
10600 | n/a | |
---|
10601 | n/a | Py_BEGIN_ALLOW_THREADS; |
---|
10602 | n/a | if (path->fd >= 0) |
---|
10603 | n/a | result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size); |
---|
10604 | n/a | else if (follow_symlinks) |
---|
10605 | n/a | result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size); |
---|
10606 | n/a | else |
---|
10607 | n/a | result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size); |
---|
10608 | n/a | Py_END_ALLOW_THREADS; |
---|
10609 | n/a | |
---|
10610 | n/a | if (result < 0) { |
---|
10611 | n/a | Py_DECREF(buffer); |
---|
10612 | n/a | if (errno == ERANGE) |
---|
10613 | n/a | continue; |
---|
10614 | n/a | path_error(path); |
---|
10615 | n/a | return NULL; |
---|
10616 | n/a | } |
---|
10617 | n/a | |
---|
10618 | n/a | if (result != buffer_size) { |
---|
10619 | n/a | /* Can only shrink. */ |
---|
10620 | n/a | _PyBytes_Resize(&buffer, result); |
---|
10621 | n/a | } |
---|
10622 | n/a | break; |
---|
10623 | n/a | } |
---|
10624 | n/a | |
---|
10625 | n/a | return buffer; |
---|
10626 | n/a | } |
---|
10627 | n/a | |
---|
10628 | n/a | |
---|
10629 | n/a | /*[clinic input] |
---|
10630 | n/a | os.setxattr |
---|
10631 | n/a | |
---|
10632 | n/a | path: path_t(allow_fd=True) |
---|
10633 | n/a | attribute: path_t |
---|
10634 | n/a | value: Py_buffer |
---|
10635 | n/a | flags: int = 0 |
---|
10636 | n/a | * |
---|
10637 | n/a | follow_symlinks: bool = True |
---|
10638 | n/a | |
---|
10639 | n/a | Set extended attribute attribute on path to value. |
---|
10640 | n/a | |
---|
10641 | n/a | path may be either a string or an open file descriptor. |
---|
10642 | n/a | If follow_symlinks is False, and the last element of the path is a symbolic |
---|
10643 | n/a | link, setxattr will modify the symbolic link itself instead of the file |
---|
10644 | n/a | the link points to. |
---|
10645 | n/a | |
---|
10646 | n/a | [clinic start generated code]*/ |
---|
10647 | n/a | |
---|
10648 | n/a | static PyObject * |
---|
10649 | n/a | os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute, |
---|
10650 | n/a | Py_buffer *value, int flags, int follow_symlinks) |
---|
10651 | n/a | /*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/ |
---|
10652 | n/a | { |
---|
10653 | n/a | ssize_t result; |
---|
10654 | n/a | |
---|
10655 | n/a | if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks)) |
---|
10656 | n/a | return NULL; |
---|
10657 | n/a | |
---|
10658 | n/a | Py_BEGIN_ALLOW_THREADS; |
---|
10659 | n/a | if (path->fd > -1) |
---|
10660 | n/a | result = fsetxattr(path->fd, attribute->narrow, |
---|
10661 | n/a | value->buf, value->len, flags); |
---|
10662 | n/a | else if (follow_symlinks) |
---|
10663 | n/a | result = setxattr(path->narrow, attribute->narrow, |
---|
10664 | n/a | value->buf, value->len, flags); |
---|
10665 | n/a | else |
---|
10666 | n/a | result = lsetxattr(path->narrow, attribute->narrow, |
---|
10667 | n/a | value->buf, value->len, flags); |
---|
10668 | n/a | Py_END_ALLOW_THREADS; |
---|
10669 | n/a | |
---|
10670 | n/a | if (result) { |
---|
10671 | n/a | path_error(path); |
---|
10672 | n/a | return NULL; |
---|
10673 | n/a | } |
---|
10674 | n/a | |
---|
10675 | n/a | Py_RETURN_NONE; |
---|
10676 | n/a | } |
---|
10677 | n/a | |
---|
10678 | n/a | |
---|
10679 | n/a | /*[clinic input] |
---|
10680 | n/a | os.removexattr |
---|
10681 | n/a | |
---|
10682 | n/a | path: path_t(allow_fd=True) |
---|
10683 | n/a | attribute: path_t |
---|
10684 | n/a | * |
---|
10685 | n/a | follow_symlinks: bool = True |
---|
10686 | n/a | |
---|
10687 | n/a | Remove extended attribute attribute on path. |
---|
10688 | n/a | |
---|
10689 | n/a | path may be either a string or an open file descriptor. |
---|
10690 | n/a | If follow_symlinks is False, and the last element of the path is a symbolic |
---|
10691 | n/a | link, removexattr will modify the symbolic link itself instead of the file |
---|
10692 | n/a | the link points to. |
---|
10693 | n/a | |
---|
10694 | n/a | [clinic start generated code]*/ |
---|
10695 | n/a | |
---|
10696 | n/a | static PyObject * |
---|
10697 | n/a | os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute, |
---|
10698 | n/a | int follow_symlinks) |
---|
10699 | n/a | /*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/ |
---|
10700 | n/a | { |
---|
10701 | n/a | ssize_t result; |
---|
10702 | n/a | |
---|
10703 | n/a | if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks)) |
---|
10704 | n/a | return NULL; |
---|
10705 | n/a | |
---|
10706 | n/a | Py_BEGIN_ALLOW_THREADS; |
---|
10707 | n/a | if (path->fd > -1) |
---|
10708 | n/a | result = fremovexattr(path->fd, attribute->narrow); |
---|
10709 | n/a | else if (follow_symlinks) |
---|
10710 | n/a | result = removexattr(path->narrow, attribute->narrow); |
---|
10711 | n/a | else |
---|
10712 | n/a | result = lremovexattr(path->narrow, attribute->narrow); |
---|
10713 | n/a | Py_END_ALLOW_THREADS; |
---|
10714 | n/a | |
---|
10715 | n/a | if (result) { |
---|
10716 | n/a | return path_error(path); |
---|
10717 | n/a | } |
---|
10718 | n/a | |
---|
10719 | n/a | Py_RETURN_NONE; |
---|
10720 | n/a | } |
---|
10721 | n/a | |
---|
10722 | n/a | |
---|
10723 | n/a | /*[clinic input] |
---|
10724 | n/a | os.listxattr |
---|
10725 | n/a | |
---|
10726 | n/a | path: path_t(allow_fd=True, nullable=True) = None |
---|
10727 | n/a | * |
---|
10728 | n/a | follow_symlinks: bool = True |
---|
10729 | n/a | |
---|
10730 | n/a | Return a list of extended attributes on path. |
---|
10731 | n/a | |
---|
10732 | n/a | path may be either None, a string, or an open file descriptor. |
---|
10733 | n/a | if path is None, listxattr will examine the current directory. |
---|
10734 | n/a | If follow_symlinks is False, and the last element of the path is a symbolic |
---|
10735 | n/a | link, listxattr will examine the symbolic link itself instead of the file |
---|
10736 | n/a | the link points to. |
---|
10737 | n/a | [clinic start generated code]*/ |
---|
10738 | n/a | |
---|
10739 | n/a | static PyObject * |
---|
10740 | n/a | os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks) |
---|
10741 | n/a | /*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/ |
---|
10742 | n/a | { |
---|
10743 | n/a | Py_ssize_t i; |
---|
10744 | n/a | PyObject *result = NULL; |
---|
10745 | n/a | const char *name; |
---|
10746 | n/a | char *buffer = NULL; |
---|
10747 | n/a | |
---|
10748 | n/a | if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks)) |
---|
10749 | n/a | goto exit; |
---|
10750 | n/a | |
---|
10751 | n/a | name = path->narrow ? path->narrow : "."; |
---|
10752 | n/a | |
---|
10753 | n/a | for (i = 0; ; i++) { |
---|
10754 | n/a | const char *start, *trace, *end; |
---|
10755 | n/a | ssize_t length; |
---|
10756 | n/a | static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 }; |
---|
10757 | n/a | Py_ssize_t buffer_size = buffer_sizes[i]; |
---|
10758 | n/a | if (!buffer_size) { |
---|
10759 | n/a | /* ERANGE */ |
---|
10760 | n/a | path_error(path); |
---|
10761 | n/a | break; |
---|
10762 | n/a | } |
---|
10763 | n/a | buffer = PyMem_MALLOC(buffer_size); |
---|
10764 | n/a | if (!buffer) { |
---|
10765 | n/a | PyErr_NoMemory(); |
---|
10766 | n/a | break; |
---|
10767 | n/a | } |
---|
10768 | n/a | |
---|
10769 | n/a | Py_BEGIN_ALLOW_THREADS; |
---|
10770 | n/a | if (path->fd > -1) |
---|
10771 | n/a | length = flistxattr(path->fd, buffer, buffer_size); |
---|
10772 | n/a | else if (follow_symlinks) |
---|
10773 | n/a | length = listxattr(name, buffer, buffer_size); |
---|
10774 | n/a | else |
---|
10775 | n/a | length = llistxattr(name, buffer, buffer_size); |
---|
10776 | n/a | Py_END_ALLOW_THREADS; |
---|
10777 | n/a | |
---|
10778 | n/a | if (length < 0) { |
---|
10779 | n/a | if (errno == ERANGE) { |
---|
10780 | n/a | PyMem_FREE(buffer); |
---|
10781 | n/a | buffer = NULL; |
---|
10782 | n/a | continue; |
---|
10783 | n/a | } |
---|
10784 | n/a | path_error(path); |
---|
10785 | n/a | break; |
---|
10786 | n/a | } |
---|
10787 | n/a | |
---|
10788 | n/a | result = PyList_New(0); |
---|
10789 | n/a | if (!result) { |
---|
10790 | n/a | goto exit; |
---|
10791 | n/a | } |
---|
10792 | n/a | |
---|
10793 | n/a | end = buffer + length; |
---|
10794 | n/a | for (trace = start = buffer; trace != end; trace++) { |
---|
10795 | n/a | if (!*trace) { |
---|
10796 | n/a | int error; |
---|
10797 | n/a | PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start, |
---|
10798 | n/a | trace - start); |
---|
10799 | n/a | if (!attribute) { |
---|
10800 | n/a | Py_DECREF(result); |
---|
10801 | n/a | result = NULL; |
---|
10802 | n/a | goto exit; |
---|
10803 | n/a | } |
---|
10804 | n/a | error = PyList_Append(result, attribute); |
---|
10805 | n/a | Py_DECREF(attribute); |
---|
10806 | n/a | if (error) { |
---|
10807 | n/a | Py_DECREF(result); |
---|
10808 | n/a | result = NULL; |
---|
10809 | n/a | goto exit; |
---|
10810 | n/a | } |
---|
10811 | n/a | start = trace + 1; |
---|
10812 | n/a | } |
---|
10813 | n/a | } |
---|
10814 | n/a | break; |
---|
10815 | n/a | } |
---|
10816 | n/a | exit: |
---|
10817 | n/a | if (buffer) |
---|
10818 | n/a | PyMem_FREE(buffer); |
---|
10819 | n/a | return result; |
---|
10820 | n/a | } |
---|
10821 | n/a | #endif /* USE_XATTRS */ |
---|
10822 | n/a | |
---|
10823 | n/a | |
---|
10824 | n/a | /*[clinic input] |
---|
10825 | n/a | os.urandom |
---|
10826 | n/a | |
---|
10827 | n/a | size: Py_ssize_t |
---|
10828 | n/a | / |
---|
10829 | n/a | |
---|
10830 | n/a | Return a bytes object containing random bytes suitable for cryptographic use. |
---|
10831 | n/a | [clinic start generated code]*/ |
---|
10832 | n/a | |
---|
10833 | n/a | static PyObject * |
---|
10834 | n/a | os_urandom_impl(PyObject *module, Py_ssize_t size) |
---|
10835 | n/a | /*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/ |
---|
10836 | n/a | { |
---|
10837 | n/a | PyObject *bytes; |
---|
10838 | n/a | int result; |
---|
10839 | n/a | |
---|
10840 | n/a | if (size < 0) |
---|
10841 | n/a | return PyErr_Format(PyExc_ValueError, |
---|
10842 | n/a | "negative argument not allowed"); |
---|
10843 | n/a | bytes = PyBytes_FromStringAndSize(NULL, size); |
---|
10844 | n/a | if (bytes == NULL) |
---|
10845 | n/a | return NULL; |
---|
10846 | n/a | |
---|
10847 | n/a | result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes)); |
---|
10848 | n/a | if (result == -1) { |
---|
10849 | n/a | Py_DECREF(bytes); |
---|
10850 | n/a | return NULL; |
---|
10851 | n/a | } |
---|
10852 | n/a | return bytes; |
---|
10853 | n/a | } |
---|
10854 | n/a | |
---|
10855 | n/a | /* Terminal size querying */ |
---|
10856 | n/a | |
---|
10857 | n/a | static PyTypeObject TerminalSizeType; |
---|
10858 | n/a | |
---|
10859 | n/a | PyDoc_STRVAR(TerminalSize_docstring, |
---|
10860 | n/a | "A tuple of (columns, lines) for holding terminal window size"); |
---|
10861 | n/a | |
---|
10862 | n/a | static PyStructSequence_Field TerminalSize_fields[] = { |
---|
10863 | n/a | {"columns", "width of the terminal window in characters"}, |
---|
10864 | n/a | {"lines", "height of the terminal window in characters"}, |
---|
10865 | n/a | {NULL, NULL} |
---|
10866 | n/a | }; |
---|
10867 | n/a | |
---|
10868 | n/a | static PyStructSequence_Desc TerminalSize_desc = { |
---|
10869 | n/a | "os.terminal_size", |
---|
10870 | n/a | TerminalSize_docstring, |
---|
10871 | n/a | TerminalSize_fields, |
---|
10872 | n/a | 2, |
---|
10873 | n/a | }; |
---|
10874 | n/a | |
---|
10875 | n/a | #if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) |
---|
10876 | n/a | /* AC 3.5: fd should accept None */ |
---|
10877 | n/a | PyDoc_STRVAR(termsize__doc__, |
---|
10878 | n/a | "Return the size of the terminal window as (columns, lines).\n" \ |
---|
10879 | n/a | "\n" \ |
---|
10880 | n/a | "The optional argument fd (default standard output) specifies\n" \ |
---|
10881 | n/a | "which file descriptor should be queried.\n" \ |
---|
10882 | n/a | "\n" \ |
---|
10883 | n/a | "If the file descriptor is not connected to a terminal, an OSError\n" \ |
---|
10884 | n/a | "is thrown.\n" \ |
---|
10885 | n/a | "\n" \ |
---|
10886 | n/a | "This function will only be defined if an implementation is\n" \ |
---|
10887 | n/a | "available for this system.\n" \ |
---|
10888 | n/a | "\n" \ |
---|
10889 | n/a | "shutil.get_terminal_size is the high-level function which should \n" \ |
---|
10890 | n/a | "normally be used, os.get_terminal_size is the low-level implementation."); |
---|
10891 | n/a | |
---|
10892 | n/a | static PyObject* |
---|
10893 | n/a | get_terminal_size(PyObject *self, PyObject *args) |
---|
10894 | n/a | { |
---|
10895 | n/a | int columns, lines; |
---|
10896 | n/a | PyObject *termsize; |
---|
10897 | n/a | |
---|
10898 | n/a | int fd = fileno(stdout); |
---|
10899 | n/a | /* Under some conditions stdout may not be connected and |
---|
10900 | n/a | * fileno(stdout) may point to an invalid file descriptor. For example |
---|
10901 | n/a | * GUI apps don't have valid standard streams by default. |
---|
10902 | n/a | * |
---|
10903 | n/a | * If this happens, and the optional fd argument is not present, |
---|
10904 | n/a | * the ioctl below will fail returning EBADF. This is what we want. |
---|
10905 | n/a | */ |
---|
10906 | n/a | |
---|
10907 | n/a | if (!PyArg_ParseTuple(args, "|i", &fd)) |
---|
10908 | n/a | return NULL; |
---|
10909 | n/a | |
---|
10910 | n/a | #ifdef TERMSIZE_USE_IOCTL |
---|
10911 | n/a | { |
---|
10912 | n/a | struct winsize w; |
---|
10913 | n/a | if (ioctl(fd, TIOCGWINSZ, &w)) |
---|
10914 | n/a | return PyErr_SetFromErrno(PyExc_OSError); |
---|
10915 | n/a | columns = w.ws_col; |
---|
10916 | n/a | lines = w.ws_row; |
---|
10917 | n/a | } |
---|
10918 | n/a | #endif /* TERMSIZE_USE_IOCTL */ |
---|
10919 | n/a | |
---|
10920 | n/a | #ifdef TERMSIZE_USE_CONIO |
---|
10921 | n/a | { |
---|
10922 | n/a | DWORD nhandle; |
---|
10923 | n/a | HANDLE handle; |
---|
10924 | n/a | CONSOLE_SCREEN_BUFFER_INFO csbi; |
---|
10925 | n/a | switch (fd) { |
---|
10926 | n/a | case 0: nhandle = STD_INPUT_HANDLE; |
---|
10927 | n/a | break; |
---|
10928 | n/a | case 1: nhandle = STD_OUTPUT_HANDLE; |
---|
10929 | n/a | break; |
---|
10930 | n/a | case 2: nhandle = STD_ERROR_HANDLE; |
---|
10931 | n/a | break; |
---|
10932 | n/a | default: |
---|
10933 | n/a | return PyErr_Format(PyExc_ValueError, "bad file descriptor"); |
---|
10934 | n/a | } |
---|
10935 | n/a | handle = GetStdHandle(nhandle); |
---|
10936 | n/a | if (handle == NULL) |
---|
10937 | n/a | return PyErr_Format(PyExc_OSError, "handle cannot be retrieved"); |
---|
10938 | n/a | if (handle == INVALID_HANDLE_VALUE) |
---|
10939 | n/a | return PyErr_SetFromWindowsErr(0); |
---|
10940 | n/a | |
---|
10941 | n/a | if (!GetConsoleScreenBufferInfo(handle, &csbi)) |
---|
10942 | n/a | return PyErr_SetFromWindowsErr(0); |
---|
10943 | n/a | |
---|
10944 | n/a | columns = csbi.srWindow.Right - csbi.srWindow.Left + 1; |
---|
10945 | n/a | lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1; |
---|
10946 | n/a | } |
---|
10947 | n/a | #endif /* TERMSIZE_USE_CONIO */ |
---|
10948 | n/a | |
---|
10949 | n/a | termsize = PyStructSequence_New(&TerminalSizeType); |
---|
10950 | n/a | if (termsize == NULL) |
---|
10951 | n/a | return NULL; |
---|
10952 | n/a | PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns)); |
---|
10953 | n/a | PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines)); |
---|
10954 | n/a | if (PyErr_Occurred()) { |
---|
10955 | n/a | Py_DECREF(termsize); |
---|
10956 | n/a | return NULL; |
---|
10957 | n/a | } |
---|
10958 | n/a | return termsize; |
---|
10959 | n/a | } |
---|
10960 | n/a | #endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */ |
---|
10961 | n/a | |
---|
10962 | n/a | |
---|
10963 | n/a | /*[clinic input] |
---|
10964 | n/a | os.cpu_count |
---|
10965 | n/a | |
---|
10966 | n/a | Return the number of CPUs in the system; return None if indeterminable. |
---|
10967 | n/a | |
---|
10968 | n/a | This number is not equivalent to the number of CPUs the current process can |
---|
10969 | n/a | use. The number of usable CPUs can be obtained with |
---|
10970 | n/a | ``len(os.sched_getaffinity(0))`` |
---|
10971 | n/a | [clinic start generated code]*/ |
---|
10972 | n/a | |
---|
10973 | n/a | static PyObject * |
---|
10974 | n/a | os_cpu_count_impl(PyObject *module) |
---|
10975 | n/a | /*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/ |
---|
10976 | n/a | { |
---|
10977 | n/a | int ncpu = 0; |
---|
10978 | n/a | #ifdef MS_WINDOWS |
---|
10979 | n/a | SYSTEM_INFO sysinfo; |
---|
10980 | n/a | GetSystemInfo(&sysinfo); |
---|
10981 | n/a | ncpu = sysinfo.dwNumberOfProcessors; |
---|
10982 | n/a | #elif defined(__hpux) |
---|
10983 | n/a | ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL); |
---|
10984 | n/a | #elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN) |
---|
10985 | n/a | ncpu = sysconf(_SC_NPROCESSORS_ONLN); |
---|
10986 | n/a | #elif defined(__DragonFly__) || \ |
---|
10987 | n/a | defined(__OpenBSD__) || \ |
---|
10988 | n/a | defined(__FreeBSD__) || \ |
---|
10989 | n/a | defined(__NetBSD__) || \ |
---|
10990 | n/a | defined(__APPLE__) |
---|
10991 | n/a | int mib[2]; |
---|
10992 | n/a | size_t len = sizeof(ncpu); |
---|
10993 | n/a | mib[0] = CTL_HW; |
---|
10994 | n/a | mib[1] = HW_NCPU; |
---|
10995 | n/a | if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0) |
---|
10996 | n/a | ncpu = 0; |
---|
10997 | n/a | #endif |
---|
10998 | n/a | if (ncpu >= 1) |
---|
10999 | n/a | return PyLong_FromLong(ncpu); |
---|
11000 | n/a | else |
---|
11001 | n/a | Py_RETURN_NONE; |
---|
11002 | n/a | } |
---|
11003 | n/a | |
---|
11004 | n/a | |
---|
11005 | n/a | /*[clinic input] |
---|
11006 | n/a | os.get_inheritable -> bool |
---|
11007 | n/a | |
---|
11008 | n/a | fd: int |
---|
11009 | n/a | / |
---|
11010 | n/a | |
---|
11011 | n/a | Get the close-on-exe flag of the specified file descriptor. |
---|
11012 | n/a | [clinic start generated code]*/ |
---|
11013 | n/a | |
---|
11014 | n/a | static int |
---|
11015 | n/a | os_get_inheritable_impl(PyObject *module, int fd) |
---|
11016 | n/a | /*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/ |
---|
11017 | n/a | { |
---|
11018 | n/a | int return_value; |
---|
11019 | n/a | _Py_BEGIN_SUPPRESS_IPH |
---|
11020 | n/a | return_value = _Py_get_inheritable(fd); |
---|
11021 | n/a | _Py_END_SUPPRESS_IPH |
---|
11022 | n/a | return return_value; |
---|
11023 | n/a | } |
---|
11024 | n/a | |
---|
11025 | n/a | |
---|
11026 | n/a | /*[clinic input] |
---|
11027 | n/a | os.set_inheritable |
---|
11028 | n/a | fd: int |
---|
11029 | n/a | inheritable: int |
---|
11030 | n/a | / |
---|
11031 | n/a | |
---|
11032 | n/a | Set the inheritable flag of the specified file descriptor. |
---|
11033 | n/a | [clinic start generated code]*/ |
---|
11034 | n/a | |
---|
11035 | n/a | static PyObject * |
---|
11036 | n/a | os_set_inheritable_impl(PyObject *module, int fd, int inheritable) |
---|
11037 | n/a | /*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/ |
---|
11038 | n/a | { |
---|
11039 | n/a | int result; |
---|
11040 | n/a | |
---|
11041 | n/a | _Py_BEGIN_SUPPRESS_IPH |
---|
11042 | n/a | result = _Py_set_inheritable(fd, inheritable, NULL); |
---|
11043 | n/a | _Py_END_SUPPRESS_IPH |
---|
11044 | n/a | if (result < 0) |
---|
11045 | n/a | return NULL; |
---|
11046 | n/a | Py_RETURN_NONE; |
---|
11047 | n/a | } |
---|
11048 | n/a | |
---|
11049 | n/a | |
---|
11050 | n/a | #ifdef MS_WINDOWS |
---|
11051 | n/a | /*[clinic input] |
---|
11052 | n/a | os.get_handle_inheritable -> bool |
---|
11053 | n/a | handle: intptr_t |
---|
11054 | n/a | / |
---|
11055 | n/a | |
---|
11056 | n/a | Get the close-on-exe flag of the specified file descriptor. |
---|
11057 | n/a | [clinic start generated code]*/ |
---|
11058 | n/a | |
---|
11059 | n/a | static int |
---|
11060 | n/a | os_get_handle_inheritable_impl(PyObject *module, intptr_t handle) |
---|
11061 | n/a | /*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/ |
---|
11062 | n/a | { |
---|
11063 | n/a | DWORD flags; |
---|
11064 | n/a | |
---|
11065 | n/a | if (!GetHandleInformation((HANDLE)handle, &flags)) { |
---|
11066 | n/a | PyErr_SetFromWindowsErr(0); |
---|
11067 | n/a | return -1; |
---|
11068 | n/a | } |
---|
11069 | n/a | |
---|
11070 | n/a | return flags & HANDLE_FLAG_INHERIT; |
---|
11071 | n/a | } |
---|
11072 | n/a | |
---|
11073 | n/a | |
---|
11074 | n/a | /*[clinic input] |
---|
11075 | n/a | os.set_handle_inheritable |
---|
11076 | n/a | handle: intptr_t |
---|
11077 | n/a | inheritable: bool |
---|
11078 | n/a | / |
---|
11079 | n/a | |
---|
11080 | n/a | Set the inheritable flag of the specified handle. |
---|
11081 | n/a | [clinic start generated code]*/ |
---|
11082 | n/a | |
---|
11083 | n/a | static PyObject * |
---|
11084 | n/a | os_set_handle_inheritable_impl(PyObject *module, intptr_t handle, |
---|
11085 | n/a | int inheritable) |
---|
11086 | n/a | /*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/ |
---|
11087 | n/a | { |
---|
11088 | n/a | DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0; |
---|
11089 | n/a | if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) { |
---|
11090 | n/a | PyErr_SetFromWindowsErr(0); |
---|
11091 | n/a | return NULL; |
---|
11092 | n/a | } |
---|
11093 | n/a | Py_RETURN_NONE; |
---|
11094 | n/a | } |
---|
11095 | n/a | #endif /* MS_WINDOWS */ |
---|
11096 | n/a | |
---|
11097 | n/a | #ifndef MS_WINDOWS |
---|
11098 | n/a | PyDoc_STRVAR(get_blocking__doc__, |
---|
11099 | n/a | "get_blocking(fd) -> bool\n" \ |
---|
11100 | n/a | "\n" \ |
---|
11101 | n/a | "Get the blocking mode of the file descriptor:\n" \ |
---|
11102 | n/a | "False if the O_NONBLOCK flag is set, True if the flag is cleared."); |
---|
11103 | n/a | |
---|
11104 | n/a | static PyObject* |
---|
11105 | n/a | posix_get_blocking(PyObject *self, PyObject *args) |
---|
11106 | n/a | { |
---|
11107 | n/a | int fd; |
---|
11108 | n/a | int blocking; |
---|
11109 | n/a | |
---|
11110 | n/a | if (!PyArg_ParseTuple(args, "i:get_blocking", &fd)) |
---|
11111 | n/a | return NULL; |
---|
11112 | n/a | |
---|
11113 | n/a | _Py_BEGIN_SUPPRESS_IPH |
---|
11114 | n/a | blocking = _Py_get_blocking(fd); |
---|
11115 | n/a | _Py_END_SUPPRESS_IPH |
---|
11116 | n/a | if (blocking < 0) |
---|
11117 | n/a | return NULL; |
---|
11118 | n/a | return PyBool_FromLong(blocking); |
---|
11119 | n/a | } |
---|
11120 | n/a | |
---|
11121 | n/a | PyDoc_STRVAR(set_blocking__doc__, |
---|
11122 | n/a | "set_blocking(fd, blocking)\n" \ |
---|
11123 | n/a | "\n" \ |
---|
11124 | n/a | "Set the blocking mode of the specified file descriptor.\n" \ |
---|
11125 | n/a | "Set the O_NONBLOCK flag if blocking is False,\n" \ |
---|
11126 | n/a | "clear the O_NONBLOCK flag otherwise."); |
---|
11127 | n/a | |
---|
11128 | n/a | static PyObject* |
---|
11129 | n/a | posix_set_blocking(PyObject *self, PyObject *args) |
---|
11130 | n/a | { |
---|
11131 | n/a | int fd, blocking, result; |
---|
11132 | n/a | |
---|
11133 | n/a | if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking)) |
---|
11134 | n/a | return NULL; |
---|
11135 | n/a | |
---|
11136 | n/a | _Py_BEGIN_SUPPRESS_IPH |
---|
11137 | n/a | result = _Py_set_blocking(fd, blocking); |
---|
11138 | n/a | _Py_END_SUPPRESS_IPH |
---|
11139 | n/a | if (result < 0) |
---|
11140 | n/a | return NULL; |
---|
11141 | n/a | Py_RETURN_NONE; |
---|
11142 | n/a | } |
---|
11143 | n/a | #endif /* !MS_WINDOWS */ |
---|
11144 | n/a | |
---|
11145 | n/a | |
---|
11146 | n/a | /*[clinic input] |
---|
11147 | n/a | class os.DirEntry "DirEntry *" "&DirEntryType" |
---|
11148 | n/a | [clinic start generated code]*/ |
---|
11149 | n/a | /*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/ |
---|
11150 | n/a | |
---|
11151 | n/a | typedef struct { |
---|
11152 | n/a | PyObject_HEAD |
---|
11153 | n/a | PyObject *name; |
---|
11154 | n/a | PyObject *path; |
---|
11155 | n/a | PyObject *stat; |
---|
11156 | n/a | PyObject *lstat; |
---|
11157 | n/a | #ifdef MS_WINDOWS |
---|
11158 | n/a | struct _Py_stat_struct win32_lstat; |
---|
11159 | n/a | __int64 win32_file_index; |
---|
11160 | n/a | int got_file_index; |
---|
11161 | n/a | #else /* POSIX */ |
---|
11162 | n/a | #ifdef HAVE_DIRENT_D_TYPE |
---|
11163 | n/a | unsigned char d_type; |
---|
11164 | n/a | #endif |
---|
11165 | n/a | ino_t d_ino; |
---|
11166 | n/a | #endif |
---|
11167 | n/a | } DirEntry; |
---|
11168 | n/a | |
---|
11169 | n/a | static void |
---|
11170 | n/a | DirEntry_dealloc(DirEntry *entry) |
---|
11171 | n/a | { |
---|
11172 | n/a | Py_XDECREF(entry->name); |
---|
11173 | n/a | Py_XDECREF(entry->path); |
---|
11174 | n/a | Py_XDECREF(entry->stat); |
---|
11175 | n/a | Py_XDECREF(entry->lstat); |
---|
11176 | n/a | Py_TYPE(entry)->tp_free((PyObject *)entry); |
---|
11177 | n/a | } |
---|
11178 | n/a | |
---|
11179 | n/a | /* Forward reference */ |
---|
11180 | n/a | static int |
---|
11181 | n/a | DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits); |
---|
11182 | n/a | |
---|
11183 | n/a | /*[clinic input] |
---|
11184 | n/a | os.DirEntry.is_symlink -> bool |
---|
11185 | n/a | |
---|
11186 | n/a | Return True if the entry is a symbolic link; cached per entry. |
---|
11187 | n/a | [clinic start generated code]*/ |
---|
11188 | n/a | |
---|
11189 | n/a | static int |
---|
11190 | n/a | os_DirEntry_is_symlink_impl(DirEntry *self) |
---|
11191 | n/a | /*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/ |
---|
11192 | n/a | { |
---|
11193 | n/a | #ifdef MS_WINDOWS |
---|
11194 | n/a | return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK; |
---|
11195 | n/a | #elif defined(HAVE_DIRENT_D_TYPE) |
---|
11196 | n/a | /* POSIX */ |
---|
11197 | n/a | if (self->d_type != DT_UNKNOWN) |
---|
11198 | n/a | return self->d_type == DT_LNK; |
---|
11199 | n/a | else |
---|
11200 | n/a | return DirEntry_test_mode(self, 0, S_IFLNK); |
---|
11201 | n/a | #else |
---|
11202 | n/a | /* POSIX without d_type */ |
---|
11203 | n/a | return DirEntry_test_mode(self, 0, S_IFLNK); |
---|
11204 | n/a | #endif |
---|
11205 | n/a | } |
---|
11206 | n/a | |
---|
11207 | n/a | static PyObject * |
---|
11208 | n/a | DirEntry_fetch_stat(DirEntry *self, int follow_symlinks) |
---|
11209 | n/a | { |
---|
11210 | n/a | int result; |
---|
11211 | n/a | STRUCT_STAT st; |
---|
11212 | n/a | PyObject *ub; |
---|
11213 | n/a | |
---|
11214 | n/a | #ifdef MS_WINDOWS |
---|
11215 | n/a | if (PyUnicode_FSDecoder(self->path, &ub)) { |
---|
11216 | n/a | const wchar_t *path = PyUnicode_AsUnicode(ub); |
---|
11217 | n/a | #else /* POSIX */ |
---|
11218 | n/a | if (PyUnicode_FSConverter(self->path, &ub)) { |
---|
11219 | n/a | const char *path = PyBytes_AS_STRING(ub); |
---|
11220 | n/a | #endif |
---|
11221 | n/a | if (follow_symlinks) |
---|
11222 | n/a | result = STAT(path, &st); |
---|
11223 | n/a | else |
---|
11224 | n/a | result = LSTAT(path, &st); |
---|
11225 | n/a | Py_DECREF(ub); |
---|
11226 | n/a | } else |
---|
11227 | n/a | return NULL; |
---|
11228 | n/a | |
---|
11229 | n/a | if (result != 0) |
---|
11230 | n/a | return path_object_error(self->path); |
---|
11231 | n/a | |
---|
11232 | n/a | return _pystat_fromstructstat(&st); |
---|
11233 | n/a | } |
---|
11234 | n/a | |
---|
11235 | n/a | static PyObject * |
---|
11236 | n/a | DirEntry_get_lstat(DirEntry *self) |
---|
11237 | n/a | { |
---|
11238 | n/a | if (!self->lstat) { |
---|
11239 | n/a | #ifdef MS_WINDOWS |
---|
11240 | n/a | self->lstat = _pystat_fromstructstat(&self->win32_lstat); |
---|
11241 | n/a | #else /* POSIX */ |
---|
11242 | n/a | self->lstat = DirEntry_fetch_stat(self, 0); |
---|
11243 | n/a | #endif |
---|
11244 | n/a | } |
---|
11245 | n/a | Py_XINCREF(self->lstat); |
---|
11246 | n/a | return self->lstat; |
---|
11247 | n/a | } |
---|
11248 | n/a | |
---|
11249 | n/a | /*[clinic input] |
---|
11250 | n/a | os.DirEntry.stat |
---|
11251 | n/a | * |
---|
11252 | n/a | follow_symlinks: bool = True |
---|
11253 | n/a | |
---|
11254 | n/a | Return stat_result object for the entry; cached per entry. |
---|
11255 | n/a | [clinic start generated code]*/ |
---|
11256 | n/a | |
---|
11257 | n/a | static PyObject * |
---|
11258 | n/a | os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks) |
---|
11259 | n/a | /*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/ |
---|
11260 | n/a | { |
---|
11261 | n/a | if (!follow_symlinks) |
---|
11262 | n/a | return DirEntry_get_lstat(self); |
---|
11263 | n/a | |
---|
11264 | n/a | if (!self->stat) { |
---|
11265 | n/a | int result = os_DirEntry_is_symlink_impl(self); |
---|
11266 | n/a | if (result == -1) |
---|
11267 | n/a | return NULL; |
---|
11268 | n/a | else if (result) |
---|
11269 | n/a | self->stat = DirEntry_fetch_stat(self, 1); |
---|
11270 | n/a | else |
---|
11271 | n/a | self->stat = DirEntry_get_lstat(self); |
---|
11272 | n/a | } |
---|
11273 | n/a | |
---|
11274 | n/a | Py_XINCREF(self->stat); |
---|
11275 | n/a | return self->stat; |
---|
11276 | n/a | } |
---|
11277 | n/a | |
---|
11278 | n/a | /* Set exception and return -1 on error, 0 for False, 1 for True */ |
---|
11279 | n/a | static int |
---|
11280 | n/a | DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits) |
---|
11281 | n/a | { |
---|
11282 | n/a | PyObject *stat = NULL; |
---|
11283 | n/a | PyObject *st_mode = NULL; |
---|
11284 | n/a | long mode; |
---|
11285 | n/a | int result; |
---|
11286 | n/a | #if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE) |
---|
11287 | n/a | int is_symlink; |
---|
11288 | n/a | int need_stat; |
---|
11289 | n/a | #endif |
---|
11290 | n/a | #ifdef MS_WINDOWS |
---|
11291 | n/a | unsigned long dir_bits; |
---|
11292 | n/a | #endif |
---|
11293 | n/a | _Py_IDENTIFIER(st_mode); |
---|
11294 | n/a | |
---|
11295 | n/a | #ifdef MS_WINDOWS |
---|
11296 | n/a | is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK; |
---|
11297 | n/a | need_stat = follow_symlinks && is_symlink; |
---|
11298 | n/a | #elif defined(HAVE_DIRENT_D_TYPE) |
---|
11299 | n/a | is_symlink = self->d_type == DT_LNK; |
---|
11300 | n/a | need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink); |
---|
11301 | n/a | #endif |
---|
11302 | n/a | |
---|
11303 | n/a | #if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE) |
---|
11304 | n/a | if (need_stat) { |
---|
11305 | n/a | #endif |
---|
11306 | n/a | stat = os_DirEntry_stat_impl(self, follow_symlinks); |
---|
11307 | n/a | if (!stat) { |
---|
11308 | n/a | if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) { |
---|
11309 | n/a | /* If file doesn't exist (anymore), then return False |
---|
11310 | n/a | (i.e., say it's not a file/directory) */ |
---|
11311 | n/a | PyErr_Clear(); |
---|
11312 | n/a | return 0; |
---|
11313 | n/a | } |
---|
11314 | n/a | goto error; |
---|
11315 | n/a | } |
---|
11316 | n/a | st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode); |
---|
11317 | n/a | if (!st_mode) |
---|
11318 | n/a | goto error; |
---|
11319 | n/a | |
---|
11320 | n/a | mode = PyLong_AsLong(st_mode); |
---|
11321 | n/a | if (mode == -1 && PyErr_Occurred()) |
---|
11322 | n/a | goto error; |
---|
11323 | n/a | Py_CLEAR(st_mode); |
---|
11324 | n/a | Py_CLEAR(stat); |
---|
11325 | n/a | result = (mode & S_IFMT) == mode_bits; |
---|
11326 | n/a | #if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE) |
---|
11327 | n/a | } |
---|
11328 | n/a | else if (is_symlink) { |
---|
11329 | n/a | assert(mode_bits != S_IFLNK); |
---|
11330 | n/a | result = 0; |
---|
11331 | n/a | } |
---|
11332 | n/a | else { |
---|
11333 | n/a | assert(mode_bits == S_IFDIR || mode_bits == S_IFREG); |
---|
11334 | n/a | #ifdef MS_WINDOWS |
---|
11335 | n/a | dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY; |
---|
11336 | n/a | if (mode_bits == S_IFDIR) |
---|
11337 | n/a | result = dir_bits != 0; |
---|
11338 | n/a | else |
---|
11339 | n/a | result = dir_bits == 0; |
---|
11340 | n/a | #else /* POSIX */ |
---|
11341 | n/a | if (mode_bits == S_IFDIR) |
---|
11342 | n/a | result = self->d_type == DT_DIR; |
---|
11343 | n/a | else |
---|
11344 | n/a | result = self->d_type == DT_REG; |
---|
11345 | n/a | #endif |
---|
11346 | n/a | } |
---|
11347 | n/a | #endif |
---|
11348 | n/a | |
---|
11349 | n/a | return result; |
---|
11350 | n/a | |
---|
11351 | n/a | error: |
---|
11352 | n/a | Py_XDECREF(st_mode); |
---|
11353 | n/a | Py_XDECREF(stat); |
---|
11354 | n/a | return -1; |
---|
11355 | n/a | } |
---|
11356 | n/a | |
---|
11357 | n/a | /*[clinic input] |
---|
11358 | n/a | os.DirEntry.is_dir -> bool |
---|
11359 | n/a | * |
---|
11360 | n/a | follow_symlinks: bool = True |
---|
11361 | n/a | |
---|
11362 | n/a | Return True if the entry is a directory; cached per entry. |
---|
11363 | n/a | [clinic start generated code]*/ |
---|
11364 | n/a | |
---|
11365 | n/a | static int |
---|
11366 | n/a | os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks) |
---|
11367 | n/a | /*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/ |
---|
11368 | n/a | { |
---|
11369 | n/a | return DirEntry_test_mode(self, follow_symlinks, S_IFDIR); |
---|
11370 | n/a | } |
---|
11371 | n/a | |
---|
11372 | n/a | /*[clinic input] |
---|
11373 | n/a | os.DirEntry.is_file -> bool |
---|
11374 | n/a | * |
---|
11375 | n/a | follow_symlinks: bool = True |
---|
11376 | n/a | |
---|
11377 | n/a | Return True if the entry is a file; cached per entry. |
---|
11378 | n/a | [clinic start generated code]*/ |
---|
11379 | n/a | |
---|
11380 | n/a | static int |
---|
11381 | n/a | os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks) |
---|
11382 | n/a | /*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/ |
---|
11383 | n/a | { |
---|
11384 | n/a | return DirEntry_test_mode(self, follow_symlinks, S_IFREG); |
---|
11385 | n/a | } |
---|
11386 | n/a | |
---|
11387 | n/a | /*[clinic input] |
---|
11388 | n/a | os.DirEntry.inode |
---|
11389 | n/a | |
---|
11390 | n/a | Return inode of the entry; cached per entry. |
---|
11391 | n/a | [clinic start generated code]*/ |
---|
11392 | n/a | |
---|
11393 | n/a | static PyObject * |
---|
11394 | n/a | os_DirEntry_inode_impl(DirEntry *self) |
---|
11395 | n/a | /*[clinic end generated code: output=156bb3a72162440e input=3ee7b872ae8649f0]*/ |
---|
11396 | n/a | { |
---|
11397 | n/a | #ifdef MS_WINDOWS |
---|
11398 | n/a | if (!self->got_file_index) { |
---|
11399 | n/a | PyObject *unicode; |
---|
11400 | n/a | const wchar_t *path; |
---|
11401 | n/a | STRUCT_STAT stat; |
---|
11402 | n/a | int result; |
---|
11403 | n/a | |
---|
11404 | n/a | if (!PyUnicode_FSDecoder(self->path, &unicode)) |
---|
11405 | n/a | return NULL; |
---|
11406 | n/a | path = PyUnicode_AsUnicode(unicode); |
---|
11407 | n/a | result = LSTAT(path, &stat); |
---|
11408 | n/a | Py_DECREF(unicode); |
---|
11409 | n/a | |
---|
11410 | n/a | if (result != 0) |
---|
11411 | n/a | return path_object_error(self->path); |
---|
11412 | n/a | |
---|
11413 | n/a | self->win32_file_index = stat.st_ino; |
---|
11414 | n/a | self->got_file_index = 1; |
---|
11415 | n/a | } |
---|
11416 | n/a | return PyLong_FromLongLong((long long)self->win32_file_index); |
---|
11417 | n/a | #else /* POSIX */ |
---|
11418 | n/a | #ifdef HAVE_LARGEFILE_SUPPORT |
---|
11419 | n/a | return PyLong_FromLongLong((long long)self->d_ino); |
---|
11420 | n/a | #else |
---|
11421 | n/a | return PyLong_FromLong((long)self->d_ino); |
---|
11422 | n/a | #endif |
---|
11423 | n/a | #endif |
---|
11424 | n/a | } |
---|
11425 | n/a | |
---|
11426 | n/a | static PyObject * |
---|
11427 | n/a | DirEntry_repr(DirEntry *self) |
---|
11428 | n/a | { |
---|
11429 | n/a | return PyUnicode_FromFormat("<DirEntry %R>", self->name); |
---|
11430 | n/a | } |
---|
11431 | n/a | |
---|
11432 | n/a | /*[clinic input] |
---|
11433 | n/a | os.DirEntry.__fspath__ |
---|
11434 | n/a | |
---|
11435 | n/a | Returns the path for the entry. |
---|
11436 | n/a | [clinic start generated code]*/ |
---|
11437 | n/a | |
---|
11438 | n/a | static PyObject * |
---|
11439 | n/a | os_DirEntry___fspath___impl(DirEntry *self) |
---|
11440 | n/a | /*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/ |
---|
11441 | n/a | { |
---|
11442 | n/a | Py_INCREF(self->path); |
---|
11443 | n/a | return self->path; |
---|
11444 | n/a | } |
---|
11445 | n/a | |
---|
11446 | n/a | static PyMemberDef DirEntry_members[] = { |
---|
11447 | n/a | {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY, |
---|
11448 | n/a | "the entry's base filename, relative to scandir() \"path\" argument"}, |
---|
11449 | n/a | {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY, |
---|
11450 | n/a | "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"}, |
---|
11451 | n/a | {NULL} |
---|
11452 | n/a | }; |
---|
11453 | n/a | |
---|
11454 | n/a | #include "clinic/posixmodule.c.h" |
---|
11455 | n/a | |
---|
11456 | n/a | static PyMethodDef DirEntry_methods[] = { |
---|
11457 | n/a | OS_DIRENTRY_IS_DIR_METHODDEF |
---|
11458 | n/a | OS_DIRENTRY_IS_FILE_METHODDEF |
---|
11459 | n/a | OS_DIRENTRY_IS_SYMLINK_METHODDEF |
---|
11460 | n/a | OS_DIRENTRY_STAT_METHODDEF |
---|
11461 | n/a | OS_DIRENTRY_INODE_METHODDEF |
---|
11462 | n/a | OS_DIRENTRY___FSPATH___METHODDEF |
---|
11463 | n/a | {NULL} |
---|
11464 | n/a | }; |
---|
11465 | n/a | |
---|
11466 | n/a | static PyTypeObject DirEntryType = { |
---|
11467 | n/a | PyVarObject_HEAD_INIT(NULL, 0) |
---|
11468 | n/a | MODNAME ".DirEntry", /* tp_name */ |
---|
11469 | n/a | sizeof(DirEntry), /* tp_basicsize */ |
---|
11470 | n/a | 0, /* tp_itemsize */ |
---|
11471 | n/a | /* methods */ |
---|
11472 | n/a | (destructor)DirEntry_dealloc, /* tp_dealloc */ |
---|
11473 | n/a | 0, /* tp_print */ |
---|
11474 | n/a | 0, /* tp_getattr */ |
---|
11475 | n/a | 0, /* tp_setattr */ |
---|
11476 | n/a | 0, /* tp_compare */ |
---|
11477 | n/a | (reprfunc)DirEntry_repr, /* tp_repr */ |
---|
11478 | n/a | 0, /* tp_as_number */ |
---|
11479 | n/a | 0, /* tp_as_sequence */ |
---|
11480 | n/a | 0, /* tp_as_mapping */ |
---|
11481 | n/a | 0, /* tp_hash */ |
---|
11482 | n/a | 0, /* tp_call */ |
---|
11483 | n/a | 0, /* tp_str */ |
---|
11484 | n/a | 0, /* tp_getattro */ |
---|
11485 | n/a | 0, /* tp_setattro */ |
---|
11486 | n/a | 0, /* tp_as_buffer */ |
---|
11487 | n/a | Py_TPFLAGS_DEFAULT, /* tp_flags */ |
---|
11488 | n/a | 0, /* tp_doc */ |
---|
11489 | n/a | 0, /* tp_traverse */ |
---|
11490 | n/a | 0, /* tp_clear */ |
---|
11491 | n/a | 0, /* tp_richcompare */ |
---|
11492 | n/a | 0, /* tp_weaklistoffset */ |
---|
11493 | n/a | 0, /* tp_iter */ |
---|
11494 | n/a | 0, /* tp_iternext */ |
---|
11495 | n/a | DirEntry_methods, /* tp_methods */ |
---|
11496 | n/a | DirEntry_members, /* tp_members */ |
---|
11497 | n/a | }; |
---|
11498 | n/a | |
---|
11499 | n/a | #ifdef MS_WINDOWS |
---|
11500 | n/a | |
---|
11501 | n/a | static wchar_t * |
---|
11502 | n/a | join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename) |
---|
11503 | n/a | { |
---|
11504 | n/a | Py_ssize_t path_len; |
---|
11505 | n/a | Py_ssize_t size; |
---|
11506 | n/a | wchar_t *result; |
---|
11507 | n/a | wchar_t ch; |
---|
11508 | n/a | |
---|
11509 | n/a | if (!path_wide) { /* Default arg: "." */ |
---|
11510 | n/a | path_wide = L"."; |
---|
11511 | n/a | path_len = 1; |
---|
11512 | n/a | } |
---|
11513 | n/a | else { |
---|
11514 | n/a | path_len = wcslen(path_wide); |
---|
11515 | n/a | } |
---|
11516 | n/a | |
---|
11517 | n/a | /* The +1's are for the path separator and the NUL */ |
---|
11518 | n/a | size = path_len + 1 + wcslen(filename) + 1; |
---|
11519 | n/a | result = PyMem_New(wchar_t, size); |
---|
11520 | n/a | if (!result) { |
---|
11521 | n/a | PyErr_NoMemory(); |
---|
11522 | n/a | return NULL; |
---|
11523 | n/a | } |
---|
11524 | n/a | wcscpy(result, path_wide); |
---|
11525 | n/a | if (path_len > 0) { |
---|
11526 | n/a | ch = result[path_len - 1]; |
---|
11527 | n/a | if (ch != SEP && ch != ALTSEP && ch != L':') |
---|
11528 | n/a | result[path_len++] = SEP; |
---|
11529 | n/a | wcscpy(result + path_len, filename); |
---|
11530 | n/a | } |
---|
11531 | n/a | return result; |
---|
11532 | n/a | } |
---|
11533 | n/a | |
---|
11534 | n/a | static PyObject * |
---|
11535 | n/a | DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW) |
---|
11536 | n/a | { |
---|
11537 | n/a | DirEntry *entry; |
---|
11538 | n/a | BY_HANDLE_FILE_INFORMATION file_info; |
---|
11539 | n/a | ULONG reparse_tag; |
---|
11540 | n/a | wchar_t *joined_path; |
---|
11541 | n/a | |
---|
11542 | n/a | entry = PyObject_New(DirEntry, &DirEntryType); |
---|
11543 | n/a | if (!entry) |
---|
11544 | n/a | return NULL; |
---|
11545 | n/a | entry->name = NULL; |
---|
11546 | n/a | entry->path = NULL; |
---|
11547 | n/a | entry->stat = NULL; |
---|
11548 | n/a | entry->lstat = NULL; |
---|
11549 | n/a | entry->got_file_index = 0; |
---|
11550 | n/a | |
---|
11551 | n/a | entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1); |
---|
11552 | n/a | if (!entry->name) |
---|
11553 | n/a | goto error; |
---|
11554 | n/a | if (path->narrow) { |
---|
11555 | n/a | Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name)); |
---|
11556 | n/a | if (!entry->name) |
---|
11557 | n/a | goto error; |
---|
11558 | n/a | } |
---|
11559 | n/a | |
---|
11560 | n/a | joined_path = join_path_filenameW(path->wide, dataW->cFileName); |
---|
11561 | n/a | if (!joined_path) |
---|
11562 | n/a | goto error; |
---|
11563 | n/a | |
---|
11564 | n/a | entry->path = PyUnicode_FromWideChar(joined_path, -1); |
---|
11565 | n/a | PyMem_Free(joined_path); |
---|
11566 | n/a | if (!entry->path) |
---|
11567 | n/a | goto error; |
---|
11568 | n/a | if (path->narrow) { |
---|
11569 | n/a | Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path)); |
---|
11570 | n/a | if (!entry->path) |
---|
11571 | n/a | goto error; |
---|
11572 | n/a | } |
---|
11573 | n/a | |
---|
11574 | n/a | find_data_to_file_info(dataW, &file_info, &reparse_tag); |
---|
11575 | n/a | _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat); |
---|
11576 | n/a | |
---|
11577 | n/a | return (PyObject *)entry; |
---|
11578 | n/a | |
---|
11579 | n/a | error: |
---|
11580 | n/a | Py_DECREF(entry); |
---|
11581 | n/a | return NULL; |
---|
11582 | n/a | } |
---|
11583 | n/a | |
---|
11584 | n/a | #else /* POSIX */ |
---|
11585 | n/a | |
---|
11586 | n/a | static char * |
---|
11587 | n/a | join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len) |
---|
11588 | n/a | { |
---|
11589 | n/a | Py_ssize_t path_len; |
---|
11590 | n/a | Py_ssize_t size; |
---|
11591 | n/a | char *result; |
---|
11592 | n/a | |
---|
11593 | n/a | if (!path_narrow) { /* Default arg: "." */ |
---|
11594 | n/a | path_narrow = "."; |
---|
11595 | n/a | path_len = 1; |
---|
11596 | n/a | } |
---|
11597 | n/a | else { |
---|
11598 | n/a | path_len = strlen(path_narrow); |
---|
11599 | n/a | } |
---|
11600 | n/a | |
---|
11601 | n/a | if (filename_len == -1) |
---|
11602 | n/a | filename_len = strlen(filename); |
---|
11603 | n/a | |
---|
11604 | n/a | /* The +1's are for the path separator and the NUL */ |
---|
11605 | n/a | size = path_len + 1 + filename_len + 1; |
---|
11606 | n/a | result = PyMem_New(char, size); |
---|
11607 | n/a | if (!result) { |
---|
11608 | n/a | PyErr_NoMemory(); |
---|
11609 | n/a | return NULL; |
---|
11610 | n/a | } |
---|
11611 | n/a | strcpy(result, path_narrow); |
---|
11612 | n/a | if (path_len > 0 && result[path_len - 1] != '/') |
---|
11613 | n/a | result[path_len++] = '/'; |
---|
11614 | n/a | strcpy(result + path_len, filename); |
---|
11615 | n/a | return result; |
---|
11616 | n/a | } |
---|
11617 | n/a | |
---|
11618 | n/a | static PyObject * |
---|
11619 | n/a | DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len, |
---|
11620 | n/a | ino_t d_ino |
---|
11621 | n/a | #ifdef HAVE_DIRENT_D_TYPE |
---|
11622 | n/a | , unsigned char d_type |
---|
11623 | n/a | #endif |
---|
11624 | n/a | ) |
---|
11625 | n/a | { |
---|
11626 | n/a | DirEntry *entry; |
---|
11627 | n/a | char *joined_path; |
---|
11628 | n/a | |
---|
11629 | n/a | entry = PyObject_New(DirEntry, &DirEntryType); |
---|
11630 | n/a | if (!entry) |
---|
11631 | n/a | return NULL; |
---|
11632 | n/a | entry->name = NULL; |
---|
11633 | n/a | entry->path = NULL; |
---|
11634 | n/a | entry->stat = NULL; |
---|
11635 | n/a | entry->lstat = NULL; |
---|
11636 | n/a | |
---|
11637 | n/a | joined_path = join_path_filename(path->narrow, name, name_len); |
---|
11638 | n/a | if (!joined_path) |
---|
11639 | n/a | goto error; |
---|
11640 | n/a | |
---|
11641 | n/a | if (!path->narrow || !PyBytes_Check(path->object)) { |
---|
11642 | n/a | entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len); |
---|
11643 | n/a | entry->path = PyUnicode_DecodeFSDefault(joined_path); |
---|
11644 | n/a | } |
---|
11645 | n/a | else { |
---|
11646 | n/a | entry->name = PyBytes_FromStringAndSize(name, name_len); |
---|
11647 | n/a | entry->path = PyBytes_FromString(joined_path); |
---|
11648 | n/a | } |
---|
11649 | n/a | PyMem_Free(joined_path); |
---|
11650 | n/a | if (!entry->name || !entry->path) |
---|
11651 | n/a | goto error; |
---|
11652 | n/a | |
---|
11653 | n/a | #ifdef HAVE_DIRENT_D_TYPE |
---|
11654 | n/a | entry->d_type = d_type; |
---|
11655 | n/a | #endif |
---|
11656 | n/a | entry->d_ino = d_ino; |
---|
11657 | n/a | |
---|
11658 | n/a | return (PyObject *)entry; |
---|
11659 | n/a | |
---|
11660 | n/a | error: |
---|
11661 | n/a | Py_XDECREF(entry); |
---|
11662 | n/a | return NULL; |
---|
11663 | n/a | } |
---|
11664 | n/a | |
---|
11665 | n/a | #endif |
---|
11666 | n/a | |
---|
11667 | n/a | |
---|
11668 | n/a | typedef struct { |
---|
11669 | n/a | PyObject_HEAD |
---|
11670 | n/a | path_t path; |
---|
11671 | n/a | #ifdef MS_WINDOWS |
---|
11672 | n/a | HANDLE handle; |
---|
11673 | n/a | WIN32_FIND_DATAW file_data; |
---|
11674 | n/a | int first_time; |
---|
11675 | n/a | #else /* POSIX */ |
---|
11676 | n/a | DIR *dirp; |
---|
11677 | n/a | #endif |
---|
11678 | n/a | } ScandirIterator; |
---|
11679 | n/a | |
---|
11680 | n/a | #ifdef MS_WINDOWS |
---|
11681 | n/a | |
---|
11682 | n/a | static int |
---|
11683 | n/a | ScandirIterator_is_closed(ScandirIterator *iterator) |
---|
11684 | n/a | { |
---|
11685 | n/a | return iterator->handle == INVALID_HANDLE_VALUE; |
---|
11686 | n/a | } |
---|
11687 | n/a | |
---|
11688 | n/a | static void |
---|
11689 | n/a | ScandirIterator_closedir(ScandirIterator *iterator) |
---|
11690 | n/a | { |
---|
11691 | n/a | HANDLE handle = iterator->handle; |
---|
11692 | n/a | |
---|
11693 | n/a | if (handle == INVALID_HANDLE_VALUE) |
---|
11694 | n/a | return; |
---|
11695 | n/a | |
---|
11696 | n/a | iterator->handle = INVALID_HANDLE_VALUE; |
---|
11697 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
11698 | n/a | FindClose(handle); |
---|
11699 | n/a | Py_END_ALLOW_THREADS |
---|
11700 | n/a | } |
---|
11701 | n/a | |
---|
11702 | n/a | static PyObject * |
---|
11703 | n/a | ScandirIterator_iternext(ScandirIterator *iterator) |
---|
11704 | n/a | { |
---|
11705 | n/a | WIN32_FIND_DATAW *file_data = &iterator->file_data; |
---|
11706 | n/a | BOOL success; |
---|
11707 | n/a | PyObject *entry; |
---|
11708 | n/a | |
---|
11709 | n/a | /* Happens if the iterator is iterated twice, or closed explicitly */ |
---|
11710 | n/a | if (iterator->handle == INVALID_HANDLE_VALUE) |
---|
11711 | n/a | return NULL; |
---|
11712 | n/a | |
---|
11713 | n/a | while (1) { |
---|
11714 | n/a | if (!iterator->first_time) { |
---|
11715 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
11716 | n/a | success = FindNextFileW(iterator->handle, file_data); |
---|
11717 | n/a | Py_END_ALLOW_THREADS |
---|
11718 | n/a | if (!success) { |
---|
11719 | n/a | /* Error or no more files */ |
---|
11720 | n/a | if (GetLastError() != ERROR_NO_MORE_FILES) |
---|
11721 | n/a | path_error(&iterator->path); |
---|
11722 | n/a | break; |
---|
11723 | n/a | } |
---|
11724 | n/a | } |
---|
11725 | n/a | iterator->first_time = 0; |
---|
11726 | n/a | |
---|
11727 | n/a | /* Skip over . and .. */ |
---|
11728 | n/a | if (wcscmp(file_data->cFileName, L".") != 0 && |
---|
11729 | n/a | wcscmp(file_data->cFileName, L"..") != 0) { |
---|
11730 | n/a | entry = DirEntry_from_find_data(&iterator->path, file_data); |
---|
11731 | n/a | if (!entry) |
---|
11732 | n/a | break; |
---|
11733 | n/a | return entry; |
---|
11734 | n/a | } |
---|
11735 | n/a | |
---|
11736 | n/a | /* Loop till we get a non-dot directory or finish iterating */ |
---|
11737 | n/a | } |
---|
11738 | n/a | |
---|
11739 | n/a | /* Error or no more files */ |
---|
11740 | n/a | ScandirIterator_closedir(iterator); |
---|
11741 | n/a | return NULL; |
---|
11742 | n/a | } |
---|
11743 | n/a | |
---|
11744 | n/a | #else /* POSIX */ |
---|
11745 | n/a | |
---|
11746 | n/a | static int |
---|
11747 | n/a | ScandirIterator_is_closed(ScandirIterator *iterator) |
---|
11748 | n/a | { |
---|
11749 | n/a | return !iterator->dirp; |
---|
11750 | n/a | } |
---|
11751 | n/a | |
---|
11752 | n/a | static void |
---|
11753 | n/a | ScandirIterator_closedir(ScandirIterator *iterator) |
---|
11754 | n/a | { |
---|
11755 | n/a | DIR *dirp = iterator->dirp; |
---|
11756 | n/a | |
---|
11757 | n/a | if (!dirp) |
---|
11758 | n/a | return; |
---|
11759 | n/a | |
---|
11760 | n/a | iterator->dirp = NULL; |
---|
11761 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
11762 | n/a | closedir(dirp); |
---|
11763 | n/a | Py_END_ALLOW_THREADS |
---|
11764 | n/a | return; |
---|
11765 | n/a | } |
---|
11766 | n/a | |
---|
11767 | n/a | static PyObject * |
---|
11768 | n/a | ScandirIterator_iternext(ScandirIterator *iterator) |
---|
11769 | n/a | { |
---|
11770 | n/a | struct dirent *direntp; |
---|
11771 | n/a | Py_ssize_t name_len; |
---|
11772 | n/a | int is_dot; |
---|
11773 | n/a | PyObject *entry; |
---|
11774 | n/a | |
---|
11775 | n/a | /* Happens if the iterator is iterated twice, or closed explicitly */ |
---|
11776 | n/a | if (!iterator->dirp) |
---|
11777 | n/a | return NULL; |
---|
11778 | n/a | |
---|
11779 | n/a | while (1) { |
---|
11780 | n/a | errno = 0; |
---|
11781 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
11782 | n/a | direntp = readdir(iterator->dirp); |
---|
11783 | n/a | Py_END_ALLOW_THREADS |
---|
11784 | n/a | |
---|
11785 | n/a | if (!direntp) { |
---|
11786 | n/a | /* Error or no more files */ |
---|
11787 | n/a | if (errno != 0) |
---|
11788 | n/a | path_error(&iterator->path); |
---|
11789 | n/a | break; |
---|
11790 | n/a | } |
---|
11791 | n/a | |
---|
11792 | n/a | /* Skip over . and .. */ |
---|
11793 | n/a | name_len = NAMLEN(direntp); |
---|
11794 | n/a | is_dot = direntp->d_name[0] == '.' && |
---|
11795 | n/a | (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2)); |
---|
11796 | n/a | if (!is_dot) { |
---|
11797 | n/a | entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name, |
---|
11798 | n/a | name_len, direntp->d_ino |
---|
11799 | n/a | #ifdef HAVE_DIRENT_D_TYPE |
---|
11800 | n/a | , direntp->d_type |
---|
11801 | n/a | #endif |
---|
11802 | n/a | ); |
---|
11803 | n/a | if (!entry) |
---|
11804 | n/a | break; |
---|
11805 | n/a | return entry; |
---|
11806 | n/a | } |
---|
11807 | n/a | |
---|
11808 | n/a | /* Loop till we get a non-dot directory or finish iterating */ |
---|
11809 | n/a | } |
---|
11810 | n/a | |
---|
11811 | n/a | /* Error or no more files */ |
---|
11812 | n/a | ScandirIterator_closedir(iterator); |
---|
11813 | n/a | return NULL; |
---|
11814 | n/a | } |
---|
11815 | n/a | |
---|
11816 | n/a | #endif |
---|
11817 | n/a | |
---|
11818 | n/a | static PyObject * |
---|
11819 | n/a | ScandirIterator_close(ScandirIterator *self, PyObject *args) |
---|
11820 | n/a | { |
---|
11821 | n/a | ScandirIterator_closedir(self); |
---|
11822 | n/a | Py_RETURN_NONE; |
---|
11823 | n/a | } |
---|
11824 | n/a | |
---|
11825 | n/a | static PyObject * |
---|
11826 | n/a | ScandirIterator_enter(PyObject *self, PyObject *args) |
---|
11827 | n/a | { |
---|
11828 | n/a | Py_INCREF(self); |
---|
11829 | n/a | return self; |
---|
11830 | n/a | } |
---|
11831 | n/a | |
---|
11832 | n/a | static PyObject * |
---|
11833 | n/a | ScandirIterator_exit(ScandirIterator *self, PyObject *args) |
---|
11834 | n/a | { |
---|
11835 | n/a | ScandirIterator_closedir(self); |
---|
11836 | n/a | Py_RETURN_NONE; |
---|
11837 | n/a | } |
---|
11838 | n/a | |
---|
11839 | n/a | static void |
---|
11840 | n/a | ScandirIterator_finalize(ScandirIterator *iterator) |
---|
11841 | n/a | { |
---|
11842 | n/a | PyObject *error_type, *error_value, *error_traceback; |
---|
11843 | n/a | |
---|
11844 | n/a | /* Save the current exception, if any. */ |
---|
11845 | n/a | PyErr_Fetch(&error_type, &error_value, &error_traceback); |
---|
11846 | n/a | |
---|
11847 | n/a | if (!ScandirIterator_is_closed(iterator)) { |
---|
11848 | n/a | ScandirIterator_closedir(iterator); |
---|
11849 | n/a | |
---|
11850 | n/a | if (PyErr_ResourceWarning((PyObject *)iterator, 1, |
---|
11851 | n/a | "unclosed scandir iterator %R", iterator)) { |
---|
11852 | n/a | /* Spurious errors can appear at shutdown */ |
---|
11853 | n/a | if (PyErr_ExceptionMatches(PyExc_Warning)) { |
---|
11854 | n/a | PyErr_WriteUnraisable((PyObject *) iterator); |
---|
11855 | n/a | } |
---|
11856 | n/a | } |
---|
11857 | n/a | } |
---|
11858 | n/a | |
---|
11859 | n/a | path_cleanup(&iterator->path); |
---|
11860 | n/a | |
---|
11861 | n/a | /* Restore the saved exception. */ |
---|
11862 | n/a | PyErr_Restore(error_type, error_value, error_traceback); |
---|
11863 | n/a | } |
---|
11864 | n/a | |
---|
11865 | n/a | static void |
---|
11866 | n/a | ScandirIterator_dealloc(ScandirIterator *iterator) |
---|
11867 | n/a | { |
---|
11868 | n/a | if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0) |
---|
11869 | n/a | return; |
---|
11870 | n/a | |
---|
11871 | n/a | Py_TYPE(iterator)->tp_free((PyObject *)iterator); |
---|
11872 | n/a | } |
---|
11873 | n/a | |
---|
11874 | n/a | static PyMethodDef ScandirIterator_methods[] = { |
---|
11875 | n/a | {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS}, |
---|
11876 | n/a | {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS}, |
---|
11877 | n/a | {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS}, |
---|
11878 | n/a | {NULL} |
---|
11879 | n/a | }; |
---|
11880 | n/a | |
---|
11881 | n/a | static PyTypeObject ScandirIteratorType = { |
---|
11882 | n/a | PyVarObject_HEAD_INIT(NULL, 0) |
---|
11883 | n/a | MODNAME ".ScandirIterator", /* tp_name */ |
---|
11884 | n/a | sizeof(ScandirIterator), /* tp_basicsize */ |
---|
11885 | n/a | 0, /* tp_itemsize */ |
---|
11886 | n/a | /* methods */ |
---|
11887 | n/a | (destructor)ScandirIterator_dealloc, /* tp_dealloc */ |
---|
11888 | n/a | 0, /* tp_print */ |
---|
11889 | n/a | 0, /* tp_getattr */ |
---|
11890 | n/a | 0, /* tp_setattr */ |
---|
11891 | n/a | 0, /* tp_compare */ |
---|
11892 | n/a | 0, /* tp_repr */ |
---|
11893 | n/a | 0, /* tp_as_number */ |
---|
11894 | n/a | 0, /* tp_as_sequence */ |
---|
11895 | n/a | 0, /* tp_as_mapping */ |
---|
11896 | n/a | 0, /* tp_hash */ |
---|
11897 | n/a | 0, /* tp_call */ |
---|
11898 | n/a | 0, /* tp_str */ |
---|
11899 | n/a | 0, /* tp_getattro */ |
---|
11900 | n/a | 0, /* tp_setattro */ |
---|
11901 | n/a | 0, /* tp_as_buffer */ |
---|
11902 | n/a | Py_TPFLAGS_DEFAULT |
---|
11903 | n/a | | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */ |
---|
11904 | n/a | 0, /* tp_doc */ |
---|
11905 | n/a | 0, /* tp_traverse */ |
---|
11906 | n/a | 0, /* tp_clear */ |
---|
11907 | n/a | 0, /* tp_richcompare */ |
---|
11908 | n/a | 0, /* tp_weaklistoffset */ |
---|
11909 | n/a | PyObject_SelfIter, /* tp_iter */ |
---|
11910 | n/a | (iternextfunc)ScandirIterator_iternext, /* tp_iternext */ |
---|
11911 | n/a | ScandirIterator_methods, /* tp_methods */ |
---|
11912 | n/a | 0, /* tp_members */ |
---|
11913 | n/a | 0, /* tp_getset */ |
---|
11914 | n/a | 0, /* tp_base */ |
---|
11915 | n/a | 0, /* tp_dict */ |
---|
11916 | n/a | 0, /* tp_descr_get */ |
---|
11917 | n/a | 0, /* tp_descr_set */ |
---|
11918 | n/a | 0, /* tp_dictoffset */ |
---|
11919 | n/a | 0, /* tp_init */ |
---|
11920 | n/a | 0, /* tp_alloc */ |
---|
11921 | n/a | 0, /* tp_new */ |
---|
11922 | n/a | 0, /* tp_free */ |
---|
11923 | n/a | 0, /* tp_is_gc */ |
---|
11924 | n/a | 0, /* tp_bases */ |
---|
11925 | n/a | 0, /* tp_mro */ |
---|
11926 | n/a | 0, /* tp_cache */ |
---|
11927 | n/a | 0, /* tp_subclasses */ |
---|
11928 | n/a | 0, /* tp_weaklist */ |
---|
11929 | n/a | 0, /* tp_del */ |
---|
11930 | n/a | 0, /* tp_version_tag */ |
---|
11931 | n/a | (destructor)ScandirIterator_finalize, /* tp_finalize */ |
---|
11932 | n/a | }; |
---|
11933 | n/a | |
---|
11934 | n/a | /*[clinic input] |
---|
11935 | n/a | os.scandir |
---|
11936 | n/a | |
---|
11937 | n/a | path : path_t(nullable=True) = None |
---|
11938 | n/a | |
---|
11939 | n/a | Return an iterator of DirEntry objects for given path. |
---|
11940 | n/a | |
---|
11941 | n/a | path can be specified as either str, bytes or path-like object. If path |
---|
11942 | n/a | is bytes, the names of yielded DirEntry objects will also be bytes; in |
---|
11943 | n/a | all other circumstances they will be str. |
---|
11944 | n/a | |
---|
11945 | n/a | If path is None, uses the path='.'. |
---|
11946 | n/a | [clinic start generated code]*/ |
---|
11947 | n/a | |
---|
11948 | n/a | static PyObject * |
---|
11949 | n/a | os_scandir_impl(PyObject *module, path_t *path) |
---|
11950 | n/a | /*[clinic end generated code: output=6eb2668b675ca89e input=e62b08b3cd41f604]*/ |
---|
11951 | n/a | { |
---|
11952 | n/a | ScandirIterator *iterator; |
---|
11953 | n/a | #ifdef MS_WINDOWS |
---|
11954 | n/a | wchar_t *path_strW; |
---|
11955 | n/a | #else |
---|
11956 | n/a | const char *path_str; |
---|
11957 | n/a | #endif |
---|
11958 | n/a | |
---|
11959 | n/a | iterator = PyObject_New(ScandirIterator, &ScandirIteratorType); |
---|
11960 | n/a | if (!iterator) |
---|
11961 | n/a | return NULL; |
---|
11962 | n/a | |
---|
11963 | n/a | #ifdef MS_WINDOWS |
---|
11964 | n/a | iterator->handle = INVALID_HANDLE_VALUE; |
---|
11965 | n/a | #else |
---|
11966 | n/a | iterator->dirp = NULL; |
---|
11967 | n/a | #endif |
---|
11968 | n/a | |
---|
11969 | n/a | memcpy(&iterator->path, path, sizeof(path_t)); |
---|
11970 | n/a | /* Move the ownership to iterator->path */ |
---|
11971 | n/a | path->object = NULL; |
---|
11972 | n/a | path->cleanup = NULL; |
---|
11973 | n/a | |
---|
11974 | n/a | #ifdef MS_WINDOWS |
---|
11975 | n/a | iterator->first_time = 1; |
---|
11976 | n/a | |
---|
11977 | n/a | path_strW = join_path_filenameW(iterator->path.wide, L"*.*"); |
---|
11978 | n/a | if (!path_strW) |
---|
11979 | n/a | goto error; |
---|
11980 | n/a | |
---|
11981 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
11982 | n/a | iterator->handle = FindFirstFileW(path_strW, &iterator->file_data); |
---|
11983 | n/a | Py_END_ALLOW_THREADS |
---|
11984 | n/a | |
---|
11985 | n/a | PyMem_Free(path_strW); |
---|
11986 | n/a | |
---|
11987 | n/a | if (iterator->handle == INVALID_HANDLE_VALUE) { |
---|
11988 | n/a | path_error(&iterator->path); |
---|
11989 | n/a | goto error; |
---|
11990 | n/a | } |
---|
11991 | n/a | #else /* POSIX */ |
---|
11992 | n/a | if (iterator->path.narrow) |
---|
11993 | n/a | path_str = iterator->path.narrow; |
---|
11994 | n/a | else |
---|
11995 | n/a | path_str = "."; |
---|
11996 | n/a | |
---|
11997 | n/a | errno = 0; |
---|
11998 | n/a | Py_BEGIN_ALLOW_THREADS |
---|
11999 | n/a | iterator->dirp = opendir(path_str); |
---|
12000 | n/a | Py_END_ALLOW_THREADS |
---|
12001 | n/a | |
---|
12002 | n/a | if (!iterator->dirp) { |
---|
12003 | n/a | path_error(&iterator->path); |
---|
12004 | n/a | goto error; |
---|
12005 | n/a | } |
---|
12006 | n/a | #endif |
---|
12007 | n/a | |
---|
12008 | n/a | return (PyObject *)iterator; |
---|
12009 | n/a | |
---|
12010 | n/a | error: |
---|
12011 | n/a | Py_DECREF(iterator); |
---|
12012 | n/a | return NULL; |
---|
12013 | n/a | } |
---|
12014 | n/a | |
---|
12015 | n/a | /* |
---|
12016 | n/a | Return the file system path representation of the object. |
---|
12017 | n/a | |
---|
12018 | n/a | If the object is str or bytes, then allow it to pass through with |
---|
12019 | n/a | an incremented refcount. If the object defines __fspath__(), then |
---|
12020 | n/a | return the result of that method. All other types raise a TypeError. |
---|
12021 | n/a | */ |
---|
12022 | n/a | PyObject * |
---|
12023 | n/a | PyOS_FSPath(PyObject *path) |
---|
12024 | n/a | { |
---|
12025 | n/a | /* For error message reasons, this function is manually inlined in |
---|
12026 | n/a | path_converter(). */ |
---|
12027 | n/a | _Py_IDENTIFIER(__fspath__); |
---|
12028 | n/a | PyObject *func = NULL; |
---|
12029 | n/a | PyObject *path_repr = NULL; |
---|
12030 | n/a | |
---|
12031 | n/a | if (PyUnicode_Check(path) || PyBytes_Check(path)) { |
---|
12032 | n/a | Py_INCREF(path); |
---|
12033 | n/a | return path; |
---|
12034 | n/a | } |
---|
12035 | n/a | |
---|
12036 | n/a | func = _PyObject_LookupSpecial(path, &PyId___fspath__); |
---|
12037 | n/a | if (NULL == func) { |
---|
12038 | n/a | return PyErr_Format(PyExc_TypeError, |
---|
12039 | n/a | "expected str, bytes or os.PathLike object, " |
---|
12040 | n/a | "not %.200s", |
---|
12041 | n/a | Py_TYPE(path)->tp_name); |
---|
12042 | n/a | } |
---|
12043 | n/a | |
---|
12044 | n/a | path_repr = _PyObject_CallNoArg(func); |
---|
12045 | n/a | Py_DECREF(func); |
---|
12046 | n/a | if (NULL == path_repr) { |
---|
12047 | n/a | return NULL; |
---|
12048 | n/a | } |
---|
12049 | n/a | |
---|
12050 | n/a | if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) { |
---|
12051 | n/a | PyErr_Format(PyExc_TypeError, |
---|
12052 | n/a | "expected %.200s.__fspath__() to return str or bytes, " |
---|
12053 | n/a | "not %.200s", Py_TYPE(path)->tp_name, |
---|
12054 | n/a | Py_TYPE(path_repr)->tp_name); |
---|
12055 | n/a | Py_DECREF(path_repr); |
---|
12056 | n/a | return NULL; |
---|
12057 | n/a | } |
---|
12058 | n/a | |
---|
12059 | n/a | return path_repr; |
---|
12060 | n/a | } |
---|
12061 | n/a | |
---|
12062 | n/a | /*[clinic input] |
---|
12063 | n/a | os.fspath |
---|
12064 | n/a | |
---|
12065 | n/a | path: object |
---|
12066 | n/a | |
---|
12067 | n/a | Return the file system path representation of the object. |
---|
12068 | n/a | |
---|
12069 | n/a | If the object is str or bytes, then allow it to pass through as-is. If the |
---|
12070 | n/a | object defines __fspath__(), then return the result of that method. All other |
---|
12071 | n/a | types raise a TypeError. |
---|
12072 | n/a | [clinic start generated code]*/ |
---|
12073 | n/a | |
---|
12074 | n/a | static PyObject * |
---|
12075 | n/a | os_fspath_impl(PyObject *module, PyObject *path) |
---|
12076 | n/a | /*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/ |
---|
12077 | n/a | { |
---|
12078 | n/a | return PyOS_FSPath(path); |
---|
12079 | n/a | } |
---|
12080 | n/a | |
---|
12081 | n/a | #ifdef HAVE_GETRANDOM_SYSCALL |
---|
12082 | n/a | /*[clinic input] |
---|
12083 | n/a | os.getrandom |
---|
12084 | n/a | |
---|
12085 | n/a | size: Py_ssize_t |
---|
12086 | n/a | flags: int=0 |
---|
12087 | n/a | |
---|
12088 | n/a | Obtain a series of random bytes. |
---|
12089 | n/a | [clinic start generated code]*/ |
---|
12090 | n/a | |
---|
12091 | n/a | static PyObject * |
---|
12092 | n/a | os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags) |
---|
12093 | n/a | /*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/ |
---|
12094 | n/a | { |
---|
12095 | n/a | PyObject *bytes; |
---|
12096 | n/a | Py_ssize_t n; |
---|
12097 | n/a | |
---|
12098 | n/a | if (size < 0) { |
---|
12099 | n/a | errno = EINVAL; |
---|
12100 | n/a | return posix_error(); |
---|
12101 | n/a | } |
---|
12102 | n/a | |
---|
12103 | n/a | bytes = PyBytes_FromStringAndSize(NULL, size); |
---|
12104 | n/a | if (bytes == NULL) { |
---|
12105 | n/a | PyErr_NoMemory(); |
---|
12106 | n/a | return NULL; |
---|
12107 | n/a | } |
---|
12108 | n/a | |
---|
12109 | n/a | while (1) { |
---|
12110 | n/a | n = syscall(SYS_getrandom, |
---|
12111 | n/a | PyBytes_AS_STRING(bytes), |
---|
12112 | n/a | PyBytes_GET_SIZE(bytes), |
---|
12113 | n/a | flags); |
---|
12114 | n/a | if (n < 0 && errno == EINTR) { |
---|
12115 | n/a | if (PyErr_CheckSignals() < 0) { |
---|
12116 | n/a | goto error; |
---|
12117 | n/a | } |
---|
12118 | n/a | |
---|
12119 | n/a | /* getrandom() was interrupted by a signal: retry */ |
---|
12120 | n/a | continue; |
---|
12121 | n/a | } |
---|
12122 | n/a | break; |
---|
12123 | n/a | } |
---|
12124 | n/a | |
---|
12125 | n/a | if (n < 0) { |
---|
12126 | n/a | PyErr_SetFromErrno(PyExc_OSError); |
---|
12127 | n/a | goto error; |
---|
12128 | n/a | } |
---|
12129 | n/a | |
---|
12130 | n/a | if (n != size) { |
---|
12131 | n/a | _PyBytes_Resize(&bytes, n); |
---|
12132 | n/a | } |
---|
12133 | n/a | |
---|
12134 | n/a | return bytes; |
---|
12135 | n/a | |
---|
12136 | n/a | error: |
---|
12137 | n/a | Py_DECREF(bytes); |
---|
12138 | n/a | return NULL; |
---|
12139 | n/a | } |
---|
12140 | n/a | #endif /* HAVE_GETRANDOM_SYSCALL */ |
---|
12141 | n/a | |
---|
12142 | n/a | |
---|
12143 | n/a | static PyMethodDef posix_methods[] = { |
---|
12144 | n/a | |
---|
12145 | n/a | OS_STAT_METHODDEF |
---|
12146 | n/a | OS_ACCESS_METHODDEF |
---|
12147 | n/a | OS_TTYNAME_METHODDEF |
---|
12148 | n/a | OS_CHDIR_METHODDEF |
---|
12149 | n/a | OS_CHFLAGS_METHODDEF |
---|
12150 | n/a | OS_CHMOD_METHODDEF |
---|
12151 | n/a | OS_FCHMOD_METHODDEF |
---|
12152 | n/a | OS_LCHMOD_METHODDEF |
---|
12153 | n/a | OS_CHOWN_METHODDEF |
---|
12154 | n/a | OS_FCHOWN_METHODDEF |
---|
12155 | n/a | OS_LCHOWN_METHODDEF |
---|
12156 | n/a | OS_LCHFLAGS_METHODDEF |
---|
12157 | n/a | OS_CHROOT_METHODDEF |
---|
12158 | n/a | OS_CTERMID_METHODDEF |
---|
12159 | n/a | OS_GETCWD_METHODDEF |
---|
12160 | n/a | OS_GETCWDB_METHODDEF |
---|
12161 | n/a | OS_LINK_METHODDEF |
---|
12162 | n/a | OS_LISTDIR_METHODDEF |
---|
12163 | n/a | OS_LSTAT_METHODDEF |
---|
12164 | n/a | OS_MKDIR_METHODDEF |
---|
12165 | n/a | OS_NICE_METHODDEF |
---|
12166 | n/a | OS_GETPRIORITY_METHODDEF |
---|
12167 | n/a | OS_SETPRIORITY_METHODDEF |
---|
12168 | n/a | #ifdef HAVE_READLINK |
---|
12169 | n/a | {"readlink", (PyCFunction)posix_readlink, |
---|
12170 | n/a | METH_VARARGS | METH_KEYWORDS, |
---|
12171 | n/a | readlink__doc__}, |
---|
12172 | n/a | #endif /* HAVE_READLINK */ |
---|
12173 | n/a | #if !defined(HAVE_READLINK) && defined(MS_WINDOWS) |
---|
12174 | n/a | {"readlink", (PyCFunction)win_readlink, |
---|
12175 | n/a | METH_VARARGS | METH_KEYWORDS, |
---|
12176 | n/a | readlink__doc__}, |
---|
12177 | n/a | #endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */ |
---|
12178 | n/a | OS_RENAME_METHODDEF |
---|
12179 | n/a | OS_REPLACE_METHODDEF |
---|
12180 | n/a | OS_RMDIR_METHODDEF |
---|
12181 | n/a | {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__}, |
---|
12182 | n/a | OS_SYMLINK_METHODDEF |
---|
12183 | n/a | OS_SYSTEM_METHODDEF |
---|
12184 | n/a | OS_UMASK_METHODDEF |
---|
12185 | n/a | OS_UNAME_METHODDEF |
---|
12186 | n/a | OS_UNLINK_METHODDEF |
---|
12187 | n/a | OS_REMOVE_METHODDEF |
---|
12188 | n/a | OS_UTIME_METHODDEF |
---|
12189 | n/a | OS_TIMES_METHODDEF |
---|
12190 | n/a | OS__EXIT_METHODDEF |
---|
12191 | n/a | OS_EXECV_METHODDEF |
---|
12192 | n/a | OS_EXECVE_METHODDEF |
---|
12193 | n/a | OS_SPAWNV_METHODDEF |
---|
12194 | n/a | OS_SPAWNVE_METHODDEF |
---|
12195 | n/a | OS_FORK1_METHODDEF |
---|
12196 | n/a | OS_FORK_METHODDEF |
---|
12197 | n/a | OS_SCHED_GET_PRIORITY_MAX_METHODDEF |
---|
12198 | n/a | OS_SCHED_GET_PRIORITY_MIN_METHODDEF |
---|
12199 | n/a | OS_SCHED_GETPARAM_METHODDEF |
---|
12200 | n/a | OS_SCHED_GETSCHEDULER_METHODDEF |
---|
12201 | n/a | OS_SCHED_RR_GET_INTERVAL_METHODDEF |
---|
12202 | n/a | OS_SCHED_SETPARAM_METHODDEF |
---|
12203 | n/a | OS_SCHED_SETSCHEDULER_METHODDEF |
---|
12204 | n/a | OS_SCHED_YIELD_METHODDEF |
---|
12205 | n/a | OS_SCHED_SETAFFINITY_METHODDEF |
---|
12206 | n/a | OS_SCHED_GETAFFINITY_METHODDEF |
---|
12207 | n/a | OS_OPENPTY_METHODDEF |
---|
12208 | n/a | OS_FORKPTY_METHODDEF |
---|
12209 | n/a | OS_GETEGID_METHODDEF |
---|
12210 | n/a | OS_GETEUID_METHODDEF |
---|
12211 | n/a | OS_GETGID_METHODDEF |
---|
12212 | n/a | #ifdef HAVE_GETGROUPLIST |
---|
12213 | n/a | {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__}, |
---|
12214 | n/a | #endif |
---|
12215 | n/a | OS_GETGROUPS_METHODDEF |
---|
12216 | n/a | OS_GETPID_METHODDEF |
---|
12217 | n/a | OS_GETPGRP_METHODDEF |
---|
12218 | n/a | OS_GETPPID_METHODDEF |
---|
12219 | n/a | OS_GETUID_METHODDEF |
---|
12220 | n/a | OS_GETLOGIN_METHODDEF |
---|
12221 | n/a | OS_KILL_METHODDEF |
---|
12222 | n/a | OS_KILLPG_METHODDEF |
---|
12223 | n/a | OS_PLOCK_METHODDEF |
---|
12224 | n/a | #ifdef MS_WINDOWS |
---|
12225 | n/a | OS_STARTFILE_METHODDEF |
---|
12226 | n/a | #endif |
---|
12227 | n/a | OS_SETUID_METHODDEF |
---|
12228 | n/a | OS_SETEUID_METHODDEF |
---|
12229 | n/a | OS_SETREUID_METHODDEF |
---|
12230 | n/a | OS_SETGID_METHODDEF |
---|
12231 | n/a | OS_SETEGID_METHODDEF |
---|
12232 | n/a | OS_SETREGID_METHODDEF |
---|
12233 | n/a | OS_SETGROUPS_METHODDEF |
---|
12234 | n/a | #ifdef HAVE_INITGROUPS |
---|
12235 | n/a | {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__}, |
---|
12236 | n/a | #endif /* HAVE_INITGROUPS */ |
---|
12237 | n/a | OS_GETPGID_METHODDEF |
---|
12238 | n/a | OS_SETPGRP_METHODDEF |
---|
12239 | n/a | OS_WAIT_METHODDEF |
---|
12240 | n/a | OS_WAIT3_METHODDEF |
---|
12241 | n/a | OS_WAIT4_METHODDEF |
---|
12242 | n/a | OS_WAITID_METHODDEF |
---|
12243 | n/a | OS_WAITPID_METHODDEF |
---|
12244 | n/a | OS_GETSID_METHODDEF |
---|
12245 | n/a | OS_SETSID_METHODDEF |
---|
12246 | n/a | OS_SETPGID_METHODDEF |
---|
12247 | n/a | OS_TCGETPGRP_METHODDEF |
---|
12248 | n/a | OS_TCSETPGRP_METHODDEF |
---|
12249 | n/a | OS_OPEN_METHODDEF |
---|
12250 | n/a | OS_CLOSE_METHODDEF |
---|
12251 | n/a | OS_CLOSERANGE_METHODDEF |
---|
12252 | n/a | OS_DEVICE_ENCODING_METHODDEF |
---|
12253 | n/a | OS_DUP_METHODDEF |
---|
12254 | n/a | OS_DUP2_METHODDEF |
---|
12255 | n/a | OS_LOCKF_METHODDEF |
---|
12256 | n/a | OS_LSEEK_METHODDEF |
---|
12257 | n/a | OS_READ_METHODDEF |
---|
12258 | n/a | OS_READV_METHODDEF |
---|
12259 | n/a | OS_PREAD_METHODDEF |
---|
12260 | n/a | OS_WRITE_METHODDEF |
---|
12261 | n/a | OS_WRITEV_METHODDEF |
---|
12262 | n/a | OS_PWRITE_METHODDEF |
---|
12263 | n/a | #ifdef HAVE_SENDFILE |
---|
12264 | n/a | {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS, |
---|
12265 | n/a | posix_sendfile__doc__}, |
---|
12266 | n/a | #endif |
---|
12267 | n/a | OS_FSTAT_METHODDEF |
---|
12268 | n/a | OS_ISATTY_METHODDEF |
---|
12269 | n/a | OS_PIPE_METHODDEF |
---|
12270 | n/a | OS_PIPE2_METHODDEF |
---|
12271 | n/a | OS_MKFIFO_METHODDEF |
---|
12272 | n/a | OS_MKNOD_METHODDEF |
---|
12273 | n/a | OS_MAJOR_METHODDEF |
---|
12274 | n/a | OS_MINOR_METHODDEF |
---|
12275 | n/a | OS_MAKEDEV_METHODDEF |
---|
12276 | n/a | OS_FTRUNCATE_METHODDEF |
---|
12277 | n/a | OS_TRUNCATE_METHODDEF |
---|
12278 | n/a | OS_POSIX_FALLOCATE_METHODDEF |
---|
12279 | n/a | OS_POSIX_FADVISE_METHODDEF |
---|
12280 | n/a | OS_PUTENV_METHODDEF |
---|
12281 | n/a | OS_UNSETENV_METHODDEF |
---|
12282 | n/a | OS_STRERROR_METHODDEF |
---|
12283 | n/a | OS_FCHDIR_METHODDEF |
---|
12284 | n/a | OS_FSYNC_METHODDEF |
---|
12285 | n/a | OS_SYNC_METHODDEF |
---|
12286 | n/a | OS_FDATASYNC_METHODDEF |
---|
12287 | n/a | OS_WCOREDUMP_METHODDEF |
---|
12288 | n/a | OS_WIFCONTINUED_METHODDEF |
---|
12289 | n/a | OS_WIFSTOPPED_METHODDEF |
---|
12290 | n/a | OS_WIFSIGNALED_METHODDEF |
---|
12291 | n/a | OS_WIFEXITED_METHODDEF |
---|
12292 | n/a | OS_WEXITSTATUS_METHODDEF |
---|
12293 | n/a | OS_WTERMSIG_METHODDEF |
---|
12294 | n/a | OS_WSTOPSIG_METHODDEF |
---|
12295 | n/a | OS_FSTATVFS_METHODDEF |
---|
12296 | n/a | OS_STATVFS_METHODDEF |
---|
12297 | n/a | OS_CONFSTR_METHODDEF |
---|
12298 | n/a | OS_SYSCONF_METHODDEF |
---|
12299 | n/a | OS_FPATHCONF_METHODDEF |
---|
12300 | n/a | OS_PATHCONF_METHODDEF |
---|
12301 | n/a | OS_ABORT_METHODDEF |
---|
12302 | n/a | OS__GETFULLPATHNAME_METHODDEF |
---|
12303 | n/a | OS__ISDIR_METHODDEF |
---|
12304 | n/a | OS__GETDISKUSAGE_METHODDEF |
---|
12305 | n/a | OS__GETFINALPATHNAME_METHODDEF |
---|
12306 | n/a | OS__GETVOLUMEPATHNAME_METHODDEF |
---|
12307 | n/a | OS_GETLOADAVG_METHODDEF |
---|
12308 | n/a | OS_URANDOM_METHODDEF |
---|
12309 | n/a | OS_SETRESUID_METHODDEF |
---|
12310 | n/a | OS_SETRESGID_METHODDEF |
---|
12311 | n/a | OS_GETRESUID_METHODDEF |
---|
12312 | n/a | OS_GETRESGID_METHODDEF |
---|
12313 | n/a | |
---|
12314 | n/a | OS_GETXATTR_METHODDEF |
---|
12315 | n/a | OS_SETXATTR_METHODDEF |
---|
12316 | n/a | OS_REMOVEXATTR_METHODDEF |
---|
12317 | n/a | OS_LISTXATTR_METHODDEF |
---|
12318 | n/a | |
---|
12319 | n/a | #if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) |
---|
12320 | n/a | {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__}, |
---|
12321 | n/a | #endif |
---|
12322 | n/a | OS_CPU_COUNT_METHODDEF |
---|
12323 | n/a | OS_GET_INHERITABLE_METHODDEF |
---|
12324 | n/a | OS_SET_INHERITABLE_METHODDEF |
---|
12325 | n/a | OS_GET_HANDLE_INHERITABLE_METHODDEF |
---|
12326 | n/a | OS_SET_HANDLE_INHERITABLE_METHODDEF |
---|
12327 | n/a | #ifndef MS_WINDOWS |
---|
12328 | n/a | {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__}, |
---|
12329 | n/a | {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__}, |
---|
12330 | n/a | #endif |
---|
12331 | n/a | OS_SCANDIR_METHODDEF |
---|
12332 | n/a | OS_FSPATH_METHODDEF |
---|
12333 | n/a | OS_GETRANDOM_METHODDEF |
---|
12334 | n/a | {NULL, NULL} /* Sentinel */ |
---|
12335 | n/a | }; |
---|
12336 | n/a | |
---|
12337 | n/a | |
---|
12338 | n/a | #if defined(HAVE_SYMLINK) && defined(MS_WINDOWS) |
---|
12339 | n/a | static int |
---|
12340 | n/a | enable_symlink() |
---|
12341 | n/a | { |
---|
12342 | n/a | HANDLE tok; |
---|
12343 | n/a | TOKEN_PRIVILEGES tok_priv; |
---|
12344 | n/a | LUID luid; |
---|
12345 | n/a | |
---|
12346 | n/a | if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok)) |
---|
12347 | n/a | return 0; |
---|
12348 | n/a | |
---|
12349 | n/a | if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid)) |
---|
12350 | n/a | return 0; |
---|
12351 | n/a | |
---|
12352 | n/a | tok_priv.PrivilegeCount = 1; |
---|
12353 | n/a | tok_priv.Privileges[0].Luid = luid; |
---|
12354 | n/a | tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; |
---|
12355 | n/a | |
---|
12356 | n/a | if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv, |
---|
12357 | n/a | sizeof(TOKEN_PRIVILEGES), |
---|
12358 | n/a | (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL)) |
---|
12359 | n/a | return 0; |
---|
12360 | n/a | |
---|
12361 | n/a | /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */ |
---|
12362 | n/a | return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1; |
---|
12363 | n/a | } |
---|
12364 | n/a | #endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */ |
---|
12365 | n/a | |
---|
12366 | n/a | static int |
---|
12367 | n/a | all_ins(PyObject *m) |
---|
12368 | n/a | { |
---|
12369 | n/a | #ifdef F_OK |
---|
12370 | n/a | if (PyModule_AddIntMacro(m, F_OK)) return -1; |
---|
12371 | n/a | #endif |
---|
12372 | n/a | #ifdef R_OK |
---|
12373 | n/a | if (PyModule_AddIntMacro(m, R_OK)) return -1; |
---|
12374 | n/a | #endif |
---|
12375 | n/a | #ifdef W_OK |
---|
12376 | n/a | if (PyModule_AddIntMacro(m, W_OK)) return -1; |
---|
12377 | n/a | #endif |
---|
12378 | n/a | #ifdef X_OK |
---|
12379 | n/a | if (PyModule_AddIntMacro(m, X_OK)) return -1; |
---|
12380 | n/a | #endif |
---|
12381 | n/a | #ifdef NGROUPS_MAX |
---|
12382 | n/a | if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1; |
---|
12383 | n/a | #endif |
---|
12384 | n/a | #ifdef TMP_MAX |
---|
12385 | n/a | if (PyModule_AddIntMacro(m, TMP_MAX)) return -1; |
---|
12386 | n/a | #endif |
---|
12387 | n/a | #ifdef WCONTINUED |
---|
12388 | n/a | if (PyModule_AddIntMacro(m, WCONTINUED)) return -1; |
---|
12389 | n/a | #endif |
---|
12390 | n/a | #ifdef WNOHANG |
---|
12391 | n/a | if (PyModule_AddIntMacro(m, WNOHANG)) return -1; |
---|
12392 | n/a | #endif |
---|
12393 | n/a | #ifdef WUNTRACED |
---|
12394 | n/a | if (PyModule_AddIntMacro(m, WUNTRACED)) return -1; |
---|
12395 | n/a | #endif |
---|
12396 | n/a | #ifdef O_RDONLY |
---|
12397 | n/a | if (PyModule_AddIntMacro(m, O_RDONLY)) return -1; |
---|
12398 | n/a | #endif |
---|
12399 | n/a | #ifdef O_WRONLY |
---|
12400 | n/a | if (PyModule_AddIntMacro(m, O_WRONLY)) return -1; |
---|
12401 | n/a | #endif |
---|
12402 | n/a | #ifdef O_RDWR |
---|
12403 | n/a | if (PyModule_AddIntMacro(m, O_RDWR)) return -1; |
---|
12404 | n/a | #endif |
---|
12405 | n/a | #ifdef O_NDELAY |
---|
12406 | n/a | if (PyModule_AddIntMacro(m, O_NDELAY)) return -1; |
---|
12407 | n/a | #endif |
---|
12408 | n/a | #ifdef O_NONBLOCK |
---|
12409 | n/a | if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1; |
---|
12410 | n/a | #endif |
---|
12411 | n/a | #ifdef O_APPEND |
---|
12412 | n/a | if (PyModule_AddIntMacro(m, O_APPEND)) return -1; |
---|
12413 | n/a | #endif |
---|
12414 | n/a | #ifdef O_DSYNC |
---|
12415 | n/a | if (PyModule_AddIntMacro(m, O_DSYNC)) return -1; |
---|
12416 | n/a | #endif |
---|
12417 | n/a | #ifdef O_RSYNC |
---|
12418 | n/a | if (PyModule_AddIntMacro(m, O_RSYNC)) return -1; |
---|
12419 | n/a | #endif |
---|
12420 | n/a | #ifdef O_SYNC |
---|
12421 | n/a | if (PyModule_AddIntMacro(m, O_SYNC)) return -1; |
---|
12422 | n/a | #endif |
---|
12423 | n/a | #ifdef O_NOCTTY |
---|
12424 | n/a | if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1; |
---|
12425 | n/a | #endif |
---|
12426 | n/a | #ifdef O_CREAT |
---|
12427 | n/a | if (PyModule_AddIntMacro(m, O_CREAT)) return -1; |
---|
12428 | n/a | #endif |
---|
12429 | n/a | #ifdef O_EXCL |
---|
12430 | n/a | if (PyModule_AddIntMacro(m, O_EXCL)) return -1; |
---|
12431 | n/a | #endif |
---|
12432 | n/a | #ifdef O_TRUNC |
---|
12433 | n/a | if (PyModule_AddIntMacro(m, O_TRUNC)) return -1; |
---|
12434 | n/a | #endif |
---|
12435 | n/a | #ifdef O_BINARY |
---|
12436 | n/a | if (PyModule_AddIntMacro(m, O_BINARY)) return -1; |
---|
12437 | n/a | #endif |
---|
12438 | n/a | #ifdef O_TEXT |
---|
12439 | n/a | if (PyModule_AddIntMacro(m, O_TEXT)) return -1; |
---|
12440 | n/a | #endif |
---|
12441 | n/a | #ifdef O_XATTR |
---|
12442 | n/a | if (PyModule_AddIntMacro(m, O_XATTR)) return -1; |
---|
12443 | n/a | #endif |
---|
12444 | n/a | #ifdef O_LARGEFILE |
---|
12445 | n/a | if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1; |
---|
12446 | n/a | #endif |
---|
12447 | n/a | #ifndef __GNU__ |
---|
12448 | n/a | #ifdef O_SHLOCK |
---|
12449 | n/a | if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1; |
---|
12450 | n/a | #endif |
---|
12451 | n/a | #ifdef O_EXLOCK |
---|
12452 | n/a | if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1; |
---|
12453 | n/a | #endif |
---|
12454 | n/a | #endif |
---|
12455 | n/a | #ifdef O_EXEC |
---|
12456 | n/a | if (PyModule_AddIntMacro(m, O_EXEC)) return -1; |
---|
12457 | n/a | #endif |
---|
12458 | n/a | #ifdef O_SEARCH |
---|
12459 | n/a | if (PyModule_AddIntMacro(m, O_SEARCH)) return -1; |
---|
12460 | n/a | #endif |
---|
12461 | n/a | #ifdef O_PATH |
---|
12462 | n/a | if (PyModule_AddIntMacro(m, O_PATH)) return -1; |
---|
12463 | n/a | #endif |
---|
12464 | n/a | #ifdef O_TTY_INIT |
---|
12465 | n/a | if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1; |
---|
12466 | n/a | #endif |
---|
12467 | n/a | #ifdef O_TMPFILE |
---|
12468 | n/a | if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1; |
---|
12469 | n/a | #endif |
---|
12470 | n/a | #ifdef PRIO_PROCESS |
---|
12471 | n/a | if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1; |
---|
12472 | n/a | #endif |
---|
12473 | n/a | #ifdef PRIO_PGRP |
---|
12474 | n/a | if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1; |
---|
12475 | n/a | #endif |
---|
12476 | n/a | #ifdef PRIO_USER |
---|
12477 | n/a | if (PyModule_AddIntMacro(m, PRIO_USER)) return -1; |
---|
12478 | n/a | #endif |
---|
12479 | n/a | #ifdef O_CLOEXEC |
---|
12480 | n/a | if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1; |
---|
12481 | n/a | #endif |
---|
12482 | n/a | #ifdef O_ACCMODE |
---|
12483 | n/a | if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1; |
---|
12484 | n/a | #endif |
---|
12485 | n/a | |
---|
12486 | n/a | |
---|
12487 | n/a | #ifdef SEEK_HOLE |
---|
12488 | n/a | if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1; |
---|
12489 | n/a | #endif |
---|
12490 | n/a | #ifdef SEEK_DATA |
---|
12491 | n/a | if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1; |
---|
12492 | n/a | #endif |
---|
12493 | n/a | |
---|
12494 | n/a | /* MS Windows */ |
---|
12495 | n/a | #ifdef O_NOINHERIT |
---|
12496 | n/a | /* Don't inherit in child processes. */ |
---|
12497 | n/a | if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1; |
---|
12498 | n/a | #endif |
---|
12499 | n/a | #ifdef _O_SHORT_LIVED |
---|
12500 | n/a | /* Optimize for short life (keep in memory). */ |
---|
12501 | n/a | /* MS forgot to define this one with a non-underscore form too. */ |
---|
12502 | n/a | if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1; |
---|
12503 | n/a | #endif |
---|
12504 | n/a | #ifdef O_TEMPORARY |
---|
12505 | n/a | /* Automatically delete when last handle is closed. */ |
---|
12506 | n/a | if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1; |
---|
12507 | n/a | #endif |
---|
12508 | n/a | #ifdef O_RANDOM |
---|
12509 | n/a | /* Optimize for random access. */ |
---|
12510 | n/a | if (PyModule_AddIntMacro(m, O_RANDOM)) return -1; |
---|
12511 | n/a | #endif |
---|
12512 | n/a | #ifdef O_SEQUENTIAL |
---|
12513 | n/a | /* Optimize for sequential access. */ |
---|
12514 | n/a | if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1; |
---|
12515 | n/a | #endif |
---|
12516 | n/a | |
---|
12517 | n/a | /* GNU extensions. */ |
---|
12518 | n/a | #ifdef O_ASYNC |
---|
12519 | n/a | /* Send a SIGIO signal whenever input or output |
---|
12520 | n/a | becomes available on file descriptor */ |
---|
12521 | n/a | if (PyModule_AddIntMacro(m, O_ASYNC)) return -1; |
---|
12522 | n/a | #endif |
---|
12523 | n/a | #ifdef O_DIRECT |
---|
12524 | n/a | /* Direct disk access. */ |
---|
12525 | n/a | if (PyModule_AddIntMacro(m, O_DIRECT)) return -1; |
---|
12526 | n/a | #endif |
---|
12527 | n/a | #ifdef O_DIRECTORY |
---|
12528 | n/a | /* Must be a directory. */ |
---|
12529 | n/a | if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1; |
---|
12530 | n/a | #endif |
---|
12531 | n/a | #ifdef O_NOFOLLOW |
---|
12532 | n/a | /* Do not follow links. */ |
---|
12533 | n/a | if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1; |
---|
12534 | n/a | #endif |
---|
12535 | n/a | #ifdef O_NOLINKS |
---|
12536 | n/a | /* Fails if link count of the named file is greater than 1 */ |
---|
12537 | n/a | if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1; |
---|
12538 | n/a | #endif |
---|
12539 | n/a | #ifdef O_NOATIME |
---|
12540 | n/a | /* Do not update the access time. */ |
---|
12541 | n/a | if (PyModule_AddIntMacro(m, O_NOATIME)) return -1; |
---|
12542 | n/a | #endif |
---|
12543 | n/a | |
---|
12544 | n/a | /* These come from sysexits.h */ |
---|
12545 | n/a | #ifdef EX_OK |
---|
12546 | n/a | if (PyModule_AddIntMacro(m, EX_OK)) return -1; |
---|
12547 | n/a | #endif /* EX_OK */ |
---|
12548 | n/a | #ifdef EX_USAGE |
---|
12549 | n/a | if (PyModule_AddIntMacro(m, EX_USAGE)) return -1; |
---|
12550 | n/a | #endif /* EX_USAGE */ |
---|
12551 | n/a | #ifdef EX_DATAERR |
---|
12552 | n/a | if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1; |
---|
12553 | n/a | #endif /* EX_DATAERR */ |
---|
12554 | n/a | #ifdef EX_NOINPUT |
---|
12555 | n/a | if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1; |
---|
12556 | n/a | #endif /* EX_NOINPUT */ |
---|
12557 | n/a | #ifdef EX_NOUSER |
---|
12558 | n/a | if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1; |
---|
12559 | n/a | #endif /* EX_NOUSER */ |
---|
12560 | n/a | #ifdef EX_NOHOST |
---|
12561 | n/a | if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1; |
---|
12562 | n/a | #endif /* EX_NOHOST */ |
---|
12563 | n/a | #ifdef EX_UNAVAILABLE |
---|
12564 | n/a | if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1; |
---|
12565 | n/a | #endif /* EX_UNAVAILABLE */ |
---|
12566 | n/a | #ifdef EX_SOFTWARE |
---|
12567 | n/a | if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1; |
---|
12568 | n/a | #endif /* EX_SOFTWARE */ |
---|
12569 | n/a | #ifdef EX_OSERR |
---|
12570 | n/a | if (PyModule_AddIntMacro(m, EX_OSERR)) return -1; |
---|
12571 | n/a | #endif /* EX_OSERR */ |
---|
12572 | n/a | #ifdef EX_OSFILE |
---|
12573 | n/a | if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1; |
---|
12574 | n/a | #endif /* EX_OSFILE */ |
---|
12575 | n/a | #ifdef EX_CANTCREAT |
---|
12576 | n/a | if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1; |
---|
12577 | n/a | #endif /* EX_CANTCREAT */ |
---|
12578 | n/a | #ifdef EX_IOERR |
---|
12579 | n/a | if (PyModule_AddIntMacro(m, EX_IOERR)) return -1; |
---|
12580 | n/a | #endif /* EX_IOERR */ |
---|
12581 | n/a | #ifdef EX_TEMPFAIL |
---|
12582 | n/a | if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1; |
---|
12583 | n/a | #endif /* EX_TEMPFAIL */ |
---|
12584 | n/a | #ifdef EX_PROTOCOL |
---|
12585 | n/a | if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1; |
---|
12586 | n/a | #endif /* EX_PROTOCOL */ |
---|
12587 | n/a | #ifdef EX_NOPERM |
---|
12588 | n/a | if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1; |
---|
12589 | n/a | #endif /* EX_NOPERM */ |
---|
12590 | n/a | #ifdef EX_CONFIG |
---|
12591 | n/a | if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1; |
---|
12592 | n/a | #endif /* EX_CONFIG */ |
---|
12593 | n/a | #ifdef EX_NOTFOUND |
---|
12594 | n/a | if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1; |
---|
12595 | n/a | #endif /* EX_NOTFOUND */ |
---|
12596 | n/a | |
---|
12597 | n/a | /* statvfs */ |
---|
12598 | n/a | #ifdef ST_RDONLY |
---|
12599 | n/a | if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1; |
---|
12600 | n/a | #endif /* ST_RDONLY */ |
---|
12601 | n/a | #ifdef ST_NOSUID |
---|
12602 | n/a | if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1; |
---|
12603 | n/a | #endif /* ST_NOSUID */ |
---|
12604 | n/a | |
---|
12605 | n/a | /* GNU extensions */ |
---|
12606 | n/a | #ifdef ST_NODEV |
---|
12607 | n/a | if (PyModule_AddIntMacro(m, ST_NODEV)) return -1; |
---|
12608 | n/a | #endif /* ST_NODEV */ |
---|
12609 | n/a | #ifdef ST_NOEXEC |
---|
12610 | n/a | if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1; |
---|
12611 | n/a | #endif /* ST_NOEXEC */ |
---|
12612 | n/a | #ifdef ST_SYNCHRONOUS |
---|
12613 | n/a | if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1; |
---|
12614 | n/a | #endif /* ST_SYNCHRONOUS */ |
---|
12615 | n/a | #ifdef ST_MANDLOCK |
---|
12616 | n/a | if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1; |
---|
12617 | n/a | #endif /* ST_MANDLOCK */ |
---|
12618 | n/a | #ifdef ST_WRITE |
---|
12619 | n/a | if (PyModule_AddIntMacro(m, ST_WRITE)) return -1; |
---|
12620 | n/a | #endif /* ST_WRITE */ |
---|
12621 | n/a | #ifdef ST_APPEND |
---|
12622 | n/a | if (PyModule_AddIntMacro(m, ST_APPEND)) return -1; |
---|
12623 | n/a | #endif /* ST_APPEND */ |
---|
12624 | n/a | #ifdef ST_NOATIME |
---|
12625 | n/a | if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1; |
---|
12626 | n/a | #endif /* ST_NOATIME */ |
---|
12627 | n/a | #ifdef ST_NODIRATIME |
---|
12628 | n/a | if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1; |
---|
12629 | n/a | #endif /* ST_NODIRATIME */ |
---|
12630 | n/a | #ifdef ST_RELATIME |
---|
12631 | n/a | if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1; |
---|
12632 | n/a | #endif /* ST_RELATIME */ |
---|
12633 | n/a | |
---|
12634 | n/a | /* FreeBSD sendfile() constants */ |
---|
12635 | n/a | #ifdef SF_NODISKIO |
---|
12636 | n/a | if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1; |
---|
12637 | n/a | #endif |
---|
12638 | n/a | #ifdef SF_MNOWAIT |
---|
12639 | n/a | if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1; |
---|
12640 | n/a | #endif |
---|
12641 | n/a | #ifdef SF_SYNC |
---|
12642 | n/a | if (PyModule_AddIntMacro(m, SF_SYNC)) return -1; |
---|
12643 | n/a | #endif |
---|
12644 | n/a | |
---|
12645 | n/a | /* constants for posix_fadvise */ |
---|
12646 | n/a | #ifdef POSIX_FADV_NORMAL |
---|
12647 | n/a | if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1; |
---|
12648 | n/a | #endif |
---|
12649 | n/a | #ifdef POSIX_FADV_SEQUENTIAL |
---|
12650 | n/a | if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1; |
---|
12651 | n/a | #endif |
---|
12652 | n/a | #ifdef POSIX_FADV_RANDOM |
---|
12653 | n/a | if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1; |
---|
12654 | n/a | #endif |
---|
12655 | n/a | #ifdef POSIX_FADV_NOREUSE |
---|
12656 | n/a | if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1; |
---|
12657 | n/a | #endif |
---|
12658 | n/a | #ifdef POSIX_FADV_WILLNEED |
---|
12659 | n/a | if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1; |
---|
12660 | n/a | #endif |
---|
12661 | n/a | #ifdef POSIX_FADV_DONTNEED |
---|
12662 | n/a | if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1; |
---|
12663 | n/a | #endif |
---|
12664 | n/a | |
---|
12665 | n/a | /* constants for waitid */ |
---|
12666 | n/a | #if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID) |
---|
12667 | n/a | if (PyModule_AddIntMacro(m, P_PID)) return -1; |
---|
12668 | n/a | if (PyModule_AddIntMacro(m, P_PGID)) return -1; |
---|
12669 | n/a | if (PyModule_AddIntMacro(m, P_ALL)) return -1; |
---|
12670 | n/a | #endif |
---|
12671 | n/a | #ifdef WEXITED |
---|
12672 | n/a | if (PyModule_AddIntMacro(m, WEXITED)) return -1; |
---|
12673 | n/a | #endif |
---|
12674 | n/a | #ifdef WNOWAIT |
---|
12675 | n/a | if (PyModule_AddIntMacro(m, WNOWAIT)) return -1; |
---|
12676 | n/a | #endif |
---|
12677 | n/a | #ifdef WSTOPPED |
---|
12678 | n/a | if (PyModule_AddIntMacro(m, WSTOPPED)) return -1; |
---|
12679 | n/a | #endif |
---|
12680 | n/a | #ifdef CLD_EXITED |
---|
12681 | n/a | if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1; |
---|
12682 | n/a | #endif |
---|
12683 | n/a | #ifdef CLD_DUMPED |
---|
12684 | n/a | if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1; |
---|
12685 | n/a | #endif |
---|
12686 | n/a | #ifdef CLD_TRAPPED |
---|
12687 | n/a | if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1; |
---|
12688 | n/a | #endif |
---|
12689 | n/a | #ifdef CLD_CONTINUED |
---|
12690 | n/a | if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1; |
---|
12691 | n/a | #endif |
---|
12692 | n/a | |
---|
12693 | n/a | /* constants for lockf */ |
---|
12694 | n/a | #ifdef F_LOCK |
---|
12695 | n/a | if (PyModule_AddIntMacro(m, F_LOCK)) return -1; |
---|
12696 | n/a | #endif |
---|
12697 | n/a | #ifdef F_TLOCK |
---|
12698 | n/a | if (PyModule_AddIntMacro(m, F_TLOCK)) return -1; |
---|
12699 | n/a | #endif |
---|
12700 | n/a | #ifdef F_ULOCK |
---|
12701 | n/a | if (PyModule_AddIntMacro(m, F_ULOCK)) return -1; |
---|
12702 | n/a | #endif |
---|
12703 | n/a | #ifdef F_TEST |
---|
12704 | n/a | if (PyModule_AddIntMacro(m, F_TEST)) return -1; |
---|
12705 | n/a | #endif |
---|
12706 | n/a | |
---|
12707 | n/a | #ifdef HAVE_SPAWNV |
---|
12708 | n/a | if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1; |
---|
12709 | n/a | if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1; |
---|
12710 | n/a | if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1; |
---|
12711 | n/a | if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1; |
---|
12712 | n/a | if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1; |
---|
12713 | n/a | #endif |
---|
12714 | n/a | |
---|
12715 | n/a | #ifdef HAVE_SCHED_H |
---|
12716 | n/a | #ifdef SCHED_OTHER |
---|
12717 | n/a | if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1; |
---|
12718 | n/a | #endif |
---|
12719 | n/a | #ifdef SCHED_FIFO |
---|
12720 | n/a | if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1; |
---|
12721 | n/a | #endif |
---|
12722 | n/a | #ifdef SCHED_RR |
---|
12723 | n/a | if (PyModule_AddIntMacro(m, SCHED_RR)) return -1; |
---|
12724 | n/a | #endif |
---|
12725 | n/a | #ifdef SCHED_SPORADIC |
---|
12726 | n/a | if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1; |
---|
12727 | n/a | #endif |
---|
12728 | n/a | #ifdef SCHED_BATCH |
---|
12729 | n/a | if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1; |
---|
12730 | n/a | #endif |
---|
12731 | n/a | #ifdef SCHED_IDLE |
---|
12732 | n/a | if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1; |
---|
12733 | n/a | #endif |
---|
12734 | n/a | #ifdef SCHED_RESET_ON_FORK |
---|
12735 | n/a | if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1; |
---|
12736 | n/a | #endif |
---|
12737 | n/a | #ifdef SCHED_SYS |
---|
12738 | n/a | if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1; |
---|
12739 | n/a | #endif |
---|
12740 | n/a | #ifdef SCHED_IA |
---|
12741 | n/a | if (PyModule_AddIntMacro(m, SCHED_IA)) return -1; |
---|
12742 | n/a | #endif |
---|
12743 | n/a | #ifdef SCHED_FSS |
---|
12744 | n/a | if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1; |
---|
12745 | n/a | #endif |
---|
12746 | n/a | #ifdef SCHED_FX |
---|
12747 | n/a | if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1; |
---|
12748 | n/a | #endif |
---|
12749 | n/a | #endif |
---|
12750 | n/a | |
---|
12751 | n/a | #ifdef USE_XATTRS |
---|
12752 | n/a | if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1; |
---|
12753 | n/a | if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1; |
---|
12754 | n/a | if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1; |
---|
12755 | n/a | #endif |
---|
12756 | n/a | |
---|
12757 | n/a | #if HAVE_DECL_RTLD_LAZY |
---|
12758 | n/a | if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1; |
---|
12759 | n/a | #endif |
---|
12760 | n/a | #if HAVE_DECL_RTLD_NOW |
---|
12761 | n/a | if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1; |
---|
12762 | n/a | #endif |
---|
12763 | n/a | #if HAVE_DECL_RTLD_GLOBAL |
---|
12764 | n/a | if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1; |
---|
12765 | n/a | #endif |
---|
12766 | n/a | #if HAVE_DECL_RTLD_LOCAL |
---|
12767 | n/a | if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1; |
---|
12768 | n/a | #endif |
---|
12769 | n/a | #if HAVE_DECL_RTLD_NODELETE |
---|
12770 | n/a | if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1; |
---|
12771 | n/a | #endif |
---|
12772 | n/a | #if HAVE_DECL_RTLD_NOLOAD |
---|
12773 | n/a | if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1; |
---|
12774 | n/a | #endif |
---|
12775 | n/a | #if HAVE_DECL_RTLD_DEEPBIND |
---|
12776 | n/a | if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1; |
---|
12777 | n/a | #endif |
---|
12778 | n/a | |
---|
12779 | n/a | #ifdef HAVE_GETRANDOM_SYSCALL |
---|
12780 | n/a | if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1; |
---|
12781 | n/a | if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1; |
---|
12782 | n/a | #endif |
---|
12783 | n/a | |
---|
12784 | n/a | return 0; |
---|
12785 | n/a | } |
---|
12786 | n/a | |
---|
12787 | n/a | |
---|
12788 | n/a | static struct PyModuleDef posixmodule = { |
---|
12789 | n/a | PyModuleDef_HEAD_INIT, |
---|
12790 | n/a | MODNAME, |
---|
12791 | n/a | posix__doc__, |
---|
12792 | n/a | -1, |
---|
12793 | n/a | posix_methods, |
---|
12794 | n/a | NULL, |
---|
12795 | n/a | NULL, |
---|
12796 | n/a | NULL, |
---|
12797 | n/a | NULL |
---|
12798 | n/a | }; |
---|
12799 | n/a | |
---|
12800 | n/a | |
---|
12801 | n/a | static const char * const have_functions[] = { |
---|
12802 | n/a | |
---|
12803 | n/a | #ifdef HAVE_FACCESSAT |
---|
12804 | n/a | "HAVE_FACCESSAT", |
---|
12805 | n/a | #endif |
---|
12806 | n/a | |
---|
12807 | n/a | #ifdef HAVE_FCHDIR |
---|
12808 | n/a | "HAVE_FCHDIR", |
---|
12809 | n/a | #endif |
---|
12810 | n/a | |
---|
12811 | n/a | #ifdef HAVE_FCHMOD |
---|
12812 | n/a | "HAVE_FCHMOD", |
---|
12813 | n/a | #endif |
---|
12814 | n/a | |
---|
12815 | n/a | #ifdef HAVE_FCHMODAT |
---|
12816 | n/a | "HAVE_FCHMODAT", |
---|
12817 | n/a | #endif |
---|
12818 | n/a | |
---|
12819 | n/a | #ifdef HAVE_FCHOWN |
---|
12820 | n/a | "HAVE_FCHOWN", |
---|
12821 | n/a | #endif |
---|
12822 | n/a | |
---|
12823 | n/a | #ifdef HAVE_FCHOWNAT |
---|
12824 | n/a | "HAVE_FCHOWNAT", |
---|
12825 | n/a | #endif |
---|
12826 | n/a | |
---|
12827 | n/a | #ifdef HAVE_FEXECVE |
---|
12828 | n/a | "HAVE_FEXECVE", |
---|
12829 | n/a | #endif |
---|
12830 | n/a | |
---|
12831 | n/a | #ifdef HAVE_FDOPENDIR |
---|
12832 | n/a | "HAVE_FDOPENDIR", |
---|
12833 | n/a | #endif |
---|
12834 | n/a | |
---|
12835 | n/a | #ifdef HAVE_FPATHCONF |
---|
12836 | n/a | "HAVE_FPATHCONF", |
---|
12837 | n/a | #endif |
---|
12838 | n/a | |
---|
12839 | n/a | #ifdef HAVE_FSTATAT |
---|
12840 | n/a | "HAVE_FSTATAT", |
---|
12841 | n/a | #endif |
---|
12842 | n/a | |
---|
12843 | n/a | #ifdef HAVE_FSTATVFS |
---|
12844 | n/a | "HAVE_FSTATVFS", |
---|
12845 | n/a | #endif |
---|
12846 | n/a | |
---|
12847 | n/a | #if defined HAVE_FTRUNCATE || defined MS_WINDOWS |
---|
12848 | n/a | "HAVE_FTRUNCATE", |
---|
12849 | n/a | #endif |
---|
12850 | n/a | |
---|
12851 | n/a | #ifdef HAVE_FUTIMENS |
---|
12852 | n/a | "HAVE_FUTIMENS", |
---|
12853 | n/a | #endif |
---|
12854 | n/a | |
---|
12855 | n/a | #ifdef HAVE_FUTIMES |
---|
12856 | n/a | "HAVE_FUTIMES", |
---|
12857 | n/a | #endif |
---|
12858 | n/a | |
---|
12859 | n/a | #ifdef HAVE_FUTIMESAT |
---|
12860 | n/a | "HAVE_FUTIMESAT", |
---|
12861 | n/a | #endif |
---|
12862 | n/a | |
---|
12863 | n/a | #ifdef HAVE_LINKAT |
---|
12864 | n/a | "HAVE_LINKAT", |
---|
12865 | n/a | #endif |
---|
12866 | n/a | |
---|
12867 | n/a | #ifdef HAVE_LCHFLAGS |
---|
12868 | n/a | "HAVE_LCHFLAGS", |
---|
12869 | n/a | #endif |
---|
12870 | n/a | |
---|
12871 | n/a | #ifdef HAVE_LCHMOD |
---|
12872 | n/a | "HAVE_LCHMOD", |
---|
12873 | n/a | #endif |
---|
12874 | n/a | |
---|
12875 | n/a | #ifdef HAVE_LCHOWN |
---|
12876 | n/a | "HAVE_LCHOWN", |
---|
12877 | n/a | #endif |
---|
12878 | n/a | |
---|
12879 | n/a | #ifdef HAVE_LSTAT |
---|
12880 | n/a | "HAVE_LSTAT", |
---|
12881 | n/a | #endif |
---|
12882 | n/a | |
---|
12883 | n/a | #ifdef HAVE_LUTIMES |
---|
12884 | n/a | "HAVE_LUTIMES", |
---|
12885 | n/a | #endif |
---|
12886 | n/a | |
---|
12887 | n/a | #ifdef HAVE_MKDIRAT |
---|
12888 | n/a | "HAVE_MKDIRAT", |
---|
12889 | n/a | #endif |
---|
12890 | n/a | |
---|
12891 | n/a | #ifdef HAVE_MKFIFOAT |
---|
12892 | n/a | "HAVE_MKFIFOAT", |
---|
12893 | n/a | #endif |
---|
12894 | n/a | |
---|
12895 | n/a | #ifdef HAVE_MKNODAT |
---|
12896 | n/a | "HAVE_MKNODAT", |
---|
12897 | n/a | #endif |
---|
12898 | n/a | |
---|
12899 | n/a | #ifdef HAVE_OPENAT |
---|
12900 | n/a | "HAVE_OPENAT", |
---|
12901 | n/a | #endif |
---|
12902 | n/a | |
---|
12903 | n/a | #ifdef HAVE_READLINKAT |
---|
12904 | n/a | "HAVE_READLINKAT", |
---|
12905 | n/a | #endif |
---|
12906 | n/a | |
---|
12907 | n/a | #ifdef HAVE_RENAMEAT |
---|
12908 | n/a | "HAVE_RENAMEAT", |
---|
12909 | n/a | #endif |
---|
12910 | n/a | |
---|
12911 | n/a | #ifdef HAVE_SYMLINKAT |
---|
12912 | n/a | "HAVE_SYMLINKAT", |
---|
12913 | n/a | #endif |
---|
12914 | n/a | |
---|
12915 | n/a | #ifdef HAVE_UNLINKAT |
---|
12916 | n/a | "HAVE_UNLINKAT", |
---|
12917 | n/a | #endif |
---|
12918 | n/a | |
---|
12919 | n/a | #ifdef HAVE_UTIMENSAT |
---|
12920 | n/a | "HAVE_UTIMENSAT", |
---|
12921 | n/a | #endif |
---|
12922 | n/a | |
---|
12923 | n/a | #ifdef MS_WINDOWS |
---|
12924 | n/a | "MS_WINDOWS", |
---|
12925 | n/a | #endif |
---|
12926 | n/a | |
---|
12927 | n/a | NULL |
---|
12928 | n/a | }; |
---|
12929 | n/a | |
---|
12930 | n/a | |
---|
12931 | n/a | PyMODINIT_FUNC |
---|
12932 | n/a | INITFUNC(void) |
---|
12933 | n/a | { |
---|
12934 | n/a | PyObject *m, *v; |
---|
12935 | n/a | PyObject *list; |
---|
12936 | n/a | const char * const *trace; |
---|
12937 | n/a | |
---|
12938 | n/a | #if defined(HAVE_SYMLINK) && defined(MS_WINDOWS) |
---|
12939 | n/a | win32_can_symlink = enable_symlink(); |
---|
12940 | n/a | #endif |
---|
12941 | n/a | |
---|
12942 | n/a | m = PyModule_Create(&posixmodule); |
---|
12943 | n/a | if (m == NULL) |
---|
12944 | n/a | return NULL; |
---|
12945 | n/a | |
---|
12946 | n/a | /* Initialize environ dictionary */ |
---|
12947 | n/a | v = convertenviron(); |
---|
12948 | n/a | Py_XINCREF(v); |
---|
12949 | n/a | if (v == NULL || PyModule_AddObject(m, "environ", v) != 0) |
---|
12950 | n/a | return NULL; |
---|
12951 | n/a | Py_DECREF(v); |
---|
12952 | n/a | |
---|
12953 | n/a | if (all_ins(m)) |
---|
12954 | n/a | return NULL; |
---|
12955 | n/a | |
---|
12956 | n/a | if (setup_confname_tables(m)) |
---|
12957 | n/a | return NULL; |
---|
12958 | n/a | |
---|
12959 | n/a | Py_INCREF(PyExc_OSError); |
---|
12960 | n/a | PyModule_AddObject(m, "error", PyExc_OSError); |
---|
12961 | n/a | |
---|
12962 | n/a | #ifdef HAVE_PUTENV |
---|
12963 | n/a | if (posix_putenv_garbage == NULL) |
---|
12964 | n/a | posix_putenv_garbage = PyDict_New(); |
---|
12965 | n/a | #endif |
---|
12966 | n/a | |
---|
12967 | n/a | if (!initialized) { |
---|
12968 | n/a | #if defined(HAVE_WAITID) && !defined(__APPLE__) |
---|
12969 | n/a | waitid_result_desc.name = MODNAME ".waitid_result"; |
---|
12970 | n/a | if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0) |
---|
12971 | n/a | return NULL; |
---|
12972 | n/a | #endif |
---|
12973 | n/a | |
---|
12974 | n/a | stat_result_desc.name = "os.stat_result"; /* see issue #19209 */ |
---|
12975 | n/a | stat_result_desc.fields[7].name = PyStructSequence_UnnamedField; |
---|
12976 | n/a | stat_result_desc.fields[8].name = PyStructSequence_UnnamedField; |
---|
12977 | n/a | stat_result_desc.fields[9].name = PyStructSequence_UnnamedField; |
---|
12978 | n/a | if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0) |
---|
12979 | n/a | return NULL; |
---|
12980 | n/a | structseq_new = StatResultType.tp_new; |
---|
12981 | n/a | StatResultType.tp_new = statresult_new; |
---|
12982 | n/a | |
---|
12983 | n/a | statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */ |
---|
12984 | n/a | if (PyStructSequence_InitType2(&StatVFSResultType, |
---|
12985 | n/a | &statvfs_result_desc) < 0) |
---|
12986 | n/a | return NULL; |
---|
12987 | n/a | #ifdef NEED_TICKS_PER_SECOND |
---|
12988 | n/a | # if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK) |
---|
12989 | n/a | ticks_per_second = sysconf(_SC_CLK_TCK); |
---|
12990 | n/a | # elif defined(HZ) |
---|
12991 | n/a | ticks_per_second = HZ; |
---|
12992 | n/a | # else |
---|
12993 | n/a | ticks_per_second = 60; /* magic fallback value; may be bogus */ |
---|
12994 | n/a | # endif |
---|
12995 | n/a | #endif |
---|
12996 | n/a | |
---|
12997 | n/a | #if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) |
---|
12998 | n/a | sched_param_desc.name = MODNAME ".sched_param"; |
---|
12999 | n/a | if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0) |
---|
13000 | n/a | return NULL; |
---|
13001 | n/a | SchedParamType.tp_new = os_sched_param; |
---|
13002 | n/a | #endif |
---|
13003 | n/a | |
---|
13004 | n/a | /* initialize TerminalSize_info */ |
---|
13005 | n/a | if (PyStructSequence_InitType2(&TerminalSizeType, |
---|
13006 | n/a | &TerminalSize_desc) < 0) |
---|
13007 | n/a | return NULL; |
---|
13008 | n/a | |
---|
13009 | n/a | /* initialize scandir types */ |
---|
13010 | n/a | if (PyType_Ready(&ScandirIteratorType) < 0) |
---|
13011 | n/a | return NULL; |
---|
13012 | n/a | if (PyType_Ready(&DirEntryType) < 0) |
---|
13013 | n/a | return NULL; |
---|
13014 | n/a | } |
---|
13015 | n/a | #if defined(HAVE_WAITID) && !defined(__APPLE__) |
---|
13016 | n/a | Py_INCREF((PyObject*) &WaitidResultType); |
---|
13017 | n/a | PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType); |
---|
13018 | n/a | #endif |
---|
13019 | n/a | Py_INCREF((PyObject*) &StatResultType); |
---|
13020 | n/a | PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType); |
---|
13021 | n/a | Py_INCREF((PyObject*) &StatVFSResultType); |
---|
13022 | n/a | PyModule_AddObject(m, "statvfs_result", |
---|
13023 | n/a | (PyObject*) &StatVFSResultType); |
---|
13024 | n/a | |
---|
13025 | n/a | #if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) |
---|
13026 | n/a | Py_INCREF(&SchedParamType); |
---|
13027 | n/a | PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType); |
---|
13028 | n/a | #endif |
---|
13029 | n/a | |
---|
13030 | n/a | times_result_desc.name = MODNAME ".times_result"; |
---|
13031 | n/a | if (PyStructSequence_InitType2(&TimesResultType, ×_result_desc) < 0) |
---|
13032 | n/a | return NULL; |
---|
13033 | n/a | PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType); |
---|
13034 | n/a | |
---|
13035 | n/a | uname_result_desc.name = MODNAME ".uname_result"; |
---|
13036 | n/a | if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0) |
---|
13037 | n/a | return NULL; |
---|
13038 | n/a | PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType); |
---|
13039 | n/a | |
---|
13040 | n/a | #ifdef __APPLE__ |
---|
13041 | n/a | /* |
---|
13042 | n/a | * Step 2 of weak-linking support on Mac OS X. |
---|
13043 | n/a | * |
---|
13044 | n/a | * The code below removes functions that are not available on the |
---|
13045 | n/a | * currently active platform. |
---|
13046 | n/a | * |
---|
13047 | n/a | * This block allow one to use a python binary that was build on |
---|
13048 | n/a | * OSX 10.4 on OSX 10.3, without losing access to new APIs on |
---|
13049 | n/a | * OSX 10.4. |
---|
13050 | n/a | */ |
---|
13051 | n/a | #ifdef HAVE_FSTATVFS |
---|
13052 | n/a | if (fstatvfs == NULL) { |
---|
13053 | n/a | if (PyObject_DelAttrString(m, "fstatvfs") == -1) { |
---|
13054 | n/a | return NULL; |
---|
13055 | n/a | } |
---|
13056 | n/a | } |
---|
13057 | n/a | #endif /* HAVE_FSTATVFS */ |
---|
13058 | n/a | |
---|
13059 | n/a | #ifdef HAVE_STATVFS |
---|
13060 | n/a | if (statvfs == NULL) { |
---|
13061 | n/a | if (PyObject_DelAttrString(m, "statvfs") == -1) { |
---|
13062 | n/a | return NULL; |
---|
13063 | n/a | } |
---|
13064 | n/a | } |
---|
13065 | n/a | #endif /* HAVE_STATVFS */ |
---|
13066 | n/a | |
---|
13067 | n/a | # ifdef HAVE_LCHOWN |
---|
13068 | n/a | if (lchown == NULL) { |
---|
13069 | n/a | if (PyObject_DelAttrString(m, "lchown") == -1) { |
---|
13070 | n/a | return NULL; |
---|
13071 | n/a | } |
---|
13072 | n/a | } |
---|
13073 | n/a | #endif /* HAVE_LCHOWN */ |
---|
13074 | n/a | |
---|
13075 | n/a | |
---|
13076 | n/a | #endif /* __APPLE__ */ |
---|
13077 | n/a | |
---|
13078 | n/a | Py_INCREF(&TerminalSizeType); |
---|
13079 | n/a | PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType); |
---|
13080 | n/a | |
---|
13081 | n/a | billion = PyLong_FromLong(1000000000); |
---|
13082 | n/a | if (!billion) |
---|
13083 | n/a | return NULL; |
---|
13084 | n/a | |
---|
13085 | n/a | /* suppress "function not used" warnings */ |
---|
13086 | n/a | { |
---|
13087 | n/a | int ignored; |
---|
13088 | n/a | fd_specified("", -1); |
---|
13089 | n/a | follow_symlinks_specified("", 1); |
---|
13090 | n/a | dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1); |
---|
13091 | n/a | dir_fd_converter(Py_None, &ignored); |
---|
13092 | n/a | dir_fd_unavailable(Py_None, &ignored); |
---|
13093 | n/a | } |
---|
13094 | n/a | |
---|
13095 | n/a | /* |
---|
13096 | n/a | * provide list of locally available functions |
---|
13097 | n/a | * so os.py can populate support_* lists |
---|
13098 | n/a | */ |
---|
13099 | n/a | list = PyList_New(0); |
---|
13100 | n/a | if (!list) |
---|
13101 | n/a | return NULL; |
---|
13102 | n/a | for (trace = have_functions; *trace; trace++) { |
---|
13103 | n/a | PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL); |
---|
13104 | n/a | if (!unicode) |
---|
13105 | n/a | return NULL; |
---|
13106 | n/a | if (PyList_Append(list, unicode)) |
---|
13107 | n/a | return NULL; |
---|
13108 | n/a | Py_DECREF(unicode); |
---|
13109 | n/a | } |
---|
13110 | n/a | PyModule_AddObject(m, "_have_functions", list); |
---|
13111 | n/a | |
---|
13112 | n/a | Py_INCREF((PyObject *) &DirEntryType); |
---|
13113 | n/a | PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType); |
---|
13114 | n/a | |
---|
13115 | n/a | initialized = 1; |
---|
13116 | n/a | |
---|
13117 | n/a | return m; |
---|
13118 | n/a | } |
---|
13119 | n/a | |
---|
13120 | n/a | #ifdef __cplusplus |
---|
13121 | n/a | } |
---|
13122 | n/a | #endif |
---|