blob: 901a746efe547af3cdc6cc4f2bbec65556306b36 [file] [log] [blame]
Victor Stinner4e314432010-10-07 21:45:39 +00001#include "Python.h"
Stefan Krah6df5cae2012-11-12 20:14:36 +01002#include "osdefs.h"
Stefan Krah6c01e382014-01-20 15:31:08 +01003#include <locale.h>
4
Victor Stinnerb306d752010-10-07 22:09:40 +00005#ifdef MS_WINDOWS
6# include <windows.h>
7#endif
Victor Stinner4e314432010-10-07 21:45:39 +00008
Brett Cannonefb00c02012-02-29 18:31:31 -05009#ifdef HAVE_LANGINFO_H
10#include <langinfo.h>
11#endif
12
Victor Stinnerdaf45552013-08-28 00:53:59 +020013#ifdef HAVE_SYS_IOCTL_H
14#include <sys/ioctl.h>
15#endif
16
17#ifdef HAVE_FCNTL_H
18#include <fcntl.h>
19#endif /* HAVE_FCNTL_H */
20
Victor Stinnere2623772012-11-12 23:04:02 +010021#ifdef __APPLE__
22extern wchar_t* _Py_DecodeUTF8_surrogateescape(const char *s, Py_ssize_t size);
23#endif
24
Victor Stinnerdaf45552013-08-28 00:53:59 +020025#ifdef O_CLOEXEC
Victor Stinnerb034eee2013-09-07 10:36:04 +020026/* Does open() support the O_CLOEXEC flag? Possible values:
Victor Stinnerdaf45552013-08-28 00:53:59 +020027
28 -1: unknown
29 0: open() ignores O_CLOEXEC flag, ex: Linux kernel older than 2.6.23
30 1: open() supports O_CLOEXEC flag, close-on-exec is set
31
32 The flag is used by _Py_open(), io.FileIO and os.open() */
33int _Py_open_cloexec_works = -1;
34#endif
35
Brett Cannonefb00c02012-02-29 18:31:31 -050036PyObject *
37_Py_device_encoding(int fd)
38{
Victor Stinner14b9b112013-06-25 00:37:25 +020039#if defined(MS_WINDOWS)
Brett Cannonefb00c02012-02-29 18:31:31 -050040 UINT cp;
41#endif
42 if (!_PyVerify_fd(fd) || !isatty(fd)) {
43 Py_RETURN_NONE;
44 }
Victor Stinner14b9b112013-06-25 00:37:25 +020045#if defined(MS_WINDOWS)
Brett Cannonefb00c02012-02-29 18:31:31 -050046 if (fd == 0)
47 cp = GetConsoleCP();
48 else if (fd == 1 || fd == 2)
49 cp = GetConsoleOutputCP();
50 else
51 cp = 0;
52 /* GetConsoleCP() and GetConsoleOutputCP() return 0 if the application
53 has no console */
54 if (cp != 0)
55 return PyUnicode_FromFormat("cp%u", (unsigned int)cp);
56#elif defined(CODESET)
57 {
58 char *codeset = nl_langinfo(CODESET);
59 if (codeset != NULL && codeset[0] != 0)
60 return PyUnicode_FromString(codeset);
61 }
62#endif
63 Py_RETURN_NONE;
64}
65
Victor Stinnerd45c7f82012-12-04 01:34:47 +010066#if !defined(__APPLE__) && !defined(MS_WINDOWS)
67extern int _Py_normalize_encoding(const char *, char *, size_t);
68
69/* Workaround FreeBSD and OpenIndiana locale encoding issue with the C locale.
70 On these operating systems, nl_langinfo(CODESET) announces an alias of the
71 ASCII encoding, whereas mbstowcs() and wcstombs() functions use the
72 ISO-8859-1 encoding. The problem is that os.fsencode() and os.fsdecode() use
73 locale.getpreferredencoding() codec. For example, if command line arguments
74 are decoded by mbstowcs() and encoded back by os.fsencode(), we get a
75 UnicodeEncodeError instead of retrieving the original byte string.
76
77 The workaround is enabled if setlocale(LC_CTYPE, NULL) returns "C",
78 nl_langinfo(CODESET) announces "ascii" (or an alias to ASCII), and at least
79 one byte in range 0x80-0xff can be decoded from the locale encoding. The
80 workaround is also enabled on error, for example if getting the locale
81 failed.
82
Philip Jenvey215c49a2013-01-15 13:24:12 -080083 Values of force_ascii:
Victor Stinnerd45c7f82012-12-04 01:34:47 +010084
85 1: the workaround is used: _Py_wchar2char() uses
86 encode_ascii_surrogateescape() and _Py_char2wchar() uses
87 decode_ascii_surrogateescape()
88 0: the workaround is not used: _Py_wchar2char() uses wcstombs() and
89 _Py_char2wchar() uses mbstowcs()
90 -1: unknown, need to call check_force_ascii() to get the value
91*/
92static int force_ascii = -1;
93
94static int
95check_force_ascii(void)
96{
97 char *loc;
98#if defined(HAVE_LANGINFO_H) && defined(CODESET)
99 char *codeset, **alias;
100 char encoding[100];
101 int is_ascii;
102 unsigned int i;
103 char* ascii_aliases[] = {
104 "ascii",
105 "646",
106 "ansi-x3.4-1968",
107 "ansi-x3-4-1968",
108 "ansi-x3.4-1986",
109 "cp367",
110 "csascii",
111 "ibm367",
112 "iso646-us",
113 "iso-646.irv-1991",
114 "iso-ir-6",
115 "us",
116 "us-ascii",
117 NULL
118 };
119#endif
120
121 loc = setlocale(LC_CTYPE, NULL);
122 if (loc == NULL)
123 goto error;
124 if (strcmp(loc, "C") != 0) {
125 /* the LC_CTYPE locale is different than C */
126 return 0;
127 }
128
129#if defined(HAVE_LANGINFO_H) && defined(CODESET)
130 codeset = nl_langinfo(CODESET);
131 if (!codeset || codeset[0] == '\0') {
132 /* CODESET is not set or empty */
133 goto error;
134 }
135 if (!_Py_normalize_encoding(codeset, encoding, sizeof(encoding)))
136 goto error;
137
138 is_ascii = 0;
139 for (alias=ascii_aliases; *alias != NULL; alias++) {
140 if (strcmp(encoding, *alias) == 0) {
141 is_ascii = 1;
142 break;
143 }
144 }
145 if (!is_ascii) {
146 /* nl_langinfo(CODESET) is not "ascii" or an alias of ASCII */
147 return 0;
148 }
149
150 for (i=0x80; i<0xff; i++) {
151 unsigned char ch;
152 wchar_t wch;
153 size_t res;
154
155 ch = (unsigned char)i;
156 res = mbstowcs(&wch, (char*)&ch, 1);
157 if (res != (size_t)-1) {
158 /* decoding a non-ASCII character from the locale encoding succeed:
159 the locale encoding is not ASCII, force ASCII */
160 return 1;
161 }
162 }
163 /* None of the bytes in the range 0x80-0xff can be decoded from the locale
164 encoding: the locale encoding is really ASCII */
165 return 0;
166#else
167 /* nl_langinfo(CODESET) is not available: always force ASCII */
168 return 1;
169#endif
170
171error:
172 /* if an error occured, force the ASCII encoding */
173 return 1;
174}
175
176static char*
177encode_ascii_surrogateescape(const wchar_t *text, size_t *error_pos)
178{
179 char *result = NULL, *out;
180 size_t len, i;
181 wchar_t ch;
182
183 if (error_pos != NULL)
184 *error_pos = (size_t)-1;
185
186 len = wcslen(text);
187
188 result = PyMem_Malloc(len + 1); /* +1 for NUL byte */
189 if (result == NULL)
190 return NULL;
191
192 out = result;
193 for (i=0; i<len; i++) {
194 ch = text[i];
195
196 if (ch <= 0x7f) {
197 /* ASCII character */
198 *out++ = (char)ch;
199 }
200 else if (0xdc80 <= ch && ch <= 0xdcff) {
201 /* UTF-8b surrogate */
202 *out++ = (char)(ch - 0xdc00);
203 }
204 else {
205 if (error_pos != NULL)
206 *error_pos = i;
207 PyMem_Free(result);
208 return NULL;
209 }
210 }
211 *out = '\0';
212 return result;
213}
214#endif /* !defined(__APPLE__) && !defined(MS_WINDOWS) */
215
216#if !defined(__APPLE__) && (!defined(MS_WINDOWS) || !defined(HAVE_MBRTOWC))
217static wchar_t*
218decode_ascii_surrogateescape(const char *arg, size_t *size)
219{
220 wchar_t *res;
221 unsigned char *in;
222 wchar_t *out;
Benjamin Petersonf18bf6f2015-01-04 16:03:17 -0600223 size_t argsize = strlen(arg) + 1;
Victor Stinnerd45c7f82012-12-04 01:34:47 +0100224
Benjamin Petersonf18bf6f2015-01-04 16:03:17 -0600225 if (argsize > PY_SSIZE_T_MAX/sizeof(wchar_t))
226 return NULL;
Benjamin Peterson10ecaa22015-01-04 16:05:39 -0600227 res = PyMem_RawMalloc(argsize*sizeof(wchar_t));
Victor Stinnerd45c7f82012-12-04 01:34:47 +0100228 if (!res)
229 return NULL;
230
231 in = (unsigned char*)arg;
232 out = res;
233 while(*in)
234 if(*in < 128)
235 *out++ = *in++;
236 else
237 *out++ = 0xdc00 + *in++;
238 *out = 0;
239 if (size != NULL)
240 *size = out - res;
241 return res;
242}
243#endif
244
Victor Stinner4e314432010-10-07 21:45:39 +0000245
246/* Decode a byte string from the locale encoding with the
247 surrogateescape error handler (undecodable bytes are decoded as characters
248 in range U+DC80..U+DCFF). If a byte sequence can be decoded as a surrogate
249 character, escape the bytes using the surrogateescape error handler instead
250 of decoding them.
251
252 Use _Py_wchar2char() to encode the character string back to a byte string.
253
Victor Stinner168e1172010-10-16 23:16:16 +0000254 Return a pointer to a newly allocated wide character string (use
Victor Stinner1a7425f2013-07-07 16:25:15 +0200255 PyMem_RawFree() to free the memory) and write the number of written wide
Victor Stinner168e1172010-10-16 23:16:16 +0000256 characters excluding the null character into *size if size is not NULL, or
Victor Stinneraf02e1c2011-12-16 23:56:01 +0100257 NULL on error (decoding or memory allocation error). If size is not NULL,
258 *size is set to (size_t)-1 on memory error and (size_t)-2 on decoding
259 error.
Victor Stinner19de4c32010-11-08 23:30:46 +0000260
261 Conversion errors should never happen, unless there is a bug in the C
262 library. */
Victor Stinner4e314432010-10-07 21:45:39 +0000263wchar_t*
Victor Stinner168e1172010-10-16 23:16:16 +0000264_Py_char2wchar(const char* arg, size_t *size)
Victor Stinner4e314432010-10-07 21:45:39 +0000265{
Victor Stinnere2623772012-11-12 23:04:02 +0100266#ifdef __APPLE__
267 wchar_t *wstr;
268 wstr = _Py_DecodeUTF8_surrogateescape(arg, strlen(arg));
Victor Stinner0d92c4f2012-11-12 23:32:21 +0100269 if (size != NULL) {
270 if (wstr != NULL)
271 *size = wcslen(wstr);
272 else
273 *size = (size_t)-1;
274 }
Victor Stinnere2623772012-11-12 23:04:02 +0100275 return wstr;
276#else
Victor Stinner4e314432010-10-07 21:45:39 +0000277 wchar_t *res;
Victor Stinnerd45c7f82012-12-04 01:34:47 +0100278 size_t argsize;
Victor Stinner4e314432010-10-07 21:45:39 +0000279 size_t count;
Victor Stinner313f10c2013-05-07 23:48:56 +0200280#ifdef HAVE_MBRTOWC
Victor Stinner4e314432010-10-07 21:45:39 +0000281 unsigned char *in;
282 wchar_t *out;
Victor Stinner4e314432010-10-07 21:45:39 +0000283 mbstate_t mbs;
284#endif
Victor Stinnerd45c7f82012-12-04 01:34:47 +0100285
286#ifndef MS_WINDOWS
287 if (force_ascii == -1)
288 force_ascii = check_force_ascii();
289
290 if (force_ascii) {
291 /* force ASCII encoding to workaround mbstowcs() issue */
292 res = decode_ascii_surrogateescape(arg, size);
293 if (res == NULL)
294 goto oom;
295 return res;
296 }
297#endif
298
299#ifdef HAVE_BROKEN_MBSTOWCS
300 /* Some platforms have a broken implementation of
301 * mbstowcs which does not count the characters that
302 * would result from conversion. Use an upper bound.
303 */
304 argsize = strlen(arg);
305#else
306 argsize = mbstowcs(NULL, arg, 0);
307#endif
Victor Stinner4e314432010-10-07 21:45:39 +0000308 if (argsize != (size_t)-1) {
Benjamin Petersonf18bf6f2015-01-04 16:03:17 -0600309 if (argsize == PY_SSIZE_T_MAX)
310 goto oom;
311 argsize += 1;
312 if (argsize > PY_SSIZE_T_MAX/sizeof(wchar_t))
313 goto oom;
Benjamin Peterson10ecaa22015-01-04 16:05:39 -0600314 res = (wchar_t *)PyMem_RawMalloc(argsize*sizeof(wchar_t));
Victor Stinner4e314432010-10-07 21:45:39 +0000315 if (!res)
316 goto oom;
Benjamin Petersonf18bf6f2015-01-04 16:03:17 -0600317 count = mbstowcs(res, arg, argsize);
Victor Stinner4e314432010-10-07 21:45:39 +0000318 if (count != (size_t)-1) {
319 wchar_t *tmp;
320 /* Only use the result if it contains no
321 surrogate characters. */
322 for (tmp = res; *tmp != 0 &&
Victor Stinner76df43d2012-10-30 01:42:39 +0100323 !Py_UNICODE_IS_SURROGATE(*tmp); tmp++)
Victor Stinner4e314432010-10-07 21:45:39 +0000324 ;
Victor Stinner168e1172010-10-16 23:16:16 +0000325 if (*tmp == 0) {
326 if (size != NULL)
327 *size = count;
Victor Stinner4e314432010-10-07 21:45:39 +0000328 return res;
Victor Stinner168e1172010-10-16 23:16:16 +0000329 }
Victor Stinner4e314432010-10-07 21:45:39 +0000330 }
Victor Stinner1a7425f2013-07-07 16:25:15 +0200331 PyMem_RawFree(res);
Victor Stinner4e314432010-10-07 21:45:39 +0000332 }
333 /* Conversion failed. Fall back to escaping with surrogateescape. */
334#ifdef HAVE_MBRTOWC
335 /* Try conversion with mbrtwoc (C99), and escape non-decodable bytes. */
336
337 /* Overallocate; as multi-byte characters are in the argument, the
338 actual output could use less memory. */
339 argsize = strlen(arg) + 1;
Benjamin Petersonf18bf6f2015-01-04 16:03:17 -0600340 if (argsize > PY_SSIZE_T_MAX/sizeof(wchar_t))
341 goto oom;
Victor Stinner1a7425f2013-07-07 16:25:15 +0200342 res = (wchar_t*)PyMem_RawMalloc(argsize*sizeof(wchar_t));
Victor Stinner19de4c32010-11-08 23:30:46 +0000343 if (!res)
344 goto oom;
Victor Stinner4e314432010-10-07 21:45:39 +0000345 in = (unsigned char*)arg;
346 out = res;
347 memset(&mbs, 0, sizeof mbs);
348 while (argsize) {
349 size_t converted = mbrtowc(out, (char*)in, argsize, &mbs);
350 if (converted == 0)
351 /* Reached end of string; null char stored. */
352 break;
353 if (converted == (size_t)-2) {
354 /* Incomplete character. This should never happen,
355 since we provide everything that we have -
356 unless there is a bug in the C library, or I
357 misunderstood how mbrtowc works. */
Victor Stinner1a7425f2013-07-07 16:25:15 +0200358 PyMem_RawFree(res);
Victor Stinneraf02e1c2011-12-16 23:56:01 +0100359 if (size != NULL)
360 *size = (size_t)-2;
Victor Stinner4e314432010-10-07 21:45:39 +0000361 return NULL;
362 }
363 if (converted == (size_t)-1) {
364 /* Conversion error. Escape as UTF-8b, and start over
365 in the initial shift state. */
366 *out++ = 0xdc00 + *in++;
367 argsize--;
368 memset(&mbs, 0, sizeof mbs);
369 continue;
370 }
Victor Stinner76df43d2012-10-30 01:42:39 +0100371 if (Py_UNICODE_IS_SURROGATE(*out)) {
Victor Stinner4e314432010-10-07 21:45:39 +0000372 /* Surrogate character. Escape the original
373 byte sequence with surrogateescape. */
374 argsize -= converted;
375 while (converted--)
376 *out++ = 0xdc00 + *in++;
377 continue;
378 }
379 /* successfully converted some bytes */
380 in += converted;
381 argsize -= converted;
382 out++;
383 }
Victor Stinnerd45c7f82012-12-04 01:34:47 +0100384 if (size != NULL)
385 *size = out - res;
Victor Stinnere2623772012-11-12 23:04:02 +0100386#else /* HAVE_MBRTOWC */
Victor Stinner4e314432010-10-07 21:45:39 +0000387 /* Cannot use C locale for escaping; manually escape as if charset
388 is ASCII (i.e. escape all bytes > 128. This will still roundtrip
389 correctly in the locale's charset, which must be an ASCII superset. */
Victor Stinnerd45c7f82012-12-04 01:34:47 +0100390 res = decode_ascii_surrogateescape(arg, size);
391 if (res == NULL)
Victor Stinneraf02e1c2011-12-16 23:56:01 +0100392 goto oom;
Victor Stinnere2623772012-11-12 23:04:02 +0100393#endif /* HAVE_MBRTOWC */
Victor Stinner4e314432010-10-07 21:45:39 +0000394 return res;
395oom:
Victor Stinneraf02e1c2011-12-16 23:56:01 +0100396 if (size != NULL)
397 *size = (size_t)-1;
Victor Stinner4e314432010-10-07 21:45:39 +0000398 return NULL;
Victor Stinnere2623772012-11-12 23:04:02 +0100399#endif /* __APPLE__ */
Victor Stinner4e314432010-10-07 21:45:39 +0000400}
401
402/* Encode a (wide) character string to the locale encoding with the
403 surrogateescape error handler (characters in range U+DC80..U+DCFF are
404 converted to bytes 0x80..0xFF).
405
406 This function is the reverse of _Py_char2wchar().
407
408 Return a pointer to a newly allocated byte string (use PyMem_Free() to free
Victor Stinneraf02e1c2011-12-16 23:56:01 +0100409 the memory), or NULL on encoding or memory allocation error.
Victor Stinner2f02a512010-11-08 22:43:46 +0000410
411 If error_pos is not NULL: *error_pos is the index of the invalid character
Victor Stinneraf02e1c2011-12-16 23:56:01 +0100412 on encoding error, or (size_t)-1 otherwise. */
Victor Stinner4e314432010-10-07 21:45:39 +0000413char*
Victor Stinner2f02a512010-11-08 22:43:46 +0000414_Py_wchar2char(const wchar_t *text, size_t *error_pos)
Victor Stinner4e314432010-10-07 21:45:39 +0000415{
Victor Stinnere2623772012-11-12 23:04:02 +0100416#ifdef __APPLE__
417 Py_ssize_t len;
418 PyObject *unicode, *bytes = NULL;
419 char *cpath;
420
421 unicode = PyUnicode_FromWideChar(text, wcslen(text));
Victor Stinner0d92c4f2012-11-12 23:32:21 +0100422 if (unicode == NULL)
Victor Stinnere2623772012-11-12 23:04:02 +0100423 return NULL;
Victor Stinnere2623772012-11-12 23:04:02 +0100424
425 bytes = _PyUnicode_AsUTF8String(unicode, "surrogateescape");
426 Py_DECREF(unicode);
427 if (bytes == NULL) {
428 PyErr_Clear();
Victor Stinner0d92c4f2012-11-12 23:32:21 +0100429 if (error_pos != NULL)
430 *error_pos = (size_t)-1;
Victor Stinnere2623772012-11-12 23:04:02 +0100431 return NULL;
432 }
433
434 len = PyBytes_GET_SIZE(bytes);
435 cpath = PyMem_Malloc(len+1);
436 if (cpath == NULL) {
Victor Stinner0d92c4f2012-11-12 23:32:21 +0100437 PyErr_Clear();
Victor Stinnere2623772012-11-12 23:04:02 +0100438 Py_DECREF(bytes);
Victor Stinner0d92c4f2012-11-12 23:32:21 +0100439 if (error_pos != NULL)
440 *error_pos = (size_t)-1;
Victor Stinnere2623772012-11-12 23:04:02 +0100441 return NULL;
442 }
443 memcpy(cpath, PyBytes_AsString(bytes), len + 1);
444 Py_DECREF(bytes);
445 return cpath;
446#else /* __APPLE__ */
Victor Stinner4e314432010-10-07 21:45:39 +0000447 const size_t len = wcslen(text);
448 char *result = NULL, *bytes = NULL;
449 size_t i, size, converted;
450 wchar_t c, buf[2];
451
Victor Stinnerd45c7f82012-12-04 01:34:47 +0100452#ifndef MS_WINDOWS
453 if (force_ascii == -1)
454 force_ascii = check_force_ascii();
455
456 if (force_ascii)
457 return encode_ascii_surrogateescape(text, error_pos);
458#endif
459
Victor Stinner4e314432010-10-07 21:45:39 +0000460 /* The function works in two steps:
461 1. compute the length of the output buffer in bytes (size)
462 2. outputs the bytes */
463 size = 0;
464 buf[1] = 0;
465 while (1) {
466 for (i=0; i < len; i++) {
467 c = text[i];
468 if (c >= 0xdc80 && c <= 0xdcff) {
469 /* UTF-8b surrogate */
470 if (bytes != NULL) {
471 *bytes++ = c - 0xdc00;
472 size--;
473 }
474 else
475 size++;
476 continue;
477 }
478 else {
479 buf[0] = c;
480 if (bytes != NULL)
481 converted = wcstombs(bytes, buf, size);
482 else
483 converted = wcstombs(NULL, buf, 0);
484 if (converted == (size_t)-1) {
485 if (result != NULL)
486 PyMem_Free(result);
Victor Stinner2f02a512010-11-08 22:43:46 +0000487 if (error_pos != NULL)
488 *error_pos = i;
Victor Stinner4e314432010-10-07 21:45:39 +0000489 return NULL;
490 }
491 if (bytes != NULL) {
492 bytes += converted;
493 size -= converted;
494 }
495 else
496 size += converted;
497 }
498 }
499 if (result != NULL) {
Victor Stinnerd45c7f82012-12-04 01:34:47 +0100500 *bytes = '\0';
Victor Stinner4e314432010-10-07 21:45:39 +0000501 break;
502 }
503
504 size += 1; /* nul byte at the end */
505 result = PyMem_Malloc(size);
Victor Stinner0d92c4f2012-11-12 23:32:21 +0100506 if (result == NULL) {
507 if (error_pos != NULL)
508 *error_pos = (size_t)-1;
Victor Stinner4e314432010-10-07 21:45:39 +0000509 return NULL;
Victor Stinner0d92c4f2012-11-12 23:32:21 +0100510 }
Victor Stinner4e314432010-10-07 21:45:39 +0000511 bytes = result;
512 }
513 return result;
Victor Stinnere2623772012-11-12 23:04:02 +0100514#endif /* __APPLE__ */
Victor Stinner4e314432010-10-07 21:45:39 +0000515}
516
Victor Stinner4e314432010-10-07 21:45:39 +0000517/* In principle, this should use HAVE__WSTAT, and _wstat
518 should be detected by autoconf. However, no current
519 POSIX system provides that function, so testing for
520 it is pointless.
521 Not sure whether the MS_WINDOWS guards are necessary:
522 perhaps for cygwin/mingw builds?
523*/
Victor Stinnerb306d752010-10-07 22:09:40 +0000524#if defined(HAVE_STAT) && !defined(MS_WINDOWS)
Victor Stinner6672d0c2010-10-07 22:53:43 +0000525
526/* Get file status. Encode the path to the locale encoding. */
527
Victor Stinnerb306d752010-10-07 22:09:40 +0000528int
529_Py_wstat(const wchar_t* path, struct stat *buf)
530{
Victor Stinner4e314432010-10-07 21:45:39 +0000531 int err;
532 char *fname;
Victor Stinner2f02a512010-11-08 22:43:46 +0000533 fname = _Py_wchar2char(path, NULL);
Victor Stinner4e314432010-10-07 21:45:39 +0000534 if (fname == NULL) {
535 errno = EINVAL;
536 return -1;
537 }
538 err = stat(fname, buf);
539 PyMem_Free(fname);
540 return err;
Victor Stinner4e314432010-10-07 21:45:39 +0000541}
542#endif
543
Victor Stinnerd45c7f82012-12-04 01:34:47 +0100544#ifdef HAVE_STAT
545
Victor Stinner6672d0c2010-10-07 22:53:43 +0000546/* Call _wstat() on Windows, or encode the path to the filesystem encoding and
547 call stat() otherwise. Only fill st_mode attribute on Windows.
548
Victor Stinnerbd0850b2011-12-18 20:47:30 +0100549 Return 0 on success, -1 on _wstat() / stat() error, -2 if an exception was
550 raised. */
Victor Stinner4e314432010-10-07 21:45:39 +0000551
552int
Victor Stinnera4a75952010-10-07 22:23:10 +0000553_Py_stat(PyObject *path, struct stat *statbuf)
Victor Stinner4e314432010-10-07 21:45:39 +0000554{
555#ifdef MS_WINDOWS
Victor Stinner4e314432010-10-07 21:45:39 +0000556 int err;
557 struct _stat wstatbuf;
Victor Stinneree587ea2011-11-17 00:51:38 +0100558 wchar_t *wpath;
Victor Stinner4e314432010-10-07 21:45:39 +0000559
Victor Stinneree587ea2011-11-17 00:51:38 +0100560 wpath = PyUnicode_AsUnicode(path);
561 if (wpath == NULL)
Victor Stinnerbd0850b2011-12-18 20:47:30 +0100562 return -2;
Victor Stinneree587ea2011-11-17 00:51:38 +0100563 err = _wstat(wpath, &wstatbuf);
Victor Stinner4e314432010-10-07 21:45:39 +0000564 if (!err)
565 statbuf->st_mode = wstatbuf.st_mode;
566 return err;
567#else
568 int ret;
Victor Stinnera4a75952010-10-07 22:23:10 +0000569 PyObject *bytes = PyUnicode_EncodeFSDefault(path);
Victor Stinner4e314432010-10-07 21:45:39 +0000570 if (bytes == NULL)
Victor Stinnerbd0850b2011-12-18 20:47:30 +0100571 return -2;
Victor Stinner4e314432010-10-07 21:45:39 +0000572 ret = stat(PyBytes_AS_STRING(bytes), statbuf);
573 Py_DECREF(bytes);
574 return ret;
575#endif
576}
577
Victor Stinnerd45c7f82012-12-04 01:34:47 +0100578#endif
579
Antoine Pitrou409b5382013-10-12 22:41:17 +0200580static int
Victor Stinnerdaf45552013-08-28 00:53:59 +0200581get_inheritable(int fd, int raise)
582{
583#ifdef MS_WINDOWS
584 HANDLE handle;
585 DWORD flags;
Victor Stinner6672d0c2010-10-07 22:53:43 +0000586
Victor Stinnerdaf45552013-08-28 00:53:59 +0200587 if (!_PyVerify_fd(fd)) {
588 if (raise)
589 PyErr_SetFromErrno(PyExc_OSError);
590 return -1;
591 }
592
593 handle = (HANDLE)_get_osfhandle(fd);
594 if (handle == INVALID_HANDLE_VALUE) {
595 if (raise)
596 PyErr_SetFromWindowsErr(0);
597 return -1;
598 }
599
600 if (!GetHandleInformation(handle, &flags)) {
601 if (raise)
602 PyErr_SetFromWindowsErr(0);
603 return -1;
604 }
605
606 return (flags & HANDLE_FLAG_INHERIT);
607#else
608 int flags;
609
610 flags = fcntl(fd, F_GETFD, 0);
611 if (flags == -1) {
612 if (raise)
613 PyErr_SetFromErrno(PyExc_OSError);
614 return -1;
615 }
616 return !(flags & FD_CLOEXEC);
617#endif
618}
619
620/* Get the inheritable flag of the specified file descriptor.
Victor Stinnerb034eee2013-09-07 10:36:04 +0200621 Return 1 if the file descriptor can be inherited, 0 if it cannot,
Victor Stinnerdaf45552013-08-28 00:53:59 +0200622 raise an exception and return -1 on error. */
623int
624_Py_get_inheritable(int fd)
625{
626 return get_inheritable(fd, 1);
627}
628
629static int
630set_inheritable(int fd, int inheritable, int raise, int *atomic_flag_works)
631{
632#ifdef MS_WINDOWS
633 HANDLE handle;
634 DWORD flags;
Victor Stinner282124b2014-09-02 11:41:04 +0200635#else
636#if defined(HAVE_SYS_IOCTL_H) && defined(FIOCLEX) && defined(FIONCLEX)
637 static int ioctl_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +0200638 int request;
639 int err;
Victor Stinner282124b2014-09-02 11:41:04 +0200640#endif
Victor Stinnerdaf45552013-08-28 00:53:59 +0200641 int flags;
642 int res;
643#endif
644
645 /* atomic_flag_works can only be used to make the file descriptor
646 non-inheritable */
647 assert(!(atomic_flag_works != NULL && inheritable));
648
649 if (atomic_flag_works != NULL && !inheritable) {
650 if (*atomic_flag_works == -1) {
651 int inheritable = get_inheritable(fd, raise);
652 if (inheritable == -1)
653 return -1;
654 *atomic_flag_works = !inheritable;
655 }
656
657 if (*atomic_flag_works)
658 return 0;
659 }
660
661#ifdef MS_WINDOWS
662 if (!_PyVerify_fd(fd)) {
663 if (raise)
664 PyErr_SetFromErrno(PyExc_OSError);
665 return -1;
666 }
667
668 handle = (HANDLE)_get_osfhandle(fd);
669 if (handle == INVALID_HANDLE_VALUE) {
670 if (raise)
671 PyErr_SetFromWindowsErr(0);
672 return -1;
673 }
674
675 if (inheritable)
676 flags = HANDLE_FLAG_INHERIT;
677 else
678 flags = 0;
679 if (!SetHandleInformation(handle, HANDLE_FLAG_INHERIT, flags)) {
680 if (raise)
681 PyErr_SetFromWindowsErr(0);
682 return -1;
683 }
684 return 0;
685
Victor Stinnerdaf45552013-08-28 00:53:59 +0200686#else
Victor Stinner282124b2014-09-02 11:41:04 +0200687
688#if defined(HAVE_SYS_IOCTL_H) && defined(FIOCLEX) && defined(FIONCLEX)
689 if (ioctl_works != 0) {
690 /* fast-path: ioctl() only requires one syscall */
691 if (inheritable)
692 request = FIONCLEX;
693 else
694 request = FIOCLEX;
695 err = ioctl(fd, request, NULL);
696 if (!err) {
697 ioctl_works = 1;
698 return 0;
699 }
700
701 if (errno != ENOTTY) {
702 if (raise)
703 PyErr_SetFromErrno(PyExc_OSError);
704 return -1;
705 }
706 else {
707 /* Issue #22258: Here, ENOTTY means "Inappropriate ioctl for
708 device". The ioctl is declared but not supported by the kernel.
709 Remember that ioctl() doesn't work. It is the case on
710 Illumos-based OS for example. */
711 ioctl_works = 0;
712 }
713 /* fallback to fcntl() if ioctl() does not work */
714 }
715#endif
716
717 /* slow-path: fcntl() requires two syscalls */
Victor Stinnerdaf45552013-08-28 00:53:59 +0200718 flags = fcntl(fd, F_GETFD);
719 if (flags < 0) {
720 if (raise)
721 PyErr_SetFromErrno(PyExc_OSError);
722 return -1;
723 }
724
725 if (inheritable)
726 flags &= ~FD_CLOEXEC;
727 else
728 flags |= FD_CLOEXEC;
729 res = fcntl(fd, F_SETFD, flags);
730 if (res < 0) {
731 if (raise)
732 PyErr_SetFromErrno(PyExc_OSError);
733 return -1;
734 }
735 return 0;
736#endif
737}
738
739/* Make the file descriptor non-inheritable.
Victor Stinnerb034eee2013-09-07 10:36:04 +0200740 Return 0 on success, set errno and return -1 on error. */
Victor Stinnerdaf45552013-08-28 00:53:59 +0200741static int
742make_non_inheritable(int fd)
743{
744 return set_inheritable(fd, 0, 0, NULL);
745}
746
747/* Set the inheritable flag of the specified file descriptor.
748 On success: return 0, on error: raise an exception if raise is nonzero
749 and return -1.
750
751 If atomic_flag_works is not NULL:
752
753 * if *atomic_flag_works==-1, check if the inheritable is set on the file
754 descriptor: if yes, set *atomic_flag_works to 1, otherwise set to 0 and
755 set the inheritable flag
756 * if *atomic_flag_works==1: do nothing
757 * if *atomic_flag_works==0: set inheritable flag to False
758
759 Set atomic_flag_works to NULL if no atomic flag was used to create the
760 file descriptor.
761
762 atomic_flag_works can only be used to make a file descriptor
763 non-inheritable: atomic_flag_works must be NULL if inheritable=1. */
764int
765_Py_set_inheritable(int fd, int inheritable, int *atomic_flag_works)
766{
767 return set_inheritable(fd, inheritable, 1, atomic_flag_works);
768}
769
770/* Open a file with the specified flags (wrapper to open() function).
771 The file descriptor is created non-inheritable. */
772int
773_Py_open(const char *pathname, int flags)
774{
775 int fd;
776#ifdef MS_WINDOWS
777 fd = open(pathname, flags | O_NOINHERIT);
778 if (fd < 0)
779 return fd;
780#else
781
782 int *atomic_flag_works;
783#ifdef O_CLOEXEC
784 atomic_flag_works = &_Py_open_cloexec_works;
785 flags |= O_CLOEXEC;
786#else
787 atomic_flag_works = NULL;
788#endif
789 fd = open(pathname, flags);
790 if (fd < 0)
791 return fd;
792
793 if (set_inheritable(fd, 0, 0, atomic_flag_works) < 0) {
794 close(fd);
795 return -1;
796 }
797#endif /* !MS_WINDOWS */
798 return fd;
799}
800
801/* Open a file. Use _wfopen() on Windows, encode the path to the locale
802 encoding and use fopen() otherwise. The file descriptor is created
803 non-inheritable. */
Victor Stinner4e314432010-10-07 21:45:39 +0000804FILE *
805_Py_wfopen(const wchar_t *path, const wchar_t *mode)
806{
Victor Stinner4e314432010-10-07 21:45:39 +0000807 FILE *f;
Victor Stinnerdaf45552013-08-28 00:53:59 +0200808#ifndef MS_WINDOWS
Victor Stinner4e314432010-10-07 21:45:39 +0000809 char *cpath;
810 char cmode[10];
811 size_t r;
812 r = wcstombs(cmode, mode, 10);
813 if (r == (size_t)-1 || r >= 10) {
814 errno = EINVAL;
815 return NULL;
816 }
Victor Stinner2f02a512010-11-08 22:43:46 +0000817 cpath = _Py_wchar2char(path, NULL);
Victor Stinner4e314432010-10-07 21:45:39 +0000818 if (cpath == NULL)
819 return NULL;
820 f = fopen(cpath, cmode);
821 PyMem_Free(cpath);
Victor Stinner4e314432010-10-07 21:45:39 +0000822#else
Victor Stinnerdaf45552013-08-28 00:53:59 +0200823 f = _wfopen(path, mode);
Victor Stinner4e314432010-10-07 21:45:39 +0000824#endif
Victor Stinnerdaf45552013-08-28 00:53:59 +0200825 if (f == NULL)
826 return NULL;
827 if (make_non_inheritable(fileno(f)) < 0) {
828 fclose(f);
829 return NULL;
830 }
831 return f;
Victor Stinner4e314432010-10-07 21:45:39 +0000832}
833
Victor Stinnerdaf45552013-08-28 00:53:59 +0200834/* Wrapper to fopen(). The file descriptor is created non-inheritable. */
835FILE*
836_Py_fopen(const char *pathname, const char *mode)
837{
838 FILE *f = fopen(pathname, mode);
839 if (f == NULL)
840 return NULL;
841 if (make_non_inheritable(fileno(f)) < 0) {
842 fclose(f);
843 return NULL;
844 }
845 return f;
846}
847
848/* Open a file. Call _wfopen() on Windows, or encode the path to the filesystem
849 encoding and call fopen() otherwise. The file descriptor is created
850 non-inheritable.
Victor Stinner6672d0c2010-10-07 22:53:43 +0000851
852 Return the new file object on success, or NULL if the file cannot be open or
Victor Stinnerdaf45552013-08-28 00:53:59 +0200853 (if PyErr_Occurred()) on unicode error. */
Victor Stinner4e314432010-10-07 21:45:39 +0000854FILE*
Victor Stinnerdaf45552013-08-28 00:53:59 +0200855_Py_fopen_obj(PyObject *path, const char *mode)
Victor Stinner4e314432010-10-07 21:45:39 +0000856{
Victor Stinnerdaf45552013-08-28 00:53:59 +0200857 FILE *f;
Victor Stinner4e314432010-10-07 21:45:39 +0000858#ifdef MS_WINDOWS
Victor Stinneree587ea2011-11-17 00:51:38 +0100859 wchar_t *wpath;
Victor Stinner4e314432010-10-07 21:45:39 +0000860 wchar_t wmode[10];
861 int usize;
Victor Stinner4e314432010-10-07 21:45:39 +0000862
Antoine Pitrou0e576f12011-12-22 10:03:38 +0100863 if (!PyUnicode_Check(path)) {
864 PyErr_Format(PyExc_TypeError,
865 "str file path expected under Windows, got %R",
866 Py_TYPE(path));
867 return NULL;
868 }
Victor Stinneree587ea2011-11-17 00:51:38 +0100869 wpath = PyUnicode_AsUnicode(path);
870 if (wpath == NULL)
871 return NULL;
872
Victor Stinner4e314432010-10-07 21:45:39 +0000873 usize = MultiByteToWideChar(CP_ACP, 0, mode, -1, wmode, sizeof(wmode));
874 if (usize == 0)
875 return NULL;
876
Victor Stinnerdaf45552013-08-28 00:53:59 +0200877 f = _wfopen(wpath, wmode);
Victor Stinner4e314432010-10-07 21:45:39 +0000878#else
Antoine Pitrou2b1cc892011-12-19 18:19:06 +0100879 PyObject *bytes;
880 if (!PyUnicode_FSConverter(path, &bytes))
Victor Stinner4e314432010-10-07 21:45:39 +0000881 return NULL;
882 f = fopen(PyBytes_AS_STRING(bytes), mode);
883 Py_DECREF(bytes);
Victor Stinner4e314432010-10-07 21:45:39 +0000884#endif
Victor Stinnerdaf45552013-08-28 00:53:59 +0200885 if (f == NULL)
886 return NULL;
887 if (make_non_inheritable(fileno(f)) < 0) {
888 fclose(f);
889 return NULL;
890 }
891 return f;
Victor Stinner4e314432010-10-07 21:45:39 +0000892}
893
894#ifdef HAVE_READLINK
Victor Stinner6672d0c2010-10-07 22:53:43 +0000895
896/* Read value of symbolic link. Encode the path to the locale encoding, decode
Victor Stinneraf02e1c2011-12-16 23:56:01 +0100897 the result from the locale encoding. Return -1 on error. */
Victor Stinner6672d0c2010-10-07 22:53:43 +0000898
Victor Stinner4e314432010-10-07 21:45:39 +0000899int
900_Py_wreadlink(const wchar_t *path, wchar_t *buf, size_t bufsiz)
901{
902 char *cpath;
Victor Stinnerb11d6cb2013-11-15 18:14:11 +0100903 char cbuf[MAXPATHLEN];
Victor Stinner3f711f42010-10-16 22:47:37 +0000904 wchar_t *wbuf;
Victor Stinner4e314432010-10-07 21:45:39 +0000905 int res;
906 size_t r1;
907
Victor Stinner2f02a512010-11-08 22:43:46 +0000908 cpath = _Py_wchar2char(path, NULL);
Victor Stinner4e314432010-10-07 21:45:39 +0000909 if (cpath == NULL) {
910 errno = EINVAL;
911 return -1;
912 }
Victor Stinnerb11d6cb2013-11-15 18:14:11 +0100913 res = (int)readlink(cpath, cbuf, Py_ARRAY_LENGTH(cbuf));
Victor Stinner4e314432010-10-07 21:45:39 +0000914 PyMem_Free(cpath);
915 if (res == -1)
916 return -1;
Victor Stinnerb11d6cb2013-11-15 18:14:11 +0100917 if (res == Py_ARRAY_LENGTH(cbuf)) {
Victor Stinner4e314432010-10-07 21:45:39 +0000918 errno = EINVAL;
919 return -1;
920 }
921 cbuf[res] = '\0'; /* buf will be null terminated */
Victor Stinner168e1172010-10-16 23:16:16 +0000922 wbuf = _Py_char2wchar(cbuf, &r1);
Victor Stinner350147b2010-10-16 22:52:09 +0000923 if (wbuf == NULL) {
924 errno = EINVAL;
925 return -1;
926 }
Victor Stinner3f711f42010-10-16 22:47:37 +0000927 if (bufsiz <= r1) {
Victor Stinner1a7425f2013-07-07 16:25:15 +0200928 PyMem_RawFree(wbuf);
Victor Stinner4e314432010-10-07 21:45:39 +0000929 errno = EINVAL;
930 return -1;
931 }
Victor Stinner3f711f42010-10-16 22:47:37 +0000932 wcsncpy(buf, wbuf, bufsiz);
Victor Stinner1a7425f2013-07-07 16:25:15 +0200933 PyMem_RawFree(wbuf);
Victor Stinner4e314432010-10-07 21:45:39 +0000934 return (int)r1;
935}
936#endif
937
938#ifdef HAVE_REALPATH
Victor Stinner6672d0c2010-10-07 22:53:43 +0000939
940/* Return the canonicalized absolute pathname. Encode path to the locale
Victor Stinneraf02e1c2011-12-16 23:56:01 +0100941 encoding, decode the result from the locale encoding.
942 Return NULL on error. */
Victor Stinner6672d0c2010-10-07 22:53:43 +0000943
Victor Stinner4e314432010-10-07 21:45:39 +0000944wchar_t*
Victor Stinner015f4d82010-10-07 22:29:53 +0000945_Py_wrealpath(const wchar_t *path,
946 wchar_t *resolved_path, size_t resolved_path_size)
Victor Stinner4e314432010-10-07 21:45:39 +0000947{
948 char *cpath;
Victor Stinnerb11d6cb2013-11-15 18:14:11 +0100949 char cresolved_path[MAXPATHLEN];
Victor Stinner0a1b8cb2010-10-16 22:55:47 +0000950 wchar_t *wresolved_path;
Victor Stinner4e314432010-10-07 21:45:39 +0000951 char *res;
952 size_t r;
Victor Stinner2f02a512010-11-08 22:43:46 +0000953 cpath = _Py_wchar2char(path, NULL);
Victor Stinner4e314432010-10-07 21:45:39 +0000954 if (cpath == NULL) {
955 errno = EINVAL;
956 return NULL;
957 }
958 res = realpath(cpath, cresolved_path);
959 PyMem_Free(cpath);
960 if (res == NULL)
961 return NULL;
Victor Stinner0a1b8cb2010-10-16 22:55:47 +0000962
Victor Stinner168e1172010-10-16 23:16:16 +0000963 wresolved_path = _Py_char2wchar(cresolved_path, &r);
Victor Stinner0a1b8cb2010-10-16 22:55:47 +0000964 if (wresolved_path == NULL) {
Victor Stinner4e314432010-10-07 21:45:39 +0000965 errno = EINVAL;
966 return NULL;
967 }
Victor Stinner0a1b8cb2010-10-16 22:55:47 +0000968 if (resolved_path_size <= r) {
Victor Stinner1a7425f2013-07-07 16:25:15 +0200969 PyMem_RawFree(wresolved_path);
Victor Stinner0a1b8cb2010-10-16 22:55:47 +0000970 errno = EINVAL;
971 return NULL;
972 }
973 wcsncpy(resolved_path, wresolved_path, resolved_path_size);
Victor Stinner1a7425f2013-07-07 16:25:15 +0200974 PyMem_RawFree(wresolved_path);
Victor Stinner4e314432010-10-07 21:45:39 +0000975 return resolved_path;
976}
977#endif
978
Victor Stinnerf4061da2010-10-14 12:37:19 +0000979/* Get the current directory. size is the buffer size in wide characters
Victor Stinneraf02e1c2011-12-16 23:56:01 +0100980 including the null character. Decode the path from the locale encoding.
981 Return NULL on error. */
Victor Stinner6672d0c2010-10-07 22:53:43 +0000982
Victor Stinner4e314432010-10-07 21:45:39 +0000983wchar_t*
984_Py_wgetcwd(wchar_t *buf, size_t size)
985{
986#ifdef MS_WINDOWS
Victor Stinner56785ea2013-06-05 00:46:29 +0200987 int isize = (int)Py_MIN(size, INT_MAX);
988 return _wgetcwd(buf, isize);
Victor Stinner4e314432010-10-07 21:45:39 +0000989#else
Victor Stinnerb11d6cb2013-11-15 18:14:11 +0100990 char fname[MAXPATHLEN];
Victor Stinnerf4061da2010-10-14 12:37:19 +0000991 wchar_t *wname;
Victor Stinner168e1172010-10-16 23:16:16 +0000992 size_t len;
Victor Stinnerf4061da2010-10-14 12:37:19 +0000993
Victor Stinnerb11d6cb2013-11-15 18:14:11 +0100994 if (getcwd(fname, Py_ARRAY_LENGTH(fname)) == NULL)
Victor Stinner4e314432010-10-07 21:45:39 +0000995 return NULL;
Victor Stinner168e1172010-10-16 23:16:16 +0000996 wname = _Py_char2wchar(fname, &len);
Victor Stinnerf4061da2010-10-14 12:37:19 +0000997 if (wname == NULL)
998 return NULL;
Victor Stinner168e1172010-10-16 23:16:16 +0000999 if (size <= len) {
Victor Stinner1a7425f2013-07-07 16:25:15 +02001000 PyMem_RawFree(wname);
Victor Stinner4e314432010-10-07 21:45:39 +00001001 return NULL;
1002 }
Victor Stinnerf4061da2010-10-14 12:37:19 +00001003 wcsncpy(buf, wname, size);
Victor Stinner1a7425f2013-07-07 16:25:15 +02001004 PyMem_RawFree(wname);
Victor Stinner4e314432010-10-07 21:45:39 +00001005 return buf;
1006#endif
1007}
1008
Victor Stinnerdaf45552013-08-28 00:53:59 +02001009/* Duplicate a file descriptor. The new file descriptor is created as
1010 non-inheritable. Return a new file descriptor on success, raise an OSError
1011 exception and return -1 on error.
1012
1013 The GIL is released to call dup(). The caller must hold the GIL. */
1014int
1015_Py_dup(int fd)
1016{
1017#ifdef MS_WINDOWS
1018 HANDLE handle;
1019 DWORD ftype;
1020#endif
1021
1022 if (!_PyVerify_fd(fd)) {
1023 PyErr_SetFromErrno(PyExc_OSError);
1024 return -1;
1025 }
1026
1027#ifdef MS_WINDOWS
1028 handle = (HANDLE)_get_osfhandle(fd);
1029 if (handle == INVALID_HANDLE_VALUE) {
1030 PyErr_SetFromWindowsErr(0);
1031 return -1;
1032 }
1033
1034 /* get the file type, ignore the error if it failed */
1035 ftype = GetFileType(handle);
1036
1037 Py_BEGIN_ALLOW_THREADS
1038 fd = dup(fd);
1039 Py_END_ALLOW_THREADS
1040 if (fd < 0) {
1041 PyErr_SetFromErrno(PyExc_OSError);
1042 return -1;
1043 }
1044
1045 /* Character files like console cannot be make non-inheritable */
1046 if (ftype != FILE_TYPE_CHAR) {
1047 if (_Py_set_inheritable(fd, 0, NULL) < 0) {
1048 close(fd);
1049 return -1;
1050 }
1051 }
1052#elif defined(HAVE_FCNTL_H) && defined(F_DUPFD_CLOEXEC)
1053 Py_BEGIN_ALLOW_THREADS
1054 fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
1055 Py_END_ALLOW_THREADS
1056 if (fd < 0) {
1057 PyErr_SetFromErrno(PyExc_OSError);
1058 return -1;
1059 }
1060
1061#else
1062 Py_BEGIN_ALLOW_THREADS
1063 fd = dup(fd);
1064 Py_END_ALLOW_THREADS
1065 if (fd < 0) {
1066 PyErr_SetFromErrno(PyExc_OSError);
1067 return -1;
1068 }
1069
1070 if (_Py_set_inheritable(fd, 0, NULL) < 0) {
1071 close(fd);
1072 return -1;
1073 }
1074#endif
1075 return fd;
1076}
1077