1 #ifndef Py_INTERNAL_FILEUTILS_H
2 #define Py_INTERNAL_FILEUTILS_H
3 #ifdef __cplusplus
4 extern "C" {
5 #endif
6
7 #ifndef Py_BUILD_CORE
8 # error "Py_BUILD_CORE must be defined to include this header"
9 #endif
10
11 #include <locale.h> /* struct lconv */
12
13
14 struct _fileutils_state {
15 int force_ascii;
16 };
17
18 typedef enum {
19 _Py_ERROR_UNKNOWN=0,
20 _Py_ERROR_STRICT,
21 _Py_ERROR_SURROGATEESCAPE,
22 _Py_ERROR_REPLACE,
23 _Py_ERROR_IGNORE,
24 _Py_ERROR_BACKSLASHREPLACE,
25 _Py_ERROR_SURROGATEPASS,
26 _Py_ERROR_XMLCHARREFREPLACE,
27 _Py_ERROR_OTHER
28 } _Py_error_handler;
29
30 PyAPI_FUNC(_Py_error_handler) _Py_GetErrorHandler(const char *errors);
31
32 PyAPI_FUNC(int) _Py_DecodeLocaleEx(
33 const char *arg,
34 wchar_t **wstr,
35 size_t *wlen,
36 const char **reason,
37 int current_locale,
38 _Py_error_handler errors);
39
40 PyAPI_FUNC(int) _Py_EncodeLocaleEx(
41 const wchar_t *text,
42 char **str,
43 size_t *error_pos,
44 const char **reason,
45 int current_locale,
46 _Py_error_handler errors);
47
48 PyAPI_FUNC(char*) _Py_EncodeLocaleRaw(
49 const wchar_t *text,
50 size_t *error_pos);
51
52 PyAPI_FUNC(PyObject *) _Py_device_encoding(int);
53
54 #if defined(MS_WINDOWS) || defined(__APPLE__)
55 /* On Windows, the count parameter of read() is an int (bpo-9015, bpo-9611).
56 On macOS 10.13, read() and write() with more than INT_MAX bytes
57 fail with EINVAL (bpo-24658). */
58 # define _PY_READ_MAX INT_MAX
59 # define _PY_WRITE_MAX INT_MAX
60 #else
61 /* write() should truncate the input to PY_SSIZE_T_MAX bytes,
62 but it's safer to do it ourself to have a portable behaviour */
63 # define _PY_READ_MAX PY_SSIZE_T_MAX
64 # define _PY_WRITE_MAX PY_SSIZE_T_MAX
65 #endif
66
67 #ifdef MS_WINDOWS
68 struct _Py_stat_struct {
69 uint64_t st_dev;
70 uint64_t st_ino;
71 unsigned short st_mode;
72 int st_nlink;
73 int st_uid;
74 int st_gid;
75 unsigned long st_rdev;
76 __int64 st_size;
77 time_t st_atime;
78 int st_atime_nsec;
79 time_t st_mtime;
80 int st_mtime_nsec;
81 time_t st_ctime;
82 int st_ctime_nsec;
83 time_t st_birthtime;
84 int st_birthtime_nsec;
85 unsigned long st_file_attributes;
86 unsigned long st_reparse_tag;
87 uint64_t st_ino_high;
88 };
89 #else
90 # define _Py_stat_struct stat
91 #endif
92
93 PyAPI_FUNC(int) _Py_fstat(
94 int fd,
95 struct _Py_stat_struct *status);
96
97 PyAPI_FUNC(int) _Py_fstat_noraise(
98 int fd,
99 struct _Py_stat_struct *status);
100
101 PyAPI_FUNC(int) _Py_stat(
102 PyObject *path,
103 struct stat *status);
104
105 PyAPI_FUNC(int) _Py_open(
106 const char *pathname,
107 int flags);
108
109 PyAPI_FUNC(int) _Py_open_noraise(
110 const char *pathname,
111 int flags);
112
113 PyAPI_FUNC(FILE *) _Py_wfopen(
114 const wchar_t *path,
115 const wchar_t *mode);
116
117 PyAPI_FUNC(Py_ssize_t) _Py_read(
118 int fd,
119 void *buf,
120 size_t count);
121
122 PyAPI_FUNC(Py_ssize_t) _Py_write(
123 int fd,
124 const void *buf,
125 size_t count);
126
127 PyAPI_FUNC(Py_ssize_t) _Py_write_noraise(
128 int fd,
129 const void *buf,
130 size_t count);
131
132 #ifdef HAVE_READLINK
133 PyAPI_FUNC(int) _Py_wreadlink(
134 const wchar_t *path,
135 wchar_t *buf,
136 /* Number of characters of 'buf' buffer
137 including the trailing NUL character */
138 size_t buflen);
139 #endif
140
141 #ifdef HAVE_REALPATH
142 PyAPI_FUNC(wchar_t*) _Py_wrealpath(
143 const wchar_t *path,
144 wchar_t *resolved_path,
145 /* Number of characters of 'resolved_path' buffer
146 including the trailing NUL character */
147 size_t resolved_path_len);
148 #endif
149
150 PyAPI_FUNC(wchar_t*) _Py_wgetcwd(
151 wchar_t *buf,
152 /* Number of characters of 'buf' buffer
153 including the trailing NUL character */
154 size_t buflen);
155
156 PyAPI_FUNC(int) _Py_get_inheritable(int fd);
157
158 PyAPI_FUNC(int) _Py_set_inheritable(int fd, int inheritable,
159 int *atomic_flag_works);
160
161 PyAPI_FUNC(int) _Py_set_inheritable_async_safe(int fd, int inheritable,
162 int *atomic_flag_works);
163
164 PyAPI_FUNC(int) _Py_dup(int fd);
165
166 PyAPI_FUNC(int) _Py_get_blocking(int fd);
167
168 PyAPI_FUNC(int) _Py_set_blocking(int fd, int blocking);
169
170 #ifdef MS_WINDOWS
171 PyAPI_FUNC(void*) _Py_get_osfhandle_noraise(int fd);
172
173 PyAPI_FUNC(void*) _Py_get_osfhandle(int fd);
174
175 PyAPI_FUNC(int) _Py_open_osfhandle_noraise(void *handle, int flags);
176
177 PyAPI_FUNC(int) _Py_open_osfhandle(void *handle, int flags);
178 #endif /* MS_WINDOWS */
179
180 // This is used after getting NULL back from Py_DecodeLocale().
181 #define DECODE_LOCALE_ERR(NAME, LEN) \
182 ((LEN) == (size_t)-2) \
183 ? _PyStatus_ERR("cannot decode " NAME) \
184 : _PyStatus_NO_MEMORY()
185
186 PyAPI_DATA(int) _Py_HasFileSystemDefaultEncodeErrors;
187
188 PyAPI_FUNC(int) _Py_DecodeUTF8Ex(
189 const char *arg,
190 Py_ssize_t arglen,
191 wchar_t **wstr,
192 size_t *wlen,
193 const char **reason,
194 _Py_error_handler errors);
195
196 PyAPI_FUNC(int) _Py_EncodeUTF8Ex(
197 const wchar_t *text,
198 char **str,
199 size_t *error_pos,
200 const char **reason,
201 int raw_malloc,
202 _Py_error_handler errors);
203
204 PyAPI_FUNC(wchar_t*) _Py_DecodeUTF8_surrogateescape(
205 const char *arg,
206 Py_ssize_t arglen,
207 size_t *wlen);
208
209 extern int
210 _Py_wstat(const wchar_t *, struct stat *);
211
212 PyAPI_FUNC(int) _Py_GetForceASCII(void);
213
214 /* Reset "force ASCII" mode (if it was initialized).
215
216 This function should be called when Python changes the LC_CTYPE locale,
217 so the "force ASCII" mode can be detected again on the new locale
218 encoding. */
219 PyAPI_FUNC(void) _Py_ResetForceASCII(void);
220
221
222 PyAPI_FUNC(int) _Py_GetLocaleconvNumeric(
223 struct lconv *lc,
224 PyObject **decimal_point,
225 PyObject **thousands_sep);
226
227 PyAPI_FUNC(void) _Py_closerange(int first, int last);
228
229 PyAPI_FUNC(wchar_t*) _Py_GetLocaleEncoding(void);
230 PyAPI_FUNC(PyObject*) _Py_GetLocaleEncodingObject(void);
231
232 #ifdef HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION
233 extern int _Py_LocaleUsesNonUnicodeWchar(void);
234
235 extern wchar_t* _Py_DecodeNonUnicodeWchar(
236 const wchar_t* native,
237 Py_ssize_t size);
238
239 extern int _Py_EncodeNonUnicodeWchar_InPlace(
240 wchar_t* unicode,
241 Py_ssize_t size);
242 #endif
243
244 extern int _Py_isabs(const wchar_t *path);
245 extern int _Py_abspath(const wchar_t *path, wchar_t **abspath_p);
246 #ifdef MS_WINDOWS
247 extern int _PyOS_getfullpathname(const wchar_t *path, wchar_t **abspath_p);
248 #endif
249 extern wchar_t * _Py_join_relfile(const wchar_t *dirname,
250 const wchar_t *relfile);
251 extern int _Py_add_relfile(wchar_t *dirname,
252 const wchar_t *relfile,
253 size_t bufsize);
254 extern size_t _Py_find_basename(const wchar_t *filename);
255 PyAPI_FUNC(wchar_t*) _Py_normpath(wchar_t *path, Py_ssize_t size);
256 extern wchar_t *_Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *length);
257
258 // The Windows Games API family does not provide these functions
259 // so provide our own implementations. Remove them in case they get added
260 // to the Games API family
261 #if defined(MS_WINDOWS_GAMES) && !defined(MS_WINDOWS_DESKTOP)
262 #include <winerror.h>
263
264 extern HRESULT PathCchSkipRoot(const wchar_t *pszPath, const wchar_t **ppszRootEnd);
265 #endif /* defined(MS_WINDOWS_GAMES) && !defined(MS_WINDOWS_DESKTOP) */
266
267 // Macros to protect CRT calls against instant termination when passed an
268 // invalid parameter (bpo-23524). IPH stands for Invalid Parameter Handler.
269 // Usage:
270 //
271 // _Py_BEGIN_SUPPRESS_IPH
272 // ...
273 // _Py_END_SUPPRESS_IPH
274 #if defined _MSC_VER && _MSC_VER >= 1900
275
276 # include <stdlib.h> // _set_thread_local_invalid_parameter_handler()
277
278 extern _invalid_parameter_handler _Py_silent_invalid_parameter_handler;
279 # define _Py_BEGIN_SUPPRESS_IPH \
280 { _invalid_parameter_handler _Py_old_handler = \
281 _set_thread_local_invalid_parameter_handler(_Py_silent_invalid_parameter_handler);
282 # define _Py_END_SUPPRESS_IPH \
283 _set_thread_local_invalid_parameter_handler(_Py_old_handler); }
284 #else
285 # define _Py_BEGIN_SUPPRESS_IPH
286 # define _Py_END_SUPPRESS_IPH
287 #endif /* _MSC_VER >= 1900 */
288
289 #ifdef __cplusplus
290 }
291 #endif
292 #endif /* !Py_INTERNAL_FILEUTILS_H */