Fix an amazing number of typos & malformed sentences reported by Detlef
[python/dscho.git] / Objects / fileobject.c
blob6d57aeacc3daa5e29f180e8617115a5c63bc8a58
1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3 The Netherlands.
5 All Rights Reserved
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI or Corporation for National Research Initiatives or
13 CNRI not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior
15 permission.
17 While CWI is the initial source for this software, a modified version
18 is made available by the Corporation for National Research Initiatives
19 (CNRI) at the Internet address ftp://ftp.python.org.
21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28 PERFORMANCE OF THIS SOFTWARE.
30 ******************************************************************/
32 /* File object implementation */
34 #include "Python.h"
35 #include "structmember.h"
37 #include <sys/types.h>
39 #ifdef HAVE_UNISTD_H
40 #include <unistd.h>
41 #endif
43 #ifdef MS_WIN32
44 #define ftruncate _chsize
45 #define fileno _fileno
46 #define HAVE_FTRUNCATE
47 #endif
49 #ifdef macintosh
50 #ifdef USE_GUSI
51 #define HAVE_FTRUNCATE
52 #endif
53 #endif
55 #ifdef THINK_C
56 #define HAVE_FOPENRF
57 #endif
58 #ifdef __MWERKS__
59 /* Mwerks fopen() doesn't always set errno */
60 #define NO_FOPEN_ERRNO
61 #endif
63 #define BUF(v) PyString_AS_STRING((PyStringObject *)v)
65 #include <errno.h>
67 typedef struct {
68 PyObject_HEAD
69 FILE *f_fp;
70 PyObject *f_name;
71 PyObject *f_mode;
72 int (*f_close) Py_PROTO((FILE *));
73 int f_softspace; /* Flag used by 'print' command */
74 } PyFileObject;
76 FILE *
77 PyFile_AsFile(f)
78 PyObject *f;
80 if (f == NULL || !PyFile_Check(f))
81 return NULL;
82 else
83 return ((PyFileObject *)f)->f_fp;
86 PyObject *
87 PyFile_Name(f)
88 PyObject *f;
90 if (f == NULL || !PyFile_Check(f))
91 return NULL;
92 else
93 return ((PyFileObject *)f)->f_name;
96 PyObject *
97 PyFile_FromFile(fp, name, mode, close)
98 FILE *fp;
99 char *name;
100 char *mode;
101 int (*close) Py_FPROTO((FILE *));
103 PyFileObject *f = PyObject_NEW(PyFileObject, &PyFile_Type);
104 if (f == NULL)
105 return NULL;
106 f->f_fp = NULL;
107 f->f_name = PyString_FromString(name);
108 f->f_mode = PyString_FromString(mode);
109 f->f_close = close;
110 f->f_softspace = 0;
111 if (f->f_name == NULL || f->f_mode == NULL) {
112 Py_DECREF(f);
113 return NULL;
115 f->f_fp = fp;
116 return (PyObject *) f;
119 PyObject *
120 PyFile_FromString(name, mode)
121 char *name, *mode;
123 extern int fclose Py_PROTO((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(f, bufsize)
158 PyObject *f;
159 int bufsize;
161 if (bufsize >= 0) {
162 #ifdef HAVE_SETVBUF
163 int type;
164 switch (bufsize) {
165 case 0:
166 type = _IONBF;
167 break;
168 case 1:
169 type = _IOLBF;
170 bufsize = BUFSIZ;
171 break;
172 default:
173 type = _IOFBF;
175 setvbuf(((PyFileObject *)f)->f_fp, (char *)NULL,
176 type, bufsize);
177 #else /* !HAVE_SETVBUF */
178 if (bufsize <= 1)
179 setbuf(((PyFileObject *)f)->f_fp, (char *)NULL);
180 #endif /* !HAVE_SETVBUF */
184 static PyObject *
185 err_closed()
187 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
188 return NULL;
191 /* Methods */
193 static void
194 file_dealloc(f)
195 PyFileObject *f;
197 if (f->f_fp != NULL && f->f_close != NULL) {
198 Py_BEGIN_ALLOW_THREADS
199 (*f->f_close)(f->f_fp);
200 Py_END_ALLOW_THREADS
202 if (f->f_name != NULL) {
203 Py_DECREF(f->f_name);
205 if (f->f_mode != NULL) {
206 Py_DECREF(f->f_mode);
208 free((char *)f);
211 static PyObject *
212 file_repr(f)
213 PyFileObject *f;
215 char buf[300];
216 sprintf(buf, "<%s file '%.256s', mode '%.10s' at %lx>",
217 f->f_fp == NULL ? "closed" : "open",
218 PyString_AsString(f->f_name),
219 PyString_AsString(f->f_mode),
220 (long)f);
221 return PyString_FromString(buf);
224 static PyObject *
225 file_close(f, args)
226 PyFileObject *f;
227 PyObject *args;
229 int sts = 0;
230 if (!PyArg_NoArgs(args))
231 return NULL;
232 if (f->f_fp != NULL) {
233 if (f->f_close != NULL) {
234 Py_BEGIN_ALLOW_THREADS
235 errno = 0;
236 sts = (*f->f_close)(f->f_fp);
237 Py_END_ALLOW_THREADS
239 f->f_fp = NULL;
241 if (sts == EOF)
242 return PyErr_SetFromErrno(PyExc_IOError);
243 if (sts != 0)
244 return PyInt_FromLong((long)sts);
245 Py_INCREF(Py_None);
246 return Py_None;
249 static PyObject *
250 file_seek(f, args)
251 PyFileObject *f;
252 PyObject *args;
254 int whence;
255 int ret;
256 off_t offset;
257 PyObject *offobj;
259 if (f->f_fp == NULL)
260 return err_closed();
261 whence = 0;
262 if (!PyArg_ParseTuple(args, "O|i", &offobj, &whence))
263 return NULL;
264 #if !defined(HAVE_LARGEFILE_SUPPORT)
265 offset = PyInt_AsLong(offobj);
266 #else
267 offset = PyLong_Check(offobj) ?
268 PyLong_AsLongLong(offobj) : PyInt_AsLong(offobj);
269 #endif
270 if (PyErr_Occurred())
271 return NULL;
272 Py_BEGIN_ALLOW_THREADS
273 errno = 0;
274 #if defined(HAVE_FSEEKO)
275 ret = fseeko(f->f_fp, offset, whence);
276 #elif defined(HAVE_FSEEK64)
277 ret = fseek64(f->f_fp, offset, whence);
278 #else
279 ret = fseek(f->f_fp, offset, whence);
280 #endif
281 Py_END_ALLOW_THREADS
282 if (ret != 0) {
283 PyErr_SetFromErrno(PyExc_IOError);
284 clearerr(f->f_fp);
285 return NULL;
287 Py_INCREF(Py_None);
288 return Py_None;
291 #ifdef HAVE_FTRUNCATE
292 static PyObject *
293 file_truncate(f, args)
294 PyFileObject *f;
295 PyObject *args;
297 int ret;
298 off_t newsize;
299 PyObject *newsizeobj;
301 if (f->f_fp == NULL)
302 return err_closed();
303 newsizeobj = NULL;
304 if (!PyArg_ParseTuple(args, "|O", &newsizeobj))
305 return NULL;
306 if (newsizeobj != NULL) {
307 #if !defined(HAVE_LARGEFILE_SUPPORT)
308 newsize = PyInt_AsLong(newsizeobj);
309 #else
310 newsize = PyLong_Check(newsizeobj) ?
311 PyLong_AsLongLong(newsizeobj) :
312 PyInt_AsLong(newsizeobj);
313 #endif
314 if (PyErr_Occurred())
315 return NULL;
316 } else {
317 /* Default to current position*/
318 Py_BEGIN_ALLOW_THREADS
319 errno = 0;
320 #if defined(HAVE_FTELLO) && defined(HAVE_LARGEFILE_SUPPORT)
321 newsize = ftello(f->f_fp);
322 #elif defined(HAVE_FTELL64) && defined(HAVE_LARGEFILE_SUPPORT)
323 newsize = ftell64(f->f_fp);
324 #else
325 newsize = ftell(f->f_fp);
326 #endif
327 Py_END_ALLOW_THREADS
328 if (newsize == -1) {
329 PyErr_SetFromErrno(PyExc_IOError);
330 clearerr(f->f_fp);
331 return NULL;
334 Py_BEGIN_ALLOW_THREADS
335 errno = 0;
336 ret = fflush(f->f_fp);
337 Py_END_ALLOW_THREADS
338 if (ret == 0) {
339 Py_BEGIN_ALLOW_THREADS
340 errno = 0;
341 ret = ftruncate(fileno(f->f_fp), newsize);
342 Py_END_ALLOW_THREADS
344 if (ret != 0) {
345 PyErr_SetFromErrno(PyExc_IOError);
346 clearerr(f->f_fp);
347 return NULL;
349 Py_INCREF(Py_None);
350 return Py_None;
352 #endif /* HAVE_FTRUNCATE */
354 static PyObject *
355 file_tell(f, args)
356 PyFileObject *f;
357 PyObject *args;
359 off_t offset;
360 if (f->f_fp == NULL)
361 return err_closed();
362 if (!PyArg_NoArgs(args))
363 return NULL;
364 Py_BEGIN_ALLOW_THREADS
365 errno = 0;
366 #if defined(HAVE_FTELLO) && defined(HAVE_LARGEFILE_SUPPORT)
367 offset = ftello(f->f_fp);
368 #elif defined(HAVE_FTELL64) && defined(HAVE_LARGEFILE_SUPPORT)
369 offset = ftell64(f->f_fp);
370 #else
371 offset = ftell(f->f_fp);
372 #endif
373 Py_END_ALLOW_THREADS
374 if (offset == -1) {
375 PyErr_SetFromErrno(PyExc_IOError);
376 clearerr(f->f_fp);
377 return NULL;
379 #if !defined(HAVE_LARGEFILE_SUPPORT)
380 return PyInt_FromLong(offset);
381 #else
382 return PyLong_FromLongLong(offset);
383 #endif
386 static PyObject *
387 file_fileno(f, args)
388 PyFileObject *f;
389 PyObject *args;
391 if (f->f_fp == NULL)
392 return err_closed();
393 if (!PyArg_NoArgs(args))
394 return NULL;
395 return PyInt_FromLong((long) fileno(f->f_fp));
398 static PyObject *
399 file_flush(f, args)
400 PyFileObject *f;
401 PyObject *args;
403 int res;
405 if (f->f_fp == NULL)
406 return err_closed();
407 if (!PyArg_NoArgs(args))
408 return NULL;
409 Py_BEGIN_ALLOW_THREADS
410 errno = 0;
411 res = fflush(f->f_fp);
412 Py_END_ALLOW_THREADS
413 if (res != 0) {
414 PyErr_SetFromErrno(PyExc_IOError);
415 clearerr(f->f_fp);
416 return NULL;
418 Py_INCREF(Py_None);
419 return Py_None;
422 static PyObject *
423 file_isatty(f, args)
424 PyFileObject *f;
425 PyObject *args;
427 long res;
428 if (f->f_fp == NULL)
429 return err_closed();
430 if (!PyArg_NoArgs(args))
431 return NULL;
432 Py_BEGIN_ALLOW_THREADS
433 res = isatty((int)fileno(f->f_fp));
434 Py_END_ALLOW_THREADS
435 return PyInt_FromLong(res);
438 /* We expect that fstat exists on most systems.
439 It's confirmed on Unix, Mac and Windows.
440 If you don't have it, add #define DONT_HAVE_FSTAT to your config.h. */
441 #ifndef DONT_HAVE_FSTAT
442 #define HAVE_FSTAT
444 #include <sys/types.h>
445 #include <sys/stat.h>
447 #endif
449 #if BUFSIZ < 8192
450 #define SMALLCHUNK 8192
451 #else
452 #define SMALLCHUNK BUFSIZ
453 #endif
455 #if SIZEOF_INT < 4
456 #define BIGCHUNK (512 * 32)
457 #else
458 #define BIGCHUNK (512 * 1024)
459 #endif
461 static size_t
462 new_buffersize(f, currentsize)
463 PyFileObject *f;
464 size_t currentsize;
466 #ifdef HAVE_FSTAT
467 long pos, end;
468 struct stat st;
469 if (fstat(fileno(f->f_fp), &st) == 0) {
470 end = st.st_size;
471 /* The following is not a bug: we really need to call lseek()
472 *and* ftell(). The reason is that some stdio libraries
473 mistakenly flush their buffer when ftell() is called and
474 the lseek() call it makes fails, thereby throwing away
475 data that cannot be recovered in any way. To avoid this,
476 we first test lseek(), and only call ftell() if lseek()
477 works. We can't use the lseek() value either, because we
478 need to take the amount of buffered data into account.
479 (Yet another reason why stdio stinks. :-) */
480 pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR);
481 if (pos >= 0)
482 pos = ftell(f->f_fp);
483 if (pos < 0)
484 clearerr(f->f_fp);
485 if (end > pos && pos >= 0)
486 return currentsize + end - pos + 1;
487 /* Add 1 so if the file were to grow we'd notice. */
489 #endif
490 if (currentsize > SMALLCHUNK) {
491 /* Keep doubling until we reach BIGCHUNK;
492 then keep adding BIGCHUNK. */
493 if (currentsize <= BIGCHUNK)
494 return currentsize + currentsize;
495 else
496 return currentsize + BIGCHUNK;
498 return currentsize + SMALLCHUNK;
501 static PyObject *
502 file_read(f, args)
503 PyFileObject *f;
504 PyObject *args;
506 long bytesrequested = -1;
507 size_t bytesread, buffersize, chunksize;
508 PyObject *v;
510 if (f->f_fp == NULL)
511 return err_closed();
512 if (!PyArg_ParseTuple(args, "|l", &bytesrequested))
513 return NULL;
514 if (bytesrequested < 0)
515 buffersize = new_buffersize(f, 0);
516 else
517 buffersize = bytesrequested;
518 v = PyString_FromStringAndSize((char *)NULL, buffersize);
519 if (v == NULL)
520 return NULL;
521 bytesread = 0;
522 for (;;) {
523 Py_BEGIN_ALLOW_THREADS
524 errno = 0;
525 chunksize = fread(BUF(v) + bytesread, 1,
526 buffersize - bytesread, f->f_fp);
527 Py_END_ALLOW_THREADS
528 if (chunksize == 0) {
529 if (!ferror(f->f_fp))
530 break;
531 PyErr_SetFromErrno(PyExc_IOError);
532 clearerr(f->f_fp);
533 Py_DECREF(v);
534 return NULL;
536 bytesread += chunksize;
537 if (bytesread < buffersize)
538 break;
539 if (bytesrequested < 0) {
540 buffersize = new_buffersize(f, buffersize);
541 if (_PyString_Resize(&v, buffersize) < 0)
542 return NULL;
545 if (bytesread != buffersize)
546 _PyString_Resize(&v, bytesread);
547 return v;
550 static PyObject *
551 file_readinto(f, args)
552 PyFileObject *f;
553 PyObject *args;
555 char *ptr;
556 int ntodo, ndone, nnow;
558 if (f->f_fp == NULL)
559 return err_closed();
560 if (!PyArg_Parse(args, "w#", &ptr, &ntodo))
561 return NULL;
562 ndone = 0;
563 while (ntodo > 0) {
564 Py_BEGIN_ALLOW_THREADS
565 errno = 0;
566 nnow = fread(ptr+ndone, 1, ntodo, f->f_fp);
567 Py_END_ALLOW_THREADS
568 if (nnow == 0) {
569 if (!ferror(f->f_fp))
570 break;
571 PyErr_SetFromErrno(PyExc_IOError);
572 clearerr(f->f_fp);
573 return NULL;
575 ndone += nnow;
576 ntodo -= nnow;
578 return PyInt_FromLong(ndone);
582 /* Internal routine to get a line.
583 Size argument interpretation:
584 > 0: max length;
585 = 0: read arbitrary line;
586 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
589 static PyObject *
590 getline(f, n)
591 PyFileObject *f;
592 int n;
594 register FILE *fp;
595 register int c;
596 register char *buf, *end;
597 int n1, n2;
598 PyObject *v;
600 fp = f->f_fp;
601 n2 = n > 0 ? n : 100;
602 v = PyString_FromStringAndSize((char *)NULL, n2);
603 if (v == NULL)
604 return NULL;
605 buf = BUF(v);
606 end = buf + n2;
608 Py_BEGIN_ALLOW_THREADS
609 for (;;) {
610 if ((c = getc(fp)) == EOF) {
611 clearerr(fp);
612 Py_BLOCK_THREADS
613 if (PyErr_CheckSignals()) {
614 Py_DECREF(v);
615 return NULL;
617 if (n < 0 && buf == BUF(v)) {
618 Py_DECREF(v);
619 PyErr_SetString(PyExc_EOFError,
620 "EOF when reading a line");
621 return NULL;
623 Py_UNBLOCK_THREADS
624 break;
626 if ((*buf++ = c) == '\n') {
627 if (n < 0)
628 buf--;
629 break;
631 if (buf == end) {
632 if (n > 0)
633 break;
634 n1 = n2;
635 n2 += 1000;
636 Py_BLOCK_THREADS
637 if (_PyString_Resize(&v, n2) < 0)
638 return NULL;
639 Py_UNBLOCK_THREADS
640 buf = BUF(v) + n1;
641 end = BUF(v) + n2;
644 Py_END_ALLOW_THREADS
646 n1 = buf - BUF(v);
647 if (n1 != n2)
648 _PyString_Resize(&v, n1);
649 return v;
652 /* External C interface */
654 PyObject *
655 PyFile_GetLine(f, n)
656 PyObject *f;
657 int n;
659 if (f == NULL) {
660 PyErr_BadInternalCall();
661 return NULL;
663 if (!PyFile_Check(f)) {
664 PyObject *reader;
665 PyObject *args;
666 PyObject *result;
667 reader = PyObject_GetAttrString(f, "readline");
668 if (reader == NULL)
669 return NULL;
670 if (n <= 0)
671 args = Py_BuildValue("()");
672 else
673 args = Py_BuildValue("(i)", n);
674 if (args == NULL) {
675 Py_DECREF(reader);
676 return NULL;
678 result = PyEval_CallObject(reader, args);
679 Py_DECREF(reader);
680 Py_DECREF(args);
681 if (result != NULL && !PyString_Check(result)) {
682 Py_DECREF(result);
683 result = NULL;
684 PyErr_SetString(PyExc_TypeError,
685 "object.readline() returned non-string");
687 if (n < 0 && result != NULL) {
688 char *s = PyString_AsString(result);
689 int len = PyString_Size(result);
690 if (len == 0) {
691 Py_DECREF(result);
692 result = NULL;
693 PyErr_SetString(PyExc_EOFError,
694 "EOF when reading a line");
696 else if (s[len-1] == '\n') {
697 if (result->ob_refcnt == 1)
698 _PyString_Resize(&result, len-1);
699 else {
700 PyObject *v;
701 v = PyString_FromStringAndSize(s,
702 len-1);
703 Py_DECREF(result);
704 result = v;
708 return result;
710 if (((PyFileObject*)f)->f_fp == NULL)
711 return err_closed();
712 return getline((PyFileObject *)f, n);
715 /* Python method */
717 static PyObject *
718 file_readline(f, args)
719 PyFileObject *f;
720 PyObject *args;
722 int n = -1;
724 if (f->f_fp == NULL)
725 return err_closed();
726 if (!PyArg_ParseTuple(args, "|i", &n))
727 return NULL;
728 if (n == 0)
729 return PyString_FromString("");
730 if (n < 0)
731 n = 0;
732 return getline(f, n);
735 static PyObject *
736 file_readlines(f, args)
737 PyFileObject *f;
738 PyObject *args;
740 long sizehint = 0;
741 PyObject *list;
742 PyObject *line;
743 char small_buffer[SMALLCHUNK];
744 char *buffer = small_buffer;
745 size_t buffersize = SMALLCHUNK;
746 PyObject *big_buffer = NULL;
747 size_t nfilled = 0;
748 size_t nread;
749 size_t totalread = 0;
750 char *p, *q, *end;
751 int err;
753 if (f->f_fp == NULL)
754 return err_closed();
755 if (!PyArg_ParseTuple(args, "|l", &sizehint))
756 return NULL;
757 if ((list = PyList_New(0)) == NULL)
758 return NULL;
759 for (;;) {
760 Py_BEGIN_ALLOW_THREADS
761 errno = 0;
762 nread = fread(buffer+nfilled, 1, buffersize-nfilled, f->f_fp);
763 Py_END_ALLOW_THREADS
764 if (nread == 0) {
765 sizehint = 0;
766 if (!ferror(f->f_fp))
767 break;
768 PyErr_SetFromErrno(PyExc_IOError);
769 clearerr(f->f_fp);
770 error:
771 Py_DECREF(list);
772 list = NULL;
773 goto cleanup;
775 totalread += nread;
776 p = memchr(buffer+nfilled, '\n', nread);
777 if (p == NULL) {
778 /* Need a larger buffer to fit this line */
779 nfilled += nread;
780 buffersize *= 2;
781 if (big_buffer == NULL) {
782 /* Create the big buffer */
783 big_buffer = PyString_FromStringAndSize(
784 NULL, buffersize);
785 if (big_buffer == NULL)
786 goto error;
787 buffer = PyString_AS_STRING(big_buffer);
788 memcpy(buffer, small_buffer, nfilled);
790 else {
791 /* Grow the big buffer */
792 _PyString_Resize(&big_buffer, buffersize);
793 buffer = PyString_AS_STRING(big_buffer);
795 continue;
797 end = buffer+nfilled+nread;
798 q = buffer;
799 do {
800 /* Process complete lines */
801 p++;
802 line = PyString_FromStringAndSize(q, p-q);
803 if (line == NULL)
804 goto error;
805 err = PyList_Append(list, line);
806 Py_DECREF(line);
807 if (err != 0)
808 goto error;
809 q = p;
810 p = memchr(q, '\n', end-q);
811 } while (p != NULL);
812 /* Move the remaining incomplete line to the start */
813 nfilled = end-q;
814 memmove(buffer, q, nfilled);
815 if (sizehint > 0)
816 if (totalread >= (size_t)sizehint)
817 break;
819 if (nfilled != 0) {
820 /* Partial last line */
821 line = PyString_FromStringAndSize(buffer, nfilled);
822 if (line == NULL)
823 goto error;
824 if (sizehint > 0) {
825 /* Need to complete the last line */
826 PyObject *rest = getline(f, 0);
827 if (rest == NULL) {
828 Py_DECREF(line);
829 goto error;
831 PyString_Concat(&line, rest);
832 Py_DECREF(rest);
833 if (line == NULL)
834 goto error;
836 err = PyList_Append(list, line);
837 Py_DECREF(line);
838 if (err != 0)
839 goto error;
841 cleanup:
842 if (big_buffer) {
843 Py_DECREF(big_buffer);
845 return list;
848 static PyObject *
849 file_write(f, args)
850 PyFileObject *f;
851 PyObject *args;
853 char *s;
854 int n, n2;
855 if (f->f_fp == NULL)
856 return err_closed();
857 if (!PyArg_Parse(args, "s#", &s, &n))
858 return NULL;
859 f->f_softspace = 0;
860 Py_BEGIN_ALLOW_THREADS
861 errno = 0;
862 n2 = fwrite(s, 1, n, f->f_fp);
863 Py_END_ALLOW_THREADS
864 if (n2 != n) {
865 PyErr_SetFromErrno(PyExc_IOError);
866 clearerr(f->f_fp);
867 return NULL;
869 Py_INCREF(Py_None);
870 return Py_None;
873 static PyObject *
874 file_writelines(f, args)
875 PyFileObject *f;
876 PyObject *args;
878 int i, n;
879 if (f->f_fp == NULL)
880 return err_closed();
881 if (args == NULL || !PyList_Check(args)) {
882 PyErr_SetString(PyExc_TypeError,
883 "writelines() requires list of strings");
884 return NULL;
886 n = PyList_Size(args);
887 f->f_softspace = 0;
888 Py_BEGIN_ALLOW_THREADS
889 errno = 0;
890 for (i = 0; i < n; i++) {
891 PyObject *line = PyList_GetItem(args, i);
892 int len;
893 int nwritten;
894 if (!PyString_Check(line)) {
895 Py_BLOCK_THREADS
896 PyErr_SetString(PyExc_TypeError,
897 "writelines() requires list of strings");
898 return NULL;
900 len = PyString_Size(line);
901 nwritten = fwrite(PyString_AsString(line), 1, len, f->f_fp);
902 if (nwritten != len) {
903 Py_BLOCK_THREADS
904 PyErr_SetFromErrno(PyExc_IOError);
905 clearerr(f->f_fp);
906 return NULL;
909 Py_END_ALLOW_THREADS
910 Py_INCREF(Py_None);
911 return Py_None;
914 static PyMethodDef file_methods[] = {
915 {"readline", (PyCFunction)file_readline, 1},
916 {"read", (PyCFunction)file_read, 1},
917 {"write", (PyCFunction)file_write, 0},
918 {"fileno", (PyCFunction)file_fileno, 0},
919 {"seek", (PyCFunction)file_seek, 1},
920 #ifdef HAVE_FTRUNCATE
921 {"truncate", (PyCFunction)file_truncate, 1},
922 #endif
923 {"tell", (PyCFunction)file_tell, 0},
924 {"readinto", (PyCFunction)file_readinto, 0},
925 {"readlines", (PyCFunction)file_readlines, 1},
926 {"writelines", (PyCFunction)file_writelines, 0},
927 {"flush", (PyCFunction)file_flush, 0},
928 {"close", (PyCFunction)file_close, 0},
929 {"isatty", (PyCFunction)file_isatty, 0},
930 {NULL, NULL} /* sentinel */
933 #define OFF(x) offsetof(PyFileObject, x)
935 static struct memberlist file_memberlist[] = {
936 {"softspace", T_INT, OFF(f_softspace)},
937 {"mode", T_OBJECT, OFF(f_mode), RO},
938 {"name", T_OBJECT, OFF(f_name), RO},
939 /* getattr(f, "closed") is implemented without this table */
940 {"closed", T_INT, 0, RO},
941 {NULL} /* Sentinel */
944 static PyObject *
945 file_getattr(f, name)
946 PyFileObject *f;
947 char *name;
949 PyObject *res;
951 res = Py_FindMethod(file_methods, (PyObject *)f, name);
952 if (res != NULL)
953 return res;
954 PyErr_Clear();
955 if (strcmp(name, "closed") == 0)
956 return PyInt_FromLong((long)(f->f_fp == 0));
957 return PyMember_Get((char *)f, file_memberlist, name);
960 static int
961 file_setattr(f, name, v)
962 PyFileObject *f;
963 char *name;
964 PyObject *v;
966 if (v == NULL) {
967 PyErr_SetString(PyExc_AttributeError,
968 "can't delete file attributes");
969 return -1;
971 return PyMember_Set((char *)f, file_memberlist, name, v);
974 PyTypeObject PyFile_Type = {
975 PyObject_HEAD_INIT(&PyType_Type)
977 "file",
978 sizeof(PyFileObject),
980 (destructor)file_dealloc, /*tp_dealloc*/
981 0, /*tp_print*/
982 (getattrfunc)file_getattr, /*tp_getattr*/
983 (setattrfunc)file_setattr, /*tp_setattr*/
984 0, /*tp_compare*/
985 (reprfunc)file_repr, /*tp_repr*/
988 /* Interface for the 'soft space' between print items. */
991 PyFile_SoftSpace(f, newflag)
992 PyObject *f;
993 int newflag;
995 int oldflag = 0;
996 if (f == NULL) {
997 /* Do nothing */
999 else if (PyFile_Check(f)) {
1000 oldflag = ((PyFileObject *)f)->f_softspace;
1001 ((PyFileObject *)f)->f_softspace = newflag;
1003 else {
1004 PyObject *v;
1005 v = PyObject_GetAttrString(f, "softspace");
1006 if (v == NULL)
1007 PyErr_Clear();
1008 else {
1009 if (PyInt_Check(v))
1010 oldflag = PyInt_AsLong(v);
1011 Py_DECREF(v);
1013 v = PyInt_FromLong((long)newflag);
1014 if (v == NULL)
1015 PyErr_Clear();
1016 else {
1017 if (PyObject_SetAttrString(f, "softspace", v) != 0)
1018 PyErr_Clear();
1019 Py_DECREF(v);
1022 return oldflag;
1025 /* Interfaces to write objects/strings to file-like objects */
1028 PyFile_WriteObject(v, f, flags)
1029 PyObject *v;
1030 PyObject *f;
1031 int flags;
1033 PyObject *writer, *value, *args, *result;
1034 if (f == NULL) {
1035 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
1036 return -1;
1038 else if (PyFile_Check(f)) {
1039 FILE *fp = PyFile_AsFile(f);
1040 if (fp == NULL) {
1041 err_closed();
1042 return -1;
1044 return PyObject_Print(v, fp, flags);
1046 writer = PyObject_GetAttrString(f, "write");
1047 if (writer == NULL)
1048 return -1;
1049 if (flags & Py_PRINT_RAW)
1050 value = PyObject_Str(v);
1051 else
1052 value = PyObject_Repr(v);
1053 if (value == NULL) {
1054 Py_DECREF(writer);
1055 return -1;
1057 args = Py_BuildValue("(O)", value);
1058 if (args == NULL) {
1059 Py_DECREF(value);
1060 Py_DECREF(writer);
1061 return -1;
1063 result = PyEval_CallObject(writer, args);
1064 Py_DECREF(args);
1065 Py_DECREF(value);
1066 Py_DECREF(writer);
1067 if (result == NULL)
1068 return -1;
1069 Py_DECREF(result);
1070 return 0;
1074 PyFile_WriteString(s, f)
1075 char *s;
1076 PyObject *f;
1078 if (f == NULL) {
1079 /* Should be caused by a pre-existing error */
1080 if(!PyErr_Occurred())
1081 PyErr_SetString(PyExc_SystemError,
1082 "null file for PyFile_WriteString");
1083 return -1;
1085 else if (PyFile_Check(f)) {
1086 FILE *fp = PyFile_AsFile(f);
1087 if (fp == NULL) {
1088 err_closed();
1089 return -1;
1091 fputs(s, fp);
1092 return 0;
1094 else if (!PyErr_Occurred()) {
1095 PyObject *v = PyString_FromString(s);
1096 int err;
1097 if (v == NULL)
1098 return -1;
1099 err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
1100 Py_DECREF(v);
1101 return err;
1103 else
1104 return -1;