* Get a FILE* handle to the file represented by the Python object */
| 209 | * Get a FILE* handle to the file represented by the Python object |
| 210 | */ |
| 211 | static inline FILE* |
| 212 | npy_PyFile_Dup2(PyObject *file, char *mode, npy_off_t *orig_pos) |
| 213 | { |
| 214 | int fd, fd2, unbuf; |
| 215 | Py_ssize_t fd2_tmp; |
| 216 | PyObject *ret, *os, *io, *io_raw; |
| 217 | npy_off_t pos; |
| 218 | FILE *handle; |
| 219 | |
| 220 | /* For Python 2 PyFileObject, use PyFile_AsFile */ |
| 221 | #if !defined(NPY_PY3K) |
| 222 | if (PyFile_Check(file)) { |
| 223 | return PyFile_AsFile(file); |
| 224 | } |
| 225 | #endif |
| 226 | |
| 227 | /* Flush first to ensure things end up in the file in the correct order */ |
| 228 | ret = PyObject_CallMethod(file, "flush", ""); |
| 229 | if (ret == NULL) { |
| 230 | return NULL; |
| 231 | } |
| 232 | Py_DECREF(ret); |
| 233 | fd = PyObject_AsFileDescriptor(file); |
| 234 | if (fd == -1) { |
| 235 | return NULL; |
| 236 | } |
| 237 | |
| 238 | /* |
| 239 | * The handle needs to be dup'd because we have to call fclose |
| 240 | * at the end |
| 241 | */ |
| 242 | os = PyImport_ImportModule("os"); |
| 243 | if (os == NULL) { |
| 244 | return NULL; |
| 245 | } |
| 246 | ret = PyObject_CallMethod(os, "dup", "i", fd); |
| 247 | Py_DECREF(os); |
| 248 | if (ret == NULL) { |
| 249 | return NULL; |
| 250 | } |
| 251 | fd2_tmp = PyNumber_AsSsize_t(ret, PyExc_IOError); |
| 252 | Py_DECREF(ret); |
| 253 | if (fd2_tmp == -1 && PyErr_Occurred()) { |
| 254 | return NULL; |
| 255 | } |
| 256 | if (fd2_tmp < INT_MIN || fd2_tmp > INT_MAX) { |
| 257 | PyErr_SetString(PyExc_IOError, |
| 258 | "Getting an 'int' from os.dup() failed"); |
| 259 | return NULL; |
| 260 | } |
| 261 | fd2 = (int)fd2_tmp; |
| 262 | |
| 263 | /* Convert to FILE* handle */ |
| 264 | #ifdef _WIN32 |
| 265 | NPY_BEGIN_SUPPRESS_IPH |
| 266 | handle = _fdopen(fd2, mode); |
| 267 | NPY_END_SUPPRESS_IPH |
| 268 | #else |
no outgoing calls
no test coverage detected