1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
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
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 */
35 #include "structmember.h"
37 #include <sys/types.h>
44 #define ftruncate _chsize
45 #define fileno _fileno
46 #define HAVE_FTRUNCATE
51 #define HAVE_FTRUNCATE
59 /* Mwerks fopen() doesn't always set errno */
60 #define NO_FOPEN_ERRNO
63 #define BUF(v) PyString_AS_STRING((PyStringObject *)v)
72 int (*f_close
) Py_PROTO((FILE *));
73 int f_softspace
; /* Flag used by 'print' command */
80 if (f
== NULL
|| !PyFile_Check(f
))
83 return ((PyFileObject
*)f
)->f_fp
;
90 if (f
== NULL
|| !PyFile_Check(f
))
93 return ((PyFileObject
*)f
)->f_name
;
97 PyFile_FromFile(fp
, name
, mode
, close
)
101 int (*close
) Py_FPROTO((FILE *));
103 PyFileObject
*f
= PyObject_NEW(PyFileObject
, &PyFile_Type
);
107 f
->f_name
= PyString_FromString(name
);
108 f
->f_mode
= PyString_FromString(mode
);
111 if (f
->f_name
== NULL
|| f
->f_mode
== NULL
) {
116 return (PyObject
*) f
;
120 PyFile_FromString(name
, mode
)
123 extern int fclose
Py_PROTO((FILE *));
125 f
= (PyFileObject
*) PyFile_FromFile((FILE *)NULL
, name
, mode
, fclose
);
131 f
->f_fp
= fopenRF(name
, mode
+1);
136 Py_BEGIN_ALLOW_THREADS
137 f
->f_fp
= fopen(name
, mode
);
140 if (f
->f_fp
== NULL
) {
141 #ifdef NO_FOPEN_ERRNO
142 /* Metroworks only, not testable, so unchanged */
144 PyErr_SetString(PyExc_IOError
, "Cannot open file");
149 PyErr_SetFromErrnoWithFilename(PyExc_IOError
, name
);
153 return (PyObject
*)f
;
157 PyFile_SetBufSize(f
, bufsize
)
175 setvbuf(((PyFileObject
*)f
)->f_fp
, (char *)NULL
,
177 #else /* !HAVE_SETVBUF */
179 setbuf(((PyFileObject
*)f
)->f_fp
, (char *)NULL
);
180 #endif /* !HAVE_SETVBUF */
187 PyErr_SetString(PyExc_ValueError
, "I/O operation on closed file");
197 if (f
->f_fp
!= NULL
&& f
->f_close
!= NULL
) {
198 Py_BEGIN_ALLOW_THREADS
199 (*f
->f_close
)(f
->f_fp
);
202 if (f
->f_name
!= NULL
) {
203 Py_DECREF(f
->f_name
);
205 if (f
->f_mode
!= NULL
) {
206 Py_DECREF(f
->f_mode
);
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
),
221 return PyString_FromString(buf
);
230 if (!PyArg_NoArgs(args
))
232 if (f
->f_fp
!= NULL
) {
233 if (f
->f_close
!= NULL
) {
234 Py_BEGIN_ALLOW_THREADS
236 sts
= (*f
->f_close
)(f
->f_fp
);
242 return PyErr_SetFromErrno(PyExc_IOError
);
244 return PyInt_FromLong((long)sts
);
262 if (!PyArg_ParseTuple(args
, "O|i", &offobj
, &whence
))
264 #if !defined(HAVE_LARGEFILE_SUPPORT)
265 offset
= PyInt_AsLong(offobj
);
267 offset
= PyLong_Check(offobj
) ?
268 PyLong_AsLongLong(offobj
) : PyInt_AsLong(offobj
);
270 if (PyErr_Occurred())
272 Py_BEGIN_ALLOW_THREADS
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
);
279 ret
= fseek(f
->f_fp
, offset
, whence
);
283 PyErr_SetFromErrno(PyExc_IOError
);
291 #ifdef HAVE_FTRUNCATE
293 file_truncate(f
, args
)
299 PyObject
*newsizeobj
;
304 if (!PyArg_ParseTuple(args
, "|O", &newsizeobj
))
306 if (newsizeobj
!= NULL
) {
307 #if !defined(HAVE_LARGEFILE_SUPPORT)
308 newsize
= PyInt_AsLong(newsizeobj
);
310 newsize
= PyLong_Check(newsizeobj
) ?
311 PyLong_AsLongLong(newsizeobj
) :
312 PyInt_AsLong(newsizeobj
);
314 if (PyErr_Occurred())
317 /* Default to current position*/
318 Py_BEGIN_ALLOW_THREADS
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
);
325 newsize
= ftell(f
->f_fp
);
329 PyErr_SetFromErrno(PyExc_IOError
);
334 Py_BEGIN_ALLOW_THREADS
336 ret
= fflush(f
->f_fp
);
339 Py_BEGIN_ALLOW_THREADS
341 ret
= ftruncate(fileno(f
->f_fp
), newsize
);
345 PyErr_SetFromErrno(PyExc_IOError
);
352 #endif /* HAVE_FTRUNCATE */
362 if (!PyArg_NoArgs(args
))
364 Py_BEGIN_ALLOW_THREADS
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
);
371 offset
= ftell(f
->f_fp
);
375 PyErr_SetFromErrno(PyExc_IOError
);
379 #if !defined(HAVE_LARGEFILE_SUPPORT)
380 return PyInt_FromLong(offset
);
382 return PyLong_FromLongLong(offset
);
393 if (!PyArg_NoArgs(args
))
395 return PyInt_FromLong((long) fileno(f
->f_fp
));
407 if (!PyArg_NoArgs(args
))
409 Py_BEGIN_ALLOW_THREADS
411 res
= fflush(f
->f_fp
);
414 PyErr_SetFromErrno(PyExc_IOError
);
430 if (!PyArg_NoArgs(args
))
432 Py_BEGIN_ALLOW_THREADS
433 res
= isatty((int)fileno(f
->f_fp
));
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
444 #include <sys/types.h>
445 #include <sys/stat.h>
450 #define SMALLCHUNK 8192
452 #define SMALLCHUNK BUFSIZ
456 #define BIGCHUNK (512 * 32)
458 #define BIGCHUNK (512 * 1024)
462 new_buffersize(f
, currentsize
)
469 if (fstat(fileno(f
->f_fp
), &st
) == 0) {
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
);
482 pos
= ftell(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. */
490 if (currentsize
> SMALLCHUNK
) {
491 /* Keep doubling until we reach BIGCHUNK;
492 then keep adding BIGCHUNK. */
493 if (currentsize
<= BIGCHUNK
)
494 return currentsize
+ currentsize
;
496 return currentsize
+ BIGCHUNK
;
498 return currentsize
+ SMALLCHUNK
;
506 long bytesrequested
= -1;
507 size_t bytesread
, buffersize
, chunksize
;
512 if (!PyArg_ParseTuple(args
, "|l", &bytesrequested
))
514 if (bytesrequested
< 0)
515 buffersize
= new_buffersize(f
, 0);
517 buffersize
= bytesrequested
;
518 v
= PyString_FromStringAndSize((char *)NULL
, buffersize
);
523 Py_BEGIN_ALLOW_THREADS
525 chunksize
= fread(BUF(v
) + bytesread
, 1,
526 buffersize
- bytesread
, f
->f_fp
);
528 if (chunksize
== 0) {
529 if (!ferror(f
->f_fp
))
531 PyErr_SetFromErrno(PyExc_IOError
);
536 bytesread
+= chunksize
;
537 if (bytesread
< buffersize
)
539 if (bytesrequested
< 0) {
540 buffersize
= new_buffersize(f
, buffersize
);
541 if (_PyString_Resize(&v
, buffersize
) < 0)
545 if (bytesread
!= buffersize
)
546 _PyString_Resize(&v
, bytesread
);
551 file_readinto(f
, args
)
556 int ntodo
, ndone
, nnow
;
560 if (!PyArg_Parse(args
, "w#", &ptr
, &ntodo
))
564 Py_BEGIN_ALLOW_THREADS
566 nnow
= fread(ptr
+ndone
, 1, ntodo
, f
->f_fp
);
569 if (!ferror(f
->f_fp
))
571 PyErr_SetFromErrno(PyExc_IOError
);
578 return PyInt_FromLong(ndone
);
582 /* Internal routine to get a line.
583 Size argument interpretation:
585 = 0: read arbitrary line;
586 < 0: strip trailing '\n', raise EOFError if EOF reached immediately
596 register char *buf
, *end
;
601 n2
= n
> 0 ? n
: 100;
602 v
= PyString_FromStringAndSize((char *)NULL
, n2
);
608 Py_BEGIN_ALLOW_THREADS
610 if ((c
= getc(fp
)) == EOF
) {
613 if (PyErr_CheckSignals()) {
617 if (n
< 0 && buf
== BUF(v
)) {
619 PyErr_SetString(PyExc_EOFError
,
620 "EOF when reading a line");
626 if ((*buf
++ = c
) == '\n') {
637 if (_PyString_Resize(&v
, n2
) < 0)
648 _PyString_Resize(&v
, n1
);
652 /* External C interface */
660 PyErr_BadInternalCall();
663 if (!PyFile_Check(f
)) {
667 reader
= PyObject_GetAttrString(f
, "readline");
671 args
= Py_BuildValue("()");
673 args
= Py_BuildValue("(i)", n
);
678 result
= PyEval_CallObject(reader
, args
);
681 if (result
!= NULL
&& !PyString_Check(result
)) {
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
);
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);
701 v
= PyString_FromStringAndSize(s
,
710 if (((PyFileObject
*)f
)->f_fp
== NULL
)
712 return getline((PyFileObject
*)f
, n
);
718 file_readline(f
, args
)
726 if (!PyArg_ParseTuple(args
, "|i", &n
))
729 return PyString_FromString("");
732 return getline(f
, n
);
736 file_readlines(f
, args
)
743 char small_buffer
[SMALLCHUNK
];
744 char *buffer
= small_buffer
;
745 size_t buffersize
= SMALLCHUNK
;
746 PyObject
*big_buffer
= NULL
;
749 size_t totalread
= 0;
755 if (!PyArg_ParseTuple(args
, "|l", &sizehint
))
757 if ((list
= PyList_New(0)) == NULL
)
760 Py_BEGIN_ALLOW_THREADS
762 nread
= fread(buffer
+nfilled
, 1, buffersize
-nfilled
, f
->f_fp
);
766 if (!ferror(f
->f_fp
))
768 PyErr_SetFromErrno(PyExc_IOError
);
776 p
= memchr(buffer
+nfilled
, '\n', nread
);
778 /* Need a larger buffer to fit this line */
781 if (big_buffer
== NULL
) {
782 /* Create the big buffer */
783 big_buffer
= PyString_FromStringAndSize(
785 if (big_buffer
== NULL
)
787 buffer
= PyString_AS_STRING(big_buffer
);
788 memcpy(buffer
, small_buffer
, nfilled
);
791 /* Grow the big buffer */
792 _PyString_Resize(&big_buffer
, buffersize
);
793 buffer
= PyString_AS_STRING(big_buffer
);
797 end
= buffer
+nfilled
+nread
;
800 /* Process complete lines */
802 line
= PyString_FromStringAndSize(q
, p
-q
);
805 err
= PyList_Append(list
, line
);
810 p
= memchr(q
, '\n', end
-q
);
812 /* Move the remaining incomplete line to the start */
814 memmove(buffer
, q
, nfilled
);
816 if (totalread
>= (size_t)sizehint
)
820 /* Partial last line */
821 line
= PyString_FromStringAndSize(buffer
, nfilled
);
825 /* Need to complete the last line */
826 PyObject
*rest
= getline(f
, 0);
831 PyString_Concat(&line
, rest
);
836 err
= PyList_Append(list
, line
);
843 Py_DECREF(big_buffer
);
857 if (!PyArg_Parse(args
, "s#", &s
, &n
))
860 Py_BEGIN_ALLOW_THREADS
862 n2
= fwrite(s
, 1, n
, f
->f_fp
);
865 PyErr_SetFromErrno(PyExc_IOError
);
874 file_writelines(f
, args
)
881 if (args
== NULL
|| !PyList_Check(args
)) {
882 PyErr_SetString(PyExc_TypeError
,
883 "writelines() requires list of strings");
886 n
= PyList_Size(args
);
888 Py_BEGIN_ALLOW_THREADS
890 for (i
= 0; i
< n
; i
++) {
891 PyObject
*line
= PyList_GetItem(args
, i
);
894 if (!PyString_Check(line
)) {
896 PyErr_SetString(PyExc_TypeError
,
897 "writelines() requires list of strings");
900 len
= PyString_Size(line
);
901 nwritten
= fwrite(PyString_AsString(line
), 1, len
, f
->f_fp
);
902 if (nwritten
!= len
) {
904 PyErr_SetFromErrno(PyExc_IOError
);
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},
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 */
945 file_getattr(f
, name
)
951 res
= Py_FindMethod(file_methods
, (PyObject
*)f
, name
);
955 if (strcmp(name
, "closed") == 0)
956 return PyInt_FromLong((long)(f
->f_fp
== 0));
957 return PyMember_Get((char *)f
, file_memberlist
, name
);
961 file_setattr(f
, name
, v
)
967 PyErr_SetString(PyExc_AttributeError
,
968 "can't delete file attributes");
971 return PyMember_Set((char *)f
, file_memberlist
, name
, v
);
974 PyTypeObject PyFile_Type
= {
975 PyObject_HEAD_INIT(&PyType_Type
)
978 sizeof(PyFileObject
),
980 (destructor
)file_dealloc
, /*tp_dealloc*/
982 (getattrfunc
)file_getattr
, /*tp_getattr*/
983 (setattrfunc
)file_setattr
, /*tp_setattr*/
985 (reprfunc
)file_repr
, /*tp_repr*/
988 /* Interface for the 'soft space' between print items. */
991 PyFile_SoftSpace(f
, newflag
)
999 else if (PyFile_Check(f
)) {
1000 oldflag
= ((PyFileObject
*)f
)->f_softspace
;
1001 ((PyFileObject
*)f
)->f_softspace
= newflag
;
1005 v
= PyObject_GetAttrString(f
, "softspace");
1010 oldflag
= PyInt_AsLong(v
);
1013 v
= PyInt_FromLong((long)newflag
);
1017 if (PyObject_SetAttrString(f
, "softspace", v
) != 0)
1025 /* Interfaces to write objects/strings to file-like objects */
1028 PyFile_WriteObject(v
, f
, flags
)
1033 PyObject
*writer
, *value
, *args
, *result
;
1035 PyErr_SetString(PyExc_TypeError
, "writeobject with NULL file");
1038 else if (PyFile_Check(f
)) {
1039 FILE *fp
= PyFile_AsFile(f
);
1044 return PyObject_Print(v
, fp
, flags
);
1046 writer
= PyObject_GetAttrString(f
, "write");
1049 if (flags
& Py_PRINT_RAW
)
1050 value
= PyObject_Str(v
);
1052 value
= PyObject_Repr(v
);
1053 if (value
== NULL
) {
1057 args
= Py_BuildValue("(O)", value
);
1063 result
= PyEval_CallObject(writer
, args
);
1074 PyFile_WriteString(s
, f
)
1079 /* Should be caused by a pre-existing error */
1080 if(!PyErr_Occurred())
1081 PyErr_SetString(PyExc_SystemError
,
1082 "null file for PyFile_WriteString");
1085 else if (PyFile_Check(f
)) {
1086 FILE *fp
= PyFile_AsFile(f
);
1094 else if (!PyErr_Occurred()) {
1095 PyObject
*v
= PyString_FromString(s
);
1099 err
= PyFile_WriteObject(v
, f
, Py_PRINT_RAW
);