bpo-29176 Use tmpfile() in curses module (#235)

The curses module used mkstemp() + fopen() to create a temporary file in
/tmp. The /tmp directory does not exist on Android. The tmpfile()
function simplifies the task a lot. It creates a temporary file in a
correct directory, takes care of cleanup and returns FILE*.

tmpfile is supported on all platforms (C89, POSIX 2001, Android,
Windows).

Signed-off-by: Christian Heimes <christian@python.org>
diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c
index 78a79e8..4d714ce 100644
--- a/Modules/_cursesmodule.c
+++ b/Modules/_cursesmodule.c
@@ -1720,22 +1720,14 @@
 {
     /* 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;
+    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)
+    fp = tmpfile();
+    if (fp == NULL)
+        return PyErr_SetFromErrno(PyExc_OSError);
+    if (_Py_set_inheritable(fileno(fp), 0, NULL) < 0)
         goto exit;
-    fp = fdopen(fd, "wb+");
-    if (fp == NULL) {
-        PyErr_SetFromErrnoWithFilename(PyExc_IOError, fn);
-        goto exit;
-    }
     res = PyCursesCheckERR(putwin(self->win, fp), "putwin");
     if (res == NULL)
         goto exit;
@@ -1754,11 +1746,7 @@
     }
 
 exit:
-    if (fp != NULL)
-        fclose(fp);
-    else if (fd != -1)
-        close(fd);
-    remove(fn);
+    fclose(fp);
     return res;
 }
 
@@ -2278,9 +2266,7 @@
 static PyObject *
 PyCurses_GetWin(PyCursesWindowObject *self, PyObject *stream)
 {
-    char fn[100];
-    int fd = -1;
-    FILE *fp = NULL;
+    FILE *fp;
     PyObject *data;
     size_t datalen;
     WINDOW *win;
@@ -2289,17 +2275,13 @@
 
     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)
+    fp = tmpfile();
+    if (fp == NULL)
+        return PyErr_SetFromErrno(PyExc_OSError);
+
+    if (_Py_set_inheritable(fileno(fp), 0, NULL) < 0)
         goto error;
-    fp = fdopen(fd, "wb+");
-    if (fp == NULL) {
-        PyErr_SetFromErrnoWithFilename(PyExc_IOError, fn);
-        goto error;
-    }
+
 
     data = _PyObject_CallMethodId(stream, &PyId_read, NULL);
     if (data == NULL)
@@ -2314,7 +2296,7 @@
     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 +2310,7 @@
     res = PyCursesWindow_New(win, NULL);
 
 error:
-    if (fp != NULL)
-        fclose(fp);
-    else if (fd != -1)
-        close(fd);
-    remove(fn);
+    fclose(fp);
     return res;
 }