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

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

Issue 18876: Problems with files opened in append mode with io module
Patch Set: Created 6 years, 5 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 | « Lib/test/test_fileio.py ('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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 #else 42 #else
43 #define SMALLCHUNK BUFSIZ 43 #define SMALLCHUNK BUFSIZ
44 #endif 44 #endif
45 45
46 typedef struct { 46 typedef struct {
47 PyObject_HEAD 47 PyObject_HEAD
48 int fd; 48 int fd;
49 unsigned int created : 1; 49 unsigned int created : 1;
50 unsigned int readable : 1; 50 unsigned int readable : 1;
51 unsigned int writable : 1; 51 unsigned int writable : 1;
52 unsigned int appending : 1;
52 signed int seekable : 2; /* -1 means unknown */ 53 signed int seekable : 2; /* -1 means unknown */
53 unsigned int closefd : 1; 54 unsigned int closefd : 1;
54 char finalizing; 55 char finalizing;
55 PyObject *weakreflist; 56 PyObject *weakreflist;
56 PyObject *dict; 57 PyObject *dict;
57 } fileio; 58 } fileio;
58 59
59 PyTypeObject PyFileIO_Type; 60 PyTypeObject PyFileIO_Type;
60 61
61 #define PyFileIO_Check(op) (PyObject_TypeCheck((op), &PyFileIO_Type)) 62 #define PyFileIO_Check(op) (PyObject_TypeCheck((op), &PyFileIO_Type))
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 fileio *self; 150 fileio *self;
150 151
151 assert(type != NULL && type->tp_alloc != NULL); 152 assert(type != NULL && type->tp_alloc != NULL);
152 153
153 self = (fileio *) type->tp_alloc(type, 0); 154 self = (fileio *) type->tp_alloc(type, 0);
154 if (self != NULL) { 155 if (self != NULL) {
155 self->fd = -1; 156 self->fd = -1;
156 self->created = 0; 157 self->created = 0;
157 self->readable = 0; 158 self->readable = 0;
158 self->writable = 0; 159 self->writable = 0;
160 self->appending = 0;
159 self->seekable = -1; 161 self->seekable = -1;
160 self->closefd = 1; 162 self->closefd = 1;
161 self->weakreflist = NULL; 163 self->weakreflist = NULL;
162 } 164 }
163 165
164 return (PyObject *) self; 166 return (PyObject *) self;
165 } 167 }
166 168
167 /* On Unix, open will succeed for directories. 169 /* On Unix, open will succeed for directories.
168 In Python, there should be no file objects referring to 170 In Python, there should be no file objects referring to
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 fileio *self = (fileio *) oself; 214 fileio *self = (fileio *) oself;
213 static char *kwlist[] = {"file", "mode", "closefd", "opener", NULL}; 215 static char *kwlist[] = {"file", "mode", "closefd", "opener", NULL};
214 const char *name = NULL; 216 const char *name = NULL;
215 PyObject *nameobj, *stringobj = NULL, *opener = Py_None; 217 PyObject *nameobj, *stringobj = NULL, *opener = Py_None;
216 char *mode = "r"; 218 char *mode = "r";
217 char *s; 219 char *s;
218 #ifdef MS_WINDOWS 220 #ifdef MS_WINDOWS
219 Py_UNICODE *widename = NULL; 221 Py_UNICODE *widename = NULL;
220 #endif 222 #endif
221 int ret = 0; 223 int ret = 0;
222 int rwa = 0, plus = 0, append = 0; 224 int rwa = 0, plus = 0;
223 int flags = 0; 225 int flags = 0;
224 int fd = -1; 226 int fd = -1;
225 int closefd = 1; 227 int closefd = 1;
226 int fd_is_own = 0; 228 int fd_is_own = 0;
227 #ifdef O_CLOEXEC 229 #ifdef O_CLOEXEC
228 int *atomic_flag_works = &_Py_open_cloexec_works; 230 int *atomic_flag_works = &_Py_open_cloexec_works;
229 #elif !defined(MS_WINDOWS) 231 #elif !defined(MS_WINDOWS)
230 int *atomic_flag_works = NULL; 232 int *atomic_flag_works = NULL;
231 #endif 233 #endif
232 234
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 goto bad_mode; 312 goto bad_mode;
311 rwa = 1; 313 rwa = 1;
312 self->writable = 1; 314 self->writable = 1;
313 flags |= O_CREAT | O_TRUNC; 315 flags |= O_CREAT | O_TRUNC;
314 break; 316 break;
315 case 'a': 317 case 'a':
316 if (rwa) 318 if (rwa)
317 goto bad_mode; 319 goto bad_mode;
318 rwa = 1; 320 rwa = 1;
319 self->writable = 1; 321 self->writable = 1;
320 flags |= O_CREAT; 322 self->appending = 1;
321 append = 1; 323 flags |= O_APPEND | O_CREAT;
322 break; 324 break;
323 case 'b': 325 case 'b':
324 break; 326 break;
325 case '+': 327 case '+':
326 if (plus) 328 if (plus)
327 goto bad_mode; 329 goto bad_mode;
328 self->readable = self->writable = 1; 330 self->readable = self->writable = 1;
329 plus = 1; 331 plus = 1;
330 break; 332 break;
331 default: 333 default:
(...skipping 10 matching lines...) Expand all
342 flags |= O_RDWR; 344 flags |= O_RDWR;
343 else if (self->readable) 345 else if (self->readable)
344 flags |= O_RDONLY; 346 flags |= O_RDONLY;
345 else 347 else
346 flags |= O_WRONLY; 348 flags |= O_WRONLY;
347 349
348 #ifdef O_BINARY 350 #ifdef O_BINARY
349 flags |= O_BINARY; 351 flags |= O_BINARY;
350 #endif 352 #endif
351 353
352 #ifdef O_APPEND
353 if (append)
354 flags |= O_APPEND;
355 #endif
356 #ifdef MS_WINDOWS 354 #ifdef MS_WINDOWS
357 flags |= O_NOINHERIT; 355 flags |= O_NOINHERIT;
358 #elif defined(O_CLOEXEC) 356 #elif defined(O_CLOEXEC)
359 flags |= O_CLOEXEC; 357 flags |= O_CLOEXEC;
360 #endif 358 #endif
361 359
362 if (fd >= 0) { 360 if (fd >= 0) {
363 if (check_fd(fd)) 361 if (check_fd(fd))
364 goto error; 362 goto error;
365 self->fd = fd; 363 self->fd = fd;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 goto error; 423 goto error;
426 424
427 #if defined(MS_WINDOWS) || defined(__CYGWIN__) 425 #if defined(MS_WINDOWS) || defined(__CYGWIN__)
428 /* don't translate newlines (\r\n <=> \n) */ 426 /* don't translate newlines (\r\n <=> \n) */
429 _setmode(self->fd, O_BINARY); 427 _setmode(self->fd, O_BINARY);
430 #endif 428 #endif
431 429
432 if (PyObject_SetAttrString((PyObject *)self, "name", nameobj) < 0) 430 if (PyObject_SetAttrString((PyObject *)self, "name", nameobj) < 0)
433 goto error; 431 goto error;
434 432
435 if (append) { 433 if (self->appending) {
436 /* For consistent behaviour, we explicitly seek to the 434 /* For consistent behaviour, we explicitly seek to the
437 end of file (otherwise, it might be done only on the 435 end of file (otherwise, it might be done only on the
438 first write()). */ 436 first write()). */
439 PyObject *pos = portable_lseek(self->fd, NULL, 2); 437 PyObject *pos = portable_lseek(self->fd, NULL, 2);
440 if (pos == NULL) 438 if (pos == NULL)
441 goto error; 439 goto error;
442 Py_DECREF(pos); 440 Py_DECREF(pos);
443 } 441 }
444 442
445 goto done; 443 goto done;
(...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after
1012 1010
1013 static char * 1011 static char *
1014 mode_string(fileio *self) 1012 mode_string(fileio *self)
1015 { 1013 {
1016 if (self->created) { 1014 if (self->created) {
1017 if (self->readable) 1015 if (self->readable)
1018 return "xb+"; 1016 return "xb+";
1019 else 1017 else
1020 return "xb"; 1018 return "xb";
1021 } 1019 }
1022 if (self->readable) { 1020 if (self->appending) {
1021 if (self->readable)
1022 return "ab+";
1023 else
1024 return "ab";
1025 }
1026 else if (self->readable) {
1023 if (self->writable) 1027 if (self->writable)
1024 return "rb+"; 1028 return "rb+";
1025 else 1029 else
1026 return "rb"; 1030 return "rb";
1027 } 1031 }
1028 else 1032 else
1029 return "wb"; 1033 return "wb";
1030 } 1034 }
1031 1035
1032 static PyObject * 1036 static PyObject *
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
1257 0, /* tp_is_gc */ 1261 0, /* tp_is_gc */
1258 0, /* tp_bases */ 1262 0, /* tp_bases */
1259 0, /* tp_mro */ 1263 0, /* tp_mro */
1260 0, /* tp_cache */ 1264 0, /* tp_cache */
1261 0, /* tp_subclasses */ 1265 0, /* tp_subclasses */
1262 0, /* tp_weaklist */ 1266 0, /* tp_weaklist */
1263 0, /* tp_del */ 1267 0, /* tp_del */
1264 0, /* tp_version_tag */ 1268 0, /* tp_version_tag */
1265 0, /* tp_finalize */ 1269 0, /* tp_finalize */
1266 }; 1270 };
OLDNEW
« no previous file with comments | « Lib/test/test_fileio.py ('k') | no next file » | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+