[pywin32-checkins] pywin32/win32/src win32consolemodule.cpp, 1.8, 1.9
OLD project page for the Python extensions for Windows
Brought to you by:
mhammond
From: Roger U. <ru...@us...> - 2006-12-11 12:18:26
|
Update of /cvsroot/pywin32/pywin32/win32/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13624/win32/src Modified Files: win32consolemodule.cpp Log Message: Duplicate handle when an existing handle is wrapped. Use PyHANDLE's error checking logic in tp_dealloc. Index: win32consolemodule.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/win32/src/win32consolemodule.cpp,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** win32consolemodule.cpp 23 Oct 2005 11:33:52 -0000 1.8 --- win32consolemodule.cpp 11 Dec 2006 12:18:24 -0000 1.9 *************** *** 758,770 **** // Use PyConsoleScreenBufferType(Handle) to wrap a pre-existing handle as returned by <om win32api.GetStdHandle>. // Will also accept a handle created by <om win32file.CreateFile> for CONIN$ or CONOUT$. ! // Only handles created by CreateConsoleScreenBuffer will be closed when Python object is destroyed class PyConsoleScreenBuffer : public PyHANDLE { public: ! PyConsoleScreenBuffer(HANDLE hconsole, BOOL bautoclose); ~PyConsoleScreenBuffer(void); static void tp_dealloc(PyObject *ob); const char *GetTypeName() {return "PyConsoleScreenBuffer";} - BOOL bAutoClose; // static struct PyMemberDef members[]; static struct PyMethodDef methods[]; --- 758,770 ---- // Use PyConsoleScreenBufferType(Handle) to wrap a pre-existing handle as returned by <om win32api.GetStdHandle>. // Will also accept a handle created by <om win32file.CreateFile> for CONIN$ or CONOUT$. ! // When an existing handle is wrapped, a copy is made using DuplicateHandle, and caller is still responsible ! // for any cleanup of original handle. class PyConsoleScreenBuffer : public PyHANDLE { public: ! PyConsoleScreenBuffer(HANDLE hconsole); ~PyConsoleScreenBuffer(void); static void tp_dealloc(PyObject *ob); const char *GetTypeName() {return "PyConsoleScreenBuffer";} // static struct PyMemberDef members[]; static struct PyMethodDef methods[]; *************** *** 900,913 **** }; - /* - ?????? Class members can't be accessed thru normal means due to offsetof failing for derived classes - which have a base with virtual methods - Maybe expose AutoClose via Get/Set methods ??????? - struct PyMemberDef PyConsoleScreenBuffer::members[] = - { - {"AutoClose", T_INT, offsetof(PyConsoleScreenBuffer, bAutoClose), 0, "Indicates whether handle should be closed when python object is destroyed"}, - {NULL} - }; - */ // @pymethod |PyConsoleScreenBuffer|SetConsoleActiveScreenBuffer|Sets this handle as the currently displayed screen buffer --- 900,903 ---- *************** *** 1567,1596 **** #define PyConsoleScreenBuffer_Check(ob) ((ob)->ob_type == &PyConsoleScreenBufferType) PyObject *PyConsoleScreenBuffer::tp_new(PyTypeObject *tp, PyObject *args, PyObject *kwargs) { static char *keywords[]={"Handle", NULL}; HANDLE h; ! if (!PyArg_ParseTupleAndKeywords(args, kwargs, "l", keywords, &h)) return NULL; ! return new PyConsoleScreenBuffer(h, FALSE); } ! PyConsoleScreenBuffer::PyConsoleScreenBuffer(HANDLE hconsole, BOOL bautoclose) : PyHANDLE(hconsole) { ob_type = &PyConsoleScreenBufferType; - bAutoClose=bautoclose; } PyConsoleScreenBuffer::~PyConsoleScreenBuffer(void) { ! // Only close handles explicitely created by CreateConsoleScreenBuffer ! // Let PyHANDLE's exception catching logic take care of it ! if (this->bAutoClose) ! this->Close(); } void PyConsoleScreenBuffer::tp_dealloc(PyObject *ob) { delete (PyConsoleScreenBuffer *)ob; } --- 1557,1607 ---- #define PyConsoleScreenBuffer_Check(ob) ((ob)->ob_type == &PyConsoleScreenBufferType) + PyObject *PyWinObject_FromConsoleScreenBuffer(HANDLE h, BOOL bDuplicate) + { + HANDLE hdup; + if (!bDuplicate) + hdup=h; + else{ + HANDLE hprocess=GetCurrentProcess(); + if (!DuplicateHandle(hprocess, h, hprocess, &hdup, 0, FALSE, DUPLICATE_SAME_ACCESS)) + return PyWin_SetAPIError("DuplicateHandle"); + } + PyObject *ret=new PyConsoleScreenBuffer(hdup); + if (ret==NULL) + PyErr_NoMemory(); + return ret; + } + PyObject *PyConsoleScreenBuffer::tp_new(PyTypeObject *tp, PyObject *args, PyObject *kwargs) { static char *keywords[]={"Handle", NULL}; HANDLE h; ! PyObject *obh; ! if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", keywords, &obh)) return NULL; ! if (!PyWinObject_AsHANDLE(obh, &h, FALSE)) ! return NULL; ! // Handle will be duplicated so caller is still responsible for original handle ! return PyWinObject_FromConsoleScreenBuffer(h, TRUE); } ! PyConsoleScreenBuffer::PyConsoleScreenBuffer(HANDLE hconsole) : PyHANDLE(hconsole) { ob_type = &PyConsoleScreenBufferType; } PyConsoleScreenBuffer::~PyConsoleScreenBuffer(void) { ! // Close happens in tp_dealloc below } void PyConsoleScreenBuffer::tp_dealloc(PyObject *ob) { + // use same error logic as in PyHANDLE::deallocFunc + PyObject *typ, *val, *tb; + PyErr_Fetch(&typ, &val, &tb); + ((PyConsoleScreenBuffer *)ob)->Close(); delete (PyConsoleScreenBuffer *)ob; + PyErr_Restore(typ, val, tb); } *************** *** 1620,1624 **** if (hconsole==INVALID_HANDLE_VALUE) return PyWin_SetAPIError("CreateConsoleScreenBuffer"); ! return new PyConsoleScreenBuffer(hconsole, TRUE); } --- 1631,1636 ---- if (hconsole==INVALID_HANDLE_VALUE) return PyWin_SetAPIError("CreateConsoleScreenBuffer"); ! // Newly created handle doesn't need to be duplicated ! return PyWinObject_FromConsoleScreenBuffer(hconsole, FALSE); } *************** *** 1986,1990 **** return Py_None; } ! return new PyConsoleScreenBuffer(h, FALSE); } --- 1998,2003 ---- return Py_None; } ! // Duplicate the handle so the processwide std handles aren't closed prematurely ! return PyWinObject_FromConsoleScreenBuffer(h, TRUE); } |