Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(2586)

Side by Side Diff: Modules/_io/fileio.c

Issue 12797: io.FileIO and io.open should support openat
Patch Set: Created 1 year, 6 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Modules/_io/_iomodule.c ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* Author: Daniel Stutzbach */ 1 /* Author: Daniel Stutzbach */
2 2
3 #define PY_SSIZE_T_CLEAN 3 #define PY_SSIZE_T_CLEAN
4 #include "Python.h" 4 #include "Python.h"
5 #include "structmember.h" 5 #include "structmember.h"
6 #ifdef HAVE_SYS_TYPES_H 6 #ifdef HAVE_SYS_TYPES_H
7 #include <sys/types.h> 7 #include <sys/types.h>
8 #endif 8 #endif
9 #ifdef HAVE_SYS_STAT_H 9 #ifdef HAVE_SYS_STAT_H
10 #include <sys/stat.h> 10 #include <sys/stat.h>
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 } 205 }
206 #endif 206 #endif
207 return 0; 207 return 0;
208 } 208 }
209 209
210 210
211 static int 211 static int
212 fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) 212 fileio_init(PyObject *oself, PyObject *args, PyObject *kwds)
213 { 213 {
214 fileio *self = (fileio *) oself; 214 fileio *self = (fileio *) oself;
215 static char *kwlist[] = {"file", "mode", "closefd", NULL}; 215 static char *kwlist[] = {"file", "mode", "closefd", "opener", NULL};
216 const char *name = NULL; 216 const char *name = NULL;
217 PyObject *nameobj, *stringobj = NULL; 217 PyObject *nameobj, *stringobj = NULL, *opener = Py_None;
218 char *mode = "r"; 218 char *mode = "r";
219 char *s; 219 char *s;
220 #ifdef MS_WINDOWS 220 #ifdef MS_WINDOWS
221 Py_UNICODE *widename = NULL; 221 Py_UNICODE *widename = NULL;
222 #endif 222 #endif
223 int ret = 0; 223 int ret = 0;
224 int rwa = 0, plus = 0, append = 0; 224 int rwa = 0, plus = 0, append = 0;
225 int flags = 0; 225 int flags = 0;
226 int fd = -1; 226 int fd = -1;
227 int closefd = 1; 227 int closefd = 1;
228 228
229 assert(PyFileIO_Check(oself)); 229 assert(PyFileIO_Check(oself));
230 if (self->fd >= 0) { 230 if (self->fd >= 0) {
231 /* Have to close the existing file first. */ 231 /* Have to close the existing file first. */
232 if (internal_close(self) < 0) 232 if (internal_close(self) < 0)
233 return -1; 233 return -1;
234 } 234 }
235 235
236 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|si:fileio", 236 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|siO:fileio",
237 kwlist, &nameobj, &mode, &closefd)) 237 kwlist, &nameobj, &mode, &closefd,
238 &opener))
238 return -1; 239 return -1;
239 240
240 if (PyFloat_Check(nameobj)) { 241 if (PyFloat_Check(nameobj)) {
241 PyErr_SetString(PyExc_TypeError, 242 PyErr_SetString(PyExc_TypeError,
242 "integer argument expected, got float"); 243 "integer argument expected, got float");
243 return -1; 244 return -1;
244 } 245 }
245 246
246 fd = PyLong_AsLong(nameobj); 247 fd = PyLong_AsLong(nameobj);
247 if (fd < 0) { 248 if (fd < 0) {
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 self->closefd = closefd; 357 self->closefd = closefd;
357 } 358 }
358 else { 359 else {
359 self->closefd = 1; 360 self->closefd = 1;
360 if (!closefd) { 361 if (!closefd) {
361 PyErr_SetString(PyExc_ValueError, 362 PyErr_SetString(PyExc_ValueError,
362 "Cannot use closefd=False with file name"); 363 "Cannot use closefd=False with file name");
363 goto error; 364 goto error;
364 } 365 }
365 366
366 Py_BEGIN_ALLOW_THREADS
367 errno = 0; 367 errno = 0;
368 if (opener == Py_None) {
369 Py_BEGIN_ALLOW_THREADS
368 #ifdef MS_WINDOWS 370 #ifdef MS_WINDOWS
369 if (widename != NULL) 371 if (widename != NULL)
370 self->fd = _wopen(widename, flags, 0666); 372 self->fd = _wopen(widename, flags, 0666);
371 else 373 else
372 #endif 374 #endif
373 self->fd = open(name, flags, 0666); 375 self->fd = open(name, flags, 0666);
374 Py_END_ALLOW_THREADS 376 Py_END_ALLOW_THREADS
377 } else {
378 PyObject *fdobj = PyObject_CallFunction(
379 opener, "Oi", nameobj, flags);
380 if (fdobj == NULL)
381 goto error;
382 if (!PyLong_Check(fdobj)) {
383 Py_DECREF(fdobj);
384 PyErr_SetString(PyExc_TypeError,
385 "expected integer from opener");
386 goto error;
387 }
388
389 self->fd = PyLong_AsLong(fdobj);
390 Py_DECREF(fdobj);
391 if (self->fd == -1) {
392 goto error;
393 }
394 }
395
375 if (self->fd < 0) { 396 if (self->fd < 0) {
376 #ifdef MS_WINDOWS 397 #ifdef MS_WINDOWS
377 if (widename != NULL) 398 if (widename != NULL)
378 PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, nameobj); 399 PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, nameobj);
379 else 400 else
380 #endif 401 #endif
381 PyErr_SetFromErrnoWithFilename(PyExc_IOError, name); 402 PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
382 goto error; 403 goto error;
383 } 404 }
384 if (dircheck(self, name) < 0) 405 if (dircheck(self, name) < 0)
(...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after
1010 static PyObject * 1031 static PyObject *
1011 fileio_getstate(fileio *self) 1032 fileio_getstate(fileio *self)
1012 { 1033 {
1013 PyErr_Format(PyExc_TypeError, 1034 PyErr_Format(PyExc_TypeError,
1014 "cannot serialize '%s' object", Py_TYPE(self)->tp_name); 1035 "cannot serialize '%s' object", Py_TYPE(self)->tp_name);
1015 return NULL; 1036 return NULL;
1016 } 1037 }
1017 1038
1018 1039
1019 PyDoc_STRVAR(fileio_doc, 1040 PyDoc_STRVAR(fileio_doc,
1020 "file(name: str[, mode: str]) -> file IO object\n" 1041 "file(name: str[, mode: str][, opener: None]) -> file IO object\n"
1021 "\n" 1042 "\n"
1022 "Open a file. The mode can be 'r', 'w' or 'a' for reading (default),\n" 1043 "Open a file. The mode can be 'r', 'w' or 'a' for reading (default),\n"
1023 "writing or appending. The file will be created if it doesn't exist\n" 1044 "writing or appending. The file will be created if it doesn't exist\n"
1024 "when opened for writing or appending; it will be truncated when\n" 1045 "when opened for writing or appending; it will be truncated when\n"
1025 "opened for writing. Add a '+' to the mode to allow simultaneous\n" 1046 "opened for writing. Add a '+' to the mode to allow simultaneous\n"
1026 "reading and writing."); 1047 "reading and writing. A custom opener can be used by passing a\n"
1048 "callable as *opener*. The underlying file descriptor for the file\n"
1049 "object is then obtained by calling opener with (*name*, *flags*).\n"
1050 "*opener* must return an open file descriptor (passing os.open as\n"
1051 "*opener* results in functionality similar to passing None).");
1027 1052
1028 PyDoc_STRVAR(read_doc, 1053 PyDoc_STRVAR(read_doc,
1029 "read(size: int) -> bytes. read at most size bytes, returned as bytes.\n" 1054 "read(size: int) -> bytes. read at most size bytes, returned as bytes.\n"
1030 "\n" 1055 "\n"
1031 "Only makes one system call, so less data may be returned than requested\n" 1056 "Only makes one system call, so less data may be returned than requested\n"
1032 "In non-blocking mode, returns None if no data is available.\n" 1057 "In non-blocking mode, returns None if no data is available.\n"
1033 "On end-of-file, returns ''."); 1058 "On end-of-file, returns ''.");
1034 1059
1035 PyDoc_STRVAR(readall_doc, 1060 PyDoc_STRVAR(readall_doc,
1036 "readall() -> bytes. read all data from the file, returned as bytes.\n" 1061 "readall() -> bytes. read all data from the file, returned as bytes.\n"
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
1176 0, /* tp_base */ 1201 0, /* tp_base */
1177 0, /* tp_dict */ 1202 0, /* tp_dict */
1178 0, /* tp_descr_get */ 1203 0, /* tp_descr_get */
1179 0, /* tp_descr_set */ 1204 0, /* tp_descr_set */
1180 offsetof(fileio, dict), /* tp_dictoffset */ 1205 offsetof(fileio, dict), /* tp_dictoffset */
1181 fileio_init, /* tp_init */ 1206 fileio_init, /* tp_init */
1182 PyType_GenericAlloc, /* tp_alloc */ 1207 PyType_GenericAlloc, /* tp_alloc */
1183 fileio_new, /* tp_new */ 1208 fileio_new, /* tp_new */
1184 PyObject_GC_Del, /* tp_free */ 1209 PyObject_GC_Del, /* tp_free */
1185 }; 1210 };
OLDNEW
« no previous file with comments | « Modules/_io/_iomodule.c ('k') | no next file » | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld cbc36f91f3f7