diff -r 2b7b203e3909 Modules/_cursesmodule.c --- a/Modules/_cursesmodule.c Wed Jan 11 20:18:03 2017 +0200 +++ b/Modules/_cursesmodule.c Thu Jan 12 12:12:11 2017 +0100 @@ -1720,27 +1720,86 @@ } } +#define MKSTEMP_TEMPLATE_TERMINATOR ".XXXXXX" + +static FILE * +mkstemp_with_dir(const char *tmpdir, const char *fname, char **fn, int raise) +{ + int fd; + size_t len; + FILE *fp = NULL; + + len = strlen(tmpdir); + *fn = (char *)PyMem_Malloc(len + 1 + strlen(fname) + + strlen(MKSTEMP_TEMPLATE_TERMINATOR) + 1); + if (*fn == NULL) { + PyErr_NoMemory(); + return NULL; + } + strcpy(*fn, tmpdir); + if (len != 0 && tmpdir[len - 1] != '/') + strcat(*fn, "/"); + strcat(*fn, fname); + strcat(*fn, MKSTEMP_TEMPLATE_TERMINATOR); + + if ((fd = mkstemp(*fn)) != -1) { + if (_Py_set_inheritable(fd, 0, NULL) == 0 && + (fp = fdopen(fd, "wb+")) != NULL) { + return fp; + } + remove(*fn); + close(fd); + } + + PyMem_Free(*fn); + if (raise) { + if (PyErr_Occurred() == NULL) + PyErr_SetFromErrnoWithFilename(PyExc_IOError, *fn); + } + else { + if (PyErr_Occurred() != NULL) + PyErr_Clear(); + } + return NULL; +} + +static FILE * +_mkstemp(const char *fname, char **fn) +{ + FILE *fp; + char **ptr; + char *env; + static char *envs[] = { "TMPDIR", "TEMP", "TMP", NULL}; + static char *dirs[] = { "/tmp", "/var/tmp", "/usr/tmp" , NULL}; + + /* First, try the environment. */ + for (ptr=envs; *ptr; ptr++) { + if ((env = getenv(*ptr)) == NULL) + continue; + if ((fp = mkstemp_with_dir(env, fname, fn, false)) != NULL) + return fp; + } + + /* Failing that, try OS-specific locations. */ + for (ptr=dirs; *ptr; ptr++) + if ((fp = mkstemp_with_dir(*ptr, fname, fn, false)) != NULL) + return fp; + + /* As a last resort, the current directory. */ + return mkstemp_with_dir(".", fname, fn, true); +} + 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; + char *fn; + 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); - goto exit; - } + if((fp = _mkstemp("py.curses.putwin", &fn)) == NULL) + return NULL; res = PyCursesCheckERR(putwin(self->win, fp), "putwin"); if (res == NULL) goto exit; @@ -1759,11 +1818,9 @@ } exit: - if (fp != NULL) - fclose(fp); - else if (fd != -1) - close(fd); + fclose(fp); remove(fn); + PyMem_Free(fn); return res; } @@ -2284,9 +2341,8 @@ static PyObject * PyCurses_GetWin(PyCursesWindowObject *self, PyObject *stream) { - char fn[100]; - int fd = -1; - FILE *fp = NULL; + char *fn; + FILE *fp; PyObject *data; size_t datalen; WINDOW *win; @@ -2295,18 +2351,8 @@ 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; - } - + if((fp = _mkstemp("py.curses.getwin", &fn)) == NULL) + return NULL; data = _PyObject_CallMethodId(stream, &PyId_read, NULL); if (data == NULL) goto error; @@ -2334,11 +2380,9 @@ res = PyCursesWindow_New(win, NULL); error: - if (fp != NULL) - fclose(fp); - else if (fd != -1) - close(fd); + fclose(fp); remove(fn); + PyMem_Free(fn); return res; }