annotate Python/fileutils.c @ 76329:005fd1fe31ab

Issue #14582: Import returns the module returned by a loader instead of sys.modules when possible. This is being done for two reasons. One is to gain a little bit of performance by skipping an unnecessary dict lookup in sys.modules. But the other (and main) reason is to be a little bit more clear in how things should work from the perspective of import's interactions with loaders. Otherwise loaders can easily forget to return the module even though PEP 302 explicitly states they are expected to return the module they loaded.
author Brett Cannon <brett@python.org>
date Sun, 15 Apr 2012 15:24:04 -0400
parents c80d9a0bd5a0
children 5db6d9ddf6e8 13dd8199c112
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
1 #include "Python.h"
65164
1f3919af8a53 Fix fileutils for Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65163
diff changeset
2 #ifdef MS_WINDOWS
1f3919af8a53 Fix fileutils for Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65163
diff changeset
3 # include <windows.h>
1f3919af8a53 Fix fileutils for Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65163
diff changeset
4 #endif
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
5
75353
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
6 #ifdef HAVE_LANGINFO_H
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
7 #include <langinfo.h>
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
8 #endif
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
9
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
10 PyObject *
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
11 _Py_device_encoding(int fd)
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
12 {
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
13 #if defined(MS_WINDOWS) || defined(MS_WIN64)
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
14 UINT cp;
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
15 #endif
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
16 if (!_PyVerify_fd(fd) || !isatty(fd)) {
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
17 Py_RETURN_NONE;
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
18 }
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
19 #if defined(MS_WINDOWS) || defined(MS_WIN64)
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
20 if (fd == 0)
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
21 cp = GetConsoleCP();
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
22 else if (fd == 1 || fd == 2)
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
23 cp = GetConsoleOutputCP();
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
24 else
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
25 cp = 0;
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
26 /* GetConsoleCP() and GetConsoleOutputCP() return 0 if the application
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
27 has no console */
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
28 if (cp != 0)
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
29 return PyUnicode_FromFormat("cp%u", (unsigned int)cp);
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
30 #elif defined(CODESET)
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
31 {
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
32 char *codeset = nl_langinfo(CODESET);
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
33 if (codeset != NULL && codeset[0] != 0)
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
34 return PyUnicode_FromString(codeset);
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
35 }
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
36 #endif
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
37 Py_RETURN_NONE;
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
38 }
c80d9a0bd5a0 Issue #14153 Create _Py_device_encoding() to prevent _io from having to import
Brett Cannon <brett@python.org>
parents: 74129
diff changeset
39
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
40 #ifdef HAVE_STAT
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
41
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
42 /* Decode a byte string from the locale encoding with the
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
43 surrogateescape error handler (undecodable bytes are decoded as characters
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
44 in range U+DC80..U+DCFF). If a byte sequence can be decoded as a surrogate
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
45 character, escape the bytes using the surrogateescape error handler instead
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
46 of decoding them.
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
47
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
48 Use _Py_wchar2char() to encode the character string back to a byte string.
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
49
65412
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
50 Return a pointer to a newly allocated wide character string (use
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
51 PyMem_Free() to free the memory) and write the number of written wide
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
52 characters excluding the null character into *size if size is not NULL, or
74002
279b0aee0cfb Add PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 73593
diff changeset
53 NULL on error (decoding or memory allocation error). If size is not NULL,
279b0aee0cfb Add PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 73593
diff changeset
54 *size is set to (size_t)-1 on memory error and (size_t)-2 on decoding
279b0aee0cfb Add PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 73593
diff changeset
55 error.
66094
76a1c5e88352 _Py_char2wchar() frees the memory on conversion error
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66092
diff changeset
56
76a1c5e88352 _Py_char2wchar() frees the memory on conversion error
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66092
diff changeset
57 Conversion errors should never happen, unless there is a bug in the C
76a1c5e88352 _Py_char2wchar() frees the memory on conversion error
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66092
diff changeset
58 library. */
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
59 wchar_t*
65412
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
60 _Py_char2wchar(const char* arg, size_t *size)
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
61 {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
62 wchar_t *res;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
63 #ifdef HAVE_BROKEN_MBSTOWCS
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
64 /* Some platforms have a broken implementation of
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
65 * mbstowcs which does not count the characters that
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
66 * would result from conversion. Use an upper bound.
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
67 */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
68 size_t argsize = strlen(arg);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
69 #else
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
70 size_t argsize = mbstowcs(NULL, arg, 0);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
71 #endif
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
72 size_t count;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
73 unsigned char *in;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
74 wchar_t *out;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
75 #ifdef HAVE_MBRTOWC
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
76 mbstate_t mbs;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
77 #endif
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
78 if (argsize != (size_t)-1) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
79 res = (wchar_t *)PyMem_Malloc((argsize+1)*sizeof(wchar_t));
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
80 if (!res)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
81 goto oom;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
82 count = mbstowcs(res, arg, argsize+1);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
83 if (count != (size_t)-1) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
84 wchar_t *tmp;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
85 /* Only use the result if it contains no
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
86 surrogate characters. */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
87 for (tmp = res; *tmp != 0 &&
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
88 (*tmp < 0xd800 || *tmp > 0xdfff); tmp++)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
89 ;
65412
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
90 if (*tmp == 0) {
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
91 if (size != NULL)
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
92 *size = count;
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
93 return res;
65412
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
94 }
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
95 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
96 PyMem_Free(res);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
97 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
98 /* Conversion failed. Fall back to escaping with surrogateescape. */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
99 #ifdef HAVE_MBRTOWC
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
100 /* Try conversion with mbrtwoc (C99), and escape non-decodable bytes. */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
101
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
102 /* Overallocate; as multi-byte characters are in the argument, the
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
103 actual output could use less memory. */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
104 argsize = strlen(arg) + 1;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
105 res = (wchar_t*)PyMem_Malloc(argsize*sizeof(wchar_t));
66094
76a1c5e88352 _Py_char2wchar() frees the memory on conversion error
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66092
diff changeset
106 if (!res)
76a1c5e88352 _Py_char2wchar() frees the memory on conversion error
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66092
diff changeset
107 goto oom;
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
108 in = (unsigned char*)arg;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
109 out = res;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
110 memset(&mbs, 0, sizeof mbs);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
111 while (argsize) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
112 size_t converted = mbrtowc(out, (char*)in, argsize, &mbs);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
113 if (converted == 0)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
114 /* Reached end of string; null char stored. */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
115 break;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
116 if (converted == (size_t)-2) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
117 /* Incomplete character. This should never happen,
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
118 since we provide everything that we have -
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
119 unless there is a bug in the C library, or I
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
120 misunderstood how mbrtowc works. */
66094
76a1c5e88352 _Py_char2wchar() frees the memory on conversion error
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66092
diff changeset
121 PyMem_Free(res);
74002
279b0aee0cfb Add PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 73593
diff changeset
122 if (size != NULL)
279b0aee0cfb Add PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 73593
diff changeset
123 *size = (size_t)-2;
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
124 return NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
125 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
126 if (converted == (size_t)-1) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
127 /* Conversion error. Escape as UTF-8b, and start over
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
128 in the initial shift state. */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
129 *out++ = 0xdc00 + *in++;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
130 argsize--;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
131 memset(&mbs, 0, sizeof mbs);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
132 continue;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
133 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
134 if (*out >= 0xd800 && *out <= 0xdfff) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
135 /* Surrogate character. Escape the original
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
136 byte sequence with surrogateescape. */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
137 argsize -= converted;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
138 while (converted--)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
139 *out++ = 0xdc00 + *in++;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
140 continue;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
141 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
142 /* successfully converted some bytes */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
143 in += converted;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
144 argsize -= converted;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
145 out++;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
146 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
147 #else
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
148 /* Cannot use C locale for escaping; manually escape as if charset
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
149 is ASCII (i.e. escape all bytes > 128. This will still roundtrip
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
150 correctly in the locale's charset, which must be an ASCII superset. */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
151 res = PyMem_Malloc((strlen(arg)+1)*sizeof(wchar_t));
74002
279b0aee0cfb Add PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 73593
diff changeset
152 if (!res)
279b0aee0cfb Add PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 73593
diff changeset
153 goto oom;
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
154 in = (unsigned char*)arg;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
155 out = res;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
156 while(*in)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
157 if(*in < 128)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
158 *out++ = *in++;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
159 else
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
160 *out++ = 0xdc00 + *in++;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
161 *out = 0;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
162 #endif
65412
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
163 if (size != NULL)
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
164 *size = out - res;
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
165 return res;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
166 oom:
74002
279b0aee0cfb Add PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 73593
diff changeset
167 if (size != NULL)
279b0aee0cfb Add PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 73593
diff changeset
168 *size = (size_t)-1;
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
169 return NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
170 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
171
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
172 /* Encode a (wide) character string to the locale encoding with the
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
173 surrogateescape error handler (characters in range U+DC80..U+DCFF are
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
174 converted to bytes 0x80..0xFF).
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
175
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
176 This function is the reverse of _Py_char2wchar().
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
177
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
178 Return a pointer to a newly allocated byte string (use PyMem_Free() to free
74002
279b0aee0cfb Add PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 73593
diff changeset
179 the memory), or NULL on encoding or memory allocation error.
66092
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
180
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
181 If error_pos is not NULL: *error_pos is the index of the invalid character
74002
279b0aee0cfb Add PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 73593
diff changeset
182 on encoding error, or (size_t)-1 otherwise. */
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
183 char*
66092
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
184 _Py_wchar2char(const wchar_t *text, size_t *error_pos)
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
185 {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
186 const size_t len = wcslen(text);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
187 char *result = NULL, *bytes = NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
188 size_t i, size, converted;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
189 wchar_t c, buf[2];
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
190
66092
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
191 if (error_pos != NULL)
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
192 *error_pos = (size_t)-1;
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
193
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
194 /* The function works in two steps:
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
195 1. compute the length of the output buffer in bytes (size)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
196 2. outputs the bytes */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
197 size = 0;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
198 buf[1] = 0;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
199 while (1) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
200 for (i=0; i < len; i++) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
201 c = text[i];
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
202 if (c >= 0xdc80 && c <= 0xdcff) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
203 /* UTF-8b surrogate */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
204 if (bytes != NULL) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
205 *bytes++ = c - 0xdc00;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
206 size--;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
207 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
208 else
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
209 size++;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
210 continue;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
211 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
212 else {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
213 buf[0] = c;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
214 if (bytes != NULL)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
215 converted = wcstombs(bytes, buf, size);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
216 else
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
217 converted = wcstombs(NULL, buf, 0);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
218 if (converted == (size_t)-1) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
219 if (result != NULL)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
220 PyMem_Free(result);
66092
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
221 if (error_pos != NULL)
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
222 *error_pos = i;
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
223 return NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
224 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
225 if (bytes != NULL) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
226 bytes += converted;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
227 size -= converted;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
228 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
229 else
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
230 size += converted;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
231 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
232 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
233 if (result != NULL) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
234 *bytes = 0;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
235 break;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
236 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
237
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
238 size += 1; /* nul byte at the end */
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
239 result = PyMem_Malloc(size);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
240 if (result == NULL)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
241 return NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
242 bytes = result;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
243 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
244 return result;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
245 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
246
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
247 /* In principle, this should use HAVE__WSTAT, and _wstat
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
248 should be detected by autoconf. However, no current
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
249 POSIX system provides that function, so testing for
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
250 it is pointless.
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
251 Not sure whether the MS_WINDOWS guards are necessary:
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
252 perhaps for cygwin/mingw builds?
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
253 */
65164
1f3919af8a53 Fix fileutils for Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65163
diff changeset
254 #if defined(HAVE_STAT) && !defined(MS_WINDOWS)
65168
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
255
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
256 /* Get file status. Encode the path to the locale encoding. */
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
257
65164
1f3919af8a53 Fix fileutils for Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65163
diff changeset
258 int
1f3919af8a53 Fix fileutils for Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65163
diff changeset
259 _Py_wstat(const wchar_t* path, struct stat *buf)
1f3919af8a53 Fix fileutils for Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65163
diff changeset
260 {
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
261 int err;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
262 char *fname;
66092
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
263 fname = _Py_wchar2char(path, NULL);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
264 if (fname == NULL) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
265 errno = EINVAL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
266 return -1;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
267 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
268 err = stat(fname, buf);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
269 PyMem_Free(fname);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
270 return err;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
271 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
272 #endif
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
273
65168
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
274 /* Call _wstat() on Windows, or encode the path to the filesystem encoding and
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
275 call stat() otherwise. Only fill st_mode attribute on Windows.
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
276
74058
2a140b01d343 import.c now catchs _Py_stat() exceptions
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74002
diff changeset
277 Return 0 on success, -1 on _wstat() / stat() error, -2 if an exception was
2a140b01d343 import.c now catchs _Py_stat() exceptions
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74002
diff changeset
278 raised. */
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
279
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
280 int
65165
2147cc152227 _Py_stat() and _Py_fopen(): avoid PyUnicode_AsWideCharString() on Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65164
diff changeset
281 _Py_stat(PyObject *path, struct stat *statbuf)
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
282 {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
283 #ifdef MS_WINDOWS
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
284 int err;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
285 struct _stat wstatbuf;
73593
94a38ad4aebf Catch PyUnicode_AS_UNICODE() errors in fileutils.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66094
diff changeset
286 wchar_t *wpath;
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
287
73593
94a38ad4aebf Catch PyUnicode_AS_UNICODE() errors in fileutils.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66094
diff changeset
288 wpath = PyUnicode_AsUnicode(path);
94a38ad4aebf Catch PyUnicode_AS_UNICODE() errors in fileutils.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66094
diff changeset
289 if (wpath == NULL)
74058
2a140b01d343 import.c now catchs _Py_stat() exceptions
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74002
diff changeset
290 return -2;
73593
94a38ad4aebf Catch PyUnicode_AS_UNICODE() errors in fileutils.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66094
diff changeset
291 err = _wstat(wpath, &wstatbuf);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
292 if (!err)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
293 statbuf->st_mode = wstatbuf.st_mode;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
294 return err;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
295 #else
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
296 int ret;
65165
2147cc152227 _Py_stat() and _Py_fopen(): avoid PyUnicode_AsWideCharString() on Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65164
diff changeset
297 PyObject *bytes = PyUnicode_EncodeFSDefault(path);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
298 if (bytes == NULL)
74058
2a140b01d343 import.c now catchs _Py_stat() exceptions
Victor Stinner <victor.stinner@haypocalc.com>
parents: 74002
diff changeset
299 return -2;
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
300 ret = stat(PyBytes_AS_STRING(bytes), statbuf);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
301 Py_DECREF(bytes);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
302 return ret;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
303 #endif
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
304 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
305
65168
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
306 /* Open a file. Use _wfopen() on Windows, encode the path to the locale
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
307 encoding and use fopen() otherwise. */
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
308
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
309 FILE *
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
310 _Py_wfopen(const wchar_t *path, const wchar_t *mode)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
311 {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
312 #ifndef MS_WINDOWS
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
313 FILE *f;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
314 char *cpath;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
315 char cmode[10];
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
316 size_t r;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
317 r = wcstombs(cmode, mode, 10);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
318 if (r == (size_t)-1 || r >= 10) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
319 errno = EINVAL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
320 return NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
321 }
66092
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
322 cpath = _Py_wchar2char(path, NULL);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
323 if (cpath == NULL)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
324 return NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
325 f = fopen(cpath, cmode);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
326 PyMem_Free(cpath);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
327 return f;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
328 #else
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
329 return _wfopen(path, mode);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
330 #endif
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
331 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
332
65168
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
333 /* Call _wfopen() on Windows, or encode the path to the filesystem encoding and
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
334 call fopen() otherwise.
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
335
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
336 Return the new file object on success, or NULL if the file cannot be open or
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
337 (if PyErr_Occurred()) on unicode error */
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
338
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
339 FILE*
65165
2147cc152227 _Py_stat() and _Py_fopen(): avoid PyUnicode_AsWideCharString() on Windows
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65164
diff changeset
340 _Py_fopen(PyObject *path, const char *mode)
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
341 {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
342 #ifdef MS_WINDOWS
73593
94a38ad4aebf Catch PyUnicode_AS_UNICODE() errors in fileutils.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66094
diff changeset
343 wchar_t *wpath;
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
344 wchar_t wmode[10];
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
345 int usize;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
346
74129
33dea851f918 Issue #13626: Add support for SSL Diffie-Hellman key exchange, through the
Antoine Pitrou <solipsis@pitrou.net>
parents: 74085
diff changeset
347 if (!PyUnicode_Check(path)) {
33dea851f918 Issue #13626: Add support for SSL Diffie-Hellman key exchange, through the
Antoine Pitrou <solipsis@pitrou.net>
parents: 74085
diff changeset
348 PyErr_Format(PyExc_TypeError,
33dea851f918 Issue #13626: Add support for SSL Diffie-Hellman key exchange, through the
Antoine Pitrou <solipsis@pitrou.net>
parents: 74085
diff changeset
349 "str file path expected under Windows, got %R",
33dea851f918 Issue #13626: Add support for SSL Diffie-Hellman key exchange, through the
Antoine Pitrou <solipsis@pitrou.net>
parents: 74085
diff changeset
350 Py_TYPE(path));
33dea851f918 Issue #13626: Add support for SSL Diffie-Hellman key exchange, through the
Antoine Pitrou <solipsis@pitrou.net>
parents: 74085
diff changeset
351 return NULL;
33dea851f918 Issue #13626: Add support for SSL Diffie-Hellman key exchange, through the
Antoine Pitrou <solipsis@pitrou.net>
parents: 74085
diff changeset
352 }
73593
94a38ad4aebf Catch PyUnicode_AS_UNICODE() errors in fileutils.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66094
diff changeset
353 wpath = PyUnicode_AsUnicode(path);
94a38ad4aebf Catch PyUnicode_AS_UNICODE() errors in fileutils.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66094
diff changeset
354 if (wpath == NULL)
94a38ad4aebf Catch PyUnicode_AS_UNICODE() errors in fileutils.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66094
diff changeset
355 return NULL;
94a38ad4aebf Catch PyUnicode_AS_UNICODE() errors in fileutils.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66094
diff changeset
356
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
357 usize = MultiByteToWideChar(CP_ACP, 0, mode, -1, wmode, sizeof(wmode));
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
358 if (usize == 0)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
359 return NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
360
73593
94a38ad4aebf Catch PyUnicode_AS_UNICODE() errors in fileutils.c
Victor Stinner <victor.stinner@haypocalc.com>
parents: 66094
diff changeset
361 return _wfopen(wpath, wmode);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
362 #else
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
363 FILE *f;
74085
a882aa30a713 _Py_fopen now allows bytes filenames under non-Windows platforms.
Antoine Pitrou <solipsis@pitrou.net>
parents: 74058
diff changeset
364 PyObject *bytes;
a882aa30a713 _Py_fopen now allows bytes filenames under non-Windows platforms.
Antoine Pitrou <solipsis@pitrou.net>
parents: 74058
diff changeset
365 if (!PyUnicode_FSConverter(path, &bytes))
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
366 return NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
367 f = fopen(PyBytes_AS_STRING(bytes), mode);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
368 Py_DECREF(bytes);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
369 return f;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
370 #endif
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
371 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
372
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
373 #ifdef HAVE_READLINK
65168
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
374
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
375 /* Read value of symbolic link. Encode the path to the locale encoding, decode
74002
279b0aee0cfb Add PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 73593
diff changeset
376 the result from the locale encoding. Return -1 on error. */
65168
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
377
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
378 int
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
379 _Py_wreadlink(const wchar_t *path, wchar_t *buf, size_t bufsiz)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
380 {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
381 char *cpath;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
382 char cbuf[PATH_MAX];
65409
e1dc9861b43f _Py_wreadlink() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65346
diff changeset
383 wchar_t *wbuf;
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
384 int res;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
385 size_t r1;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
386
66092
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
387 cpath = _Py_wchar2char(path, NULL);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
388 if (cpath == NULL) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
389 errno = EINVAL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
390 return -1;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
391 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
392 res = (int)readlink(cpath, cbuf, PATH_MAX);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
393 PyMem_Free(cpath);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
394 if (res == -1)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
395 return -1;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
396 if (res == PATH_MAX) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
397 errno = EINVAL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
398 return -1;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
399 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
400 cbuf[res] = '\0'; /* buf will be null terminated */
65412
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
401 wbuf = _Py_char2wchar(cbuf, &r1);
65410
6dcba93d6262 _Py_wreadlink(): catch _Py_char2wchar() failure
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65409
diff changeset
402 if (wbuf == NULL) {
6dcba93d6262 _Py_wreadlink(): catch _Py_char2wchar() failure
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65409
diff changeset
403 errno = EINVAL;
6dcba93d6262 _Py_wreadlink(): catch _Py_char2wchar() failure
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65409
diff changeset
404 return -1;
6dcba93d6262 _Py_wreadlink(): catch _Py_char2wchar() failure
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65409
diff changeset
405 }
65409
e1dc9861b43f _Py_wreadlink() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65346
diff changeset
406 if (bufsiz <= r1) {
e1dc9861b43f _Py_wreadlink() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65346
diff changeset
407 PyMem_Free(wbuf);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
408 errno = EINVAL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
409 return -1;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
410 }
65409
e1dc9861b43f _Py_wreadlink() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65346
diff changeset
411 wcsncpy(buf, wbuf, bufsiz);
e1dc9861b43f _Py_wreadlink() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65346
diff changeset
412 PyMem_Free(wbuf);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
413 return (int)r1;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
414 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
415 #endif
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
416
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
417 #ifdef HAVE_REALPATH
65168
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
418
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
419 /* Return the canonicalized absolute pathname. Encode path to the locale
74002
279b0aee0cfb Add PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 73593
diff changeset
420 encoding, decode the result from the locale encoding.
279b0aee0cfb Add PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 73593
diff changeset
421 Return NULL on error. */
65168
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
422
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
423 wchar_t*
65166
8fd5d06462e6 _Py_wrealpath() requires the size of the output buffer
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65165
diff changeset
424 _Py_wrealpath(const wchar_t *path,
8fd5d06462e6 _Py_wrealpath() requires the size of the output buffer
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65165
diff changeset
425 wchar_t *resolved_path, size_t resolved_path_size)
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
426 {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
427 char *cpath;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
428 char cresolved_path[PATH_MAX];
65411
df0e348e7176 _Py_wrealpath() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65410
diff changeset
429 wchar_t *wresolved_path;
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
430 char *res;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
431 size_t r;
66092
1b5f47e2e0f0 PyUnicode_EncodeFS() raises an exception if _Py_wchar2char() fails
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65412
diff changeset
432 cpath = _Py_wchar2char(path, NULL);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
433 if (cpath == NULL) {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
434 errno = EINVAL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
435 return NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
436 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
437 res = realpath(cpath, cresolved_path);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
438 PyMem_Free(cpath);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
439 if (res == NULL)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
440 return NULL;
65411
df0e348e7176 _Py_wrealpath() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65410
diff changeset
441
65412
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
442 wresolved_path = _Py_char2wchar(cresolved_path, &r);
65411
df0e348e7176 _Py_wrealpath() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65410
diff changeset
443 if (wresolved_path == NULL) {
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
444 errno = EINVAL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
445 return NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
446 }
65411
df0e348e7176 _Py_wrealpath() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65410
diff changeset
447 if (resolved_path_size <= r) {
df0e348e7176 _Py_wrealpath() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65410
diff changeset
448 PyMem_Free(wresolved_path);
df0e348e7176 _Py_wrealpath() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65410
diff changeset
449 errno = EINVAL;
df0e348e7176 _Py_wrealpath() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65410
diff changeset
450 return NULL;
df0e348e7176 _Py_wrealpath() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65410
diff changeset
451 }
df0e348e7176 _Py_wrealpath() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65410
diff changeset
452 wcsncpy(resolved_path, wresolved_path, resolved_path_size);
df0e348e7176 _Py_wrealpath() uses _Py_char2wchar() to decode the result, to support
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65410
diff changeset
453 PyMem_Free(wresolved_path);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
454 return resolved_path;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
455 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
456 #endif
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
457
65312
a27fc0ff3678 _Py_wgetcwd() decodes the path using _Py_char2wchar() to support surrogates
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65168
diff changeset
458 /* Get the current directory. size is the buffer size in wide characters
74002
279b0aee0cfb Add PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 73593
diff changeset
459 including the null character. Decode the path from the locale encoding.
279b0aee0cfb Add PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 73593
diff changeset
460 Return NULL on error. */
65168
1c4774b4e98a fileutils.c: document which encodings are used
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65166
diff changeset
461
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
462 wchar_t*
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
463 _Py_wgetcwd(wchar_t *buf, size_t size)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
464 {
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
465 #ifdef MS_WINDOWS
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
466 return _wgetcwd(buf, size);
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
467 #else
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
468 char fname[PATH_MAX];
65312
a27fc0ff3678 _Py_wgetcwd() decodes the path using _Py_char2wchar() to support surrogates
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65168
diff changeset
469 wchar_t *wname;
65412
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
470 size_t len;
65312
a27fc0ff3678 _Py_wgetcwd() decodes the path using _Py_char2wchar() to support surrogates
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65168
diff changeset
471
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
472 if (getcwd(fname, PATH_MAX) == NULL)
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
473 return NULL;
65412
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
474 wname = _Py_char2wchar(fname, &len);
65312
a27fc0ff3678 _Py_wgetcwd() decodes the path using _Py_char2wchar() to support surrogates
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65168
diff changeset
475 if (wname == NULL)
a27fc0ff3678 _Py_wgetcwd() decodes the path using _Py_char2wchar() to support surrogates
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65168
diff changeset
476 return NULL;
65412
3794c9b50824 Add an optional size argument to _Py_char2wchar()
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65411
diff changeset
477 if (size <= len) {
65312
a27fc0ff3678 _Py_wgetcwd() decodes the path using _Py_char2wchar() to support surrogates
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65168
diff changeset
478 PyMem_Free(wname);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
479 return NULL;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
480 }
65312
a27fc0ff3678 _Py_wgetcwd() decodes the path using _Py_char2wchar() to support surrogates
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65168
diff changeset
481 wcsncpy(buf, wname, size);
a27fc0ff3678 _Py_wgetcwd() decodes the path using _Py_char2wchar() to support surrogates
Victor Stinner <victor.stinner@haypocalc.com>
parents: 65168
diff changeset
482 PyMem_Free(wname);
65162
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
483 return buf;
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
484 #endif
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
485 }
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
486
39014f0abc32 Create fileutils.c/.h
Victor Stinner <victor.stinner@haypocalc.com>
parents:
diff changeset
487 #endif