blob: 227e92a79ef5b20e5ea973148ea7a47fbba633ef [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;
223
Victor Stinner65bf9cf2013-07-07 16:35:54 +0200224 res = PyMem_RawMalloc((strlen(arg)+1)*sizeof(wchar_t));
Victor Stinnerd45c7f82012-12-04 01:34:47 +0100225 if (!res)
226 return NULL;
227
228 in = (unsigned char*)arg;
229 out = res;
230 while(*in)
231 if(*in < 128)
232 *out++ = *in++;
233 else
234 *out++ = 0xdc00 + *in++;
235 *out = 0;
236 if (size != NULL)
237 *size = out - res;
238 return res;
239}
240#endif
241
Victor Stinner4e314432010-10-07 21:45:39 +0000242
243/* Decode a byte string from the locale encoding with the
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200244 surrogateescape error handler: undecodable bytes are decoded as characters
245 in range U+DC80..U+DCFF. If a byte sequence can be decoded as a surrogate
Victor Stinner4e314432010-10-07 21:45:39 +0000246 character, escape the bytes using the surrogateescape error handler instead
247 of decoding them.
248
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200249 Return a pointer to a newly allocated wide character string, use
250 PyMem_RawFree() to free the memory. If size is not NULL, write the number of
251 wide characters excluding the null character into *size
Victor Stinner4e314432010-10-07 21:45:39 +0000252
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200253 Return NULL on decoding error or memory allocation error. If *size* is not
254 NULL, *size is set to (size_t)-1 on memory error or set to (size_t)-2 on
255 decoding error.
Victor Stinner19de4c32010-11-08 23:30:46 +0000256
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200257 Decoding errors should never happen, unless there is a bug in the C
258 library.
259
260 Use the Py_EncodeLocale() function to encode the character string back to a
261 byte string. */
Victor Stinner4e314432010-10-07 21:45:39 +0000262wchar_t*
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200263Py_DecodeLocale(const char* arg, size_t *size)
Victor Stinner4e314432010-10-07 21:45:39 +0000264{
Victor Stinnere2623772012-11-12 23:04:02 +0100265#ifdef __APPLE__
266 wchar_t *wstr;
267 wstr = _Py_DecodeUTF8_surrogateescape(arg, strlen(arg));
Victor Stinner0d92c4f2012-11-12 23:32:21 +0100268 if (size != NULL) {
269 if (wstr != NULL)
270 *size = wcslen(wstr);
271 else
272 *size = (size_t)-1;
273 }
Victor Stinnere2623772012-11-12 23:04:02 +0100274 return wstr;
275#else
Victor Stinner4e314432010-10-07 21:45:39 +0000276 wchar_t *res;
Victor Stinnerd45c7f82012-12-04 01:34:47 +0100277 size_t argsize;
Victor Stinner4e314432010-10-07 21:45:39 +0000278 size_t count;
Victor Stinner313f10c2013-05-07 23:48:56 +0200279#ifdef HAVE_MBRTOWC
Victor Stinner4e314432010-10-07 21:45:39 +0000280 unsigned char *in;
281 wchar_t *out;
Victor Stinner4e314432010-10-07 21:45:39 +0000282 mbstate_t mbs;
283#endif
Victor Stinnerd45c7f82012-12-04 01:34:47 +0100284
285#ifndef MS_WINDOWS
286 if (force_ascii == -1)
287 force_ascii = check_force_ascii();
288
289 if (force_ascii) {
290 /* force ASCII encoding to workaround mbstowcs() issue */
291 res = decode_ascii_surrogateescape(arg, size);
292 if (res == NULL)
293 goto oom;
294 return res;
295 }
296#endif
297
298#ifdef HAVE_BROKEN_MBSTOWCS
299 /* Some platforms have a broken implementation of
300 * mbstowcs which does not count the characters that
301 * would result from conversion. Use an upper bound.
302 */
303 argsize = strlen(arg);
304#else
305 argsize = mbstowcs(NULL, arg, 0);
306#endif
Victor Stinner4e314432010-10-07 21:45:39 +0000307 if (argsize != (size_t)-1) {
Victor Stinner1a7425f2013-07-07 16:25:15 +0200308 res = (wchar_t *)PyMem_RawMalloc((argsize+1)*sizeof(wchar_t));
Victor Stinner4e314432010-10-07 21:45:39 +0000309 if (!res)
310 goto oom;
311 count = mbstowcs(res, arg, argsize+1);
312 if (count != (size_t)-1) {
313 wchar_t *tmp;
314 /* Only use the result if it contains no
315 surrogate characters. */
316 for (tmp = res; *tmp != 0 &&
Victor Stinner76df43d2012-10-30 01:42:39 +0100317 !Py_UNICODE_IS_SURROGATE(*tmp); tmp++)
Victor Stinner4e314432010-10-07 21:45:39 +0000318 ;
Victor Stinner168e1172010-10-16 23:16:16 +0000319 if (*tmp == 0) {
320 if (size != NULL)
321 *size = count;
Victor Stinner4e314432010-10-07 21:45:39 +0000322 return res;
Victor Stinner168e1172010-10-16 23:16:16 +0000323 }
Victor Stinner4e314432010-10-07 21:45:39 +0000324 }
Victor Stinner1a7425f2013-07-07 16:25:15 +0200325 PyMem_RawFree(res);
Victor Stinner4e314432010-10-07 21:45:39 +0000326 }
327 /* Conversion failed. Fall back to escaping with surrogateescape. */
328#ifdef HAVE_MBRTOWC
329 /* Try conversion with mbrtwoc (C99), and escape non-decodable bytes. */
330
331 /* Overallocate; as multi-byte characters are in the argument, the
332 actual output could use less memory. */
333 argsize = strlen(arg) + 1;
Victor Stinner1a7425f2013-07-07 16:25:15 +0200334 res = (wchar_t*)PyMem_RawMalloc(argsize*sizeof(wchar_t));
Victor Stinner19de4c32010-11-08 23:30:46 +0000335 if (!res)
336 goto oom;
Victor Stinner4e314432010-10-07 21:45:39 +0000337 in = (unsigned char*)arg;
338 out = res;
339 memset(&mbs, 0, sizeof mbs);
340 while (argsize) {
341 size_t converted = mbrtowc(out, (char*)in, argsize, &mbs);
342 if (converted == 0)
343 /* Reached end of string; null char stored. */
344 break;
345 if (converted == (size_t)-2) {
346 /* Incomplete character. This should never happen,
347 since we provide everything that we have -
348 unless there is a bug in the C library, or I
349 misunderstood how mbrtowc works. */
Victor Stinner1a7425f2013-07-07 16:25:15 +0200350 PyMem_RawFree(res);
Victor Stinneraf02e1c2011-12-16 23:56:01 +0100351 if (size != NULL)
352 *size = (size_t)-2;
Victor Stinner4e314432010-10-07 21:45:39 +0000353 return NULL;
354 }
355 if (converted == (size_t)-1) {
356 /* Conversion error. Escape as UTF-8b, and start over
357 in the initial shift state. */
358 *out++ = 0xdc00 + *in++;
359 argsize--;
360 memset(&mbs, 0, sizeof mbs);
361 continue;
362 }
Victor Stinner76df43d2012-10-30 01:42:39 +0100363 if (Py_UNICODE_IS_SURROGATE(*out)) {
Victor Stinner4e314432010-10-07 21:45:39 +0000364 /* Surrogate character. Escape the original
365 byte sequence with surrogateescape. */
366 argsize -= converted;
367 while (converted--)
368 *out++ = 0xdc00 + *in++;
369 continue;
370 }
371 /* successfully converted some bytes */
372 in += converted;
373 argsize -= converted;
374 out++;
375 }
Victor Stinnerd45c7f82012-12-04 01:34:47 +0100376 if (size != NULL)
377 *size = out - res;
Victor Stinnere2623772012-11-12 23:04:02 +0100378#else /* HAVE_MBRTOWC */
Victor Stinner4e314432010-10-07 21:45:39 +0000379 /* Cannot use C locale for escaping; manually escape as if charset
380 is ASCII (i.e. escape all bytes > 128. This will still roundtrip
381 correctly in the locale's charset, which must be an ASCII superset. */
Victor Stinnerd45c7f82012-12-04 01:34:47 +0100382 res = decode_ascii_surrogateescape(arg, size);
383 if (res == NULL)
Victor Stinneraf02e1c2011-12-16 23:56:01 +0100384 goto oom;
Victor Stinnere2623772012-11-12 23:04:02 +0100385#endif /* HAVE_MBRTOWC */
Victor Stinner4e314432010-10-07 21:45:39 +0000386 return res;
387oom:
Victor Stinneraf02e1c2011-12-16 23:56:01 +0100388 if (size != NULL)
389 *size = (size_t)-1;
Victor Stinner4e314432010-10-07 21:45:39 +0000390 return NULL;
Victor Stinnere2623772012-11-12 23:04:02 +0100391#endif /* __APPLE__ */
Victor Stinner4e314432010-10-07 21:45:39 +0000392}
393
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200394/* Encode a wide character string to the locale encoding with the
395 surrogateescape error handler: surrogate characters in the range
396 U+DC80..U+DCFF are converted to bytes 0x80..0xFF.
Victor Stinner4e314432010-10-07 21:45:39 +0000397
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200398 Return a pointer to a newly allocated byte string, use PyMem_Free() to free
399 the memory. Return NULL on encoding or memory allocation error.
Victor Stinner4e314432010-10-07 21:45:39 +0000400
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200401 If error_pos is not NULL, *error_pos is set to the index of the invalid
402 character on encoding error, or set to (size_t)-1 otherwise.
Victor Stinner2f02a512010-11-08 22:43:46 +0000403
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200404 Use the Py_DecodeLocale() function to decode the bytes string back to a wide
405 character string. */
Victor Stinner4e314432010-10-07 21:45:39 +0000406char*
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200407Py_EncodeLocale(const wchar_t *text, size_t *error_pos)
Victor Stinner4e314432010-10-07 21:45:39 +0000408{
Victor Stinnere2623772012-11-12 23:04:02 +0100409#ifdef __APPLE__
410 Py_ssize_t len;
411 PyObject *unicode, *bytes = NULL;
412 char *cpath;
413
414 unicode = PyUnicode_FromWideChar(text, wcslen(text));
Victor Stinner0d92c4f2012-11-12 23:32:21 +0100415 if (unicode == NULL)
Victor Stinnere2623772012-11-12 23:04:02 +0100416 return NULL;
Victor Stinnere2623772012-11-12 23:04:02 +0100417
418 bytes = _PyUnicode_AsUTF8String(unicode, "surrogateescape");
419 Py_DECREF(unicode);
420 if (bytes == NULL) {
421 PyErr_Clear();
Victor Stinner0d92c4f2012-11-12 23:32:21 +0100422 if (error_pos != NULL)
423 *error_pos = (size_t)-1;
Victor Stinnere2623772012-11-12 23:04:02 +0100424 return NULL;
425 }
426
427 len = PyBytes_GET_SIZE(bytes);
428 cpath = PyMem_Malloc(len+1);
429 if (cpath == NULL) {
Victor Stinner0d92c4f2012-11-12 23:32:21 +0100430 PyErr_Clear();
Victor Stinnere2623772012-11-12 23:04:02 +0100431 Py_DECREF(bytes);
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 memcpy(cpath, PyBytes_AsString(bytes), len + 1);
437 Py_DECREF(bytes);
438 return cpath;
439#else /* __APPLE__ */
Victor Stinner4e314432010-10-07 21:45:39 +0000440 const size_t len = wcslen(text);
441 char *result = NULL, *bytes = NULL;
442 size_t i, size, converted;
443 wchar_t c, buf[2];
444
Victor Stinnerd45c7f82012-12-04 01:34:47 +0100445#ifndef MS_WINDOWS
446 if (force_ascii == -1)
447 force_ascii = check_force_ascii();
448
449 if (force_ascii)
450 return encode_ascii_surrogateescape(text, error_pos);
451#endif
452
Victor Stinner4e314432010-10-07 21:45:39 +0000453 /* The function works in two steps:
454 1. compute the length of the output buffer in bytes (size)
455 2. outputs the bytes */
456 size = 0;
457 buf[1] = 0;
458 while (1) {
459 for (i=0; i < len; i++) {
460 c = text[i];
461 if (c >= 0xdc80 && c <= 0xdcff) {
462 /* UTF-8b surrogate */
463 if (bytes != NULL) {
464 *bytes++ = c - 0xdc00;
465 size--;
466 }
467 else
468 size++;
469 continue;
470 }
471 else {
472 buf[0] = c;
473 if (bytes != NULL)
474 converted = wcstombs(bytes, buf, size);
475 else
476 converted = wcstombs(NULL, buf, 0);
477 if (converted == (size_t)-1) {
478 if (result != NULL)
479 PyMem_Free(result);
Victor Stinner2f02a512010-11-08 22:43:46 +0000480 if (error_pos != NULL)
481 *error_pos = i;
Victor Stinner4e314432010-10-07 21:45:39 +0000482 return NULL;
483 }
484 if (bytes != NULL) {
485 bytes += converted;
486 size -= converted;
487 }
488 else
489 size += converted;
490 }
491 }
492 if (result != NULL) {
Victor Stinnerd45c7f82012-12-04 01:34:47 +0100493 *bytes = '\0';
Victor Stinner4e314432010-10-07 21:45:39 +0000494 break;
495 }
496
497 size += 1; /* nul byte at the end */
498 result = PyMem_Malloc(size);
Victor Stinner0d92c4f2012-11-12 23:32:21 +0100499 if (result == NULL) {
500 if (error_pos != NULL)
501 *error_pos = (size_t)-1;
Victor Stinner4e314432010-10-07 21:45:39 +0000502 return NULL;
Victor Stinner0d92c4f2012-11-12 23:32:21 +0100503 }
Victor Stinner4e314432010-10-07 21:45:39 +0000504 bytes = result;
505 }
506 return result;
Victor Stinnere2623772012-11-12 23:04:02 +0100507#endif /* __APPLE__ */
Victor Stinner4e314432010-10-07 21:45:39 +0000508}
509
Victor Stinner4e314432010-10-07 21:45:39 +0000510/* In principle, this should use HAVE__WSTAT, and _wstat
511 should be detected by autoconf. However, no current
512 POSIX system provides that function, so testing for
513 it is pointless.
514 Not sure whether the MS_WINDOWS guards are necessary:
515 perhaps for cygwin/mingw builds?
516*/
Victor Stinnerb306d752010-10-07 22:09:40 +0000517#if defined(HAVE_STAT) && !defined(MS_WINDOWS)
Victor Stinner6672d0c2010-10-07 22:53:43 +0000518
519/* Get file status. Encode the path to the locale encoding. */
520
Victor Stinnerb306d752010-10-07 22:09:40 +0000521int
522_Py_wstat(const wchar_t* path, struct stat *buf)
523{
Victor Stinner4e314432010-10-07 21:45:39 +0000524 int err;
525 char *fname;
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200526 fname = Py_EncodeLocale(path, NULL);
Victor Stinner4e314432010-10-07 21:45:39 +0000527 if (fname == NULL) {
528 errno = EINVAL;
529 return -1;
530 }
531 err = stat(fname, buf);
532 PyMem_Free(fname);
533 return err;
Victor Stinner4e314432010-10-07 21:45:39 +0000534}
535#endif
536
Victor Stinnerd45c7f82012-12-04 01:34:47 +0100537#ifdef HAVE_STAT
538
Victor Stinner6672d0c2010-10-07 22:53:43 +0000539/* Call _wstat() on Windows, or encode the path to the filesystem encoding and
540 call stat() otherwise. Only fill st_mode attribute on Windows.
541
Victor Stinnerbd0850b2011-12-18 20:47:30 +0100542 Return 0 on success, -1 on _wstat() / stat() error, -2 if an exception was
543 raised. */
Victor Stinner4e314432010-10-07 21:45:39 +0000544
545int
Victor Stinnera4a75952010-10-07 22:23:10 +0000546_Py_stat(PyObject *path, struct stat *statbuf)
Victor Stinner4e314432010-10-07 21:45:39 +0000547{
548#ifdef MS_WINDOWS
Victor Stinner4e314432010-10-07 21:45:39 +0000549 int err;
550 struct _stat wstatbuf;
Victor Stinneree587ea2011-11-17 00:51:38 +0100551 wchar_t *wpath;
Victor Stinner4e314432010-10-07 21:45:39 +0000552
Victor Stinneree587ea2011-11-17 00:51:38 +0100553 wpath = PyUnicode_AsUnicode(path);
554 if (wpath == NULL)
Victor Stinnerbd0850b2011-12-18 20:47:30 +0100555 return -2;
Victor Stinneree587ea2011-11-17 00:51:38 +0100556 err = _wstat(wpath, &wstatbuf);
Victor Stinner4e314432010-10-07 21:45:39 +0000557 if (!err)
558 statbuf->st_mode = wstatbuf.st_mode;
559 return err;
560#else
561 int ret;
Victor Stinnera4a75952010-10-07 22:23:10 +0000562 PyObject *bytes = PyUnicode_EncodeFSDefault(path);
Victor Stinner4e314432010-10-07 21:45:39 +0000563 if (bytes == NULL)
Victor Stinnerbd0850b2011-12-18 20:47:30 +0100564 return -2;
Victor Stinner4e314432010-10-07 21:45:39 +0000565 ret = stat(PyBytes_AS_STRING(bytes), statbuf);
566 Py_DECREF(bytes);
567 return ret;
568#endif
569}
570
Victor Stinnerd45c7f82012-12-04 01:34:47 +0100571#endif
572
Antoine Pitrou409b5382013-10-12 22:41:17 +0200573static int
Victor Stinnerdaf45552013-08-28 00:53:59 +0200574get_inheritable(int fd, int raise)
575{
576#ifdef MS_WINDOWS
577 HANDLE handle;
578 DWORD flags;
Victor Stinner6672d0c2010-10-07 22:53:43 +0000579
Victor Stinnerdaf45552013-08-28 00:53:59 +0200580 if (!_PyVerify_fd(fd)) {
581 if (raise)
582 PyErr_SetFromErrno(PyExc_OSError);
583 return -1;
584 }
585
586 handle = (HANDLE)_get_osfhandle(fd);
587 if (handle == INVALID_HANDLE_VALUE) {
588 if (raise)
589 PyErr_SetFromWindowsErr(0);
590 return -1;
591 }
592
593 if (!GetHandleInformation(handle, &flags)) {
594 if (raise)
595 PyErr_SetFromWindowsErr(0);
596 return -1;
597 }
598
599 return (flags & HANDLE_FLAG_INHERIT);
600#else
601 int flags;
602
603 flags = fcntl(fd, F_GETFD, 0);
604 if (flags == -1) {
605 if (raise)
606 PyErr_SetFromErrno(PyExc_OSError);
607 return -1;
608 }
609 return !(flags & FD_CLOEXEC);
610#endif
611}
612
613/* Get the inheritable flag of the specified file descriptor.
Victor Stinnerb034eee2013-09-07 10:36:04 +0200614 Return 1 if the file descriptor can be inherited, 0 if it cannot,
Victor Stinnerdaf45552013-08-28 00:53:59 +0200615 raise an exception and return -1 on error. */
616int
617_Py_get_inheritable(int fd)
618{
619 return get_inheritable(fd, 1);
620}
621
622static int
623set_inheritable(int fd, int inheritable, int raise, int *atomic_flag_works)
624{
625#ifdef MS_WINDOWS
626 HANDLE handle;
627 DWORD flags;
628#elif defined(HAVE_SYS_IOCTL_H) && defined(FIOCLEX) && defined(FIONCLEX)
629 int request;
630 int err;
631#elif defined(HAVE_FCNTL_H)
632 int flags;
633 int res;
634#endif
635
636 /* atomic_flag_works can only be used to make the file descriptor
637 non-inheritable */
638 assert(!(atomic_flag_works != NULL && inheritable));
639
640 if (atomic_flag_works != NULL && !inheritable) {
641 if (*atomic_flag_works == -1) {
642 int inheritable = get_inheritable(fd, raise);
643 if (inheritable == -1)
644 return -1;
645 *atomic_flag_works = !inheritable;
646 }
647
648 if (*atomic_flag_works)
649 return 0;
650 }
651
652#ifdef MS_WINDOWS
653 if (!_PyVerify_fd(fd)) {
654 if (raise)
655 PyErr_SetFromErrno(PyExc_OSError);
656 return -1;
657 }
658
659 handle = (HANDLE)_get_osfhandle(fd);
660 if (handle == INVALID_HANDLE_VALUE) {
661 if (raise)
662 PyErr_SetFromWindowsErr(0);
663 return -1;
664 }
665
666 if (inheritable)
667 flags = HANDLE_FLAG_INHERIT;
668 else
669 flags = 0;
670 if (!SetHandleInformation(handle, HANDLE_FLAG_INHERIT, flags)) {
671 if (raise)
672 PyErr_SetFromWindowsErr(0);
673 return -1;
674 }
675 return 0;
676
677#elif defined(HAVE_SYS_IOCTL_H) && defined(FIOCLEX) && defined(FIONCLEX)
678 if (inheritable)
679 request = FIONCLEX;
680 else
681 request = FIOCLEX;
Stefan Krah49d04792013-11-14 15:35:47 +0100682 err = ioctl(fd, request, NULL);
Victor Stinnerdaf45552013-08-28 00:53:59 +0200683 if (err) {
684 if (raise)
685 PyErr_SetFromErrno(PyExc_OSError);
686 return -1;
687 }
688 return 0;
689
690#else
691 flags = fcntl(fd, F_GETFD);
692 if (flags < 0) {
693 if (raise)
694 PyErr_SetFromErrno(PyExc_OSError);
695 return -1;
696 }
697
698 if (inheritable)
699 flags &= ~FD_CLOEXEC;
700 else
701 flags |= FD_CLOEXEC;
702 res = fcntl(fd, F_SETFD, flags);
703 if (res < 0) {
704 if (raise)
705 PyErr_SetFromErrno(PyExc_OSError);
706 return -1;
707 }
708 return 0;
709#endif
710}
711
712/* Make the file descriptor non-inheritable.
Victor Stinnerb034eee2013-09-07 10:36:04 +0200713 Return 0 on success, set errno and return -1 on error. */
Victor Stinnerdaf45552013-08-28 00:53:59 +0200714static int
715make_non_inheritable(int fd)
716{
717 return set_inheritable(fd, 0, 0, NULL);
718}
719
720/* Set the inheritable flag of the specified file descriptor.
721 On success: return 0, on error: raise an exception if raise is nonzero
722 and return -1.
723
724 If atomic_flag_works is not NULL:
725
726 * if *atomic_flag_works==-1, check if the inheritable is set on the file
727 descriptor: if yes, set *atomic_flag_works to 1, otherwise set to 0 and
728 set the inheritable flag
729 * if *atomic_flag_works==1: do nothing
730 * if *atomic_flag_works==0: set inheritable flag to False
731
732 Set atomic_flag_works to NULL if no atomic flag was used to create the
733 file descriptor.
734
735 atomic_flag_works can only be used to make a file descriptor
736 non-inheritable: atomic_flag_works must be NULL if inheritable=1. */
737int
738_Py_set_inheritable(int fd, int inheritable, int *atomic_flag_works)
739{
740 return set_inheritable(fd, inheritable, 1, atomic_flag_works);
741}
742
743/* Open a file with the specified flags (wrapper to open() function).
744 The file descriptor is created non-inheritable. */
745int
746_Py_open(const char *pathname, int flags)
747{
748 int fd;
749#ifdef MS_WINDOWS
750 fd = open(pathname, flags | O_NOINHERIT);
751 if (fd < 0)
752 return fd;
753#else
754
755 int *atomic_flag_works;
756#ifdef O_CLOEXEC
757 atomic_flag_works = &_Py_open_cloexec_works;
758 flags |= O_CLOEXEC;
759#else
760 atomic_flag_works = NULL;
761#endif
762 fd = open(pathname, flags);
763 if (fd < 0)
764 return fd;
765
766 if (set_inheritable(fd, 0, 0, atomic_flag_works) < 0) {
767 close(fd);
768 return -1;
769 }
770#endif /* !MS_WINDOWS */
771 return fd;
772}
773
774/* Open a file. Use _wfopen() on Windows, encode the path to the locale
775 encoding and use fopen() otherwise. The file descriptor is created
776 non-inheritable. */
Victor Stinner4e314432010-10-07 21:45:39 +0000777FILE *
778_Py_wfopen(const wchar_t *path, const wchar_t *mode)
779{
Victor Stinner4e314432010-10-07 21:45:39 +0000780 FILE *f;
Victor Stinnerdaf45552013-08-28 00:53:59 +0200781#ifndef MS_WINDOWS
Victor Stinner4e314432010-10-07 21:45:39 +0000782 char *cpath;
783 char cmode[10];
784 size_t r;
785 r = wcstombs(cmode, mode, 10);
786 if (r == (size_t)-1 || r >= 10) {
787 errno = EINVAL;
788 return NULL;
789 }
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200790 cpath = Py_EncodeLocale(path, NULL);
Victor Stinner4e314432010-10-07 21:45:39 +0000791 if (cpath == NULL)
792 return NULL;
793 f = fopen(cpath, cmode);
794 PyMem_Free(cpath);
Victor Stinner4e314432010-10-07 21:45:39 +0000795#else
Victor Stinnerdaf45552013-08-28 00:53:59 +0200796 f = _wfopen(path, mode);
Victor Stinner4e314432010-10-07 21:45:39 +0000797#endif
Victor Stinnerdaf45552013-08-28 00:53:59 +0200798 if (f == NULL)
799 return NULL;
800 if (make_non_inheritable(fileno(f)) < 0) {
801 fclose(f);
802 return NULL;
803 }
804 return f;
Victor Stinner4e314432010-10-07 21:45:39 +0000805}
806
Victor Stinnerdaf45552013-08-28 00:53:59 +0200807/* Wrapper to fopen(). The file descriptor is created non-inheritable. */
808FILE*
809_Py_fopen(const char *pathname, const char *mode)
810{
811 FILE *f = fopen(pathname, mode);
812 if (f == NULL)
813 return NULL;
814 if (make_non_inheritable(fileno(f)) < 0) {
815 fclose(f);
816 return NULL;
817 }
818 return f;
819}
820
821/* Open a file. Call _wfopen() on Windows, or encode the path to the filesystem
822 encoding and call fopen() otherwise. The file descriptor is created
823 non-inheritable.
Victor Stinner6672d0c2010-10-07 22:53:43 +0000824
825 Return the new file object on success, or NULL if the file cannot be open or
Victor Stinnerdaf45552013-08-28 00:53:59 +0200826 (if PyErr_Occurred()) on unicode error. */
Victor Stinner4e314432010-10-07 21:45:39 +0000827FILE*
Victor Stinnerdaf45552013-08-28 00:53:59 +0200828_Py_fopen_obj(PyObject *path, const char *mode)
Victor Stinner4e314432010-10-07 21:45:39 +0000829{
Victor Stinnerdaf45552013-08-28 00:53:59 +0200830 FILE *f;
Victor Stinner4e314432010-10-07 21:45:39 +0000831#ifdef MS_WINDOWS
Victor Stinneree587ea2011-11-17 00:51:38 +0100832 wchar_t *wpath;
Victor Stinner4e314432010-10-07 21:45:39 +0000833 wchar_t wmode[10];
834 int usize;
Victor Stinner4e314432010-10-07 21:45:39 +0000835
Antoine Pitrou0e576f12011-12-22 10:03:38 +0100836 if (!PyUnicode_Check(path)) {
837 PyErr_Format(PyExc_TypeError,
838 "str file path expected under Windows, got %R",
839 Py_TYPE(path));
840 return NULL;
841 }
Victor Stinneree587ea2011-11-17 00:51:38 +0100842 wpath = PyUnicode_AsUnicode(path);
843 if (wpath == NULL)
844 return NULL;
845
Victor Stinner4e314432010-10-07 21:45:39 +0000846 usize = MultiByteToWideChar(CP_ACP, 0, mode, -1, wmode, sizeof(wmode));
847 if (usize == 0)
848 return NULL;
849
Victor Stinnerdaf45552013-08-28 00:53:59 +0200850 f = _wfopen(wpath, wmode);
Victor Stinner4e314432010-10-07 21:45:39 +0000851#else
Antoine Pitrou2b1cc892011-12-19 18:19:06 +0100852 PyObject *bytes;
853 if (!PyUnicode_FSConverter(path, &bytes))
Victor Stinner4e314432010-10-07 21:45:39 +0000854 return NULL;
855 f = fopen(PyBytes_AS_STRING(bytes), mode);
856 Py_DECREF(bytes);
Victor Stinner4e314432010-10-07 21:45:39 +0000857#endif
Victor Stinnerdaf45552013-08-28 00:53:59 +0200858 if (f == NULL)
859 return NULL;
860 if (make_non_inheritable(fileno(f)) < 0) {
861 fclose(f);
862 return NULL;
863 }
864 return f;
Victor Stinner4e314432010-10-07 21:45:39 +0000865}
866
867#ifdef HAVE_READLINK
Victor Stinner6672d0c2010-10-07 22:53:43 +0000868
869/* Read value of symbolic link. Encode the path to the locale encoding, decode
Victor Stinneraf02e1c2011-12-16 23:56:01 +0100870 the result from the locale encoding. Return -1 on error. */
Victor Stinner6672d0c2010-10-07 22:53:43 +0000871
Victor Stinner4e314432010-10-07 21:45:39 +0000872int
873_Py_wreadlink(const wchar_t *path, wchar_t *buf, size_t bufsiz)
874{
875 char *cpath;
Victor Stinnerb11d6cb2013-11-15 18:14:11 +0100876 char cbuf[MAXPATHLEN];
Victor Stinner3f711f42010-10-16 22:47:37 +0000877 wchar_t *wbuf;
Victor Stinner4e314432010-10-07 21:45:39 +0000878 int res;
879 size_t r1;
880
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200881 cpath = Py_EncodeLocale(path, NULL);
Victor Stinner4e314432010-10-07 21:45:39 +0000882 if (cpath == NULL) {
883 errno = EINVAL;
884 return -1;
885 }
Victor Stinnerb11d6cb2013-11-15 18:14:11 +0100886 res = (int)readlink(cpath, cbuf, Py_ARRAY_LENGTH(cbuf));
Victor Stinner4e314432010-10-07 21:45:39 +0000887 PyMem_Free(cpath);
888 if (res == -1)
889 return -1;
Victor Stinnerb11d6cb2013-11-15 18:14:11 +0100890 if (res == Py_ARRAY_LENGTH(cbuf)) {
Victor Stinner4e314432010-10-07 21:45:39 +0000891 errno = EINVAL;
892 return -1;
893 }
894 cbuf[res] = '\0'; /* buf will be null terminated */
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200895 wbuf = Py_DecodeLocale(cbuf, &r1);
Victor Stinner350147b2010-10-16 22:52:09 +0000896 if (wbuf == NULL) {
897 errno = EINVAL;
898 return -1;
899 }
Victor Stinner3f711f42010-10-16 22:47:37 +0000900 if (bufsiz <= r1) {
Victor Stinner1a7425f2013-07-07 16:25:15 +0200901 PyMem_RawFree(wbuf);
Victor Stinner4e314432010-10-07 21:45:39 +0000902 errno = EINVAL;
903 return -1;
904 }
Victor Stinner3f711f42010-10-16 22:47:37 +0000905 wcsncpy(buf, wbuf, bufsiz);
Victor Stinner1a7425f2013-07-07 16:25:15 +0200906 PyMem_RawFree(wbuf);
Victor Stinner4e314432010-10-07 21:45:39 +0000907 return (int)r1;
908}
909#endif
910
911#ifdef HAVE_REALPATH
Victor Stinner6672d0c2010-10-07 22:53:43 +0000912
913/* Return the canonicalized absolute pathname. Encode path to the locale
Victor Stinneraf02e1c2011-12-16 23:56:01 +0100914 encoding, decode the result from the locale encoding.
915 Return NULL on error. */
Victor Stinner6672d0c2010-10-07 22:53:43 +0000916
Victor Stinner4e314432010-10-07 21:45:39 +0000917wchar_t*
Victor Stinner015f4d82010-10-07 22:29:53 +0000918_Py_wrealpath(const wchar_t *path,
919 wchar_t *resolved_path, size_t resolved_path_size)
Victor Stinner4e314432010-10-07 21:45:39 +0000920{
921 char *cpath;
Victor Stinnerb11d6cb2013-11-15 18:14:11 +0100922 char cresolved_path[MAXPATHLEN];
Victor Stinner0a1b8cb2010-10-16 22:55:47 +0000923 wchar_t *wresolved_path;
Victor Stinner4e314432010-10-07 21:45:39 +0000924 char *res;
925 size_t r;
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200926 cpath = Py_EncodeLocale(path, NULL);
Victor Stinner4e314432010-10-07 21:45:39 +0000927 if (cpath == NULL) {
928 errno = EINVAL;
929 return NULL;
930 }
931 res = realpath(cpath, cresolved_path);
932 PyMem_Free(cpath);
933 if (res == NULL)
934 return NULL;
Victor Stinner0a1b8cb2010-10-16 22:55:47 +0000935
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200936 wresolved_path = Py_DecodeLocale(cresolved_path, &r);
Victor Stinner0a1b8cb2010-10-16 22:55:47 +0000937 if (wresolved_path == NULL) {
Victor Stinner4e314432010-10-07 21:45:39 +0000938 errno = EINVAL;
939 return NULL;
940 }
Victor Stinner0a1b8cb2010-10-16 22:55:47 +0000941 if (resolved_path_size <= r) {
Victor Stinner1a7425f2013-07-07 16:25:15 +0200942 PyMem_RawFree(wresolved_path);
Victor Stinner0a1b8cb2010-10-16 22:55:47 +0000943 errno = EINVAL;
944 return NULL;
945 }
946 wcsncpy(resolved_path, wresolved_path, resolved_path_size);
Victor Stinner1a7425f2013-07-07 16:25:15 +0200947 PyMem_RawFree(wresolved_path);
Victor Stinner4e314432010-10-07 21:45:39 +0000948 return resolved_path;
949}
950#endif
951
Victor Stinnerf4061da2010-10-14 12:37:19 +0000952/* Get the current directory. size is the buffer size in wide characters
Victor Stinneraf02e1c2011-12-16 23:56:01 +0100953 including the null character. Decode the path from the locale encoding.
954 Return NULL on error. */
Victor Stinner6672d0c2010-10-07 22:53:43 +0000955
Victor Stinner4e314432010-10-07 21:45:39 +0000956wchar_t*
957_Py_wgetcwd(wchar_t *buf, size_t size)
958{
959#ifdef MS_WINDOWS
Victor Stinner56785ea2013-06-05 00:46:29 +0200960 int isize = (int)Py_MIN(size, INT_MAX);
961 return _wgetcwd(buf, isize);
Victor Stinner4e314432010-10-07 21:45:39 +0000962#else
Victor Stinnerb11d6cb2013-11-15 18:14:11 +0100963 char fname[MAXPATHLEN];
Victor Stinnerf4061da2010-10-14 12:37:19 +0000964 wchar_t *wname;
Victor Stinner168e1172010-10-16 23:16:16 +0000965 size_t len;
Victor Stinnerf4061da2010-10-14 12:37:19 +0000966
Victor Stinnerb11d6cb2013-11-15 18:14:11 +0100967 if (getcwd(fname, Py_ARRAY_LENGTH(fname)) == NULL)
Victor Stinner4e314432010-10-07 21:45:39 +0000968 return NULL;
Victor Stinnerf6a271a2014-08-01 12:28:48 +0200969 wname = Py_DecodeLocale(fname, &len);
Victor Stinnerf4061da2010-10-14 12:37:19 +0000970 if (wname == NULL)
971 return NULL;
Victor Stinner168e1172010-10-16 23:16:16 +0000972 if (size <= len) {
Victor Stinner1a7425f2013-07-07 16:25:15 +0200973 PyMem_RawFree(wname);
Victor Stinner4e314432010-10-07 21:45:39 +0000974 return NULL;
975 }
Victor Stinnerf4061da2010-10-14 12:37:19 +0000976 wcsncpy(buf, wname, size);
Victor Stinner1a7425f2013-07-07 16:25:15 +0200977 PyMem_RawFree(wname);
Victor Stinner4e314432010-10-07 21:45:39 +0000978 return buf;
979#endif
980}
981
Victor Stinnerdaf45552013-08-28 00:53:59 +0200982/* Duplicate a file descriptor. The new file descriptor is created as
983 non-inheritable. Return a new file descriptor on success, raise an OSError
984 exception and return -1 on error.
985
986 The GIL is released to call dup(). The caller must hold the GIL. */
987int
988_Py_dup(int fd)
989{
990#ifdef MS_WINDOWS
991 HANDLE handle;
992 DWORD ftype;
993#endif
994
995 if (!_PyVerify_fd(fd)) {
996 PyErr_SetFromErrno(PyExc_OSError);
997 return -1;
998 }
999
1000#ifdef MS_WINDOWS
1001 handle = (HANDLE)_get_osfhandle(fd);
1002 if (handle == INVALID_HANDLE_VALUE) {
1003 PyErr_SetFromWindowsErr(0);
1004 return -1;
1005 }
1006
1007 /* get the file type, ignore the error if it failed */
1008 ftype = GetFileType(handle);
1009
1010 Py_BEGIN_ALLOW_THREADS
1011 fd = dup(fd);
1012 Py_END_ALLOW_THREADS
1013 if (fd < 0) {
1014 PyErr_SetFromErrno(PyExc_OSError);
1015 return -1;
1016 }
1017
1018 /* Character files like console cannot be make non-inheritable */
1019 if (ftype != FILE_TYPE_CHAR) {
1020 if (_Py_set_inheritable(fd, 0, NULL) < 0) {
1021 close(fd);
1022 return -1;
1023 }
1024 }
1025#elif defined(HAVE_FCNTL_H) && defined(F_DUPFD_CLOEXEC)
1026 Py_BEGIN_ALLOW_THREADS
1027 fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
1028 Py_END_ALLOW_THREADS
1029 if (fd < 0) {
1030 PyErr_SetFromErrno(PyExc_OSError);
1031 return -1;
1032 }
1033
1034#else
1035 Py_BEGIN_ALLOW_THREADS
1036 fd = dup(fd);
1037 Py_END_ALLOW_THREADS
1038 if (fd < 0) {
1039 PyErr_SetFromErrno(PyExc_OSError);
1040 return -1;
1041 }
1042
1043 if (_Py_set_inheritable(fd, 0, NULL) < 0) {
1044 close(fd);
1045 return -1;
1046 }
1047#endif
1048 return fd;
1049}
1050
Victor Stinner1db9e7b2014-07-29 22:32:47 +02001051#ifndef MS_WINDOWS
1052/* Get the blocking mode of the file descriptor.
1053 Return 0 if the O_NONBLOCK flag is set, 1 if the flag is cleared,
1054 raise an exception and return -1 on error. */
1055int
1056_Py_get_blocking(int fd)
1057{
1058 int flags = fcntl(fd, F_GETFL, 0);
1059 if (flags < 0) {
1060 PyErr_SetFromErrno(PyExc_OSError);
1061 return -1;
1062 }
1063
1064 return !(flags & O_NONBLOCK);
1065}
1066
1067/* Set the blocking mode of the specified file descriptor.
1068
1069 Set the O_NONBLOCK flag if blocking is False, clear the O_NONBLOCK flag
1070 otherwise.
1071
1072 Return 0 on success, raise an exception and return -1 on error. */
1073int
1074_Py_set_blocking(int fd, int blocking)
1075{
1076#if defined(HAVE_SYS_IOCTL_H) && defined(FIONBIO)
1077 int arg = !blocking;
1078 if (ioctl(fd, FIONBIO, &arg) < 0)
1079 goto error;
1080#else
1081 int flags, res;
1082
1083 flags = fcntl(fd, F_GETFL, 0);
1084 if (flags < 0)
1085 goto error;
1086
1087 if (blocking)
1088 flags = flags & (~O_NONBLOCK);
1089 else
1090 flags = flags | O_NONBLOCK;
1091
1092 res = fcntl(fd, F_SETFL, flags);
1093 if (res < 0)
1094 goto error;
1095#endif
1096 return 0;
1097
1098error:
1099 PyErr_SetFromErrno(PyExc_OSError);
1100 return -1;
1101}
1102#endif
1103