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