Add forgotten initialization. Fixes bug #120994, "Traceback with
[python/dscho.git] / Objects / fileobject.c
blob96d3830d8b69f81945c8f8354be3e191aeac9d5b
2 /* File object implementation */
4 #include "Python.h"
5 #include "structmember.h"
7 #ifndef DONT_HAVE_SYS_TYPES_H
8 #include <sys/types.h>
9 #endif /* DONT_HAVE_SYS_TYPES_H */
11 /* We expect that fstat exists on most systems.
12 It's confirmed on Unix, Mac and Windows.
13 If you don't have it, add #define DONT_HAVE_FSTAT to your config.h. */
14 #ifndef DONT_HAVE_FSTAT
15 #define HAVE_FSTAT
17 #ifndef DONT_HAVE_SYS_TYPES_H
18 #include <sys/types.h>
19 #endif
21 #ifndef DONT_HAVE_SYS_STAT_H
22 #include <sys/stat.h>
23 #else
24 #ifdef HAVE_STAT_H
25 #include <stat.h>
26 #endif
27 #endif
29 #endif /* DONT_HAVE_FSTAT */
31 #ifdef HAVE_UNISTD_H
32 #include <unistd.h>
33 #endif
35 #ifdef MS_WIN32
36 #define fileno _fileno
37 /* can (almost fully) duplicate with _chsize, see file_truncate */
38 #define HAVE_FTRUNCATE
39 #endif
41 #ifdef macintosh
42 #ifdef USE_GUSI
43 #define HAVE_FTRUNCATE
44 #endif
45 #endif
47 #ifdef __MWERKS__
48 /* Mwerks fopen() doesn't always set errno */
49 #define NO_FOPEN_ERRNO
50 #endif
52 #define BUF(v) PyString_AS_STRING((PyStringObject *)v)
54 #ifndef DONT_HAVE_ERRNO_H
55 #include <errno.h>
56 #endif
58 /* define the appropriate 64-bit capable tell() function */
59 #if defined(MS_WIN64)
60 #define TELL64 _telli64
61 #elif defined(__NetBSD__) || defined(__OpenBSD__) || defined(_HAVE_BSDI) || defined(__APPLE__)
62 /* NOTE: this is only used on older
63 NetBSD prior to f*o() funcions */
64 #define TELL64(fd) lseek((fd),0,SEEK_CUR)
65 #endif
68 typedef struct {
69 PyObject_HEAD
70 FILE *f_fp;
71 PyObject *f_name;
72 PyObject *f_mode;
73 int (*f_close)(FILE *);
74 int f_softspace; /* Flag used by 'print' command */
75 int f_binary; /* Flag which indicates whether the file is open
76 open in binary (1) or test (0) mode */
77 } PyFileObject;
79 FILE *
80 PyFile_AsFile(PyObject *f)
82 if (f == NULL || !PyFile_Check(f))
83 return NULL;
84 else
85 return ((PyFileObject *)f)->f_fp;
88 PyObject *
89 PyFile_Name(PyObject *f)
91 if (f == NULL || !PyFile_Check(f))
92 return NULL;
93 else
94 return ((PyFileObject *)f)->f_name;
97 PyObject *
98 PyFile_FromFile(FILE *fp, char *name, char *mode, int (*close)(FILE *))
100 PyFileObject *f = PyObject_NEW(PyFileObject, &PyFile_Type);
101 if (f == NULL)
102 return NULL;
103 f->f_fp = NULL;
104 f->f_name = PyString_FromString(name);
105 f->f_mode = PyString_FromString(mode);
106 f->f_close = close;
107 f->f_softspace = 0;
108 if (strchr(mode,'b') != NULL)
109 f->f_binary = 1;
110 else
111 f->f_binary = 0;
112 if (f->f_name == NULL || f->f_mode == NULL) {
113 Py_DECREF(f);
114 return NULL;
116 f->f_fp = fp;
117 return (PyObject *) f;
120 PyObject *
121 PyFile_FromString(char *name, char *mode)
123 extern int fclose(FILE *);
124 PyFileObject *f;
125 f = (PyFileObject *) PyFile_FromFile((FILE *)NULL, name, mode, fclose);
126 if (f == NULL)
127 return NULL;
128 #ifdef HAVE_FOPENRF
129 if (*mode == '*') {
130 FILE *fopenRF();
131 f->f_fp = fopenRF(name, mode+1);
133 else
134 #endif
136 Py_BEGIN_ALLOW_THREADS
137 f->f_fp = fopen(name, mode);
138 Py_END_ALLOW_THREADS
140 if (f->f_fp == NULL) {
141 #ifdef NO_FOPEN_ERRNO
142 /* Metroworks only, not testable, so unchanged */
143 if ( errno == 0 ) {
144 PyErr_SetString(PyExc_IOError, "Cannot open file");
145 Py_DECREF(f);
146 return NULL;
148 #endif
149 PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
150 Py_DECREF(f);
151 return NULL;
153 return (PyObject *)f;
156 void
157 PyFile_SetBufSize(PyObject *f, int bufsize)
159 if (bufsize >= 0) {
160 #ifdef HAVE_SETVBUF
161 int type;
162 switch (bufsize) {
163 case 0:
164 type = _IONBF;
165 break;
166 case 1:
167 type = _IOLBF;
168 bufsize = BUFSIZ;
169 break;
170 default:
171 type = _IOFBF;
173 setvbuf(((PyFileObject *)f)->f_fp, (char *)NULL,
174 type, bufsize);
175 #else /* !HAVE_SETVBUF */
176 if (bufsize <= 1)
177 setbuf(((PyFileObject *)f)->f_fp, (char *)NULL);
178 #endif /* !HAVE_SETVBUF */
182 static PyObject *
183 err_closed(void)
185 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
186 return NULL;
189 /* Methods */
191 static void
192 file_dealloc(PyFileObject *f)
194 if (f->f_fp != NULL && f->f_close != NULL) {
195 Py_BEGIN_ALLOW_THREADS
196 (*f->f_close)(f->f_fp);
197 Py_END_ALLOW_THREADS
199 if (f->f_name != NULL) {
200 Py_DECREF(f->f_name);
202 if (f->f_mode != NULL) {
203 Py_DECREF(f->f_mode);
205 PyObject_DEL(f);
208 static PyObject *
209 file_repr(PyFileObject *f)
211 char buf[300];
212 sprintf(buf, "<%s file '%.256s', mode '%.10s' at %p>",
213 f->f_fp == NULL ? "closed" : "open",
214 PyString_AsString(f->f_name),
215 PyString_AsString(f->f_mode),
217 return PyString_FromString(buf);
220 static PyObject *
221 file_close(PyFileObject *f, PyObject *args)
223 int sts = 0;
224 if (!PyArg_NoArgs(args))
225 return NULL;
226 if (f->f_fp != NULL) {
227 if (f->f_close != NULL) {
228 Py_BEGIN_ALLOW_THREADS
229 errno = 0;
230 sts = (*f->f_close)(f->f_fp);
231 Py_END_ALLOW_THREADS
233 f->f_fp = NULL;
235 if (sts == EOF)
236 return PyErr_SetFromErrno(PyExc_IOError);
237 if (sts != 0)
238 return PyInt_FromLong((long)sts);
239 Py_INCREF(Py_None);
240 return Py_None;
244 /* a portable fseek() function
245 return 0 on success, non-zero on failure (with errno set) */
247 #if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
248 _portable_fseek(FILE *fp, fpos_t offset, int whence)
249 #else
250 _portable_fseek(FILE *fp, off_t offset, int whence)
251 #endif
253 #if defined(HAVE_FSEEKO)
254 return fseeko(fp, offset, whence);
255 #elif defined(HAVE_FSEEK64)
256 return fseek64(fp, offset, whence);
257 #elif defined(__BEOS__)
258 return _fseek(fp, offset, whence);
259 #elif defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_FPOS_T >= 8
260 /* lacking a 64-bit capable fseek() (as Win64 does) use a 64-bit capable
261 fsetpos() and tell() to implement fseek()*/
262 fpos_t pos;
263 switch (whence) {
264 case SEEK_CUR:
265 if (fgetpos(fp, &pos) != 0)
266 return -1;
267 offset += pos;
268 break;
269 case SEEK_END:
270 /* do a "no-op" seek first to sync the buffering so that
271 the low-level tell() can be used correctly */
272 if (fseek(fp, 0, SEEK_END) != 0)
273 return -1;
274 if ((pos = TELL64(fileno(fp))) == -1L)
275 return -1;
276 offset += pos;
277 break;
278 /* case SEEK_SET: break; */
280 return fsetpos(fp, &offset);
281 #else
282 return fseek(fp, offset, whence);
283 #endif
287 /* a portable ftell() function
288 Return -1 on failure with errno set appropriately, current file
289 position on success */
290 #if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
291 fpos_t
292 #else
293 off_t
294 #endif
295 _portable_ftell(FILE* fp)
297 #if defined(HAVE_FTELLO) && defined(HAVE_LARGEFILE_SUPPORT)
298 return ftello(fp);
299 #elif defined(HAVE_FTELL64) && defined(HAVE_LARGEFILE_SUPPORT)
300 return ftell64(fp);
301 #elif SIZEOF_FPOS_T >= 8 && defined(HAVE_LARGEFILE_SUPPORT)
302 fpos_t pos;
303 if (fgetpos(fp, &pos) != 0)
304 return -1;
305 return pos;
306 #else
307 return ftell(fp);
308 #endif
312 static PyObject *
313 file_seek(PyFileObject *f, PyObject *args)
315 int whence;
316 int ret;
317 #if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
318 fpos_t offset, pos;
319 #else
320 off_t offset;
321 #endif /* !MS_WIN64 */
322 PyObject *offobj;
324 if (f->f_fp == NULL)
325 return err_closed();
326 whence = 0;
327 if (!PyArg_ParseTuple(args, "O|i:seek", &offobj, &whence))
328 return NULL;
329 #if !defined(HAVE_LARGEFILE_SUPPORT)
330 offset = PyInt_AsLong(offobj);
331 #else
332 offset = PyLong_Check(offobj) ?
333 PyLong_AsLongLong(offobj) : PyInt_AsLong(offobj);
334 #endif
335 if (PyErr_Occurred())
336 return NULL;
338 Py_BEGIN_ALLOW_THREADS
339 errno = 0;
340 ret = _portable_fseek(f->f_fp, offset, whence);
341 Py_END_ALLOW_THREADS
343 if (ret != 0) {
344 PyErr_SetFromErrno(PyExc_IOError);
345 clearerr(f->f_fp);
346 return NULL;
348 Py_INCREF(Py_None);
349 return Py_None;
353 #ifdef HAVE_FTRUNCATE
354 static PyObject *
355 file_truncate(PyFileObject *f, PyObject *args)
357 int ret;
358 #if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
359 fpos_t newsize;
360 #else
361 off_t newsize;
362 #endif
363 PyObject *newsizeobj;
365 if (f->f_fp == NULL)
366 return err_closed();
367 newsizeobj = NULL;
368 if (!PyArg_ParseTuple(args, "|O:truncate", &newsizeobj))
369 return NULL;
370 if (newsizeobj != NULL) {
371 #if !defined(HAVE_LARGEFILE_SUPPORT)
372 newsize = PyInt_AsLong(newsizeobj);
373 #else
374 newsize = PyLong_Check(newsizeobj) ?
375 PyLong_AsLongLong(newsizeobj) :
376 PyInt_AsLong(newsizeobj);
377 #endif
378 if (PyErr_Occurred())
379 return NULL;
380 } else {
381 /* Default to current position*/
382 Py_BEGIN_ALLOW_THREADS
383 errno = 0;
384 newsize = _portable_ftell(f->f_fp);
385 Py_END_ALLOW_THREADS
386 if (newsize == -1) {
387 PyErr_SetFromErrno(PyExc_IOError);
388 clearerr(f->f_fp);
389 return NULL;
392 Py_BEGIN_ALLOW_THREADS
393 errno = 0;
394 ret = fflush(f->f_fp);
395 Py_END_ALLOW_THREADS
396 if (ret != 0) goto onioerror;
398 #ifdef MS_WIN32
399 /* can use _chsize; if, however, the newsize overflows 32-bits then
400 _chsize is *not* adequate; in this case, an OverflowError is raised */
401 if (newsize > LONG_MAX) {
402 PyErr_SetString(PyExc_OverflowError,
403 "the new size is too long for _chsize (it is limited to 32-bit values)");
404 return NULL;
405 } else {
406 Py_BEGIN_ALLOW_THREADS
407 errno = 0;
408 ret = _chsize(fileno(f->f_fp), newsize);
409 Py_END_ALLOW_THREADS
410 if (ret != 0) goto onioerror;
412 #else
413 Py_BEGIN_ALLOW_THREADS
414 errno = 0;
415 ret = ftruncate(fileno(f->f_fp), newsize);
416 Py_END_ALLOW_THREADS
417 if (ret != 0) goto onioerror;
418 #endif /* !MS_WIN32 */
420 Py_INCREF(Py_None);
421 return Py_None;
423 onioerror:
424 PyErr_SetFromErrno(PyExc_IOError);
425 clearerr(f->f_fp);
426 return NULL;
428 #endif /* HAVE_FTRUNCATE */
430 static PyObject *
431 file_tell(PyFileObject *f, PyObject *args)
433 #if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8
434 fpos_t pos;
435 #else
436 off_t pos;
437 #endif
439 if (f->f_fp == NULL)
440 return err_closed();
441 if (!PyArg_NoArgs(args))
442 return NULL;
443 Py_BEGIN_ALLOW_THREADS
444 errno = 0;
445 pos = _portable_ftell(f->f_fp);
446 Py_END_ALLOW_THREADS
447 if (pos == -1) {
448 PyErr_SetFromErrno(PyExc_IOError);
449 clearerr(f->f_fp);
450 return NULL;
452 #if !defined(HAVE_LARGEFILE_SUPPORT)
453 return PyInt_FromLong(pos);
454 #else
455 return PyLong_FromLongLong(pos);
456 #endif
459 static PyObject *
460 file_fileno(PyFileObject *f, PyObject *args)
462 if (f->f_fp == NULL)
463 return err_closed();
464 if (!PyArg_NoArgs(args))
465 return NULL;
466 return PyInt_FromLong((long) fileno(f->f_fp));
469 static PyObject *
470 file_flush(PyFileObject *f, PyObject *args)
472 int res;
474 if (f->f_fp == NULL)
475 return err_closed();
476 if (!PyArg_NoArgs(args))
477 return NULL;
478 Py_BEGIN_ALLOW_THREADS
479 errno = 0;
480 res = fflush(f->f_fp);
481 Py_END_ALLOW_THREADS
482 if (res != 0) {
483 PyErr_SetFromErrno(PyExc_IOError);
484 clearerr(f->f_fp);
485 return NULL;
487 Py_INCREF(Py_None);
488 return Py_None;
491 static PyObject *
492 file_isatty(PyFileObject *f, PyObject *args)
494 long res;
495 if (f->f_fp == NULL)
496 return err_closed();
497 if (!PyArg_NoArgs(args))
498 return NULL;
499 Py_BEGIN_ALLOW_THREADS
500 res = isatty((int)fileno(f->f_fp));
501 Py_END_ALLOW_THREADS
502 return PyInt_FromLong(res);
506 #if BUFSIZ < 8192
507 #define SMALLCHUNK 8192
508 #else
509 #define SMALLCHUNK BUFSIZ
510 #endif
512 #if SIZEOF_INT < 4
513 #define BIGCHUNK (512 * 32)
514 #else
515 #define BIGCHUNK (512 * 1024)
516 #endif
518 static size_t
519 new_buffersize(PyFileObject *f, size_t currentsize)
521 #ifdef HAVE_FSTAT
522 long pos, end;
523 struct stat st;
524 if (fstat(fileno(f->f_fp), &st) == 0) {
525 end = st.st_size;
526 /* The following is not a bug: we really need to call lseek()
527 *and* ftell(). The reason is that some stdio libraries
528 mistakenly flush their buffer when ftell() is called and
529 the lseek() call it makes fails, thereby throwing away
530 data that cannot be recovered in any way. To avoid this,
531 we first test lseek(), and only call ftell() if lseek()
532 works. We can't use the lseek() value either, because we
533 need to take the amount of buffered data into account.
534 (Yet another reason why stdio stinks. :-) */
535 pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR);
536 if (pos >= 0)
537 pos = ftell(f->f_fp);
538 if (pos < 0)
539 clearerr(f->f_fp);
540 if (end > pos && pos >= 0)
541 return currentsize + end - pos + 1;
542 /* Add 1 so if the file were to grow we'd notice. */
544 #endif
545 if (currentsize > SMALLCHUNK) {
546 /* Keep doubling until we reach BIGCHUNK;
547 then keep adding BIGCHUNK. */
548 if (currentsize <= BIGCHUNK)
549 return currentsize + currentsize;
550 else
551 return currentsize + BIGCHUNK;
553 return currentsize + SMALLCHUNK;
556 static PyObject *
557 file_read(PyFileObject *f, PyObject *args)
559 long bytesrequested = -1;
560 size_t bytesread, buffersize, chunksize;
561 PyObject *v;
563 if (f->f_fp == NULL)
564 return err_closed();
565 if (!PyArg_ParseTuple(args, "|l:read", &bytesrequested))
566 return NULL;
567 if (bytesrequested < 0)
568 buffersize = new_buffersize(f, (size_t)0);
569 else
570 buffersize = bytesrequested;
571 if (buffersize > INT_MAX) {
572 PyErr_SetString(PyExc_OverflowError,
573 "requested number of bytes is more than a Python string can hold");
574 return NULL;
576 v = PyString_FromStringAndSize((char *)NULL, buffersize);
577 if (v == NULL)
578 return NULL;
579 bytesread = 0;
580 for (;;) {
581 Py_BEGIN_ALLOW_THREADS
582 errno = 0;
583 chunksize = fread(BUF(v) + bytesread, 1,
584 buffersize - bytesread, f->f_fp);
585 Py_END_ALLOW_THREADS
586 if (chunksize == 0) {
587 if (!ferror(f->f_fp))
588 break;
589 PyErr_SetFromErrno(PyExc_IOError);
590 clearerr(f->f_fp);
591 Py_DECREF(v);
592 return NULL;
594 bytesread += chunksize;
595 if (bytesread < buffersize)
596 break;
597 if (bytesrequested < 0) {
598 buffersize = new_buffersize(f, buffersize);
599 if (_PyString_Resize(&v, buffersize) < 0)
600 return NULL;
603 if (bytesread != buffersize)
604 _PyString_Resize(&v, bytesread);
605 return v;
608 static PyObject *
609 file_readinto(PyFileObject *f, PyObject *args)
611 char *ptr;
612 size_t ntodo, ndone, nnow;
614 if (f->f_fp == NULL)
615 return err_closed();
616 if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
617 return NULL;
618 ndone = 0;
619 while (ntodo > 0) {
620 Py_BEGIN_ALLOW_THREADS
621 errno = 0;
622 nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
623 Py_END_ALLOW_THREADS
624 if (nnow == 0) {
625 if (!ferror(f->f_fp))
626 break;
627 PyErr_SetFromErrno(PyExc_IOError);
628 clearerr(f->f_fp);
629 return NULL;
631 ndone += nnow;
632 ntodo -= nnow;
634 return PyInt_FromLong((long)ndone);
638 /* Internal routine to get a line.
639 Size argument interpretation:
640 > 0: max length;
641 = 0: read arbitrary line;
642 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
645 static PyObject *
646 get_line(PyFileObject *f, int n)
648 register FILE *fp = f->f_fp;
649 register int c;
650 char *buf, *end;
651 size_t n1, n2;
652 PyObject *v;
654 #if defined(HAVE_GETLINE) && defined(_GNU_SOURCE)
655 /* Use GNU libc extension getline() for arbitrary-sized lines */
656 if (n == 0) {
657 size_t size = 0;
658 buf = NULL;
659 Py_BEGIN_ALLOW_THREADS
660 n1 = getline(&buf, &size, fp);
661 Py_END_ALLOW_THREADS
662 if (n1 == -1) {
663 if (buf){
664 free(buf);
666 clearerr(fp);
667 if (PyErr_CheckSignals()) {
668 return NULL;
670 if (n < 0 && feof(fp)) {
671 PyErr_SetString(PyExc_EOFError,
672 "EOF when reading a line");
673 return NULL;
675 return PyString_FromStringAndSize(NULL, 0);
677 /* No error */
679 v = PyString_FromStringAndSize(buf, n1);
680 free(buf);
681 return v;
683 #endif
685 n2 = n > 0 ? n : 100;
686 v = PyString_FromStringAndSize((char *)NULL, n2);
687 if (v == NULL)
688 return NULL;
689 buf = BUF(v);
690 end = buf + n2;
692 Py_BEGIN_ALLOW_THREADS
693 for (;;) {
694 if ((c = getc(fp)) == EOF) {
695 clearerr(fp);
696 Py_BLOCK_THREADS
697 if (PyErr_CheckSignals()) {
698 Py_DECREF(v);
699 return NULL;
701 if (n < 0 && buf == BUF(v)) {
702 Py_DECREF(v);
703 PyErr_SetString(PyExc_EOFError,
704 "EOF when reading a line");
705 return NULL;
707 Py_UNBLOCK_THREADS
708 break;
710 if ((*buf++ = c) == '\n') {
711 if (n < 0)
712 buf--;
713 break;
715 if (buf == end) {
716 if (n > 0)
717 break;
718 n1 = n2;
719 n2 += 1000;
720 if (n2 > INT_MAX) {
721 PyErr_SetString(PyExc_OverflowError,
722 "line is longer than a Python string can hold");
723 return NULL;
725 Py_BLOCK_THREADS
726 if (_PyString_Resize(&v, n2) < 0)
727 return NULL;
728 Py_UNBLOCK_THREADS
729 buf = BUF(v) + n1;
730 end = BUF(v) + n2;
733 Py_END_ALLOW_THREADS
735 n1 = buf - BUF(v);
736 if (n1 != n2)
737 _PyString_Resize(&v, n1);
738 return v;
741 /* External C interface */
743 PyObject *
744 PyFile_GetLine(PyObject *f, int n)
746 if (f == NULL) {
747 PyErr_BadInternalCall();
748 return NULL;
750 if (!PyFile_Check(f)) {
751 PyObject *reader;
752 PyObject *args;
753 PyObject *result;
754 reader = PyObject_GetAttrString(f, "readline");
755 if (reader == NULL)
756 return NULL;
757 if (n <= 0)
758 args = Py_BuildValue("()");
759 else
760 args = Py_BuildValue("(i)", n);
761 if (args == NULL) {
762 Py_DECREF(reader);
763 return NULL;
765 result = PyEval_CallObject(reader, args);
766 Py_DECREF(reader);
767 Py_DECREF(args);
768 if (result != NULL && !PyString_Check(result)) {
769 Py_DECREF(result);
770 result = NULL;
771 PyErr_SetString(PyExc_TypeError,
772 "object.readline() returned non-string");
774 if (n < 0 && result != NULL) {
775 char *s = PyString_AsString(result);
776 int len = PyString_Size(result);
777 if (len == 0) {
778 Py_DECREF(result);
779 result = NULL;
780 PyErr_SetString(PyExc_EOFError,
781 "EOF when reading a line");
783 else if (s[len-1] == '\n') {
784 if (result->ob_refcnt == 1)
785 _PyString_Resize(&result, len-1);
786 else {
787 PyObject *v;
788 v = PyString_FromStringAndSize(s,
789 len-1);
790 Py_DECREF(result);
791 result = v;
795 return result;
797 if (((PyFileObject*)f)->f_fp == NULL)
798 return err_closed();
799 return get_line((PyFileObject *)f, n);
802 /* Python method */
804 static PyObject *
805 file_readline(PyFileObject *f, PyObject *args)
807 int n = -1;
809 if (f->f_fp == NULL)
810 return err_closed();
811 if (!PyArg_ParseTuple(args, "|i:readline", &n))
812 return NULL;
813 if (n == 0)
814 return PyString_FromString("");
815 if (n < 0)
816 n = 0;
817 return get_line(f, n);
820 static PyObject *
821 file_readlines(PyFileObject *f, PyObject *args)
823 long sizehint = 0;
824 PyObject *list;
825 PyObject *line;
826 char small_buffer[SMALLCHUNK];
827 char *buffer = small_buffer;
828 size_t buffersize = SMALLCHUNK;
829 PyObject *big_buffer = NULL;
830 size_t nfilled = 0;
831 size_t nread;
832 size_t totalread = 0;
833 char *p, *q, *end;
834 int err;
836 if (f->f_fp == NULL)
837 return err_closed();
838 if (!PyArg_ParseTuple(args, "|l:readlines", &sizehint))
839 return NULL;
840 if ((list = PyList_New(0)) == NULL)
841 return NULL;
842 for (;;) {
843 Py_BEGIN_ALLOW_THREADS
844 errno = 0;
845 nread = fread(buffer+nfilled, 1, buffersize-nfilled, f->f_fp);
846 Py_END_ALLOW_THREADS
847 if (nread == 0) {
848 sizehint = 0;
849 if (!ferror(f->f_fp))
850 break;
851 PyErr_SetFromErrno(PyExc_IOError);
852 clearerr(f->f_fp);
853 error:
854 Py_DECREF(list);
855 list = NULL;
856 goto cleanup;
858 totalread += nread;
859 p = memchr(buffer+nfilled, '\n', nread);
860 if (p == NULL) {
861 /* Need a larger buffer to fit this line */
862 nfilled += nread;
863 buffersize *= 2;
864 if (buffersize > INT_MAX) {
865 PyErr_SetString(PyExc_OverflowError,
866 "line is longer than a Python string can hold");
867 goto error;
869 if (big_buffer == NULL) {
870 /* Create the big buffer */
871 big_buffer = PyString_FromStringAndSize(
872 NULL, buffersize);
873 if (big_buffer == NULL)
874 goto error;
875 buffer = PyString_AS_STRING(big_buffer);
876 memcpy(buffer, small_buffer, nfilled);
878 else {
879 /* Grow the big buffer */
880 _PyString_Resize(&big_buffer, buffersize);
881 buffer = PyString_AS_STRING(big_buffer);
883 continue;
885 end = buffer+nfilled+nread;
886 q = buffer;
887 do {
888 /* Process complete lines */
889 p++;
890 line = PyString_FromStringAndSize(q, p-q);
891 if (line == NULL)
892 goto error;
893 err = PyList_Append(list, line);
894 Py_DECREF(line);
895 if (err != 0)
896 goto error;
897 q = p;
898 p = memchr(q, '\n', end-q);
899 } while (p != NULL);
900 /* Move the remaining incomplete line to the start */
901 nfilled = end-q;
902 memmove(buffer, q, nfilled);
903 if (sizehint > 0)
904 if (totalread >= (size_t)sizehint)
905 break;
907 if (nfilled != 0) {
908 /* Partial last line */
909 line = PyString_FromStringAndSize(buffer, nfilled);
910 if (line == NULL)
911 goto error;
912 if (sizehint > 0) {
913 /* Need to complete the last line */
914 PyObject *rest = get_line(f, 0);
915 if (rest == NULL) {
916 Py_DECREF(line);
917 goto error;
919 PyString_Concat(&line, rest);
920 Py_DECREF(rest);
921 if (line == NULL)
922 goto error;
924 err = PyList_Append(list, line);
925 Py_DECREF(line);
926 if (err != 0)
927 goto error;
929 cleanup:
930 if (big_buffer) {
931 Py_DECREF(big_buffer);
933 return list;
936 static PyObject *
937 file_write(PyFileObject *f, PyObject *args)
939 char *s;
940 int n, n2;
941 if (f->f_fp == NULL)
942 return err_closed();
943 if (!PyArg_Parse(args, f->f_binary ? "s#" : "t#", &s, &n))
944 return NULL;
945 f->f_softspace = 0;
946 Py_BEGIN_ALLOW_THREADS
947 errno = 0;
948 n2 = fwrite(s, 1, n, f->f_fp);
949 Py_END_ALLOW_THREADS
950 if (n2 != n) {
951 PyErr_SetFromErrno(PyExc_IOError);
952 clearerr(f->f_fp);
953 return NULL;
955 Py_INCREF(Py_None);
956 return Py_None;
959 static PyObject *
960 file_writelines(PyFileObject *f, PyObject *args)
962 #define CHUNKSIZE 1000
963 PyObject *list, *line;
964 PyObject *result;
965 int i, j, index, len, nwritten, islist;
967 if (f->f_fp == NULL)
968 return err_closed();
969 if (args == NULL || !PySequence_Check(args)) {
970 PyErr_SetString(PyExc_TypeError,
971 "writelines() argument must be a sequence of strings");
972 return NULL;
974 islist = PyList_Check(args);
976 /* Strategy: slurp CHUNKSIZE lines into a private list,
977 checking that they are all strings, then write that list
978 without holding the interpreter lock, then come back for more. */
979 index = 0;
980 if (islist)
981 list = NULL;
982 else {
983 list = PyList_New(CHUNKSIZE);
984 if (list == NULL)
985 return NULL;
987 result = NULL;
989 for (;;) {
990 if (islist) {
991 Py_XDECREF(list);
992 list = PyList_GetSlice(args, index, index+CHUNKSIZE);
993 if (list == NULL)
994 return NULL;
995 j = PyList_GET_SIZE(list);
997 else {
998 for (j = 0; j < CHUNKSIZE; j++) {
999 line = PySequence_GetItem(args, index+j);
1000 if (line == NULL) {
1001 if (PyErr_ExceptionMatches(
1002 PyExc_IndexError)) {
1003 PyErr_Clear();
1004 break;
1006 /* Some other error occurred.
1007 XXX We may lose some output. */
1008 goto error;
1010 PyList_SetItem(list, j, line);
1013 if (j == 0)
1014 break;
1016 /* Check that all entries are indeed strings. If not,
1017 apply the same rules as for file.write() and
1018 convert the results to strings. This is slow, but
1019 seems to be the only way since all conversion APIs
1020 could potentially execute Python code. */
1021 for (i = 0; i < j; i++) {
1022 PyObject *v = PyList_GET_ITEM(list, i);
1023 if (!PyString_Check(v)) {
1024 const char *buffer;
1025 int len;
1026 if (((f->f_binary &&
1027 PyObject_AsReadBuffer(v,
1028 (const void**)&buffer,
1029 &len)) ||
1030 PyObject_AsCharBuffer(v,
1031 &buffer,
1032 &len))) {
1033 PyErr_SetString(PyExc_TypeError,
1034 "writelines() argument must be a sequence of strings");
1035 goto error;
1037 line = PyString_FromStringAndSize(buffer,
1038 len);
1039 if (line == NULL)
1040 goto error;
1041 Py_DECREF(v);
1042 PyList_SET_ITEM(list, i, line);
1046 /* Since we are releasing the global lock, the
1047 following code may *not* execute Python code. */
1048 Py_BEGIN_ALLOW_THREADS
1049 f->f_softspace = 0;
1050 errno = 0;
1051 for (i = 0; i < j; i++) {
1052 line = PyList_GET_ITEM(list, i);
1053 len = PyString_GET_SIZE(line);
1054 nwritten = fwrite(PyString_AS_STRING(line),
1055 1, len, f->f_fp);
1056 if (nwritten != len) {
1057 Py_BLOCK_THREADS
1058 PyErr_SetFromErrno(PyExc_IOError);
1059 clearerr(f->f_fp);
1060 goto error;
1063 Py_END_ALLOW_THREADS
1065 if (j < CHUNKSIZE)
1066 break;
1067 index += CHUNKSIZE;
1070 Py_INCREF(Py_None);
1071 result = Py_None;
1072 error:
1073 Py_XDECREF(list);
1074 return result;
1077 static PyMethodDef file_methods[] = {
1078 {"readline", (PyCFunction)file_readline, 1},
1079 {"read", (PyCFunction)file_read, 1},
1080 {"write", (PyCFunction)file_write, 0},
1081 {"fileno", (PyCFunction)file_fileno, 0},
1082 {"seek", (PyCFunction)file_seek, 1},
1083 #ifdef HAVE_FTRUNCATE
1084 {"truncate", (PyCFunction)file_truncate, 1},
1085 #endif
1086 {"tell", (PyCFunction)file_tell, 0},
1087 {"readinto", (PyCFunction)file_readinto, 0},
1088 {"readlines", (PyCFunction)file_readlines, 1},
1089 {"writelines", (PyCFunction)file_writelines, 0},
1090 {"flush", (PyCFunction)file_flush, 0},
1091 {"close", (PyCFunction)file_close, 0},
1092 {"isatty", (PyCFunction)file_isatty, 0},
1093 {NULL, NULL} /* sentinel */
1096 #define OFF(x) offsetof(PyFileObject, x)
1098 static struct memberlist file_memberlist[] = {
1099 {"softspace", T_INT, OFF(f_softspace)},
1100 {"mode", T_OBJECT, OFF(f_mode), RO},
1101 {"name", T_OBJECT, OFF(f_name), RO},
1102 /* getattr(f, "closed") is implemented without this table */
1103 {"closed", T_INT, 0, RO},
1104 {NULL} /* Sentinel */
1107 static PyObject *
1108 file_getattr(PyFileObject *f, char *name)
1110 PyObject *res;
1112 res = Py_FindMethod(file_methods, (PyObject *)f, name);
1113 if (res != NULL)
1114 return res;
1115 PyErr_Clear();
1116 if (strcmp(name, "closed") == 0)
1117 return PyInt_FromLong((long)(f->f_fp == 0));
1118 return PyMember_Get((char *)f, file_memberlist, name);
1121 static int
1122 file_setattr(PyFileObject *f, char *name, PyObject *v)
1124 if (v == NULL) {
1125 PyErr_SetString(PyExc_AttributeError,
1126 "can't delete file attributes");
1127 return -1;
1129 return PyMember_Set((char *)f, file_memberlist, name, v);
1132 PyTypeObject PyFile_Type = {
1133 PyObject_HEAD_INIT(&PyType_Type)
1135 "file",
1136 sizeof(PyFileObject),
1138 (destructor)file_dealloc, /*tp_dealloc*/
1139 0, /*tp_print*/
1140 (getattrfunc)file_getattr, /*tp_getattr*/
1141 (setattrfunc)file_setattr, /*tp_setattr*/
1142 0, /*tp_compare*/
1143 (reprfunc)file_repr, /*tp_repr*/
1146 /* Interface for the 'soft space' between print items. */
1149 PyFile_SoftSpace(PyObject *f, int newflag)
1151 int oldflag = 0;
1152 if (f == NULL) {
1153 /* Do nothing */
1155 else if (PyFile_Check(f)) {
1156 oldflag = ((PyFileObject *)f)->f_softspace;
1157 ((PyFileObject *)f)->f_softspace = newflag;
1159 else {
1160 PyObject *v;
1161 v = PyObject_GetAttrString(f, "softspace");
1162 if (v == NULL)
1163 PyErr_Clear();
1164 else {
1165 if (PyInt_Check(v))
1166 oldflag = PyInt_AsLong(v);
1167 Py_DECREF(v);
1169 v = PyInt_FromLong((long)newflag);
1170 if (v == NULL)
1171 PyErr_Clear();
1172 else {
1173 if (PyObject_SetAttrString(f, "softspace", v) != 0)
1174 PyErr_Clear();
1175 Py_DECREF(v);
1178 return oldflag;
1181 /* Interfaces to write objects/strings to file-like objects */
1184 PyFile_WriteObject(PyObject *v, PyObject *f, int flags)
1186 PyObject *writer, *value, *args, *result;
1187 if (f == NULL) {
1188 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
1189 return -1;
1191 else if (PyFile_Check(f)) {
1192 FILE *fp = PyFile_AsFile(f);
1193 if (fp == NULL) {
1194 err_closed();
1195 return -1;
1197 return PyObject_Print(v, fp, flags);
1199 writer = PyObject_GetAttrString(f, "write");
1200 if (writer == NULL)
1201 return -1;
1202 if (flags & Py_PRINT_RAW)
1203 value = PyObject_Str(v);
1204 else
1205 value = PyObject_Repr(v);
1206 if (value == NULL) {
1207 Py_DECREF(writer);
1208 return -1;
1210 args = Py_BuildValue("(O)", value);
1211 if (args == NULL) {
1212 Py_DECREF(value);
1213 Py_DECREF(writer);
1214 return -1;
1216 result = PyEval_CallObject(writer, args);
1217 Py_DECREF(args);
1218 Py_DECREF(value);
1219 Py_DECREF(writer);
1220 if (result == NULL)
1221 return -1;
1222 Py_DECREF(result);
1223 return 0;
1227 PyFile_WriteString(char *s, PyObject *f)
1229 if (f == NULL) {
1230 /* Should be caused by a pre-existing error */
1231 if (!PyErr_Occurred())
1232 PyErr_SetString(PyExc_SystemError,
1233 "null file for PyFile_WriteString");
1234 return -1;
1236 else if (PyFile_Check(f)) {
1237 FILE *fp = PyFile_AsFile(f);
1238 if (fp == NULL) {
1239 err_closed();
1240 return -1;
1242 fputs(s, fp);
1243 return 0;
1245 else if (!PyErr_Occurred()) {
1246 PyObject *v = PyString_FromString(s);
1247 int err;
1248 if (v == NULL)
1249 return -1;
1250 err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
1251 Py_DECREF(v);
1252 return err;
1254 else
1255 return -1;
1258 /* Try to get a file-descriptor from a Python object. If the object
1259 is an integer or long integer, its value is returned. If not, the
1260 object's fileno() method is called if it exists; the method must return
1261 an integer or long integer, which is returned as the file descriptor value.
1262 -1 is returned on failure.
1265 int PyObject_AsFileDescriptor(PyObject *o)
1267 int fd;
1268 PyObject *meth;
1270 if (PyInt_Check(o)) {
1271 fd = PyInt_AsLong(o);
1273 else if (PyLong_Check(o)) {
1274 fd = PyLong_AsLong(o);
1276 else if ((meth = PyObject_GetAttrString(o, "fileno")) != NULL)
1278 PyObject *fno = PyEval_CallObject(meth, NULL);
1279 Py_DECREF(meth);
1280 if (fno == NULL)
1281 return -1;
1283 if (PyInt_Check(fno)) {
1284 fd = PyInt_AsLong(fno);
1285 Py_DECREF(fno);
1287 else if (PyLong_Check(fno)) {
1288 fd = PyLong_AsLong(fno);
1289 Py_DECREF(fno);
1291 else {
1292 PyErr_SetString(PyExc_TypeError,
1293 "fileno() returned a non-integer");
1294 Py_DECREF(fno);
1295 return -1;
1298 else {
1299 PyErr_SetString(PyExc_TypeError,
1300 "argument must be an int, or have a fileno() method.");
1301 return -1;
1304 if (fd < 0) {
1305 PyErr_Format(PyExc_ValueError,
1306 "file descriptor cannot be a negative integer (%i)",
1307 fd);
1308 return -1;
1310 return fd;