Skip to content

Commit e742bfe

Browse files
committed
On Unix, avoid a conversion to wchar_t in getpath.c
* Replace _Py_wstat() with _Py_stat() in isfile() and isxfile(). * Replace _Py_wfopen() with Py_fopen() in readlines().
1 parent 3a1b547 commit e742bfe

2 files changed

Lines changed: 49 additions & 49 deletions

File tree

Modules/getpath.c

Lines changed: 43 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -198,57 +198,67 @@ getpath_isdir(PyObject *Py_UNUSED(self), PyObject *args)
198198
static PyObject *
199199
getpath_isfile(PyObject *Py_UNUSED(self), PyObject *args)
200200
{
201-
PyObject *r = NULL;
202201
PyObject *pathobj;
203-
const wchar_t *path;
204202
if (!PyArg_ParseTuple(args, "U", &pathobj)) {
205203
return NULL;
206204
}
207-
path = PyUnicode_AsWideCharString(pathobj, NULL);
208-
if (path) {
205+
206+
int isfile;
209207
#ifdef MS_WINDOWS
210-
DWORD attr = GetFileAttributesW(path);
211-
r = (attr != INVALID_FILE_ATTRIBUTES) &&
212-
!(attr & FILE_ATTRIBUTE_DIRECTORY) ? Py_True : Py_False;
208+
wchar_t *path = PyUnicode_AsWideCharString(pathobj, NULL);
209+
if (path == NULL) {
210+
return NULL;
211+
}
212+
213+
DWORD attr = GetFileAttributesW(path);
214+
PyMem_Free(path);
215+
isfile = ((attr != INVALID_FILE_ATTRIBUTES)
216+
&& !(attr & FILE_ATTRIBUTE_DIRECTORY));
213217
#else
214-
struct stat st;
215-
r = (_Py_wstat(path, &st) == 0) && S_ISREG(st.st_mode) ? Py_True : Py_False;
216-
#endif
217-
PyMem_Free((void *)path);
218+
struct stat st;
219+
int res = _Py_stat(pathobj, &st);
220+
if (res == -2) {
221+
return NULL;
218222
}
219-
return Py_XNewRef(r);
223+
isfile = ((res == 0) && S_ISREG(st.st_mode));
224+
#endif
225+
return PyBool_FromLong(isfile);
220226
}
221227

222228

223229
static PyObject *
224230
getpath_isxfile(PyObject *Py_UNUSED(self), PyObject *args)
225231
{
226-
PyObject *r = NULL;
227232
PyObject *pathobj;
228-
const wchar_t *path;
229-
Py_ssize_t cchPath;
230233
if (!PyArg_ParseTuple(args, "U", &pathobj)) {
231234
return NULL;
232235
}
233-
path = PyUnicode_AsWideCharString(pathobj, &cchPath);
234-
if (path) {
236+
237+
int isxfile;
235238
#ifdef MS_WINDOWS
236-
DWORD attr = GetFileAttributesW(path);
237-
r = (attr != INVALID_FILE_ATTRIBUTES) &&
238-
!(attr & FILE_ATTRIBUTE_DIRECTORY) &&
239-
(cchPath >= 4) &&
240-
(CompareStringOrdinal(path + cchPath - 4, -1, L".exe", -1, 1 /* ignore case */) == CSTR_EQUAL)
241-
? Py_True : Py_False;
239+
Py_ssize_t cchPath;
240+
wchar_t *path = PyUnicode_AsWideCharString(pathobj, &cchPath);
241+
if (path == NULL) {
242+
return NULL;
243+
}
244+
245+
DWORD attr = GetFileAttributesW(path);
246+
PyMem_Free(path);
247+
isxfile = (attr != INVALID_FILE_ATTRIBUTES) &&
248+
!(attr & FILE_ATTRIBUTE_DIRECTORY) &&
249+
(cchPath >= 4) &&
250+
(CompareStringOrdinal(path + cchPath - 4, -1, L".exe", -1, 1 /* ignore case */) == CSTR_EQUAL);
242251
#else
243-
struct stat st;
244-
r = (_Py_wstat(path, &st) == 0) &&
245-
S_ISREG(st.st_mode) &&
246-
(st.st_mode & 0111)
247-
? Py_True : Py_False;
248-
#endif
249-
PyMem_Free((void *)path);
252+
struct stat st;
253+
int res = _Py_stat(pathobj, &st);
254+
if (res == -2) {
255+
return NULL;
250256
}
251-
return Py_XNewRef(r);
257+
isxfile = ((res == 0)
258+
&& S_ISREG(st.st_mode)
259+
&& (st.st_mode & 0111));
260+
#endif
261+
return PyBool_FromLong(isxfile);
252262
}
253263

254264

@@ -340,25 +350,16 @@ getpath_joinpath(PyObject *Py_UNUSED(self), PyObject *args)
340350
static PyObject *
341351
getpath_readlines(PyObject *Py_UNUSED(self), PyObject *args)
342352
{
343-
PyObject *r = NULL;
344353
PyObject *pathobj;
345-
const wchar_t *path;
346354
if (!PyArg_ParseTuple(args, "U", &pathobj)) {
347355
return NULL;
348356
}
349-
path = PyUnicode_AsWideCharString(pathobj, NULL);
350-
if (!path) {
351-
return NULL;
352-
}
353-
FILE *fp = _Py_wfopen(path, L"rb");
357+
FILE *fp = Py_fopen(pathobj, "rb");
354358
if (!fp) {
355-
PyErr_SetFromErrno(PyExc_OSError);
356-
PyMem_Free((void *)path);
357359
return NULL;
358360
}
359-
PyMem_Free((void *)path);
360361

361-
r = PyList_New(0);
362+
PyObject *r = PyList_New(0);
362363
if (!r) {
363364
fclose(fp);
364365
return NULL;

Python/fileutils.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1368,22 +1368,21 @@ _Py_stat(PyObject *path, struct stat *statbuf)
13681368
PyMem_Free(wpath);
13691369
return err;
13701370
#else
1371-
int ret;
1372-
PyObject *bytes;
1373-
char *cpath;
1374-
1375-
bytes = PyUnicode_EncodeFSDefault(path);
1376-
if (bytes == NULL)
1371+
PyObject *bytes = PyUnicode_EncodeFSDefault(path);
1372+
if (bytes == NULL) {
13771373
return -2;
1374+
}
13781375

13791376
/* check for embedded null bytes */
1377+
char *cpath;
13801378
if (PyBytes_AsStringAndSize(bytes, &cpath, NULL) == -1) {
13811379
Py_DECREF(bytes);
13821380
return -2;
13831381
}
13841382

1385-
ret = stat(cpath, statbuf);
1383+
int ret = stat(cpath, statbuf);
13861384
Py_DECREF(bytes);
1385+
assert(ret == 0 || ret == -1);
13871386
return ret;
13881387
#endif
13891388
}

0 commit comments

Comments
 (0)