blob: c5c8d4e990a6f633e511813e880925aab2930064 [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
Victor Stinnerf6a271a2014-08-01 12:28:48 +020085 1: the workaround is used: Py_EncodeLocale() uses
86 encode_ascii_surrogateescape() and Py_DecodeLocale() uses
Victor Stinnerd45c7f82012-12-04 01:34:47 +010087 decode_ascii_surrogateescape()
Victor Stinnerf6a271a2014-08-01 12:28:48 +020088 0: the workaround is not used: Py_EncodeLocale() uses wcstombs() and
89 Py_DecodeLocale() uses mbstowcs()
Victor Stinnerd45c7f82012-12-04 01:34:47 +010090 -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
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200247 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
Victor Stinner4e314432010-10-07 21:45:39 +0000249 character, escape the bytes using the surrogateescape error handler instead
250 of decoding them.
251
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200252 Return a pointer to a newly allocated wide character string, use
253 PyMem_RawFree() to free the memory. If size is not NULL, write the number of
254 wide characters excluding the null character into *size
Victor Stinner4e314432010-10-07 21:45:39 +0000255
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200256 Return NULL on decoding error or memory allocation error. If *size* is not
257 NULL, *size is set to (size_t)-1 on memory error or set to (size_t)-2 on
258 decoding error.
Victor Stinner19de4c32010-11-08 23:30:46 +0000259
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200260 Decoding errors should never happen, unless there is a bug in the C
261 library.
262
263 Use the Py_EncodeLocale() function to encode the character string back to a
264 byte string. */
Victor Stinner4e314432010-10-07 21:45:39 +0000265wchar_t*
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200266Py_DecodeLocale(const char* arg, size_t *size)
Victor Stinner4e314432010-10-07 21:45:39 +0000267{
Victor Stinnere2623772012-11-12 23:04:02 +0100268#ifdef __APPLE__
269 wchar_t *wstr;
270 wstr = _Py_DecodeUTF8_surrogateescape(arg, strlen(arg));
Victor Stinner0d92c4f2012-11-12 23:32:21 +0100271 if (size != NULL) {
272 if (wstr != NULL)
273 *size = wcslen(wstr);
274 else
275 *size = (size_t)-1;
276 }
Victor Stinnere2623772012-11-12 23:04:02 +0100277 return wstr;
278#else
Victor Stinner4e314432010-10-07 21:45:39 +0000279 wchar_t *res;
Victor Stinnerd45c7f82012-12-04 01:34:47 +0100280 size_t argsize;
Victor Stinner4e314432010-10-07 21:45:39 +0000281 size_t count;
Victor Stinner313f10c2013-05-07 23:48:56 +0200282#ifdef HAVE_MBRTOWC
Victor Stinner4e314432010-10-07 21:45:39 +0000283 unsigned char *in;
284 wchar_t *out;
Victor Stinner4e314432010-10-07 21:45:39 +0000285 mbstate_t mbs;
286#endif
Victor Stinnerd45c7f82012-12-04 01:34:47 +0100287
288#ifndef MS_WINDOWS
289 if (force_ascii == -1)
290 force_ascii = check_force_ascii();
291
292 if (force_ascii) {
293 /* force ASCII encoding to workaround mbstowcs() issue */
294 res = decode_ascii_surrogateescape(arg, size);
295 if (res == NULL)
296 goto oom;
297 return res;
298 }
299#endif
300
301#ifdef HAVE_BROKEN_MBSTOWCS
302 /* Some platforms have a broken implementation of
303 * mbstowcs which does not count the characters that
304 * would result from conversion. Use an upper bound.
305 */
306 argsize = strlen(arg);
307#else
308 argsize = mbstowcs(NULL, arg, 0);
309#endif
Victor Stinner4e314432010-10-07 21:45:39 +0000310 if (argsize != (size_t)-1) {
Benjamin Petersonf18bf6f2015-01-04 16:03:17 -0600311 if (argsize == PY_SSIZE_T_MAX)
312 goto oom;
313 argsize += 1;
314 if (argsize > PY_SSIZE_T_MAX/sizeof(wchar_t))
315 goto oom;
Benjamin Peterson10ecaa22015-01-04 16:05:39 -0600316 res = (wchar_t *)PyMem_RawMalloc(argsize*sizeof(wchar_t));
Victor Stinner4e314432010-10-07 21:45:39 +0000317 if (!res)
318 goto oom;
Benjamin Petersonf18bf6f2015-01-04 16:03:17 -0600319 count = mbstowcs(res, arg, argsize);
Victor Stinner4e314432010-10-07 21:45:39 +0000320 if (count != (size_t)-1) {
321 wchar_t *tmp;
322 /* Only use the result if it contains no
323 surrogate characters. */
324 for (tmp = res; *tmp != 0 &&
Victor Stinner76df43d2012-10-30 01:42:39 +0100325 !Py_UNICODE_IS_SURROGATE(*tmp); tmp++)
Victor Stinner4e314432010-10-07 21:45:39 +0000326 ;
Victor Stinner168e1172010-10-16 23:16:16 +0000327 if (*tmp == 0) {
328 if (size != NULL)
329 *size = count;
Victor Stinner4e314432010-10-07 21:45:39 +0000330 return res;
Victor Stinner168e1172010-10-16 23:16:16 +0000331 }
Victor Stinner4e314432010-10-07 21:45:39 +0000332 }
Victor Stinner1a7425f2013-07-07 16:25:15 +0200333 PyMem_RawFree(res);
Victor Stinner4e314432010-10-07 21:45:39 +0000334 }
335 /* Conversion failed. Fall back to escaping with surrogateescape. */
336#ifdef HAVE_MBRTOWC
337 /* Try conversion with mbrtwoc (C99), and escape non-decodable bytes. */
338
339 /* Overallocate; as multi-byte characters are in the argument, the
340 actual output could use less memory. */
341 argsize = strlen(arg) + 1;
Benjamin Petersonf18bf6f2015-01-04 16:03:17 -0600342 if (argsize > PY_SSIZE_T_MAX/sizeof(wchar_t))
343 goto oom;
Victor Stinner1a7425f2013-07-07 16:25:15 +0200344 res = (wchar_t*)PyMem_RawMalloc(argsize*sizeof(wchar_t));
Victor Stinner19de4c32010-11-08 23:30:46 +0000345 if (!res)
346 goto oom;
Victor Stinner4e314432010-10-07 21:45:39 +0000347 in = (unsigned char*)arg;
348 out = res;
349 memset(&mbs, 0, sizeof mbs);
350 while (argsize) {
351 size_t converted = mbrtowc(out, (char*)in, argsize, &mbs);
352 if (converted == 0)
353 /* Reached end of string; null char stored. */
354 break;
355 if (converted == (size_t)-2) {
356 /* Incomplete character. This should never happen,
357 since we provide everything that we have -
358 unless there is a bug in the C library, or I
359 misunderstood how mbrtowc works. */
Victor Stinner1a7425f2013-07-07 16:25:15 +0200360 PyMem_RawFree(res);
Victor Stinneraf02e1c2011-12-16 23:56:01 +0100361 if (size != NULL)
362 *size = (size_t)-2;
Victor Stinner4e314432010-10-07 21:45:39 +0000363 return NULL;
364 }
365 if (converted == (size_t)-1) {
366 /* Conversion error. Escape as UTF-8b, and start over
367 in the initial shift state. */
368 *out++ = 0xdc00 + *in++;
369 argsize--;
370 memset(&mbs, 0, sizeof mbs);
371 continue;
372 }
Victor Stinner76df43d2012-10-30 01:42:39 +0100373 if (Py_UNICODE_IS_SURROGATE(*out)) {
Victor Stinner4e314432010-10-07 21:45:39 +0000374 /* Surrogate character. Escape the original
375 byte sequence with surrogateescape. */
376 argsize -= converted;
377 while (converted--)
378 *out++ = 0xdc00 + *in++;
379 continue;
380 }
381 /* successfully converted some bytes */
382 in += converted;
383 argsize -= converted;
384 out++;
385 }
Victor Stinnerd45c7f82012-12-04 01:34:47 +0100386 if (size != NULL)
387 *size = out - res;
Victor Stinnere2623772012-11-12 23:04:02 +0100388#else /* HAVE_MBRTOWC */
Victor Stinner4e314432010-10-07 21:45:39 +0000389 /* Cannot use C locale for escaping; manually escape as if charset
390 is ASCII (i.e. escape all bytes > 128. This will still roundtrip
391 correctly in the locale's charset, which must be an ASCII superset. */
Victor Stinnerd45c7f82012-12-04 01:34:47 +0100392 res = decode_ascii_surrogateescape(arg, size);
393 if (res == NULL)
Victor Stinneraf02e1c2011-12-16 23:56:01 +0100394 goto oom;
Victor Stinnere2623772012-11-12 23:04:02 +0100395#endif /* HAVE_MBRTOWC */
Victor Stinner4e314432010-10-07 21:45:39 +0000396 return res;
397oom:
Victor Stinneraf02e1c2011-12-16 23:56:01 +0100398 if (size != NULL)
399 *size = (size_t)-1;
Victor Stinner4e314432010-10-07 21:45:39 +0000400 return NULL;
Victor Stinnere2623772012-11-12 23:04:02 +0100401#endif /* __APPLE__ */
Victor Stinner4e314432010-10-07 21:45:39 +0000402}
403
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200404/* Encode a wide character string to the locale encoding with the
405 surrogateescape error handler: surrogate characters in the range
406 U+DC80..U+DCFF are converted to bytes 0x80..0xFF.
Victor Stinner4e314432010-10-07 21:45:39 +0000407
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200408 Return a pointer to a newly allocated byte string, use PyMem_Free() to free
409 the memory. Return NULL on encoding or memory allocation error.
Victor Stinner4e314432010-10-07 21:45:39 +0000410
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200411 If error_pos is not NULL, *error_pos is set to the index of the invalid
412 character on encoding error, or set to (size_t)-1 otherwise.
Victor Stinner2f02a512010-11-08 22:43:46 +0000413
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200414 Use the Py_DecodeLocale() function to decode the bytes string back to a wide
415 character string. */
Victor Stinner4e314432010-10-07 21:45:39 +0000416char*
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200417Py_EncodeLocale(const wchar_t *text, size_t *error_pos)
Victor Stinner4e314432010-10-07 21:45:39 +0000418{
Victor Stinnere2623772012-11-12 23:04:02 +0100419#ifdef __APPLE__
420 Py_ssize_t len;
421 PyObject *unicode, *bytes = NULL;
422 char *cpath;
423
424 unicode = PyUnicode_FromWideChar(text, wcslen(text));
Victor Stinner0d92c4f2012-11-12 23:32:21 +0100425 if (unicode == NULL)
Victor Stinnere2623772012-11-12 23:04:02 +0100426 return NULL;
Victor Stinnere2623772012-11-12 23:04:02 +0100427
428 bytes = _PyUnicode_AsUTF8String(unicode, "surrogateescape");
429 Py_DECREF(unicode);
430 if (bytes == NULL) {
431 PyErr_Clear();
Victor Stinner0d92c4f2012-11-12 23:32:21 +0100432 if (error_pos != NULL)
433 *error_pos = (size_t)-1;
Victor Stinnere2623772012-11-12 23:04:02 +0100434 return NULL;
435 }
436
437 len = PyBytes_GET_SIZE(bytes);
438 cpath = PyMem_Malloc(len+1);
439 if (cpath == NULL) {
Victor Stinner0d92c4f2012-11-12 23:32:21 +0100440 PyErr_Clear();
Victor Stinnere2623772012-11-12 23:04:02 +0100441 Py_DECREF(bytes);
Victor Stinner0d92c4f2012-11-12 23:32:21 +0100442 if (error_pos != NULL)
443 *error_pos = (size_t)-1;
Victor Stinnere2623772012-11-12 23:04:02 +0100444 return NULL;
445 }
446 memcpy(cpath, PyBytes_AsString(bytes), len + 1);
447 Py_DECREF(bytes);
448 return cpath;
449#else /* __APPLE__ */
Victor Stinner4e314432010-10-07 21:45:39 +0000450 const size_t len = wcslen(text);
451 char *result = NULL, *bytes = NULL;
452 size_t i, size, converted;
453 wchar_t c, buf[2];
454
Victor Stinnerd45c7f82012-12-04 01:34:47 +0100455#ifndef MS_WINDOWS
456 if (force_ascii == -1)
457 force_ascii = check_force_ascii();
458
459 if (force_ascii)
460 return encode_ascii_surrogateescape(text, error_pos);
461#endif
462
Victor Stinner4e314432010-10-07 21:45:39 +0000463 /* The function works in two steps:
464 1. compute the length of the output buffer in bytes (size)
465 2. outputs the bytes */
466 size = 0;
467 buf[1] = 0;
468 while (1) {
469 for (i=0; i < len; i++) {
470 c = text[i];
471 if (c >= 0xdc80 && c <= 0xdcff) {
472 /* UTF-8b surrogate */
473 if (bytes != NULL) {
474 *bytes++ = c - 0xdc00;
475 size--;
476 }
477 else
478 size++;
479 continue;
480 }
481 else {
482 buf[0] = c;
483 if (bytes != NULL)
484 converted = wcstombs(bytes, buf, size);
485 else
486 converted = wcstombs(NULL, buf, 0);
487 if (converted == (size_t)-1) {
488 if (result != NULL)
489 PyMem_Free(result);
Victor Stinner2f02a512010-11-08 22:43:46 +0000490 if (error_pos != NULL)
491 *error_pos = i;
Victor Stinner4e314432010-10-07 21:45:39 +0000492 return NULL;
493 }
494 if (bytes != NULL) {
495 bytes += converted;
496 size -= converted;
497 }
498 else
499 size += converted;
500 }
501 }
502 if (result != NULL) {
Victor Stinnerd45c7f82012-12-04 01:34:47 +0100503 *bytes = '\0';
Victor Stinner4e314432010-10-07 21:45:39 +0000504 break;
505 }
506
507 size += 1; /* nul byte at the end */
508 result = PyMem_Malloc(size);
Victor Stinner0d92c4f2012-11-12 23:32:21 +0100509 if (result == NULL) {
510 if (error_pos != NULL)
511 *error_pos = (size_t)-1;
Victor Stinner4e314432010-10-07 21:45:39 +0000512 return NULL;
Victor Stinner0d92c4f2012-11-12 23:32:21 +0100513 }
Victor Stinner4e314432010-10-07 21:45:39 +0000514 bytes = result;
515 }
516 return result;
Victor Stinnere2623772012-11-12 23:04:02 +0100517#endif /* __APPLE__ */
Victor Stinner4e314432010-10-07 21:45:39 +0000518}
519
Victor Stinner4e314432010-10-07 21:45:39 +0000520/* In principle, this should use HAVE__WSTAT, and _wstat
521 should be detected by autoconf. However, no current
522 POSIX system provides that function, so testing for
523 it is pointless.
524 Not sure whether the MS_WINDOWS guards are necessary:
525 perhaps for cygwin/mingw builds?
526*/
Victor Stinnerb306d752010-10-07 22:09:40 +0000527#if defined(HAVE_STAT) && !defined(MS_WINDOWS)
Victor Stinner6672d0c2010-10-07 22:53:43 +0000528
529/* Get file status. Encode the path to the locale encoding. */
530
Victor Stinnerb306d752010-10-07 22:09:40 +0000531int
532_Py_wstat(const wchar_t* path, struct stat *buf)
533{
Victor Stinner4e314432010-10-07 21:45:39 +0000534 int err;
535 char *fname;
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200536 fname = Py_EncodeLocale(path, NULL);
Victor Stinner4e314432010-10-07 21:45:39 +0000537 if (fname == NULL) {
538 errno = EINVAL;
539 return -1;
540 }
541 err = stat(fname, buf);
542 PyMem_Free(fname);
543 return err;
Victor Stinner4e314432010-10-07 21:45:39 +0000544}
545#endif
546
Victor Stinnerd45c7f82012-12-04 01:34:47 +0100547#ifdef HAVE_STAT
548
Victor Stinner6672d0c2010-10-07 22:53:43 +0000549/* Call _wstat() on Windows, or encode the path to the filesystem encoding and
550 call stat() otherwise. Only fill st_mode attribute on Windows.
551
Victor Stinnerbd0850b2011-12-18 20:47:30 +0100552 Return 0 on success, -1 on _wstat() / stat() error, -2 if an exception was
553 raised. */
Victor Stinner4e314432010-10-07 21:45:39 +0000554
555int
Victor Stinnera4a75952010-10-07 22:23:10 +0000556_Py_stat(PyObject *path, struct stat *statbuf)
Victor Stinner4e314432010-10-07 21:45:39 +0000557{
558#ifdef MS_WINDOWS
Victor Stinner4e314432010-10-07 21:45:39 +0000559 int err;
560 struct _stat wstatbuf;
Victor Stinneree587ea2011-11-17 00:51:38 +0100561 wchar_t *wpath;
Victor Stinner4e314432010-10-07 21:45:39 +0000562
Victor Stinneree587ea2011-11-17 00:51:38 +0100563 wpath = PyUnicode_AsUnicode(path);
564 if (wpath == NULL)
Victor Stinnerbd0850b2011-12-18 20:47:30 +0100565 return -2;
Victor Stinneree587ea2011-11-17 00:51:38 +0100566 err = _wstat(wpath, &wstatbuf);
Victor Stinner4e314432010-10-07 21:45:39 +0000567 if (!err)
568 statbuf->st_mode = wstatbuf.st_mode;
569 return err;
570#else
571 int ret;
Victor Stinnera4a75952010-10-07 22:23:10 +0000572 PyObject *bytes = PyUnicode_EncodeFSDefault(path);
Victor Stinner4e314432010-10-07 21:45:39 +0000573 if (bytes == NULL)
Victor Stinnerbd0850b2011-12-18 20:47:30 +0100574 return -2;
Victor Stinner4e314432010-10-07 21:45:39 +0000575 ret = stat(PyBytes_AS_STRING(bytes), statbuf);
576 Py_DECREF(bytes);
577 return ret;
578#endif
579}
580
Victor Stinnerd45c7f82012-12-04 01:34:47 +0100581#endif
582
Antoine Pitrou409b5382013-10-12 22:41:17 +0200583static int
Victor Stinnerdaf45552013-08-28 00:53:59 +0200584get_inheritable(int fd, int raise)
585{
586#ifdef MS_WINDOWS
587 HANDLE handle;
588 DWORD flags;
Victor Stinner6672d0c2010-10-07 22:53:43 +0000589
Victor Stinnerdaf45552013-08-28 00:53:59 +0200590 if (!_PyVerify_fd(fd)) {
591 if (raise)
592 PyErr_SetFromErrno(PyExc_OSError);
593 return -1;
594 }
595
596 handle = (HANDLE)_get_osfhandle(fd);
597 if (handle == INVALID_HANDLE_VALUE) {
598 if (raise)
599 PyErr_SetFromWindowsErr(0);
600 return -1;
601 }
602
603 if (!GetHandleInformation(handle, &flags)) {
604 if (raise)
605 PyErr_SetFromWindowsErr(0);
606 return -1;
607 }
608
609 return (flags & HANDLE_FLAG_INHERIT);
610#else
611 int flags;
612
613 flags = fcntl(fd, F_GETFD, 0);
614 if (flags == -1) {
615 if (raise)
616 PyErr_SetFromErrno(PyExc_OSError);
617 return -1;
618 }
619 return !(flags & FD_CLOEXEC);
620#endif
621}
622
623/* Get the inheritable flag of the specified file descriptor.
Victor Stinnerb034eee2013-09-07 10:36:04 +0200624 Return 1 if the file descriptor can be inherited, 0 if it cannot,
Victor Stinnerdaf45552013-08-28 00:53:59 +0200625 raise an exception and return -1 on error. */
626int
627_Py_get_inheritable(int fd)
628{
629 return get_inheritable(fd, 1);
630}
631
632static int
633set_inheritable(int fd, int inheritable, int raise, int *atomic_flag_works)
634{
635#ifdef MS_WINDOWS
636 HANDLE handle;
637 DWORD flags;
Victor Stinner282124b2014-09-02 11:41:04 +0200638#else
639#if defined(HAVE_SYS_IOCTL_H) && defined(FIOCLEX) && defined(FIONCLEX)
640 static int ioctl_works = -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +0200641 int request;
642 int err;
Victor Stinner282124b2014-09-02 11:41:04 +0200643#endif
Victor Stinnerdaf45552013-08-28 00:53:59 +0200644 int flags;
645 int res;
646#endif
647
648 /* atomic_flag_works can only be used to make the file descriptor
649 non-inheritable */
650 assert(!(atomic_flag_works != NULL && inheritable));
651
652 if (atomic_flag_works != NULL && !inheritable) {
653 if (*atomic_flag_works == -1) {
654 int inheritable = get_inheritable(fd, raise);
655 if (inheritable == -1)
656 return -1;
657 *atomic_flag_works = !inheritable;
658 }
659
660 if (*atomic_flag_works)
661 return 0;
662 }
663
664#ifdef MS_WINDOWS
665 if (!_PyVerify_fd(fd)) {
666 if (raise)
667 PyErr_SetFromErrno(PyExc_OSError);
668 return -1;
669 }
670
671 handle = (HANDLE)_get_osfhandle(fd);
672 if (handle == INVALID_HANDLE_VALUE) {
673 if (raise)
674 PyErr_SetFromWindowsErr(0);
675 return -1;
676 }
677
678 if (inheritable)
679 flags = HANDLE_FLAG_INHERIT;
680 else
681 flags = 0;
682 if (!SetHandleInformation(handle, HANDLE_FLAG_INHERIT, flags)) {
683 if (raise)
684 PyErr_SetFromWindowsErr(0);
685 return -1;
686 }
687 return 0;
688
Victor Stinnerdaf45552013-08-28 00:53:59 +0200689#else
Victor Stinner282124b2014-09-02 11:41:04 +0200690
691#if defined(HAVE_SYS_IOCTL_H) && defined(FIOCLEX) && defined(FIONCLEX)
692 if (ioctl_works != 0) {
693 /* fast-path: ioctl() only requires one syscall */
694 if (inheritable)
695 request = FIONCLEX;
696 else
697 request = FIOCLEX;
698 err = ioctl(fd, request, NULL);
699 if (!err) {
700 ioctl_works = 1;
701 return 0;
702 }
703
704 if (errno != ENOTTY) {
705 if (raise)
706 PyErr_SetFromErrno(PyExc_OSError);
707 return -1;
708 }
709 else {
710 /* Issue #22258: Here, ENOTTY means "Inappropriate ioctl for
711 device". The ioctl is declared but not supported by the kernel.
712 Remember that ioctl() doesn't work. It is the case on
713 Illumos-based OS for example. */
714 ioctl_works = 0;
715 }
716 /* fallback to fcntl() if ioctl() does not work */
717 }
718#endif
719
720 /* slow-path: fcntl() requires two syscalls */
Victor Stinnerdaf45552013-08-28 00:53:59 +0200721 flags = fcntl(fd, F_GETFD);
722 if (flags < 0) {
723 if (raise)
724 PyErr_SetFromErrno(PyExc_OSError);
725 return -1;
726 }
727
728 if (inheritable)
729 flags &= ~FD_CLOEXEC;
730 else
731 flags |= FD_CLOEXEC;
732 res = fcntl(fd, F_SETFD, flags);
733 if (res < 0) {
734 if (raise)
735 PyErr_SetFromErrno(PyExc_OSError);
736 return -1;
737 }
738 return 0;
739#endif
740}
741
742/* Make the file descriptor non-inheritable.
Victor Stinnerb034eee2013-09-07 10:36:04 +0200743 Return 0 on success, set errno and return -1 on error. */
Victor Stinnerdaf45552013-08-28 00:53:59 +0200744static int
745make_non_inheritable(int fd)
746{
747 return set_inheritable(fd, 0, 0, NULL);
748}
749
750/* Set the inheritable flag of the specified file descriptor.
751 On success: return 0, on error: raise an exception if raise is nonzero
752 and return -1.
753
754 If atomic_flag_works is not NULL:
755
756 * if *atomic_flag_works==-1, check if the inheritable is set on the file
757 descriptor: if yes, set *atomic_flag_works to 1, otherwise set to 0 and
758 set the inheritable flag
759 * if *atomic_flag_works==1: do nothing
760 * if *atomic_flag_works==0: set inheritable flag to False
761
762 Set atomic_flag_works to NULL if no atomic flag was used to create the
763 file descriptor.
764
765 atomic_flag_works can only be used to make a file descriptor
766 non-inheritable: atomic_flag_works must be NULL if inheritable=1. */
767int
768_Py_set_inheritable(int fd, int inheritable, int *atomic_flag_works)
769{
770 return set_inheritable(fd, inheritable, 1, atomic_flag_works);
771}
772
773/* Open a file with the specified flags (wrapper to open() function).
774 The file descriptor is created non-inheritable. */
775int
776_Py_open(const char *pathname, int flags)
777{
778 int fd;
779#ifdef MS_WINDOWS
780 fd = open(pathname, flags | O_NOINHERIT);
781 if (fd < 0)
782 return fd;
783#else
784
785 int *atomic_flag_works;
786#ifdef O_CLOEXEC
787 atomic_flag_works = &_Py_open_cloexec_works;
788 flags |= O_CLOEXEC;
789#else
790 atomic_flag_works = NULL;
791#endif
792 fd = open(pathname, flags);
793 if (fd < 0)
794 return fd;
795
796 if (set_inheritable(fd, 0, 0, atomic_flag_works) < 0) {
797 close(fd);
798 return -1;
799 }
800#endif /* !MS_WINDOWS */
801 return fd;
802}
803
804/* Open a file. Use _wfopen() on Windows, encode the path to the locale
805 encoding and use fopen() otherwise. The file descriptor is created
806 non-inheritable. */
Victor Stinner4e314432010-10-07 21:45:39 +0000807FILE *
808_Py_wfopen(const wchar_t *path, const wchar_t *mode)
809{
Victor Stinner4e314432010-10-07 21:45:39 +0000810 FILE *f;
Victor Stinnerdaf45552013-08-28 00:53:59 +0200811#ifndef MS_WINDOWS
Victor Stinner4e314432010-10-07 21:45:39 +0000812 char *cpath;
813 char cmode[10];
814 size_t r;
815 r = wcstombs(cmode, mode, 10);
816 if (r == (size_t)-1 || r >= 10) {
817 errno = EINVAL;
818 return NULL;
819 }
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200820 cpath = Py_EncodeLocale(path, NULL);
Victor Stinner4e314432010-10-07 21:45:39 +0000821 if (cpath == NULL)
822 return NULL;
823 f = fopen(cpath, cmode);
824 PyMem_Free(cpath);
Victor Stinner4e314432010-10-07 21:45:39 +0000825#else
Victor Stinnerdaf45552013-08-28 00:53:59 +0200826 f = _wfopen(path, mode);
Victor Stinner4e314432010-10-07 21:45:39 +0000827#endif
Victor Stinnerdaf45552013-08-28 00:53:59 +0200828 if (f == NULL)
829 return NULL;
830 if (make_non_inheritable(fileno(f)) < 0) {
831 fclose(f);
832 return NULL;
833 }
834 return f;
Victor Stinner4e314432010-10-07 21:45:39 +0000835}
836
Victor Stinnerdaf45552013-08-28 00:53:59 +0200837/* Wrapper to fopen(). The file descriptor is created non-inheritable. */
838FILE*
839_Py_fopen(const char *pathname, const char *mode)
840{
841 FILE *f = fopen(pathname, mode);
842 if (f == NULL)
843 return NULL;
844 if (make_non_inheritable(fileno(f)) < 0) {
845 fclose(f);
846 return NULL;
847 }
848 return f;
849}
850
851/* Open a file. Call _wfopen() on Windows, or encode the path to the filesystem
852 encoding and call fopen() otherwise. The file descriptor is created
853 non-inheritable.
Victor Stinner6672d0c2010-10-07 22:53:43 +0000854
855 Return the new file object on success, or NULL if the file cannot be open or
Victor Stinnerdaf45552013-08-28 00:53:59 +0200856 (if PyErr_Occurred()) on unicode error. */
Victor Stinner4e314432010-10-07 21:45:39 +0000857FILE*
Victor Stinnerdaf45552013-08-28 00:53:59 +0200858_Py_fopen_obj(PyObject *path, const char *mode)
Victor Stinner4e314432010-10-07 21:45:39 +0000859{
Victor Stinnerdaf45552013-08-28 00:53:59 +0200860 FILE *f;
Victor Stinner4e314432010-10-07 21:45:39 +0000861#ifdef MS_WINDOWS
Victor Stinneree587ea2011-11-17 00:51:38 +0100862 wchar_t *wpath;
Victor Stinner4e314432010-10-07 21:45:39 +0000863 wchar_t wmode[10];
864 int usize;
Victor Stinner4e314432010-10-07 21:45:39 +0000865
Antoine Pitrou0e576f12011-12-22 10:03:38 +0100866 if (!PyUnicode_Check(path)) {
867 PyErr_Format(PyExc_TypeError,
868 "str file path expected under Windows, got %R",
869 Py_TYPE(path));
870 return NULL;
871 }
Victor Stinneree587ea2011-11-17 00:51:38 +0100872 wpath = PyUnicode_AsUnicode(path);
873 if (wpath == NULL)
874 return NULL;
875
Victor Stinner4e314432010-10-07 21:45:39 +0000876 usize = MultiByteToWideChar(CP_ACP, 0, mode, -1, wmode, sizeof(wmode));
877 if (usize == 0)
878 return NULL;
879
Victor Stinnerdaf45552013-08-28 00:53:59 +0200880 f = _wfopen(wpath, wmode);
Victor Stinner4e314432010-10-07 21:45:39 +0000881#else
Antoine Pitrou2b1cc892011-12-19 18:19:06 +0100882 PyObject *bytes;
883 if (!PyUnicode_FSConverter(path, &bytes))
Victor Stinner4e314432010-10-07 21:45:39 +0000884 return NULL;
885 f = fopen(PyBytes_AS_STRING(bytes), mode);
886 Py_DECREF(bytes);
Victor Stinner4e314432010-10-07 21:45:39 +0000887#endif
Victor Stinnerdaf45552013-08-28 00:53:59 +0200888 if (f == NULL)
889 return NULL;
890 if (make_non_inheritable(fileno(f)) < 0) {
891 fclose(f);
892 return NULL;
893 }
894 return f;
Victor Stinner4e314432010-10-07 21:45:39 +0000895}
896
897#ifdef HAVE_READLINK
Victor Stinner6672d0c2010-10-07 22:53:43 +0000898
899/* Read value of symbolic link. Encode the path to the locale encoding, decode
Victor Stinneraf02e1c2011-12-16 23:56:01 +0100900 the result from the locale encoding. Return -1 on error. */
Victor Stinner6672d0c2010-10-07 22:53:43 +0000901
Victor Stinner4e314432010-10-07 21:45:39 +0000902int
903_Py_wreadlink(const wchar_t *path, wchar_t *buf, size_t bufsiz)
904{
905 char *cpath;
Victor Stinnerb11d6cb2013-11-15 18:14:11 +0100906 char cbuf[MAXPATHLEN];
Victor Stinner3f711f42010-10-16 22:47:37 +0000907 wchar_t *wbuf;
Victor Stinner4e314432010-10-07 21:45:39 +0000908 int res;
909 size_t r1;
910
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200911 cpath = Py_EncodeLocale(path, NULL);
Victor Stinner4e314432010-10-07 21:45:39 +0000912 if (cpath == NULL) {
913 errno = EINVAL;
914 return -1;
915 }
Victor Stinnerb11d6cb2013-11-15 18:14:11 +0100916 res = (int)readlink(cpath, cbuf, Py_ARRAY_LENGTH(cbuf));
Victor Stinner4e314432010-10-07 21:45:39 +0000917 PyMem_Free(cpath);
918 if (res == -1)
919 return -1;
Victor Stinnerb11d6cb2013-11-15 18:14:11 +0100920 if (res == Py_ARRAY_LENGTH(cbuf)) {
Victor Stinner4e314432010-10-07 21:45:39 +0000921 errno = EINVAL;
922 return -1;
923 }
924 cbuf[res] = '\0'; /* buf will be null terminated */
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200925 wbuf = Py_DecodeLocale(cbuf, &r1);
Victor Stinner350147b2010-10-16 22:52:09 +0000926 if (wbuf == NULL) {
927 errno = EINVAL;
928 return -1;
929 }
Victor Stinner3f711f42010-10-16 22:47:37 +0000930 if (bufsiz <= r1) {
Victor Stinner1a7425f2013-07-07 16:25:15 +0200931 PyMem_RawFree(wbuf);
Victor Stinner4e314432010-10-07 21:45:39 +0000932 errno = EINVAL;
933 return -1;
934 }
Victor Stinner3f711f42010-10-16 22:47:37 +0000935 wcsncpy(buf, wbuf, bufsiz);
Victor Stinner1a7425f2013-07-07 16:25:15 +0200936 PyMem_RawFree(wbuf);
Victor Stinner4e314432010-10-07 21:45:39 +0000937 return (int)r1;
938}
939#endif
940
941#ifdef HAVE_REALPATH
Victor Stinner6672d0c2010-10-07 22:53:43 +0000942
943/* Return the canonicalized absolute pathname. Encode path to the locale
Victor Stinneraf02e1c2011-12-16 23:56:01 +0100944 encoding, decode the result from the locale encoding.
945 Return NULL on error. */
Victor Stinner6672d0c2010-10-07 22:53:43 +0000946
Victor Stinner4e314432010-10-07 21:45:39 +0000947wchar_t*
Victor Stinner015f4d82010-10-07 22:29:53 +0000948_Py_wrealpath(const wchar_t *path,
949 wchar_t *resolved_path, size_t resolved_path_size)
Victor Stinner4e314432010-10-07 21:45:39 +0000950{
951 char *cpath;
Victor Stinnerb11d6cb2013-11-15 18:14:11 +0100952 char cresolved_path[MAXPATHLEN];
Victor Stinner0a1b8cb2010-10-16 22:55:47 +0000953 wchar_t *wresolved_path;
Victor Stinner4e314432010-10-07 21:45:39 +0000954 char *res;
955 size_t r;
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200956 cpath = Py_EncodeLocale(path, NULL);
Victor Stinner4e314432010-10-07 21:45:39 +0000957 if (cpath == NULL) {
958 errno = EINVAL;
959 return NULL;
960 }
961 res = realpath(cpath, cresolved_path);
962 PyMem_Free(cpath);
963 if (res == NULL)
964 return NULL;
Victor Stinner0a1b8cb2010-10-16 22:55:47 +0000965
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200966 wresolved_path = Py_DecodeLocale(cresolved_path, &r);
Victor Stinner0a1b8cb2010-10-16 22:55:47 +0000967 if (wresolved_path == NULL) {
Victor Stinner4e314432010-10-07 21:45:39 +0000968 errno = EINVAL;
969 return NULL;
970 }
Victor Stinner0a1b8cb2010-10-16 22:55:47 +0000971 if (resolved_path_size <= r) {
Victor Stinner1a7425f2013-07-07 16:25:15 +0200972 PyMem_RawFree(wresolved_path);
Victor Stinner0a1b8cb2010-10-16 22:55:47 +0000973 errno = EINVAL;
974 return NULL;
975 }
976 wcsncpy(resolved_path, wresolved_path, resolved_path_size);
Victor Stinner1a7425f2013-07-07 16:25:15 +0200977 PyMem_RawFree(wresolved_path);
Victor Stinner4e314432010-10-07 21:45:39 +0000978 return resolved_path;
979}
980#endif
981
Victor Stinnerf4061da2010-10-14 12:37:19 +0000982/* Get the current directory. size is the buffer size in wide characters
Victor Stinneraf02e1c2011-12-16 23:56:01 +0100983 including the null character. Decode the path from the locale encoding.
984 Return NULL on error. */
Victor Stinner6672d0c2010-10-07 22:53:43 +0000985
Victor Stinner4e314432010-10-07 21:45:39 +0000986wchar_t*
987_Py_wgetcwd(wchar_t *buf, size_t size)
988{
989#ifdef MS_WINDOWS
Victor Stinner56785ea2013-06-05 00:46:29 +0200990 int isize = (int)Py_MIN(size, INT_MAX);
991 return _wgetcwd(buf, isize);
Victor Stinner4e314432010-10-07 21:45:39 +0000992#else
Victor Stinnerb11d6cb2013-11-15 18:14:11 +0100993 char fname[MAXPATHLEN];
Victor Stinnerf4061da2010-10-14 12:37:19 +0000994 wchar_t *wname;
Victor Stinner168e1172010-10-16 23:16:16 +0000995 size_t len;
Victor Stinnerf4061da2010-10-14 12:37:19 +0000996
Victor Stinnerb11d6cb2013-11-15 18:14:11 +0100997 if (getcwd(fname, Py_ARRAY_LENGTH(fname)) == NULL)
Victor Stinner4e314432010-10-07 21:45:39 +0000998 return NULL;
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200999 wname = Py_DecodeLocale(fname, &len);
Victor Stinnerf4061da2010-10-14 12:37:19 +00001000 if (wname == NULL)
1001 return NULL;
Victor Stinner168e1172010-10-16 23:16:16 +00001002 if (size <= len) {
Victor Stinner1a7425f2013-07-07 16:25:15 +02001003 PyMem_RawFree(wname);
Victor Stinner4e314432010-10-07 21:45:39 +00001004 return NULL;
1005 }
Victor Stinnerf4061da2010-10-14 12:37:19 +00001006 wcsncpy(buf, wname, size);
Victor Stinner1a7425f2013-07-07 16:25:15 +02001007 PyMem_RawFree(wname);
Victor Stinner4e314432010-10-07 21:45:39 +00001008 return buf;
1009#endif
1010}
1011
Victor Stinnerdaf45552013-08-28 00:53:59 +02001012/* Duplicate a file descriptor. The new file descriptor is created as
1013 non-inheritable. Return a new file descriptor on success, raise an OSError
1014 exception and return -1 on error.
1015
1016 The GIL is released to call dup(). The caller must hold the GIL. */
1017int
1018_Py_dup(int fd)
1019{
1020#ifdef MS_WINDOWS
1021 HANDLE handle;
1022 DWORD ftype;
1023#endif
1024
1025 if (!_PyVerify_fd(fd)) {
1026 PyErr_SetFromErrno(PyExc_OSError);
1027 return -1;
1028 }
1029
1030#ifdef MS_WINDOWS
1031 handle = (HANDLE)_get_osfhandle(fd);
1032 if (handle == INVALID_HANDLE_VALUE) {
1033 PyErr_SetFromWindowsErr(0);
1034 return -1;
1035 }
1036
1037 /* get the file type, ignore the error if it failed */
1038 ftype = GetFileType(handle);
1039
1040 Py_BEGIN_ALLOW_THREADS
1041 fd = dup(fd);
1042 Py_END_ALLOW_THREADS
1043 if (fd < 0) {
1044 PyErr_SetFromErrno(PyExc_OSError);
1045 return -1;
1046 }
1047
1048 /* Character files like console cannot be make non-inheritable */
1049 if (ftype != FILE_TYPE_CHAR) {
1050 if (_Py_set_inheritable(fd, 0, NULL) < 0) {
1051 close(fd);
1052 return -1;
1053 }
1054 }
1055#elif defined(HAVE_FCNTL_H) && defined(F_DUPFD_CLOEXEC)
1056 Py_BEGIN_ALLOW_THREADS
1057 fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
1058 Py_END_ALLOW_THREADS
1059 if (fd < 0) {
1060 PyErr_SetFromErrno(PyExc_OSError);
1061 return -1;
1062 }
1063
1064#else
1065 Py_BEGIN_ALLOW_THREADS
1066 fd = dup(fd);
1067 Py_END_ALLOW_THREADS
1068 if (fd < 0) {
1069 PyErr_SetFromErrno(PyExc_OSError);
1070 return -1;
1071 }
1072
1073 if (_Py_set_inheritable(fd, 0, NULL) < 0) {
1074 close(fd);
1075 return -1;
1076 }
1077#endif
1078 return fd;
1079}
1080
Victor Stinner1db9e7b2014-07-29 22:32:47 +02001081#ifndef MS_WINDOWS
1082/* Get the blocking mode of the file descriptor.
1083 Return 0 if the O_NONBLOCK flag is set, 1 if the flag is cleared,
1084 raise an exception and return -1 on error. */
1085int
1086_Py_get_blocking(int fd)
1087{
1088 int flags = fcntl(fd, F_GETFL, 0);
1089 if (flags < 0) {
1090 PyErr_SetFromErrno(PyExc_OSError);
1091 return -1;
1092 }
1093
1094 return !(flags & O_NONBLOCK);
1095}
1096
1097/* Set the blocking mode of the specified file descriptor.
1098
1099 Set the O_NONBLOCK flag if blocking is False, clear the O_NONBLOCK flag
1100 otherwise.
1101
1102 Return 0 on success, raise an exception and return -1 on error. */
1103int
1104_Py_set_blocking(int fd, int blocking)
1105{
1106#if defined(HAVE_SYS_IOCTL_H) && defined(FIONBIO)
1107 int arg = !blocking;
1108 if (ioctl(fd, FIONBIO, &arg) < 0)
1109 goto error;
1110#else
1111 int flags, res;
1112
1113 flags = fcntl(fd, F_GETFL, 0);
1114 if (flags < 0)
1115 goto error;
1116
1117 if (blocking)
1118 flags = flags & (~O_NONBLOCK);
1119 else
1120 flags = flags | O_NONBLOCK;
1121
1122 res = fcntl(fd, F_SETFL, flags);
1123 if (res < 0)
1124 goto error;
1125#endif
1126 return 0;
1127
1128error:
1129 PyErr_SetFromErrno(PyExc_OSError);
1130 return -1;
1131}
1132#endif
1133