diff -r ab25f53c5c25 Modules/_cursesmodule.c --- a/Modules/_cursesmodule.c Fri Feb 10 10:34:37 2017 +0100 +++ b/Modules/_cursesmodule.c Fri Feb 10 11:10:44 2017 +0100 @@ -1715,30 +1715,90 @@ PyCursesWindow_Overwrite(PyCursesWindowO } } +static void +close_temporary_file(PyObject *fp) +{ + PyObject *exc, *val, *tb, *res; + + PyErr_Fetch(&exc, &val, &tb); + + res = PyObject_CallMethod(fp, "close", NULL); + if (res) { + Py_DECREF(res); + } + else { + PyErr_WriteUnraisable(fp); + } + + PyErr_Restore(exc, val, tb); +} + +static PyObject* +temporary_file(FILE **fp) +{ + PyObject *tempfile, *fileobj, *fileno; + int fd, fd2; + + tempfile = PyImport_ImportModuleNoBlock("tempfile"); + if (tempfile == NULL) { + return NULL; + } + + fileobj = PyObject_CallMethod(tempfile, "TemporaryFile", NULL); + Py_DECREF(tempfile); + if (fileobj == NULL) { + return NULL; + } + + fileno = PyObject_CallMethod(fileobj, "fileno", NULL); + if (fileno == NULL) { + goto error; + } + fd = _PyLong_AsInt(fileno); + Py_DECREF(fileno); + if (fd < 0 && PyErr_Occurred()) { + goto error; + } + + /* Duplicate the file descriptor to be able call fileobj.close() + and fclose() */ + fd2 = _Py_dup(fd); + if (fd2 < 0) { + goto error; + } + + *fp = fdopen(fd2, "wb+"); + if (*fp == NULL) { + close(fd2); + goto error; + } + return fileobj; + +error: + close_temporary_file(fileobj); + Py_DECREF(fileobj); + return NULL; +} + static PyObject * PyCursesWindow_PutWin(PyCursesWindowObject *self, PyObject *stream) { /* We have to simulate this by writing to a temporary FILE*, then reading back, then writing to the argument stream. */ - char fn[100]; - int fd = -1; - FILE *fp = NULL; + PyObject *fileobj; + FILE *fp; PyObject *res = NULL; - strcpy(fn, "/tmp/py.curses.putwin.XXXXXX"); - fd = mkstemp(fn); - if (fd < 0) - return PyErr_SetFromErrnoWithFilename(PyExc_IOError, fn); - if (_Py_set_inheritable(fd, 0, NULL) < 0) - goto exit; - fp = fdopen(fd, "wb+"); - if (fp == NULL) { - PyErr_SetFromErrnoWithFilename(PyExc_IOError, fn); + fileobj = temporary_file(&fp); + if (fileobj == NULL) { + return NULL; + } + + res = PyCursesCheckERR(putwin(self->win, fp), "putwin"); + if (res == NULL) { goto exit; } - res = PyCursesCheckERR(putwin(self->win, fp), "putwin"); - if (res == NULL) - goto exit; + fseek(fp, 0, 0); while (1) { char buf[BUFSIZ]; @@ -1754,11 +1814,13 @@ PyCursesWindow_PutWin(PyCursesWindowObje } exit: - if (fp != NULL) + if (fp) { fclose(fp); - else if (fd != -1) - close(fd); - remove(fn); + } + if (fileobj) { + close_temporary_file(fileobj); + Py_DECREF(fileobj); + } return res; } @@ -2278,9 +2340,8 @@ PyCurses_UngetMouse(PyObject *self, PyOb static PyObject * PyCurses_GetWin(PyCursesWindowObject *self, PyObject *stream) { - char fn[100]; - int fd = -1; - FILE *fp = NULL; + PyObject *fileobj; + FILE *fp; PyObject *data; size_t datalen; WINDOW *win; @@ -2289,16 +2350,9 @@ PyCurses_GetWin(PyCursesWindowObject *se PyCursesInitialised; - strcpy(fn, "/tmp/py.curses.getwin.XXXXXX"); - fd = mkstemp(fn); - if (fd < 0) - return PyErr_SetFromErrnoWithFilename(PyExc_IOError, fn); - if (_Py_set_inheritable(fd, 0, NULL) < 0) - goto error; - fp = fdopen(fd, "wb+"); - if (fp == NULL) { - PyErr_SetFromErrnoWithFilename(PyExc_IOError, fn); - goto error; + fileobj = temporary_file(&fp); + if (fileobj == NULL) { + return NULL; } data = _PyObject_CallMethodId(stream, &PyId_read, NULL); @@ -2314,7 +2368,7 @@ PyCurses_GetWin(PyCursesWindowObject *se datalen = PyBytes_GET_SIZE(data); if (fwrite(PyBytes_AS_STRING(data), 1, datalen, fp) != datalen) { Py_DECREF(data); - PyErr_SetFromErrnoWithFilename(PyExc_IOError, fn); + PyErr_SetFromErrno(PyExc_OSError); goto error; } Py_DECREF(data); @@ -2328,11 +2382,13 @@ PyCurses_GetWin(PyCursesWindowObject *se res = PyCursesWindow_New(win, NULL); error: - if (fp != NULL) + if (fp) { fclose(fp); - else if (fd != -1) - close(fd); - remove(fn); + } + if (fileobj) { + close_temporary_file(fileobj); + Py_DECREF(fileobj); + } return res; }