Skip to content

Commit f52b705

Browse files
author
Victor Stinner
committed
Create _Py_fopen() for PyUnicodeObject path
Call _wfopen() on Windows, or fopen() otherwise. Return the new file object on success, or NULL if the file cannot be open or (if PyErr_Occurred()) on unicode error.
1 parent 17d1e2a commit f52b705

2 files changed

Lines changed: 35 additions & 1 deletion

File tree

Include/Python.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@ PyAPI_FUNC(wchar_t *) _Py_char2wchar(char *);
135135
PyAPI_FUNC(char*) _Py_wchar2char(const wchar_t *text);
136136
PyAPI_FUNC(FILE *) _Py_wfopen(const wchar_t *path, const wchar_t *mode);
137137

138-
/* _Py_stat lives in import.c */
138+
/* These functions live in import.c */
139+
PyAPI_FUNC(FILE*) _Py_fopen(PyObject *unicode, const char *mode);
139140
#ifdef HAVE_STAT
140141
int _Py_stat(PyObject *unicode, struct stat *statbuf);
141142
#endif

Python/import.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1960,6 +1960,39 @@ case_ok(char *buf, Py_ssize_t len, Py_ssize_t namelen, char *name)
19601960
#endif
19611961
}
19621962

1963+
/* Call _wfopen() on Windows, or fopen() otherwise. Return the new file
1964+
object on success, or NULL if the file cannot be open or (if
1965+
PyErr_Occurred()) on unicode error */
1966+
1967+
FILE*
1968+
_Py_fopen(PyObject *unicode, const char *mode)
1969+
{
1970+
#ifdef MS_WINDOWS
1971+
wchar_t path[MAXPATHLEN+1];
1972+
wchar_t wmode[10];
1973+
Py_ssize_t len;
1974+
int usize;
1975+
1976+
len = PyUnicode_AsWideChar((PyUnicodeObject*)unicode, path, MAXPATHLEN);
1977+
if (len == -1)
1978+
return NULL;
1979+
path[len] = L'\0';
1980+
1981+
usize = MultiByteToWideChar(CP_ACP, 0, mode, -1, wmode, sizeof(wmode));
1982+
if (usize == 0)
1983+
return NULL;
1984+
1985+
return _wfopen(path, wmode);
1986+
#else
1987+
FILE *f;
1988+
PyObject *bytes = PyUnicode_EncodeFSDefault(unicode);
1989+
if (bytes == NULL)
1990+
return NULL;
1991+
f = fopen(PyBytes_AS_STRING(bytes), mode);
1992+
Py_DECREF(bytes);
1993+
return f;
1994+
#endif
1995+
}
19631996

19641997
#ifdef HAVE_STAT
19651998

0 commit comments

Comments
 (0)