Issue #28161: Opening CON for write access fails
Issue #28162: WindowsConsoleIO readall() fails if first line starts with Ctrl+Z Issue #28163: WindowsConsoleIO fileno() passes wrong flags to _open_osfhandle Issue #28164: _PyIO_get_console_type fails for various paths
This commit is contained in:
commit
b401d723ac
10
Misc/NEWS
10
Misc/NEWS
|
@ -77,6 +77,16 @@ Library
|
||||||
Windows
|
Windows
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #28161: Opening CON for write access fails
|
||||||
|
|
||||||
|
- Issue #28162: WindowsConsoleIO readall() fails if first line starts with
|
||||||
|
Ctrl+Z
|
||||||
|
|
||||||
|
- Issue #28163: WindowsConsoleIO fileno() passes wrong flags to
|
||||||
|
_open_osfhandle
|
||||||
|
|
||||||
|
- Issue #28164: _PyIO_get_console_type fails for various paths
|
||||||
|
|
||||||
- Issue #28137: Renames Windows path file to ._pth
|
- Issue #28137: Renames Windows path file to ._pth
|
||||||
|
|
||||||
- Issue #28138: Windows ._pth file should allow import site
|
- Issue #28138: Windows ._pth file should allow import site
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
#include "_iomodule.h"
|
#include "_iomodule.h"
|
||||||
|
|
||||||
|
@ -68,27 +69,34 @@ char _PyIO_get_console_type(PyObject *path_or_fd) {
|
||||||
return _get_console_type(handle);
|
return _get_console_type(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *decoded = Py_None;
|
PyObject *decoded, *decoded_upper;
|
||||||
Py_INCREF(decoded);
|
|
||||||
|
|
||||||
int d = PyUnicode_FSDecoder(path_or_fd, &decoded);
|
int d = PyUnicode_FSDecoder(path_or_fd, &decoded);
|
||||||
if (!d) {
|
if (!d) {
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
|
return '\0';
|
||||||
|
}
|
||||||
|
if (!PyUnicode_Check(decoded)) {
|
||||||
Py_CLEAR(decoded);
|
Py_CLEAR(decoded);
|
||||||
return '\0';
|
return '\0';
|
||||||
}
|
}
|
||||||
|
decoded_upper = PyObject_CallMethod(decoded, "upper", "");
|
||||||
|
Py_CLEAR(decoded);
|
||||||
|
if (!decoded_upper) {
|
||||||
|
PyErr_Clear();
|
||||||
|
return '\0';
|
||||||
|
}
|
||||||
|
|
||||||
char m = '\0';
|
char m = '\0';
|
||||||
if (!PyUnicode_Check(decoded)) {
|
if (PyUnicode_CompareWithASCIIString(decoded_upper, "CONIN$") == 0) {
|
||||||
return '\0';
|
|
||||||
} else if (PyUnicode_CompareWithASCIIString(decoded, "CONIN$") == 0) {
|
|
||||||
m = 'r';
|
m = 'r';
|
||||||
} else if (PyUnicode_CompareWithASCIIString(decoded, "CONOUT$") == 0 ||
|
} else if (PyUnicode_CompareWithASCIIString(decoded_upper, "CONOUT$") == 0) {
|
||||||
PyUnicode_CompareWithASCIIString(decoded, "CON") == 0) {
|
|
||||||
m = 'w';
|
m = 'w';
|
||||||
|
} else if (PyUnicode_CompareWithASCIIString(decoded_upper, "CON") == 0) {
|
||||||
|
m = 'x';
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_CLEAR(decoded);
|
Py_CLEAR(decoded_upper);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,6 +235,7 @@ _io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj,
|
||||||
{
|
{
|
||||||
const char *s;
|
const char *s;
|
||||||
wchar_t *name = NULL;
|
wchar_t *name = NULL;
|
||||||
|
char console_type = '\0';
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int rwa = 0;
|
int rwa = 0;
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
|
@ -270,6 +279,7 @@ _io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj,
|
||||||
|
|
||||||
Py_ssize_t length;
|
Py_ssize_t length;
|
||||||
name = PyUnicode_AsWideCharString(decodedname, &length);
|
name = PyUnicode_AsWideCharString(decodedname, &length);
|
||||||
|
console_type = _PyIO_get_console_type(decodedname);
|
||||||
Py_CLEAR(decodedname);
|
Py_CLEAR(decodedname);
|
||||||
if (name == NULL)
|
if (name == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -294,12 +304,16 @@ _io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj,
|
||||||
goto bad_mode;
|
goto bad_mode;
|
||||||
rwa = 1;
|
rwa = 1;
|
||||||
self->readable = 1;
|
self->readable = 1;
|
||||||
|
if (console_type == 'x')
|
||||||
|
console_type = 'r';
|
||||||
break;
|
break;
|
||||||
case 'w':
|
case 'w':
|
||||||
if (rwa)
|
if (rwa)
|
||||||
goto bad_mode;
|
goto bad_mode;
|
||||||
rwa = 1;
|
rwa = 1;
|
||||||
self->writable = 1;
|
self->writable = 1;
|
||||||
|
if (console_type == 'x')
|
||||||
|
console_type = 'w';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
PyErr_Format(PyExc_ValueError,
|
PyErr_Format(PyExc_ValueError,
|
||||||
|
@ -327,7 +341,7 @@ _io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->writable)
|
if (self->writable)
|
||||||
access |= GENERIC_WRITE;
|
access = GENERIC_WRITE;
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
/* Attempt to open for read/write initially, then fall back
|
/* Attempt to open for read/write initially, then fall back
|
||||||
|
@ -347,12 +361,15 @@ _io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->writable && _get_console_type(self->handle) != 'w') {
|
if (console_type == '\0')
|
||||||
|
console_type = _get_console_type(self->handle);
|
||||||
|
|
||||||
|
if (self->writable && console_type != 'w') {
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"Cannot open console input buffer for writing");
|
"Cannot open console input buffer for writing");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (self->readable && _get_console_type(self->handle) != 'r') {
|
if (self->readable && console_type != 'r') {
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"Cannot open console output buffer for reading");
|
"Cannot open console output buffer for reading");
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -440,9 +457,9 @@ _io__WindowsConsoleIO_fileno_impl(winconsoleio *self)
|
||||||
if (self->fd < 0 && self->handle != INVALID_HANDLE_VALUE) {
|
if (self->fd < 0 && self->handle != INVALID_HANDLE_VALUE) {
|
||||||
_Py_BEGIN_SUPPRESS_IPH
|
_Py_BEGIN_SUPPRESS_IPH
|
||||||
if (self->writable)
|
if (self->writable)
|
||||||
self->fd = _open_osfhandle((intptr_t)self->handle, 'wb');
|
self->fd = _open_osfhandle((intptr_t)self->handle, _O_WRONLY | _O_BINARY);
|
||||||
else
|
else
|
||||||
self->fd = _open_osfhandle((intptr_t)self->handle, 'rb');
|
self->fd = _open_osfhandle((intptr_t)self->handle, _O_RDONLY | _O_BINARY);
|
||||||
_Py_END_SUPPRESS_IPH
|
_Py_END_SUPPRESS_IPH
|
||||||
}
|
}
|
||||||
if (self->fd < 0)
|
if (self->fd < 0)
|
||||||
|
@ -776,7 +793,7 @@ _io__WindowsConsoleIO_readall_impl(winconsoleio *self)
|
||||||
len += n;
|
len += n;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len > 0 && buf[0] == '\x1a' && _buflen(self) == 0) {
|
if (len == 0 || buf[0] == '\x1a' && _buflen(self) == 0) {
|
||||||
/* when the result starts with ^Z we return an empty buffer */
|
/* when the result starts with ^Z we return an empty buffer */
|
||||||
PyMem_Free(buf);
|
PyMem_Free(buf);
|
||||||
return PyBytes_FromStringAndSize(NULL, 0);
|
return PyBytes_FromStringAndSize(NULL, 0);
|
||||||
|
|
Loading…
Reference in New Issue