1 #include "Python.h"
2 #include "pycore_fileutils.h"
3 #include "osdefs.h" // SEP
4 #include <locale.h>
5
6 #ifdef MS_WINDOWS
7 # include <malloc.h>
8 # include <windows.h>
9 extern int winerror_to_errno(int);
10 #endif
11
12 #ifdef HAVE_LANGINFO_H
13 #include <langinfo.h>
14 #endif
15
16 #ifdef HAVE_SYS_IOCTL_H
17 #include <sys/ioctl.h>
18 #endif
19
20 #ifdef HAVE_FCNTL_H
21 #include <fcntl.h>
22 #endif /* HAVE_FCNTL_H */
23
24 #ifdef O_CLOEXEC
25 /* Does open() support the O_CLOEXEC flag? Possible values:
26
27 -1: unknown
28 0: open() ignores O_CLOEXEC flag, ex: Linux kernel older than 2.6.23
29 1: open() supports O_CLOEXEC flag, close-on-exec is set
30
31 The flag is used by _Py_open(), _Py_open_noraise(), io.FileIO
32 and os.open(). */
33 int _Py_open_cloexec_works = -1;
34 #endif
35
36
37 static int
get_surrogateescape(_Py_error_handler errors,int * surrogateescape)38 get_surrogateescape(_Py_error_handler errors, int *surrogateescape)
39 {
40 switch (errors)
41 {
42 case _Py_ERROR_STRICT:
43 *surrogateescape = 0;
44 return 0;
45 case _Py_ERROR_SURROGATEESCAPE:
46 *surrogateescape = 1;
47 return 0;
48 default:
49 return -1;
50 }
51 }
52
53
54 PyObject *
_Py_device_encoding(int fd)55 _Py_device_encoding(int fd)
56 {
57 #if defined(MS_WINDOWS)
58 UINT cp;
59 #endif
60 int valid;
61 _Py_BEGIN_SUPPRESS_IPH
62 valid = isatty(fd);
63 _Py_END_SUPPRESS_IPH
64 if (!valid)
65 Py_RETURN_NONE;
66
67 #if defined(MS_WINDOWS)
68 if (fd == 0)
69 cp = GetConsoleCP();
70 else if (fd == 1 || fd == 2)
71 cp = GetConsoleOutputCP();
72 else
73 cp = 0;
74 /* GetConsoleCP() and GetConsoleOutputCP() return 0 if the application
75 has no console */
76 if (cp != 0)
77 return PyUnicode_FromFormat("cp%u", (unsigned int)cp);
78 #elif defined(CODESET)
79 {
80 char *codeset = nl_langinfo(CODESET);
81 if (codeset != NULL && codeset[0] != 0)
82 return PyUnicode_FromString(codeset);
83 }
84 #endif
85 Py_RETURN_NONE;
86 }
87
88 #if !defined(_Py_FORCE_UTF8_FS_ENCODING) && !defined(MS_WINDOWS)
89
90 #define USE_FORCE_ASCII
91
92 extern int _Py_normalize_encoding(const char *, char *, size_t);
93
94 /* Workaround FreeBSD and OpenIndiana locale encoding issue with the C locale
95 and POSIX locale. nl_langinfo(CODESET) announces an alias of the
96 ASCII encoding, whereas mbstowcs() and wcstombs() functions use the
97 ISO-8859-1 encoding. The problem is that os.fsencode() and os.fsdecode() use
98 locale.getpreferredencoding() codec. For example, if command line arguments
99 are decoded by mbstowcs() and encoded back by os.fsencode(), we get a
100 UnicodeEncodeError instead of retrieving the original byte string.
101
102 The workaround is enabled if setlocale(LC_CTYPE, NULL) returns "C",
103 nl_langinfo(CODESET) announces "ascii" (or an alias to ASCII), and at least
104 one byte in range 0x80-0xff can be decoded from the locale encoding. The
105 workaround is also enabled on error, for example if getting the locale
106 failed.
107
108 On HP-UX with the C locale or the POSIX locale, nl_langinfo(CODESET)
109 announces "roman8" but mbstowcs() uses Latin1 in practice. Force also the
110 ASCII encoding in this case.
111
112 Values of force_ascii:
113
114 1: the workaround is used: Py_EncodeLocale() uses
115 encode_ascii_surrogateescape() and Py_DecodeLocale() uses
116 decode_ascii()
117 0: the workaround is not used: Py_EncodeLocale() uses wcstombs() and
118 Py_DecodeLocale() uses mbstowcs()
119 -1: unknown, need to call check_force_ascii() to get the value
120 */
121 static int force_ascii = -1;
122
123 static int
check_force_ascii(void)124 check_force_ascii(void)
125 {
126 char *loc = setlocale(LC_CTYPE, NULL);
127 if (loc == NULL) {
128 goto error;
129 }
130 if (strcmp(loc, "C") != 0 && strcmp(loc, "POSIX") != 0) {
131 /* the LC_CTYPE locale is different than C and POSIX */
132 return 0;
133 }
134
135 #if defined(HAVE_LANGINFO_H) && defined(CODESET)
136 const char *codeset = nl_langinfo(CODESET);
137 if (!codeset || codeset[0] == '\0') {
138 /* CODESET is not set or empty */
139 goto error;
140 }
141
142 char encoding[20]; /* longest name: "iso_646.irv_1991\0" */
143 if (!_Py_normalize_encoding(codeset, encoding, sizeof(encoding))) {
144 goto error;
145 }
146
147 #ifdef __hpux
148 if (strcmp(encoding, "roman8") == 0) {
149 unsigned char ch;
150 wchar_t wch;
151 size_t res;
152
153 ch = (unsigned char)0xA7;
154 res = mbstowcs(&wch, (char*)&ch, 1);
155 if (res != (size_t)-1 && wch == L'\xA7') {
156 /* On HP-UX withe C locale or the POSIX locale,
157 nl_langinfo(CODESET) announces "roman8", whereas mbstowcs() uses
158 Latin1 encoding in practice. Force ASCII in this case.
159
160 Roman8 decodes 0xA7 to U+00CF. Latin1 decodes 0xA7 to U+00A7. */
161 return 1;
162 }
163 }
164 #else
165 const char* ascii_aliases[] = {
166 "ascii",
167 /* Aliases from Lib/encodings/aliases.py */
168 "646",
169 "ansi_x3.4_1968",
170 "ansi_x3.4_1986",
171 "ansi_x3_4_1968",
172 "cp367",
173 "csascii",
174 "ibm367",
175 "iso646_us",
176 "iso_646.irv_1991",
177 "iso_ir_6",
178 "us",
179 "us_ascii",
180 NULL
181 };
182
183 int is_ascii = 0;
184 for (const char **alias=ascii_aliases; *alias != NULL; alias++) {
185 if (strcmp(encoding, *alias) == 0) {
186 is_ascii = 1;
187 break;
188 }
189 }
190 if (!is_ascii) {
191 /* nl_langinfo(CODESET) is not "ascii" or an alias of ASCII */
192 return 0;
193 }
194
195 for (unsigned int i=0x80; i<=0xff; i++) {
196 char ch[1];
197 wchar_t wch[1];
198 size_t res;
199
200 unsigned uch = (unsigned char)i;
201 ch[0] = (char)uch;
202 res = mbstowcs(wch, ch, 1);
203 if (res != (size_t)-1) {
204 /* decoding a non-ASCII character from the locale encoding succeed:
205 the locale encoding is not ASCII, force ASCII */
206 return 1;
207 }
208 }
209 /* None of the bytes in the range 0x80-0xff can be decoded from the locale
210 encoding: the locale encoding is really ASCII */
211 #endif /* !defined(__hpux) */
212 return 0;
213 #else
214 /* nl_langinfo(CODESET) is not available: always force ASCII */
215 return 1;
216 #endif /* defined(HAVE_LANGINFO_H) && defined(CODESET) */
217
218 error:
219 /* if an error occurred, force the ASCII encoding */
220 return 1;
221 }
222
223
224 int
_Py_GetForceASCII(void)225 _Py_GetForceASCII(void)
226 {
227 if (force_ascii == -1) {
228 force_ascii = check_force_ascii();
229 }
230 return force_ascii;
231 }
232
233
234 void
_Py_ResetForceASCII(void)235 _Py_ResetForceASCII(void)
236 {
237 force_ascii = -1;
238 }
239
240
241 static int
encode_ascii(const wchar_t * text,char ** str,size_t * error_pos,const char ** reason,int raw_malloc,_Py_error_handler errors)242 encode_ascii(const wchar_t *text, char **str,
243 size_t *error_pos, const char **reason,
244 int raw_malloc, _Py_error_handler errors)
245 {
246 char *result = NULL, *out;
247 size_t len, i;
248 wchar_t ch;
249
250 int surrogateescape;
251 if (get_surrogateescape(errors, &surrogateescape) < 0) {
252 return -3;
253 }
254
255 len = wcslen(text);
256
257 /* +1 for NULL byte */
258 if (raw_malloc) {
259 result = PyMem_RawMalloc(len + 1);
260 }
261 else {
262 result = PyMem_Malloc(len + 1);
263 }
264 if (result == NULL) {
265 return -1;
266 }
267
268 out = result;
269 for (i=0; i<len; i++) {
270 ch = text[i];
271
272 if (ch <= 0x7f) {
273 /* ASCII character */
274 *out++ = (char)ch;
275 }
276 else if (surrogateescape && 0xdc80 <= ch && ch <= 0xdcff) {
277 /* UTF-8b surrogate */
278 *out++ = (char)(ch - 0xdc00);
279 }
280 else {
281 if (raw_malloc) {
282 PyMem_RawFree(result);
283 }
284 else {
285 PyMem_Free(result);
286 }
287 if (error_pos != NULL) {
288 *error_pos = i;
289 }
290 if (reason) {
291 *reason = "encoding error";
292 }
293 return -2;
294 }
295 }
296 *out = '\0';
297 *str = result;
298 return 0;
299 }
300 #else
301 int
_Py_GetForceASCII(void)302 _Py_GetForceASCII(void)
303 {
304 return 0;
305 }
306
307 void
_Py_ResetForceASCII(void)308 _Py_ResetForceASCII(void)
309 {
310 /* nothing to do */
311 }
312 #endif /* !defined(_Py_FORCE_UTF8_FS_ENCODING) && !defined(MS_WINDOWS) */
313
314
315 #if !defined(HAVE_MBRTOWC) || defined(USE_FORCE_ASCII)
316 static int
decode_ascii(const char * arg,wchar_t ** wstr,size_t * wlen,const char ** reason,_Py_error_handler errors)317 decode_ascii(const char *arg, wchar_t **wstr, size_t *wlen,
318 const char **reason, _Py_error_handler errors)
319 {
320 wchar_t *res;
321 unsigned char *in;
322 wchar_t *out;
323 size_t argsize = strlen(arg) + 1;
324
325 int surrogateescape;
326 if (get_surrogateescape(errors, &surrogateescape) < 0) {
327 return -3;
328 }
329
330 if (argsize > PY_SSIZE_T_MAX / sizeof(wchar_t)) {
331 return -1;
332 }
333 res = PyMem_RawMalloc(argsize * sizeof(wchar_t));
334 if (!res) {
335 return -1;
336 }
337
338 out = res;
339 for (in = (unsigned char*)arg; *in; in++) {
340 unsigned char ch = *in;
341 if (ch < 128) {
342 *out++ = ch;
343 }
344 else {
345 if (!surrogateescape) {
346 PyMem_RawFree(res);
347 if (wlen) {
348 *wlen = in - (unsigned char*)arg;
349 }
350 if (reason) {
351 *reason = "decoding error";
352 }
353 return -2;
354 }
355 *out++ = 0xdc00 + ch;
356 }
357 }
358 *out = 0;
359
360 if (wlen != NULL) {
361 *wlen = out - res;
362 }
363 *wstr = res;
364 return 0;
365 }
366 #endif /* !HAVE_MBRTOWC */
367
368 static int
decode_current_locale(const char * arg,wchar_t ** wstr,size_t * wlen,const char ** reason,_Py_error_handler errors)369 decode_current_locale(const char* arg, wchar_t **wstr, size_t *wlen,
370 const char **reason, _Py_error_handler errors)
371 {
372 wchar_t *res;
373 size_t argsize;
374 size_t count;
375 #ifdef HAVE_MBRTOWC
376 unsigned char *in;
377 wchar_t *out;
378 mbstate_t mbs;
379 #endif
380
381 int surrogateescape;
382 if (get_surrogateescape(errors, &surrogateescape) < 0) {
383 return -3;
384 }
385
386 #ifdef HAVE_BROKEN_MBSTOWCS
387 /* Some platforms have a broken implementation of
388 * mbstowcs which does not count the characters that
389 * would result from conversion. Use an upper bound.
390 */
391 argsize = strlen(arg);
392 #else
393 argsize = mbstowcs(NULL, arg, 0);
394 #endif
395 if (argsize != (size_t)-1) {
396 if (argsize > PY_SSIZE_T_MAX / sizeof(wchar_t) - 1) {
397 return -1;
398 }
399 res = (wchar_t *)PyMem_RawMalloc((argsize + 1) * sizeof(wchar_t));
400 if (!res) {
401 return -1;
402 }
403
404 count = mbstowcs(res, arg, argsize + 1);
405 if (count != (size_t)-1) {
406 wchar_t *tmp;
407 /* Only use the result if it contains no
408 surrogate characters. */
409 for (tmp = res; *tmp != 0 &&
410 !Py_UNICODE_IS_SURROGATE(*tmp); tmp++)
411 ;
412 if (*tmp == 0) {
413 if (wlen != NULL) {
414 *wlen = count;
415 }
416 *wstr = res;
417 return 0;
418 }
419 }
420 PyMem_RawFree(res);
421 }
422
423 /* Conversion failed. Fall back to escaping with surrogateescape. */
424 #ifdef HAVE_MBRTOWC
425 /* Try conversion with mbrtwoc (C99), and escape non-decodable bytes. */
426
427 /* Overallocate; as multi-byte characters are in the argument, the
428 actual output could use less memory. */
429 argsize = strlen(arg) + 1;
430 if (argsize > PY_SSIZE_T_MAX / sizeof(wchar_t)) {
431 return -1;
432 }
433 res = (wchar_t*)PyMem_RawMalloc(argsize * sizeof(wchar_t));
434 if (!res) {
435 return -1;
436 }
437
438 in = (unsigned char*)arg;
439 out = res;
440 memset(&mbs, 0, sizeof mbs);
441 while (argsize) {
442 size_t converted = mbrtowc(out, (char*)in, argsize, &mbs);
443 if (converted == 0) {
444 /* Reached end of string; null char stored. */
445 break;
446 }
447
448 if (converted == (size_t)-2) {
449 /* Incomplete character. This should never happen,
450 since we provide everything that we have -
451 unless there is a bug in the C library, or I
452 misunderstood how mbrtowc works. */
453 goto decode_error;
454 }
455
456 if (converted == (size_t)-1) {
457 if (!surrogateescape) {
458 goto decode_error;
459 }
460
461 /* Conversion error. Escape as UTF-8b, and start over
462 in the initial shift state. */
463 *out++ = 0xdc00 + *in++;
464 argsize--;
465 memset(&mbs, 0, sizeof mbs);
466 continue;
467 }
468
469 if (Py_UNICODE_IS_SURROGATE(*out)) {
470 if (!surrogateescape) {
471 goto decode_error;
472 }
473
474 /* Surrogate character. Escape the original
475 byte sequence with surrogateescape. */
476 argsize -= converted;
477 while (converted--) {
478 *out++ = 0xdc00 + *in++;
479 }
480 continue;
481 }
482 /* successfully converted some bytes */
483 in += converted;
484 argsize -= converted;
485 out++;
486 }
487 if (wlen != NULL) {
488 *wlen = out - res;
489 }
490 *wstr = res;
491 return 0;
492
493 decode_error:
494 PyMem_RawFree(res);
495 if (wlen) {
496 *wlen = in - (unsigned char*)arg;
497 }
498 if (reason) {
499 *reason = "decoding error";
500 }
501 return -2;
502 #else /* HAVE_MBRTOWC */
503 /* Cannot use C locale for escaping; manually escape as if charset
504 is ASCII (i.e. escape all bytes > 128. This will still roundtrip
505 correctly in the locale's charset, which must be an ASCII superset. */
506 return decode_ascii(arg, wstr, wlen, reason, errors);
507 #endif /* HAVE_MBRTOWC */
508 }
509
510
511 /* Decode a byte string from the locale encoding.
512
513 Use the strict error handler if 'surrogateescape' is zero. Use the
514 surrogateescape error handler if 'surrogateescape' is non-zero: undecodable
515 bytes are decoded as characters in range U+DC80..U+DCFF. If a byte sequence
516 can be decoded as a surrogate character, escape the bytes using the
517 surrogateescape error handler instead of decoding them.
518
519 On success, return 0 and write the newly allocated wide character string into
520 *wstr (use PyMem_RawFree() to free the memory). If wlen is not NULL, write
521 the number of wide characters excluding the null character into *wlen.
522
523 On memory allocation failure, return -1.
524
525 On decoding error, return -2. If wlen is not NULL, write the start of
526 invalid byte sequence in the input string into *wlen. If reason is not NULL,
527 write the decoding error message into *reason.
528
529 Return -3 if the error handler 'errors' is not supported.
530
531 Use the Py_EncodeLocaleEx() function to encode the character string back to
532 a byte string. */
533 int
_Py_DecodeLocaleEx(const char * arg,wchar_t ** wstr,size_t * wlen,const char ** reason,int current_locale,_Py_error_handler errors)534 _Py_DecodeLocaleEx(const char* arg, wchar_t **wstr, size_t *wlen,
535 const char **reason,
536 int current_locale, _Py_error_handler errors)
537 {
538 if (current_locale) {
539 #ifdef _Py_FORCE_UTF8_LOCALE
540 return _Py_DecodeUTF8Ex(arg, strlen(arg), wstr, wlen, reason,
541 errors);
542 #else
543 return decode_current_locale(arg, wstr, wlen, reason, errors);
544 #endif
545 }
546
547 #ifdef _Py_FORCE_UTF8_FS_ENCODING
548 return _Py_DecodeUTF8Ex(arg, strlen(arg), wstr, wlen, reason,
549 errors);
550 #else
551 int use_utf8 = (Py_UTF8Mode == 1);
552 #ifdef MS_WINDOWS
553 use_utf8 |= !Py_LegacyWindowsFSEncodingFlag;
554 #endif
555 if (use_utf8) {
556 return _Py_DecodeUTF8Ex(arg, strlen(arg), wstr, wlen, reason,
557 errors);
558 }
559
560 #ifdef USE_FORCE_ASCII
561 if (force_ascii == -1) {
562 force_ascii = check_force_ascii();
563 }
564
565 if (force_ascii) {
566 /* force ASCII encoding to workaround mbstowcs() issue */
567 return decode_ascii(arg, wstr, wlen, reason, errors);
568 }
569 #endif
570
571 return decode_current_locale(arg, wstr, wlen, reason, errors);
572 #endif /* !_Py_FORCE_UTF8_FS_ENCODING */
573 }
574
575
576 /* Decode a byte string from the locale encoding with the
577 surrogateescape error handler: undecodable bytes are decoded as characters
578 in range U+DC80..U+DCFF. If a byte sequence can be decoded as a surrogate
579 character, escape the bytes using the surrogateescape error handler instead
580 of decoding them.
581
582 Return a pointer to a newly allocated wide character string, use
583 PyMem_RawFree() to free the memory. If size is not NULL, write the number of
584 wide characters excluding the null character into *size
585
586 Return NULL on decoding error or memory allocation error. If *size* is not
587 NULL, *size is set to (size_t)-1 on memory error or set to (size_t)-2 on
588 decoding error.
589
590 Decoding errors should never happen, unless there is a bug in the C
591 library.
592
593 Use the Py_EncodeLocale() function to encode the character string back to a
594 byte string. */
595 wchar_t*
Py_DecodeLocale(const char * arg,size_t * wlen)596 Py_DecodeLocale(const char* arg, size_t *wlen)
597 {
598 wchar_t *wstr;
599 int res = _Py_DecodeLocaleEx(arg, &wstr, wlen,
600 NULL, 0,
601 _Py_ERROR_SURROGATEESCAPE);
602 if (res != 0) {
603 assert(res != -3);
604 if (wlen != NULL) {
605 *wlen = (size_t)res;
606 }
607 return NULL;
608 }
609 return wstr;
610 }
611
612
613 static int
encode_current_locale(const wchar_t * text,char ** str,size_t * error_pos,const char ** reason,int raw_malloc,_Py_error_handler errors)614 encode_current_locale(const wchar_t *text, char **str,
615 size_t *error_pos, const char **reason,
616 int raw_malloc, _Py_error_handler errors)
617 {
618 const size_t len = wcslen(text);
619 char *result = NULL, *bytes = NULL;
620 size_t i, size, converted;
621 wchar_t c, buf[2];
622
623 int surrogateescape;
624 if (get_surrogateescape(errors, &surrogateescape) < 0) {
625 return -3;
626 }
627
628 /* The function works in two steps:
629 1. compute the length of the output buffer in bytes (size)
630 2. outputs the bytes */
631 size = 0;
632 buf[1] = 0;
633 while (1) {
634 for (i=0; i < len; i++) {
635 c = text[i];
636 if (c >= 0xdc80 && c <= 0xdcff) {
637 if (!surrogateescape) {
638 goto encode_error;
639 }
640 /* UTF-8b surrogate */
641 if (bytes != NULL) {
642 *bytes++ = c - 0xdc00;
643 size--;
644 }
645 else {
646 size++;
647 }
648 continue;
649 }
650 else {
651 buf[0] = c;
652 if (bytes != NULL) {
653 converted = wcstombs(bytes, buf, size);
654 }
655 else {
656 converted = wcstombs(NULL, buf, 0);
657 }
658 if (converted == (size_t)-1) {
659 goto encode_error;
660 }
661 if (bytes != NULL) {
662 bytes += converted;
663 size -= converted;
664 }
665 else {
666 size += converted;
667 }
668 }
669 }
670 if (result != NULL) {
671 *bytes = '\0';
672 break;
673 }
674
675 size += 1; /* nul byte at the end */
676 if (raw_malloc) {
677 result = PyMem_RawMalloc(size);
678 }
679 else {
680 result = PyMem_Malloc(size);
681 }
682 if (result == NULL) {
683 return -1;
684 }
685 bytes = result;
686 }
687 *str = result;
688 return 0;
689
690 encode_error:
691 if (raw_malloc) {
692 PyMem_RawFree(result);
693 }
694 else {
695 PyMem_Free(result);
696 }
697 if (error_pos != NULL) {
698 *error_pos = i;
699 }
700 if (reason) {
701 *reason = "encoding error";
702 }
703 return -2;
704 }
705
706
707 /* Encode a string to the locale encoding.
708
709 Parameters:
710
711 * raw_malloc: if non-zero, allocate memory using PyMem_RawMalloc() instead
712 of PyMem_Malloc().
713 * current_locale: if non-zero, use the current LC_CTYPE, otherwise use
714 Python filesystem encoding.
715 * errors: error handler like "strict" or "surrogateescape".
716
717 Return value:
718
719 0: success, *str is set to a newly allocated decoded string.
720 -1: memory allocation failure
721 -2: encoding error, set *error_pos and *reason (if set).
722 -3: the error handler 'errors' is not supported.
723 */
724 static int
encode_locale_ex(const wchar_t * text,char ** str,size_t * error_pos,const char ** reason,int raw_malloc,int current_locale,_Py_error_handler errors)725 encode_locale_ex(const wchar_t *text, char **str, size_t *error_pos,
726 const char **reason,
727 int raw_malloc, int current_locale, _Py_error_handler errors)
728 {
729 if (current_locale) {
730 #ifdef _Py_FORCE_UTF8_LOCALE
731 return _Py_EncodeUTF8Ex(text, str, error_pos, reason,
732 raw_malloc, errors);
733 #else
734 return encode_current_locale(text, str, error_pos, reason,
735 raw_malloc, errors);
736 #endif
737 }
738
739 #ifdef _Py_FORCE_UTF8_FS_ENCODING
740 return _Py_EncodeUTF8Ex(text, str, error_pos, reason,
741 raw_malloc, errors);
742 #else
743 int use_utf8 = (Py_UTF8Mode == 1);
744 #ifdef MS_WINDOWS
745 use_utf8 |= !Py_LegacyWindowsFSEncodingFlag;
746 #endif
747 if (use_utf8) {
748 return _Py_EncodeUTF8Ex(text, str, error_pos, reason,
749 raw_malloc, errors);
750 }
751
752 #ifdef USE_FORCE_ASCII
753 if (force_ascii == -1) {
754 force_ascii = check_force_ascii();
755 }
756
757 if (force_ascii) {
758 return encode_ascii(text, str, error_pos, reason,
759 raw_malloc, errors);
760 }
761 #endif
762
763 return encode_current_locale(text, str, error_pos, reason,
764 raw_malloc, errors);
765 #endif /* _Py_FORCE_UTF8_FS_ENCODING */
766 }
767
768 static char*
encode_locale(const wchar_t * text,size_t * error_pos,int raw_malloc,int current_locale)769 encode_locale(const wchar_t *text, size_t *error_pos,
770 int raw_malloc, int current_locale)
771 {
772 char *str;
773 int res = encode_locale_ex(text, &str, error_pos, NULL,
774 raw_malloc, current_locale,
775 _Py_ERROR_SURROGATEESCAPE);
776 if (res != -2 && error_pos) {
777 *error_pos = (size_t)-1;
778 }
779 if (res != 0) {
780 return NULL;
781 }
782 return str;
783 }
784
785 /* Encode a wide character string to the locale encoding with the
786 surrogateescape error handler: surrogate characters in the range
787 U+DC80..U+DCFF are converted to bytes 0x80..0xFF.
788
789 Return a pointer to a newly allocated byte string, use PyMem_Free() to free
790 the memory. Return NULL on encoding or memory allocation error.
791
792 If error_pos is not NULL, *error_pos is set to (size_t)-1 on success, or set
793 to the index of the invalid character on encoding error.
794
795 Use the Py_DecodeLocale() function to decode the bytes string back to a wide
796 character string. */
797 char*
Py_EncodeLocale(const wchar_t * text,size_t * error_pos)798 Py_EncodeLocale(const wchar_t *text, size_t *error_pos)
799 {
800 return encode_locale(text, error_pos, 0, 0);
801 }
802
803
804 /* Similar to Py_EncodeLocale(), but result must be freed by PyMem_RawFree()
805 instead of PyMem_Free(). */
806 char*
_Py_EncodeLocaleRaw(const wchar_t * text,size_t * error_pos)807 _Py_EncodeLocaleRaw(const wchar_t *text, size_t *error_pos)
808 {
809 return encode_locale(text, error_pos, 1, 0);
810 }
811
812
813 int
_Py_EncodeLocaleEx(const wchar_t * text,char ** str,size_t * error_pos,const char ** reason,int current_locale,_Py_error_handler errors)814 _Py_EncodeLocaleEx(const wchar_t *text, char **str,
815 size_t *error_pos, const char **reason,
816 int current_locale, _Py_error_handler errors)
817 {
818 return encode_locale_ex(text, str, error_pos, reason, 1,
819 current_locale, errors);
820 }
821
822
823 #ifdef MS_WINDOWS
824 static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
825
826 static void
FILE_TIME_to_time_t_nsec(FILETIME * in_ptr,time_t * time_out,int * nsec_out)827 FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
828 {
829 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
830 /* Cannot simply cast and dereference in_ptr,
831 since it might not be aligned properly */
832 __int64 in;
833 memcpy(&in, in_ptr, sizeof(in));
834 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
835 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
836 }
837
838 void
_Py_time_t_to_FILE_TIME(time_t time_in,int nsec_in,FILETIME * out_ptr)839 _Py_time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
840 {
841 /* XXX endianness */
842 __int64 out;
843 out = time_in + secs_between_epochs;
844 out = out * 10000000 + nsec_in / 100;
845 memcpy(out_ptr, &out, sizeof(out));
846 }
847
848 /* Below, we *know* that ugo+r is 0444 */
849 #if _S_IREAD != 0400
850 #error Unsupported C library
851 #endif
852 static int
attributes_to_mode(DWORD attr)853 attributes_to_mode(DWORD attr)
854 {
855 int m = 0;
856 if (attr & FILE_ATTRIBUTE_DIRECTORY)
857 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
858 else
859 m |= _S_IFREG;
860 if (attr & FILE_ATTRIBUTE_READONLY)
861 m |= 0444;
862 else
863 m |= 0666;
864 return m;
865 }
866
867 void
_Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION * info,ULONG reparse_tag,struct _Py_stat_struct * result)868 _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag,
869 struct _Py_stat_struct *result)
870 {
871 memset(result, 0, sizeof(*result));
872 result->st_mode = attributes_to_mode(info->dwFileAttributes);
873 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
874 result->st_dev = info->dwVolumeSerialNumber;
875 result->st_rdev = result->st_dev;
876 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
877 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
878 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
879 result->st_nlink = info->nNumberOfLinks;
880 result->st_ino = (((uint64_t)info->nFileIndexHigh) << 32) + info->nFileIndexLow;
881 /* bpo-37834: Only actual symlinks set the S_IFLNK flag. But lstat() will
882 open other name surrogate reparse points without traversing them. To
883 detect/handle these, check st_file_attributes and st_reparse_tag. */
884 result->st_reparse_tag = reparse_tag;
885 if (info->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT &&
886 reparse_tag == IO_REPARSE_TAG_SYMLINK) {
887 /* first clear the S_IFMT bits */
888 result->st_mode ^= (result->st_mode & S_IFMT);
889 /* now set the bits that make this a symlink */
890 result->st_mode |= S_IFLNK;
891 }
892 result->st_file_attributes = info->dwFileAttributes;
893 }
894 #endif
895
896 /* Return information about a file.
897
898 On POSIX, use fstat().
899
900 On Windows, use GetFileType() and GetFileInformationByHandle() which support
901 files larger than 2 GiB. fstat() may fail with EOVERFLOW on files larger
902 than 2 GiB because the file size type is a signed 32-bit integer: see issue
903 #23152.
904
905 On Windows, set the last Windows error and return nonzero on error. On
906 POSIX, set errno and return nonzero on error. Fill status and return 0 on
907 success. */
908 int
_Py_fstat_noraise(int fd,struct _Py_stat_struct * status)909 _Py_fstat_noraise(int fd, struct _Py_stat_struct *status)
910 {
911 #ifdef MS_WINDOWS
912 BY_HANDLE_FILE_INFORMATION info;
913 HANDLE h;
914 int type;
915
916 _Py_BEGIN_SUPPRESS_IPH
917 h = (HANDLE)_get_osfhandle(fd);
918 _Py_END_SUPPRESS_IPH
919
920 if (h == INVALID_HANDLE_VALUE) {
921 /* errno is already set by _get_osfhandle, but we also set
922 the Win32 error for callers who expect that */
923 SetLastError(ERROR_INVALID_HANDLE);
924 return -1;
925 }
926 memset(status, 0, sizeof(*status));
927
928 type = GetFileType(h);
929 if (type == FILE_TYPE_UNKNOWN) {
930 DWORD error = GetLastError();
931 if (error != 0) {
932 errno = winerror_to_errno(error);
933 return -1;
934 }
935 /* else: valid but unknown file */
936 }
937
938 if (type != FILE_TYPE_DISK) {
939 if (type == FILE_TYPE_CHAR)
940 status->st_mode = _S_IFCHR;
941 else if (type == FILE_TYPE_PIPE)
942 status->st_mode = _S_IFIFO;
943 return 0;
944 }
945
946 if (!GetFileInformationByHandle(h, &info)) {
947 /* The Win32 error is already set, but we also set errno for
948 callers who expect it */
949 errno = winerror_to_errno(GetLastError());
950 return -1;
951 }
952
953 _Py_attribute_data_to_stat(&info, 0, status);
954 /* specific to fstat() */
955 status->st_ino = (((uint64_t)info.nFileIndexHigh) << 32) + info.nFileIndexLow;
956 return 0;
957 #else
958 return fstat(fd, status);
959 #endif
960 }
961
962 /* Return information about a file.
963
964 On POSIX, use fstat().
965
966 On Windows, use GetFileType() and GetFileInformationByHandle() which support
967 files larger than 2 GiB. fstat() may fail with EOVERFLOW on files larger
968 than 2 GiB because the file size type is a signed 32-bit integer: see issue
969 #23152.
970
971 Raise an exception and return -1 on error. On Windows, set the last Windows
972 error on error. On POSIX, set errno on error. Fill status and return 0 on
973 success.
974
975 Release the GIL to call GetFileType() and GetFileInformationByHandle(), or
976 to call fstat(). The caller must hold the GIL. */
977 int
_Py_fstat(int fd,struct _Py_stat_struct * status)978 _Py_fstat(int fd, struct _Py_stat_struct *status)
979 {
980 int res;
981
982 assert(PyGILState_Check());
983
984 Py_BEGIN_ALLOW_THREADS
985 res = _Py_fstat_noraise(fd, status);
986 Py_END_ALLOW_THREADS
987
988 if (res != 0) {
989 #ifdef MS_WINDOWS
990 PyErr_SetFromWindowsErr(0);
991 #else
992 PyErr_SetFromErrno(PyExc_OSError);
993 #endif
994 return -1;
995 }
996 return 0;
997 }
998
999 /* Call _wstat() on Windows, or encode the path to the filesystem encoding and
1000 call stat() otherwise. Only fill st_mode attribute on Windows.
1001
1002 Return 0 on success, -1 on _wstat() / stat() error, -2 if an exception was
1003 raised. */
1004
1005 int
_Py_stat(PyObject * path,struct stat * statbuf)1006 _Py_stat(PyObject *path, struct stat *statbuf)
1007 {
1008 #ifdef MS_WINDOWS
1009 int err;
1010 struct _stat wstatbuf;
1011 const wchar_t *wpath;
1012
1013 wpath = _PyUnicode_AsUnicode(path);
1014 if (wpath == NULL)
1015 return -2;
1016
1017 err = _wstat(wpath, &wstatbuf);
1018 if (!err)
1019 statbuf->st_mode = wstatbuf.st_mode;
1020 return err;
1021 #else
1022 int ret;
1023 PyObject *bytes;
1024 char *cpath;
1025
1026 bytes = PyUnicode_EncodeFSDefault(path);
1027 if (bytes == NULL)
1028 return -2;
1029
1030 /* check for embedded null bytes */
1031 if (PyBytes_AsStringAndSize(bytes, &cpath, NULL) == -1) {
1032 Py_DECREF(bytes);
1033 return -2;
1034 }
1035
1036 ret = stat(cpath, statbuf);
1037 Py_DECREF(bytes);
1038 return ret;
1039 #endif
1040 }
1041
1042
1043 /* This function MUST be kept async-signal-safe on POSIX when raise=0. */
1044 static int
get_inheritable(int fd,int raise)1045 get_inheritable(int fd, int raise)
1046 {
1047 #ifdef MS_WINDOWS
1048 HANDLE handle;
1049 DWORD flags;
1050
1051 _Py_BEGIN_SUPPRESS_IPH
1052 handle = (HANDLE)_get_osfhandle(fd);
1053 _Py_END_SUPPRESS_IPH
1054 if (handle == INVALID_HANDLE_VALUE) {
1055 if (raise)
1056 PyErr_SetFromErrno(PyExc_OSError);
1057 return -1;
1058 }
1059
1060 if (!GetHandleInformation(handle, &flags)) {
1061 if (raise)
1062 PyErr_SetFromWindowsErr(0);
1063 return -1;
1064 }
1065
1066 return (flags & HANDLE_FLAG_INHERIT);
1067 #else
1068 int flags;
1069
1070 flags = fcntl(fd, F_GETFD, 0);
1071 if (flags == -1) {
1072 if (raise)
1073 PyErr_SetFromErrno(PyExc_OSError);
1074 return -1;
1075 }
1076 return !(flags & FD_CLOEXEC);
1077 #endif
1078 }
1079
1080 /* Get the inheritable flag of the specified file descriptor.
1081 Return 1 if the file descriptor can be inherited, 0 if it cannot,
1082 raise an exception and return -1 on error. */
1083 int
_Py_get_inheritable(int fd)1084 _Py_get_inheritable(int fd)
1085 {
1086 return get_inheritable(fd, 1);
1087 }
1088
1089
1090 /* This function MUST be kept async-signal-safe on POSIX when raise=0. */
1091 static int
set_inheritable(int fd,int inheritable,int raise,int * atomic_flag_works)1092 set_inheritable(int fd, int inheritable, int raise, int *atomic_flag_works)
1093 {
1094 #ifdef MS_WINDOWS
1095 HANDLE handle;
1096 DWORD flags;
1097 #else
1098 #if defined(HAVE_SYS_IOCTL_H) && defined(FIOCLEX) && defined(FIONCLEX)
1099 static int ioctl_works = -1;
1100 int request;
1101 int err;
1102 #endif
1103 int flags, new_flags;
1104 int res;
1105 #endif
1106
1107 /* atomic_flag_works can only be used to make the file descriptor
1108 non-inheritable */
1109 assert(!(atomic_flag_works != NULL && inheritable));
1110
1111 if (atomic_flag_works != NULL && !inheritable) {
1112 if (*atomic_flag_works == -1) {
1113 int isInheritable = get_inheritable(fd, raise);
1114 if (isInheritable == -1)
1115 return -1;
1116 *atomic_flag_works = !isInheritable;
1117 }
1118
1119 if (*atomic_flag_works)
1120 return 0;
1121 }
1122
1123 #ifdef MS_WINDOWS
1124 _Py_BEGIN_SUPPRESS_IPH
1125 handle = (HANDLE)_get_osfhandle(fd);
1126 _Py_END_SUPPRESS_IPH
1127 if (handle == INVALID_HANDLE_VALUE) {
1128 if (raise)
1129 PyErr_SetFromErrno(PyExc_OSError);
1130 return -1;
1131 }
1132
1133 if (inheritable)
1134 flags = HANDLE_FLAG_INHERIT;
1135 else
1136 flags = 0;
1137
1138 /* This check can be removed once support for Windows 7 ends. */
1139 #define CONSOLE_PSEUDOHANDLE(handle) (((ULONG_PTR)(handle) & 0x3) == 0x3 && \
1140 GetFileType(handle) == FILE_TYPE_CHAR)
1141
1142 if (!CONSOLE_PSEUDOHANDLE(handle) &&
1143 !SetHandleInformation(handle, HANDLE_FLAG_INHERIT, flags)) {
1144 if (raise)
1145 PyErr_SetFromWindowsErr(0);
1146 return -1;
1147 }
1148 #undef CONSOLE_PSEUDOHANDLE
1149 return 0;
1150
1151 #else
1152
1153 #if defined(HAVE_SYS_IOCTL_H) && defined(FIOCLEX) && defined(FIONCLEX)
1154 if (ioctl_works != 0 && raise != 0) {
1155 /* fast-path: ioctl() only requires one syscall */
1156 /* caveat: raise=0 is an indicator that we must be async-signal-safe
1157 * thus avoid using ioctl() so we skip the fast-path. */
1158 if (inheritable)
1159 request = FIONCLEX;
1160 else
1161 request = FIOCLEX;
1162 err = ioctl(fd, request, NULL);
1163 if (!err) {
1164 ioctl_works = 1;
1165 return 0;
1166 }
1167
1168 #ifdef __linux__
1169 if (errno == EBADF) {
1170 // On Linux, ioctl(FIOCLEX) will fail with EBADF for O_PATH file descriptors
1171 // Fall through to the fcntl() path
1172 }
1173 else
1174 #endif
1175 if (errno != ENOTTY && errno != EACCES) {
1176 if (raise)
1177 PyErr_SetFromErrno(PyExc_OSError);
1178 return -1;
1179 }
1180 else {
1181 /* Issue #22258: Here, ENOTTY means "Inappropriate ioctl for
1182 device". The ioctl is declared but not supported by the kernel.
1183 Remember that ioctl() doesn't work. It is the case on
1184 Illumos-based OS for example.
1185
1186 Issue #27057: When SELinux policy disallows ioctl it will fail
1187 with EACCES. While FIOCLEX is safe operation it may be
1188 unavailable because ioctl was denied altogether.
1189 This can be the case on Android. */
1190 ioctl_works = 0;
1191 }
1192 /* fallback to fcntl() if ioctl() does not work */
1193 }
1194 #endif
1195
1196 /* slow-path: fcntl() requires two syscalls */
1197 flags = fcntl(fd, F_GETFD);
1198 if (flags < 0) {
1199 if (raise)
1200 PyErr_SetFromErrno(PyExc_OSError);
1201 return -1;
1202 }
1203
1204 if (inheritable) {
1205 new_flags = flags & ~FD_CLOEXEC;
1206 }
1207 else {
1208 new_flags = flags | FD_CLOEXEC;
1209 }
1210
1211 if (new_flags == flags) {
1212 /* FD_CLOEXEC flag already set/cleared: nothing to do */
1213 return 0;
1214 }
1215
1216 res = fcntl(fd, F_SETFD, new_flags);
1217 if (res < 0) {
1218 if (raise)
1219 PyErr_SetFromErrno(PyExc_OSError);
1220 return -1;
1221 }
1222 return 0;
1223 #endif
1224 }
1225
1226 /* Make the file descriptor non-inheritable.
1227 Return 0 on success, set errno and return -1 on error. */
1228 static int
make_non_inheritable(int fd)1229 make_non_inheritable(int fd)
1230 {
1231 return set_inheritable(fd, 0, 0, NULL);
1232 }
1233
1234 /* Set the inheritable flag of the specified file descriptor.
1235 On success: return 0, on error: raise an exception and return -1.
1236
1237 If atomic_flag_works is not NULL:
1238
1239 * if *atomic_flag_works==-1, check if the inheritable is set on the file
1240 descriptor: if yes, set *atomic_flag_works to 1, otherwise set to 0 and
1241 set the inheritable flag
1242 * if *atomic_flag_works==1: do nothing
1243 * if *atomic_flag_works==0: set inheritable flag to False
1244
1245 Set atomic_flag_works to NULL if no atomic flag was used to create the
1246 file descriptor.
1247
1248 atomic_flag_works can only be used to make a file descriptor
1249 non-inheritable: atomic_flag_works must be NULL if inheritable=1. */
1250 int
_Py_set_inheritable(int fd,int inheritable,int * atomic_flag_works)1251 _Py_set_inheritable(int fd, int inheritable, int *atomic_flag_works)
1252 {
1253 return set_inheritable(fd, inheritable, 1, atomic_flag_works);
1254 }
1255
1256 /* Same as _Py_set_inheritable() but on error, set errno and
1257 don't raise an exception.
1258 This function is async-signal-safe. */
1259 int
_Py_set_inheritable_async_safe(int fd,int inheritable,int * atomic_flag_works)1260 _Py_set_inheritable_async_safe(int fd, int inheritable, int *atomic_flag_works)
1261 {
1262 return set_inheritable(fd, inheritable, 0, atomic_flag_works);
1263 }
1264
1265 static int
_Py_open_impl(const char * pathname,int flags,int gil_held)1266 _Py_open_impl(const char *pathname, int flags, int gil_held)
1267 {
1268 int fd;
1269 int async_err = 0;
1270 #ifndef MS_WINDOWS
1271 int *atomic_flag_works;
1272 #endif
1273
1274 #ifdef MS_WINDOWS
1275 flags |= O_NOINHERIT;
1276 #elif defined(O_CLOEXEC)
1277 atomic_flag_works = &_Py_open_cloexec_works;
1278 flags |= O_CLOEXEC;
1279 #else
1280 atomic_flag_works = NULL;
1281 #endif
1282
1283 if (gil_held) {
1284 PyObject *pathname_obj = PyUnicode_DecodeFSDefault(pathname);
1285 if (pathname_obj == NULL) {
1286 return -1;
1287 }
1288 if (PySys_Audit("open", "OOi", pathname_obj, Py_None, flags) < 0) {
1289 Py_DECREF(pathname_obj);
1290 return -1;
1291 }
1292
1293 do {
1294 Py_BEGIN_ALLOW_THREADS
1295 fd = open(pathname, flags);
1296 Py_END_ALLOW_THREADS
1297 } while (fd < 0
1298 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1299 if (async_err) {
1300 Py_DECREF(pathname_obj);
1301 return -1;
1302 }
1303 if (fd < 0) {
1304 PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, pathname_obj, NULL);
1305 Py_DECREF(pathname_obj);
1306 return -1;
1307 }
1308 Py_DECREF(pathname_obj);
1309 }
1310 else {
1311 fd = open(pathname, flags);
1312 if (fd < 0)
1313 return -1;
1314 }
1315
1316 #ifndef MS_WINDOWS
1317 if (set_inheritable(fd, 0, gil_held, atomic_flag_works) < 0) {
1318 close(fd);
1319 return -1;
1320 }
1321 #endif
1322
1323 return fd;
1324 }
1325
1326 /* Open a file with the specified flags (wrapper to open() function).
1327 Return a file descriptor on success. Raise an exception and return -1 on
1328 error.
1329
1330 The file descriptor is created non-inheritable.
1331
1332 When interrupted by a signal (open() fails with EINTR), retry the syscall,
1333 except if the Python signal handler raises an exception.
1334
1335 Release the GIL to call open(). The caller must hold the GIL. */
1336 int
_Py_open(const char * pathname,int flags)1337 _Py_open(const char *pathname, int flags)
1338 {
1339 /* _Py_open() must be called with the GIL held. */
1340 assert(PyGILState_Check());
1341 return _Py_open_impl(pathname, flags, 1);
1342 }
1343
1344 /* Open a file with the specified flags (wrapper to open() function).
1345 Return a file descriptor on success. Set errno and return -1 on error.
1346
1347 The file descriptor is created non-inheritable.
1348
1349 If interrupted by a signal, fail with EINTR. */
1350 int
_Py_open_noraise(const char * pathname,int flags)1351 _Py_open_noraise(const char *pathname, int flags)
1352 {
1353 return _Py_open_impl(pathname, flags, 0);
1354 }
1355
1356 /* Open a file. Use _wfopen() on Windows, encode the path to the locale
1357 encoding and use fopen() otherwise.
1358
1359 The file descriptor is created non-inheritable.
1360
1361 If interrupted by a signal, fail with EINTR. */
1362 FILE *
_Py_wfopen(const wchar_t * path,const wchar_t * mode)1363 _Py_wfopen(const wchar_t *path, const wchar_t *mode)
1364 {
1365 FILE *f;
1366 if (PySys_Audit("open", "uui", path, mode, 0) < 0) {
1367 return NULL;
1368 }
1369 #ifndef MS_WINDOWS
1370 char *cpath;
1371 char cmode[10];
1372 size_t r;
1373 r = wcstombs(cmode, mode, 10);
1374 if (r == (size_t)-1 || r >= 10) {
1375 errno = EINVAL;
1376 return NULL;
1377 }
1378 cpath = _Py_EncodeLocaleRaw(path, NULL);
1379 if (cpath == NULL) {
1380 return NULL;
1381 }
1382 f = fopen(cpath, cmode);
1383 PyMem_RawFree(cpath);
1384 #else
1385 f = _wfopen(path, mode);
1386 #endif
1387 if (f == NULL)
1388 return NULL;
1389 if (make_non_inheritable(fileno(f)) < 0) {
1390 fclose(f);
1391 return NULL;
1392 }
1393 return f;
1394 }
1395
1396 /* Wrapper to fopen().
1397
1398 The file descriptor is created non-inheritable.
1399
1400 If interrupted by a signal, fail with EINTR. */
1401 FILE*
_Py_fopen(const char * pathname,const char * mode)1402 _Py_fopen(const char *pathname, const char *mode)
1403 {
1404 PyObject *pathname_obj = PyUnicode_DecodeFSDefault(pathname);
1405 if (pathname_obj == NULL) {
1406 return NULL;
1407 }
1408 if (PySys_Audit("open", "Osi", pathname_obj, mode, 0) < 0) {
1409 Py_DECREF(pathname_obj);
1410 return NULL;
1411 }
1412 Py_DECREF(pathname_obj);
1413
1414 FILE *f = fopen(pathname, mode);
1415 if (f == NULL)
1416 return NULL;
1417 if (make_non_inheritable(fileno(f)) < 0) {
1418 fclose(f);
1419 return NULL;
1420 }
1421 return f;
1422 }
1423
1424 /* Open a file. Call _wfopen() on Windows, or encode the path to the filesystem
1425 encoding and call fopen() otherwise.
1426
1427 Return the new file object on success. Raise an exception and return NULL
1428 on error.
1429
1430 The file descriptor is created non-inheritable.
1431
1432 When interrupted by a signal (open() fails with EINTR), retry the syscall,
1433 except if the Python signal handler raises an exception.
1434
1435 Release the GIL to call _wfopen() or fopen(). The caller must hold
1436 the GIL. */
1437 FILE*
_Py_fopen_obj(PyObject * path,const char * mode)1438 _Py_fopen_obj(PyObject *path, const char *mode)
1439 {
1440 FILE *f;
1441 int async_err = 0;
1442 #ifdef MS_WINDOWS
1443 const wchar_t *wpath;
1444 wchar_t wmode[10];
1445 int usize;
1446
1447 assert(PyGILState_Check());
1448
1449 if (PySys_Audit("open", "Osi", path, mode, 0) < 0) {
1450 return NULL;
1451 }
1452 if (!PyUnicode_Check(path)) {
1453 PyErr_Format(PyExc_TypeError,
1454 "str file path expected under Windows, got %R",
1455 Py_TYPE(path));
1456 return NULL;
1457 }
1458 wpath = _PyUnicode_AsUnicode(path);
1459 if (wpath == NULL)
1460 return NULL;
1461
1462 usize = MultiByteToWideChar(CP_ACP, 0, mode, -1,
1463 wmode, Py_ARRAY_LENGTH(wmode));
1464 if (usize == 0) {
1465 PyErr_SetFromWindowsErr(0);
1466 return NULL;
1467 }
1468
1469 do {
1470 Py_BEGIN_ALLOW_THREADS
1471 f = _wfopen(wpath, wmode);
1472 Py_END_ALLOW_THREADS
1473 } while (f == NULL
1474 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1475 #else
1476 PyObject *bytes;
1477 const char *path_bytes;
1478
1479 assert(PyGILState_Check());
1480
1481 if (!PyUnicode_FSConverter(path, &bytes))
1482 return NULL;
1483 path_bytes = PyBytes_AS_STRING(bytes);
1484
1485 if (PySys_Audit("open", "Osi", path, mode, 0) < 0) {
1486 Py_DECREF(bytes);
1487 return NULL;
1488 }
1489
1490 do {
1491 Py_BEGIN_ALLOW_THREADS
1492 f = fopen(path_bytes, mode);
1493 Py_END_ALLOW_THREADS
1494 } while (f == NULL
1495 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1496
1497 Py_DECREF(bytes);
1498 #endif
1499 if (async_err)
1500 return NULL;
1501
1502 if (f == NULL) {
1503 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path);
1504 return NULL;
1505 }
1506
1507 if (set_inheritable(fileno(f), 0, 1, NULL) < 0) {
1508 fclose(f);
1509 return NULL;
1510 }
1511 return f;
1512 }
1513
1514 /* Read count bytes from fd into buf.
1515
1516 On success, return the number of read bytes, it can be lower than count.
1517 If the current file offset is at or past the end of file, no bytes are read,
1518 and read() returns zero.
1519
1520 On error, raise an exception, set errno and return -1.
1521
1522 When interrupted by a signal (read() fails with EINTR), retry the syscall.
1523 If the Python signal handler raises an exception, the function returns -1
1524 (the syscall is not retried).
1525
1526 Release the GIL to call read(). The caller must hold the GIL. */
1527 Py_ssize_t
_Py_read(int fd,void * buf,size_t count)1528 _Py_read(int fd, void *buf, size_t count)
1529 {
1530 Py_ssize_t n;
1531 int err;
1532 int async_err = 0;
1533
1534 assert(PyGILState_Check());
1535
1536 /* _Py_read() must not be called with an exception set, otherwise the
1537 * caller may think that read() was interrupted by a signal and the signal
1538 * handler raised an exception. */
1539 assert(!PyErr_Occurred());
1540
1541 if (count > _PY_READ_MAX) {
1542 count = _PY_READ_MAX;
1543 }
1544
1545 _Py_BEGIN_SUPPRESS_IPH
1546 do {
1547 Py_BEGIN_ALLOW_THREADS
1548 errno = 0;
1549 #ifdef MS_WINDOWS
1550 n = read(fd, buf, (int)count);
1551 #else
1552 n = read(fd, buf, count);
1553 #endif
1554 /* save/restore errno because PyErr_CheckSignals()
1555 * and PyErr_SetFromErrno() can modify it */
1556 err = errno;
1557 Py_END_ALLOW_THREADS
1558 } while (n < 0 && err == EINTR &&
1559 !(async_err = PyErr_CheckSignals()));
1560 _Py_END_SUPPRESS_IPH
1561
1562 if (async_err) {
1563 /* read() was interrupted by a signal (failed with EINTR)
1564 * and the Python signal handler raised an exception */
1565 errno = err;
1566 assert(errno == EINTR && PyErr_Occurred());
1567 return -1;
1568 }
1569 if (n < 0) {
1570 PyErr_SetFromErrno(PyExc_OSError);
1571 errno = err;
1572 return -1;
1573 }
1574
1575 return n;
1576 }
1577
1578 static Py_ssize_t
_Py_write_impl(int fd,const void * buf,size_t count,int gil_held)1579 _Py_write_impl(int fd, const void *buf, size_t count, int gil_held)
1580 {
1581 Py_ssize_t n;
1582 int err;
1583 int async_err = 0;
1584
1585 _Py_BEGIN_SUPPRESS_IPH
1586 #ifdef MS_WINDOWS
1587 if (count > 32767 && isatty(fd)) {
1588 /* Issue #11395: the Windows console returns an error (12: not
1589 enough space error) on writing into stdout if stdout mode is
1590 binary and the length is greater than 66,000 bytes (or less,
1591 depending on heap usage). */
1592 count = 32767;
1593 }
1594 #endif
1595 if (count > _PY_WRITE_MAX) {
1596 count = _PY_WRITE_MAX;
1597 }
1598
1599 if (gil_held) {
1600 do {
1601 Py_BEGIN_ALLOW_THREADS
1602 errno = 0;
1603 #ifdef MS_WINDOWS
1604 n = write(fd, buf, (int)count);
1605 #else
1606 n = write(fd, buf, count);
1607 #endif
1608 /* save/restore errno because PyErr_CheckSignals()
1609 * and PyErr_SetFromErrno() can modify it */
1610 err = errno;
1611 Py_END_ALLOW_THREADS
1612 } while (n < 0 && err == EINTR &&
1613 !(async_err = PyErr_CheckSignals()));
1614 }
1615 else {
1616 do {
1617 errno = 0;
1618 #ifdef MS_WINDOWS
1619 n = write(fd, buf, (int)count);
1620 #else
1621 n = write(fd, buf, count);
1622 #endif
1623 err = errno;
1624 } while (n < 0 && err == EINTR);
1625 }
1626 _Py_END_SUPPRESS_IPH
1627
1628 if (async_err) {
1629 /* write() was interrupted by a signal (failed with EINTR)
1630 and the Python signal handler raised an exception (if gil_held is
1631 nonzero). */
1632 errno = err;
1633 assert(errno == EINTR && (!gil_held || PyErr_Occurred()));
1634 return -1;
1635 }
1636 if (n < 0) {
1637 if (gil_held)
1638 PyErr_SetFromErrno(PyExc_OSError);
1639 errno = err;
1640 return -1;
1641 }
1642
1643 return n;
1644 }
1645
1646 /* Write count bytes of buf into fd.
1647
1648 On success, return the number of written bytes, it can be lower than count
1649 including 0. On error, raise an exception, set errno and return -1.
1650
1651 When interrupted by a signal (write() fails with EINTR), retry the syscall.
1652 If the Python signal handler raises an exception, the function returns -1
1653 (the syscall is not retried).
1654
1655 Release the GIL to call write(). The caller must hold the GIL. */
1656 Py_ssize_t
_Py_write(int fd,const void * buf,size_t count)1657 _Py_write(int fd, const void *buf, size_t count)
1658 {
1659 assert(PyGILState_Check());
1660
1661 /* _Py_write() must not be called with an exception set, otherwise the
1662 * caller may think that write() was interrupted by a signal and the signal
1663 * handler raised an exception. */
1664 assert(!PyErr_Occurred());
1665
1666 return _Py_write_impl(fd, buf, count, 1);
1667 }
1668
1669 /* Write count bytes of buf into fd.
1670 *
1671 * On success, return the number of written bytes, it can be lower than count
1672 * including 0. On error, set errno and return -1.
1673 *
1674 * When interrupted by a signal (write() fails with EINTR), retry the syscall
1675 * without calling the Python signal handler. */
1676 Py_ssize_t
_Py_write_noraise(int fd,const void * buf,size_t count)1677 _Py_write_noraise(int fd, const void *buf, size_t count)
1678 {
1679 return _Py_write_impl(fd, buf, count, 0);
1680 }
1681
1682 #ifdef HAVE_READLINK
1683
1684 /* Read value of symbolic link. Encode the path to the locale encoding, decode
1685 the result from the locale encoding.
1686
1687 Return -1 on encoding error, on readlink() error, if the internal buffer is
1688 too short, on decoding error, or if 'buf' is too short. */
1689 int
_Py_wreadlink(const wchar_t * path,wchar_t * buf,size_t buflen)1690 _Py_wreadlink(const wchar_t *path, wchar_t *buf, size_t buflen)
1691 {
1692 char *cpath;
1693 char cbuf[MAXPATHLEN];
1694 size_t cbuf_len = Py_ARRAY_LENGTH(cbuf);
1695 wchar_t *wbuf;
1696 Py_ssize_t res;
1697 size_t r1;
1698
1699 cpath = _Py_EncodeLocaleRaw(path, NULL);
1700 if (cpath == NULL) {
1701 errno = EINVAL;
1702 return -1;
1703 }
1704 res = readlink(cpath, cbuf, cbuf_len);
1705 PyMem_RawFree(cpath);
1706 if (res == -1) {
1707 return -1;
1708 }
1709 if ((size_t)res == cbuf_len) {
1710 errno = EINVAL;
1711 return -1;
1712 }
1713 cbuf[res] = '\0'; /* buf will be null terminated */
1714 wbuf = Py_DecodeLocale(cbuf, &r1);
1715 if (wbuf == NULL) {
1716 errno = EINVAL;
1717 return -1;
1718 }
1719 /* wbuf must have space to store the trailing NUL character */
1720 if (buflen <= r1) {
1721 PyMem_RawFree(wbuf);
1722 errno = EINVAL;
1723 return -1;
1724 }
1725 wcsncpy(buf, wbuf, buflen);
1726 PyMem_RawFree(wbuf);
1727 return (int)r1;
1728 }
1729 #endif
1730
1731 #ifdef HAVE_REALPATH
1732
1733 /* Return the canonicalized absolute pathname. Encode path to the locale
1734 encoding, decode the result from the locale encoding.
1735
1736 Return NULL on encoding error, realpath() error, decoding error
1737 or if 'resolved_path' is too short. */
1738 wchar_t*
_Py_wrealpath(const wchar_t * path,wchar_t * resolved_path,size_t resolved_path_len)1739 _Py_wrealpath(const wchar_t *path,
1740 wchar_t *resolved_path, size_t resolved_path_len)
1741 {
1742 char *cpath;
1743 char cresolved_path[MAXPATHLEN];
1744 wchar_t *wresolved_path;
1745 char *res;
1746 size_t r;
1747 cpath = _Py_EncodeLocaleRaw(path, NULL);
1748 if (cpath == NULL) {
1749 errno = EINVAL;
1750 return NULL;
1751 }
1752 res = realpath(cpath, cresolved_path);
1753 PyMem_RawFree(cpath);
1754 if (res == NULL)
1755 return NULL;
1756
1757 wresolved_path = Py_DecodeLocale(cresolved_path, &r);
1758 if (wresolved_path == NULL) {
1759 errno = EINVAL;
1760 return NULL;
1761 }
1762 /* wresolved_path must have space to store the trailing NUL character */
1763 if (resolved_path_len <= r) {
1764 PyMem_RawFree(wresolved_path);
1765 errno = EINVAL;
1766 return NULL;
1767 }
1768 wcsncpy(resolved_path, wresolved_path, resolved_path_len);
1769 PyMem_RawFree(wresolved_path);
1770 return resolved_path;
1771 }
1772 #endif
1773
1774
1775 #ifndef MS_WINDOWS
1776 int
_Py_isabs(const wchar_t * path)1777 _Py_isabs(const wchar_t *path)
1778 {
1779 return (path[0] == SEP);
1780 }
1781 #endif
1782
1783
1784 /* Get an absolute path.
1785 On error (ex: fail to get the current directory), return -1.
1786 On memory allocation failure, set *abspath_p to NULL and return 0.
1787 On success, return a newly allocated to *abspath_p to and return 0.
1788 The string must be freed by PyMem_RawFree(). */
1789 int
_Py_abspath(const wchar_t * path,wchar_t ** abspath_p)1790 _Py_abspath(const wchar_t *path, wchar_t **abspath_p)
1791 {
1792 #ifdef MS_WINDOWS
1793 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
1794 DWORD result;
1795
1796 result = GetFullPathNameW(path,
1797 Py_ARRAY_LENGTH(woutbuf), woutbuf,
1798 NULL);
1799 if (!result) {
1800 return -1;
1801 }
1802
1803 if (result > Py_ARRAY_LENGTH(woutbuf)) {
1804 if ((size_t)result <= (size_t)PY_SSIZE_T_MAX / sizeof(wchar_t)) {
1805 woutbufp = PyMem_RawMalloc((size_t)result * sizeof(wchar_t));
1806 }
1807 else {
1808 woutbufp = NULL;
1809 }
1810 if (!woutbufp) {
1811 *abspath_p = NULL;
1812 return 0;
1813 }
1814
1815 result = GetFullPathNameW(path, result, woutbufp, NULL);
1816 if (!result) {
1817 PyMem_RawFree(woutbufp);
1818 return -1;
1819 }
1820 }
1821
1822 if (woutbufp != woutbuf) {
1823 *abspath_p = woutbufp;
1824 return 0;
1825 }
1826
1827 *abspath_p = _PyMem_RawWcsdup(woutbufp);
1828 return 0;
1829 #else
1830 if (_Py_isabs(path)) {
1831 *abspath_p = _PyMem_RawWcsdup(path);
1832 return 0;
1833 }
1834
1835 wchar_t cwd[MAXPATHLEN + 1];
1836 cwd[Py_ARRAY_LENGTH(cwd) - 1] = 0;
1837 if (!_Py_wgetcwd(cwd, Py_ARRAY_LENGTH(cwd) - 1)) {
1838 /* unable to get the current directory */
1839 return -1;
1840 }
1841
1842 size_t cwd_len = wcslen(cwd);
1843 size_t path_len = wcslen(path);
1844 size_t len = cwd_len + 1 + path_len + 1;
1845 if (len <= (size_t)PY_SSIZE_T_MAX / sizeof(wchar_t)) {
1846 *abspath_p = PyMem_RawMalloc(len * sizeof(wchar_t));
1847 }
1848 else {
1849 *abspath_p = NULL;
1850 }
1851 if (*abspath_p == NULL) {
1852 return 0;
1853 }
1854
1855 wchar_t *abspath = *abspath_p;
1856 memcpy(abspath, cwd, cwd_len * sizeof(wchar_t));
1857 abspath += cwd_len;
1858
1859 *abspath = (wchar_t)SEP;
1860 abspath++;
1861
1862 memcpy(abspath, path, path_len * sizeof(wchar_t));
1863 abspath += path_len;
1864
1865 *abspath = 0;
1866 return 0;
1867 #endif
1868 }
1869
1870
1871 /* Get the current directory. buflen is the buffer size in wide characters
1872 including the null character. Decode the path from the locale encoding.
1873
1874 Return NULL on getcwd() error, on decoding error, or if 'buf' is
1875 too short. */
1876 wchar_t*
_Py_wgetcwd(wchar_t * buf,size_t buflen)1877 _Py_wgetcwd(wchar_t *buf, size_t buflen)
1878 {
1879 #ifdef MS_WINDOWS
1880 int ibuflen = (int)Py_MIN(buflen, INT_MAX);
1881 return _wgetcwd(buf, ibuflen);
1882 #else
1883 char fname[MAXPATHLEN];
1884 wchar_t *wname;
1885 size_t len;
1886
1887 if (getcwd(fname, Py_ARRAY_LENGTH(fname)) == NULL)
1888 return NULL;
1889 wname = Py_DecodeLocale(fname, &len);
1890 if (wname == NULL)
1891 return NULL;
1892 /* wname must have space to store the trailing NUL character */
1893 if (buflen <= len) {
1894 PyMem_RawFree(wname);
1895 return NULL;
1896 }
1897 wcsncpy(buf, wname, buflen);
1898 PyMem_RawFree(wname);
1899 return buf;
1900 #endif
1901 }
1902
1903 /* Duplicate a file descriptor. The new file descriptor is created as
1904 non-inheritable. Return a new file descriptor on success, raise an OSError
1905 exception and return -1 on error.
1906
1907 The GIL is released to call dup(). The caller must hold the GIL. */
1908 int
_Py_dup(int fd)1909 _Py_dup(int fd)
1910 {
1911 #ifdef MS_WINDOWS
1912 HANDLE handle;
1913 #endif
1914
1915 assert(PyGILState_Check());
1916
1917 #ifdef MS_WINDOWS
1918 _Py_BEGIN_SUPPRESS_IPH
1919 handle = (HANDLE)_get_osfhandle(fd);
1920 _Py_END_SUPPRESS_IPH
1921 if (handle == INVALID_HANDLE_VALUE) {
1922 PyErr_SetFromErrno(PyExc_OSError);
1923 return -1;
1924 }
1925
1926 Py_BEGIN_ALLOW_THREADS
1927 _Py_BEGIN_SUPPRESS_IPH
1928 fd = dup(fd);
1929 _Py_END_SUPPRESS_IPH
1930 Py_END_ALLOW_THREADS
1931 if (fd < 0) {
1932 PyErr_SetFromErrno(PyExc_OSError);
1933 return -1;
1934 }
1935
1936 if (_Py_set_inheritable(fd, 0, NULL) < 0) {
1937 _Py_BEGIN_SUPPRESS_IPH
1938 close(fd);
1939 _Py_END_SUPPRESS_IPH
1940 return -1;
1941 }
1942 #elif defined(HAVE_FCNTL_H) && defined(F_DUPFD_CLOEXEC)
1943 Py_BEGIN_ALLOW_THREADS
1944 _Py_BEGIN_SUPPRESS_IPH
1945 fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
1946 _Py_END_SUPPRESS_IPH
1947 Py_END_ALLOW_THREADS
1948 if (fd < 0) {
1949 PyErr_SetFromErrno(PyExc_OSError);
1950 return -1;
1951 }
1952
1953 #else
1954 Py_BEGIN_ALLOW_THREADS
1955 _Py_BEGIN_SUPPRESS_IPH
1956 fd = dup(fd);
1957 _Py_END_SUPPRESS_IPH
1958 Py_END_ALLOW_THREADS
1959 if (fd < 0) {
1960 PyErr_SetFromErrno(PyExc_OSError);
1961 return -1;
1962 }
1963
1964 if (_Py_set_inheritable(fd, 0, NULL) < 0) {
1965 _Py_BEGIN_SUPPRESS_IPH
1966 close(fd);
1967 _Py_END_SUPPRESS_IPH
1968 return -1;
1969 }
1970 #endif
1971 return fd;
1972 }
1973
1974 #ifndef MS_WINDOWS
1975 /* Get the blocking mode of the file descriptor.
1976 Return 0 if the O_NONBLOCK flag is set, 1 if the flag is cleared,
1977 raise an exception and return -1 on error. */
1978 int
_Py_get_blocking(int fd)1979 _Py_get_blocking(int fd)
1980 {
1981 int flags;
1982 _Py_BEGIN_SUPPRESS_IPH
1983 flags = fcntl(fd, F_GETFL, 0);
1984 _Py_END_SUPPRESS_IPH
1985 if (flags < 0) {
1986 PyErr_SetFromErrno(PyExc_OSError);
1987 return -1;
1988 }
1989
1990 return !(flags & O_NONBLOCK);
1991 }
1992
1993 /* Set the blocking mode of the specified file descriptor.
1994
1995 Set the O_NONBLOCK flag if blocking is False, clear the O_NONBLOCK flag
1996 otherwise.
1997
1998 Return 0 on success, raise an exception and return -1 on error. */
1999 int
_Py_set_blocking(int fd,int blocking)2000 _Py_set_blocking(int fd, int blocking)
2001 {
2002 #if defined(HAVE_SYS_IOCTL_H) && defined(FIONBIO)
2003 int arg = !blocking;
2004 if (ioctl(fd, FIONBIO, &arg) < 0)
2005 goto error;
2006 #else
2007 int flags, res;
2008
2009 _Py_BEGIN_SUPPRESS_IPH
2010 flags = fcntl(fd, F_GETFL, 0);
2011 if (flags >= 0) {
2012 if (blocking)
2013 flags = flags & (~O_NONBLOCK);
2014 else
2015 flags = flags | O_NONBLOCK;
2016
2017 res = fcntl(fd, F_SETFL, flags);
2018 } else {
2019 res = -1;
2020 }
2021 _Py_END_SUPPRESS_IPH
2022
2023 if (res < 0)
2024 goto error;
2025 #endif
2026 return 0;
2027
2028 error:
2029 PyErr_SetFromErrno(PyExc_OSError);
2030 return -1;
2031 }
2032 #endif
2033
2034
2035 int
_Py_GetLocaleconvNumeric(struct lconv * lc,PyObject ** decimal_point,PyObject ** thousands_sep)2036 _Py_GetLocaleconvNumeric(struct lconv *lc,
2037 PyObject **decimal_point, PyObject **thousands_sep)
2038 {
2039 assert(decimal_point != NULL);
2040 assert(thousands_sep != NULL);
2041
2042 #ifndef MS_WINDOWS
2043 int change_locale = 0;
2044 if ((strlen(lc->decimal_point) > 1 || ((unsigned char)lc->decimal_point[0]) > 127)) {
2045 change_locale = 1;
2046 }
2047 if ((strlen(lc->thousands_sep) > 1 || ((unsigned char)lc->thousands_sep[0]) > 127)) {
2048 change_locale = 1;
2049 }
2050
2051 /* Keep a copy of the LC_CTYPE locale */
2052 char *oldloc = NULL, *loc = NULL;
2053 if (change_locale) {
2054 oldloc = setlocale(LC_CTYPE, NULL);
2055 if (!oldloc) {
2056 PyErr_SetString(PyExc_RuntimeWarning,
2057 "failed to get LC_CTYPE locale");
2058 return -1;
2059 }
2060
2061 oldloc = _PyMem_Strdup(oldloc);
2062 if (!oldloc) {
2063 PyErr_NoMemory();
2064 return -1;
2065 }
2066
2067 loc = setlocale(LC_NUMERIC, NULL);
2068 if (loc != NULL && strcmp(loc, oldloc) == 0) {
2069 loc = NULL;
2070 }
2071
2072 if (loc != NULL) {
2073 /* Only set the locale temporarily the LC_CTYPE locale
2074 if LC_NUMERIC locale is different than LC_CTYPE locale and
2075 decimal_point and/or thousands_sep are non-ASCII or longer than
2076 1 byte */
2077 setlocale(LC_CTYPE, loc);
2078 }
2079 }
2080
2081 #define GET_LOCALE_STRING(ATTR) PyUnicode_DecodeLocale(lc->ATTR, NULL)
2082 #else /* MS_WINDOWS */
2083 /* Use _W_* fields of Windows strcut lconv */
2084 #define GET_LOCALE_STRING(ATTR) PyUnicode_FromWideChar(lc->_W_ ## ATTR, -1)
2085 #endif /* MS_WINDOWS */
2086
2087 int res = -1;
2088
2089 *decimal_point = GET_LOCALE_STRING(decimal_point);
2090 if (*decimal_point == NULL) {
2091 goto done;
2092 }
2093
2094 *thousands_sep = GET_LOCALE_STRING(thousands_sep);
2095 if (*thousands_sep == NULL) {
2096 goto done;
2097 }
2098
2099 res = 0;
2100
2101 done:
2102 #ifndef MS_WINDOWS
2103 if (loc != NULL) {
2104 setlocale(LC_CTYPE, oldloc);
2105 }
2106 PyMem_Free(oldloc);
2107 #endif
2108 return res;
2109
2110 #undef GET_LOCALE_STRING
2111 }
2112