source: python/vendor/Python-2.6.5/Modules/_fileio.c

Last change on this file was 2, checked in by Yuri Dario, 15 years ago

Initial import for vendor code.

  • Property svn:eol-style set to native
File size: 20.8 KB
Line 
1/* Author: Daniel Stutzbach */
2
3#define PY_SSIZE_T_CLEAN
4#include "Python.h"
5#include <sys/types.h>
6#include <sys/stat.h>
7#include <fcntl.h>
8#include <stddef.h> /* For offsetof */
9
10/*
11 * Known likely problems:
12 *
13 * - Files larger then 2**32-1
14 * - Files with unicode filenames
15 * - Passing numbers greater than 2**32-1 when an integer is expected
16 * - Making it work on Windows and other oddball platforms
17 *
18 * To Do:
19 *
20 * - autoconfify header file inclusion
21 */
22
23#ifdef MS_WINDOWS
24/* can simulate truncate with Win32 API functions; see file_truncate */
25#define HAVE_FTRUNCATE
26#define WIN32_LEAN_AND_MEAN
27#include <windows.h>
28#endif
29
30typedef struct {
31 PyObject_HEAD
32 int fd;
33 unsigned int readable : 1;
34 unsigned int writable : 1;
35 signed int seekable : 2; /* -1 means unknown */
36 signed int closefd : 1;
37 PyObject *weakreflist;
38} PyFileIOObject;
39
40PyTypeObject PyFileIO_Type;
41
42#define PyFileIO_Check(op) (PyObject_TypeCheck((op), &PyFileIO_Type))
43
44static PyObject *
45portable_lseek(int fd, PyObject *posobj, int whence);
46
47/* Returns 0 on success, errno (which is < 0) on failure. */
48static int
49internal_close(PyFileIOObject *self)
50{
51 int save_errno = 0;
52 if (self->fd >= 0) {
53 int fd = self->fd;
54 self->fd = -1;
55 Py_BEGIN_ALLOW_THREADS
56 if (close(fd) < 0)
57 save_errno = errno;
58 Py_END_ALLOW_THREADS
59 }
60 return save_errno;
61}
62
63static PyObject *
64fileio_close(PyFileIOObject *self)
65{
66 if (!self->closefd) {
67 self->fd = -1;
68 Py_RETURN_NONE;
69 }
70 errno = internal_close(self);
71 if (errno < 0) {
72 PyErr_SetFromErrno(PyExc_IOError);
73 return NULL;
74 }
75
76 Py_RETURN_NONE;
77}
78
79static PyObject *
80fileio_new(PyTypeObject *type, PyObject *args, PyObject *kews)
81{
82 PyFileIOObject *self;
83
84 assert(type != NULL && type->tp_alloc != NULL);
85
86 self = (PyFileIOObject *) type->tp_alloc(type, 0);
87 if (self != NULL) {
88 self->fd = -1;
89 self->readable = 0;
90 self->writable = 0;
91 self->seekable = -1;
92 self->closefd = 1;
93 self->weakreflist = NULL;
94 }
95
96 return (PyObject *) self;
97}
98
99/* On Unix, open will succeed for directories.
100 In Python, there should be no file objects referring to
101 directories, so we need a check. */
102
103static int
104dircheck(PyFileIOObject* self, char *name)
105{
106#if defined(HAVE_FSTAT) && defined(S_IFDIR) && defined(EISDIR)
107 struct stat buf;
108 if (self->fd < 0)
109 return 0;
110 if (fstat(self->fd, &buf) == 0 && S_ISDIR(buf.st_mode)) {
111 char *msg = strerror(EISDIR);
112 PyObject *exc;
113 internal_close(self);
114
115 exc = PyObject_CallFunction(PyExc_IOError, "(iss)",
116 EISDIR, msg, name);
117 PyErr_SetObject(PyExc_IOError, exc);
118 Py_XDECREF(exc);
119 return -1;
120 }
121#endif
122 return 0;
123}
124
125static int
126check_fd(int fd)
127{
128#if defined(HAVE_FSTAT)
129 struct stat buf;
130 if (fstat(fd, &buf) < 0 && errno == EBADF) {
131 PyObject *exc;
132 char *msg = strerror(EBADF);
133 exc = PyObject_CallFunction(PyExc_OSError, "(is)",
134 EBADF, msg);
135 PyErr_SetObject(PyExc_OSError, exc);
136 Py_XDECREF(exc);
137 return -1;
138 }
139#endif
140 return 0;
141}
142
143
144static int
145fileio_init(PyObject *oself, PyObject *args, PyObject *kwds)
146{
147 PyFileIOObject *self = (PyFileIOObject *) oself;
148 static char *kwlist[] = {"file", "mode", "closefd", NULL};
149 char *name = NULL;
150 char *mode = "r";
151 char *s;
152#ifdef MS_WINDOWS
153 Py_UNICODE *widename = NULL;
154#endif
155 int ret = 0;
156 int rwa = 0, plus = 0, append = 0;
157 int flags = 0;
158 int fd = -1;
159 int closefd = 1;
160
161 assert(PyFileIO_Check(oself));
162 if (self->fd >= 0) {
163 /* Have to close the existing file first. */
164 if (internal_close(self) < 0)
165 return -1;
166 }
167
168 if (PyArg_ParseTupleAndKeywords(args, kwds, "i|si:fileio",
169 kwlist, &fd, &mode, &closefd)) {
170 if (fd < 0) {
171 PyErr_SetString(PyExc_ValueError,
172 "Negative filedescriptor");
173 return -1;
174 }
175 if (check_fd(fd))
176 return -1;
177 }
178 else {
179 PyErr_Clear();
180
181#ifdef Py_WIN_WIDE_FILENAMES
182 if (GetVersion() < 0x80000000) {
183 /* On NT, so wide API available */
184 PyObject *po;
185 if (PyArg_ParseTupleAndKeywords(args, kwds, "U|si:fileio",
186 kwlist, &po, &mode, &closefd)
187 ) {
188 widename = PyUnicode_AS_UNICODE(po);
189 } else {
190 /* Drop the argument parsing error as narrow
191 strings are also valid. */
192 PyErr_Clear();
193 }
194 }
195 if (widename == NULL)
196#endif
197 {
198 if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|si:fileio",
199 kwlist,
200 Py_FileSystemDefaultEncoding,
201 &name, &mode, &closefd))
202 return -1;
203 }
204 }
205
206 s = mode;
207 while (*s) {
208 switch (*s++) {
209 case 'r':
210 if (rwa) {
211 bad_mode:
212 PyErr_SetString(PyExc_ValueError,
213 "Must have exactly one of read/write/append mode");
214 goto error;
215 }
216 rwa = 1;
217 self->readable = 1;
218 break;
219 case 'w':
220 if (rwa)
221 goto bad_mode;
222 rwa = 1;
223 self->writable = 1;
224 flags |= O_CREAT | O_TRUNC;
225 break;
226 case 'a':
227 if (rwa)
228 goto bad_mode;
229 rwa = 1;
230 self->writable = 1;
231 flags |= O_CREAT;
232 append = 1;
233 break;
234 case 'b':
235 break;
236 case '+':
237 if (plus)
238 goto bad_mode;
239 self->readable = self->writable = 1;
240 plus = 1;
241 break;
242 default:
243 PyErr_Format(PyExc_ValueError,
244 "invalid mode: %.200s", mode);
245 goto error;
246 }
247 }
248
249 if (!rwa)
250 goto bad_mode;
251
252 if (self->readable && self->writable)
253 flags |= O_RDWR;
254 else if (self->readable)
255 flags |= O_RDONLY;
256 else
257 flags |= O_WRONLY;
258
259#ifdef O_BINARY
260 flags |= O_BINARY;
261#endif
262
263#ifdef O_APPEND
264 if (append)
265 flags |= O_APPEND;
266#endif
267
268 if (fd >= 0) {
269 self->fd = fd;
270 self->closefd = closefd;
271 }
272 else {
273 self->closefd = 1;
274 if (!closefd) {
275 PyErr_SetString(PyExc_ValueError,
276 "Cannot use closefd=False with file name");
277 goto error;
278 }
279
280 Py_BEGIN_ALLOW_THREADS
281 errno = 0;
282#ifdef MS_WINDOWS
283 if (widename != NULL)
284 self->fd = _wopen(widename, flags, 0666);
285 else
286#endif
287 self->fd = open(name, flags, 0666);
288 Py_END_ALLOW_THREADS
289 if (self->fd < 0) {
290#ifdef MS_WINDOWS
291 if (widename != NULL)
292 PyErr_SetFromErrnoWithUnicodeFilename(PyExc_IOError, widename);
293 else
294#endif
295 PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
296 goto error;
297 }
298 if(dircheck(self, name) < 0)
299 goto error;
300 }
301
302 if (append) {
303 /* For consistent behaviour, we explicitly seek to the
304 end of file (otherwise, it might be done only on the
305 first write()). */
306 PyObject *pos = portable_lseek(self->fd, NULL, 2);
307 if (pos == NULL)
308 goto error;
309 Py_DECREF(pos);
310 }
311
312 goto done;
313
314 error:
315 ret = -1;
316
317 done:
318 PyMem_Free(name);
319 return ret;
320}
321
322static void
323fileio_dealloc(PyFileIOObject *self)
324{
325 if (self->weakreflist != NULL)
326 PyObject_ClearWeakRefs((PyObject *) self);
327
328 if (self->fd >= 0 && self->closefd) {
329 errno = internal_close(self);
330 if (errno < 0) {
331 PySys_WriteStderr("close failed: [Errno %d] %s\n",
332 errno, strerror(errno));
333 }
334 }
335
336 Py_TYPE(self)->tp_free((PyObject *)self);
337}
338
339static PyObject *
340err_closed(void)
341{
342 PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
343 return NULL;
344}
345
346static PyObject *
347err_mode(char *action)
348{
349 PyErr_Format(PyExc_ValueError, "File not open for %s", action);
350 return NULL;
351}
352
353static PyObject *
354fileio_fileno(PyFileIOObject *self)
355{
356 if (self->fd < 0)
357 return err_closed();
358 return PyInt_FromLong((long) self->fd);
359}
360
361static PyObject *
362fileio_readable(PyFileIOObject *self)
363{
364 if (self->fd < 0)
365 return err_closed();
366 return PyBool_FromLong((long) self->readable);
367}
368
369static PyObject *
370fileio_writable(PyFileIOObject *self)
371{
372 if (self->fd < 0)
373 return err_closed();
374 return PyBool_FromLong((long) self->writable);
375}
376
377static PyObject *
378fileio_seekable(PyFileIOObject *self)
379{
380 if (self->fd < 0)
381 return err_closed();
382 if (self->seekable < 0) {
383 int ret;
384 Py_BEGIN_ALLOW_THREADS
385 ret = lseek(self->fd, 0, SEEK_CUR);
386 Py_END_ALLOW_THREADS
387 if (ret < 0)
388 self->seekable = 0;
389 else
390 self->seekable = 1;
391 }
392 return PyBool_FromLong((long) self->seekable);
393}
394
395static PyObject *
396fileio_readinto(PyFileIOObject *self, PyObject *args)
397{
398 Py_buffer pbuf;
399 Py_ssize_t n;
400
401 if (self->fd < 0)
402 return err_closed();
403 if (!self->readable)
404 return err_mode("reading");
405
406 if (!PyArg_ParseTuple(args, "w*", &pbuf))
407 return NULL;
408
409 Py_BEGIN_ALLOW_THREADS
410 errno = 0;
411 n = read(self->fd, pbuf.buf, pbuf.len);
412 Py_END_ALLOW_THREADS
413 PyBuffer_Release(&pbuf);
414 if (n < 0) {
415 if (errno == EAGAIN)
416 Py_RETURN_NONE;
417 PyErr_SetFromErrno(PyExc_IOError);
418 return NULL;
419 }
420
421 return PyLong_FromSsize_t(n);
422}
423
424#define DEFAULT_BUFFER_SIZE (8*1024)
425
426static PyObject *
427fileio_readall(PyFileIOObject *self)
428{
429 PyObject *result;
430 Py_ssize_t total = 0;
431 int n;
432
433 result = PyString_FromStringAndSize(NULL, DEFAULT_BUFFER_SIZE);
434 if (result == NULL)
435 return NULL;
436
437 while (1) {
438 Py_ssize_t newsize = total + DEFAULT_BUFFER_SIZE;
439 if (PyString_GET_SIZE(result) < newsize) {
440 if (_PyString_Resize(&result, newsize) < 0) {
441 if (total == 0) {
442 Py_DECREF(result);
443 return NULL;
444 }
445 PyErr_Clear();
446 break;
447 }
448 }
449 Py_BEGIN_ALLOW_THREADS
450 errno = 0;
451 n = read(self->fd,
452 PyString_AS_STRING(result) + total,
453 newsize - total);
454 Py_END_ALLOW_THREADS
455 if (n == 0)
456 break;
457 if (n < 0) {
458 if (total > 0)
459 break;
460 if (errno == EAGAIN) {
461 Py_DECREF(result);
462 Py_RETURN_NONE;
463 }
464 Py_DECREF(result);
465 PyErr_SetFromErrno(PyExc_IOError);
466 return NULL;
467 }
468 total += n;
469 }
470
471 if (PyString_GET_SIZE(result) > total) {
472 if (_PyString_Resize(&result, total) < 0) {
473 /* This should never happen, but just in case */
474 Py_DECREF(result);
475 return NULL;
476 }
477 }
478 return result;
479}
480
481static PyObject *
482fileio_read(PyFileIOObject *self, PyObject *args)
483{
484 char *ptr;
485 Py_ssize_t n;
486 Py_ssize_t size = -1;
487 PyObject *bytes;
488
489 if (self->fd < 0)
490 return err_closed();
491 if (!self->readable)
492 return err_mode("reading");
493
494 if (!PyArg_ParseTuple(args, "|n", &size))
495 return NULL;
496
497 if (size < 0) {
498 return fileio_readall(self);
499 }
500
501 bytes = PyString_FromStringAndSize(NULL, size);
502 if (bytes == NULL)
503 return NULL;
504 ptr = PyString_AS_STRING(bytes);
505
506 Py_BEGIN_ALLOW_THREADS
507 errno = 0;
508 n = read(self->fd, ptr, size);
509 Py_END_ALLOW_THREADS
510
511 if (n < 0) {
512 if (errno == EAGAIN)
513 Py_RETURN_NONE;
514 PyErr_SetFromErrno(PyExc_IOError);
515 return NULL;
516 }
517
518 if (n != size) {
519 if (_PyString_Resize(&bytes, n) < 0) {
520 Py_DECREF(bytes);
521 return NULL;
522 }
523 }
524
525 return (PyObject *) bytes;
526}
527
528static PyObject *
529fileio_write(PyFileIOObject *self, PyObject *args)
530{
531 Py_buffer pbuf;
532 Py_ssize_t n;
533
534 if (self->fd < 0)
535 return err_closed();
536 if (!self->writable)
537 return err_mode("writing");
538
539 if (!PyArg_ParseTuple(args, "s*", &pbuf))
540 return NULL;
541
542 Py_BEGIN_ALLOW_THREADS
543 errno = 0;
544 n = write(self->fd, pbuf.buf, pbuf.len);
545 Py_END_ALLOW_THREADS
546
547 PyBuffer_Release(&pbuf);
548
549 if (n < 0) {
550 if (errno == EAGAIN)
551 Py_RETURN_NONE;
552 PyErr_SetFromErrno(PyExc_IOError);
553 return NULL;
554 }
555
556 return PyLong_FromSsize_t(n);
557}
558
559/* XXX Windows support below is likely incomplete */
560
561#if defined(MS_WIN64) || defined(MS_WINDOWS)
562typedef PY_LONG_LONG Py_off_t;
563#else
564typedef off_t Py_off_t;
565#endif
566
567/* Cribbed from posix_lseek() */
568static PyObject *
569portable_lseek(int fd, PyObject *posobj, int whence)
570{
571 Py_off_t pos, res;
572
573#ifdef SEEK_SET
574 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
575 switch (whence) {
576#if SEEK_SET != 0
577 case 0: whence = SEEK_SET; break;
578#endif
579#if SEEK_CUR != 1
580 case 1: whence = SEEK_CUR; break;
581#endif
582#if SEEL_END != 2
583 case 2: whence = SEEK_END; break;
584#endif
585 }
586#endif /* SEEK_SET */
587
588 if (posobj == NULL)
589 pos = 0;
590 else {
591 if(PyFloat_Check(posobj)) {
592 PyErr_SetString(PyExc_TypeError, "an integer is required");
593 return NULL;
594 }
595#if defined(HAVE_LARGEFILE_SUPPORT)
596 pos = PyLong_AsLongLong(posobj);
597#else
598 pos = PyLong_AsLong(posobj);
599#endif
600 if (PyErr_Occurred())
601 return NULL;
602 }
603
604 Py_BEGIN_ALLOW_THREADS
605#if defined(MS_WIN64) || defined(MS_WINDOWS)
606 res = _lseeki64(fd, pos, whence);
607#else
608 res = lseek(fd, pos, whence);
609#endif
610 Py_END_ALLOW_THREADS
611 if (res < 0)
612 return PyErr_SetFromErrno(PyExc_IOError);
613
614#if defined(HAVE_LARGEFILE_SUPPORT)
615 return PyLong_FromLongLong(res);
616#else
617 return PyLong_FromLong(res);
618#endif
619}
620
621static PyObject *
622fileio_seek(PyFileIOObject *self, PyObject *args)
623{
624 PyObject *posobj;
625 int whence = 0;
626
627 if (self->fd < 0)
628 return err_closed();
629
630 if (!PyArg_ParseTuple(args, "O|i", &posobj, &whence))
631 return NULL;
632
633 return portable_lseek(self->fd, posobj, whence);
634}
635
636static PyObject *
637fileio_tell(PyFileIOObject *self, PyObject *args)
638{
639 if (self->fd < 0)
640 return err_closed();
641
642 return portable_lseek(self->fd, NULL, 1);
643}
644
645#ifdef HAVE_FTRUNCATE
646static PyObject *
647fileio_truncate(PyFileIOObject *self, PyObject *args)
648{
649 PyObject *posobj = NULL; /* the new size wanted by the user */
650#ifndef MS_WINDOWS
651 Py_off_t pos;
652#endif
653 int ret;
654 int fd;
655
656 fd = self->fd;
657 if (fd < 0)
658 return err_closed();
659 if (!self->writable)
660 return err_mode("writing");
661
662 if (!PyArg_ParseTuple(args, "|O", &posobj))
663 return NULL;
664
665 if (posobj == Py_None || posobj == NULL) {
666 /* Get the current position. */
667 posobj = portable_lseek(fd, NULL, 1);
668 if (posobj == NULL)
669 return NULL;
670 }
671 else {
672 Py_INCREF(posobj);
673 }
674
675#ifdef MS_WINDOWS
676 /* MS _chsize doesn't work if newsize doesn't fit in 32 bits,
677 so don't even try using it. */
678 {
679 PyObject *oldposobj, *tempposobj;
680 HANDLE hFile;
681
682 /* we save the file pointer position */
683 oldposobj = portable_lseek(fd, NULL, 1);
684 if (oldposobj == NULL) {
685 Py_DECREF(posobj);
686 return NULL;
687 }
688
689 /* we then move to the truncation position */
690 tempposobj = portable_lseek(fd, posobj, 0);
691 if (tempposobj == NULL) {
692 Py_DECREF(oldposobj);
693 Py_DECREF(posobj);
694 return NULL;
695 }
696 Py_DECREF(tempposobj);
697
698 /* Truncate. Note that this may grow the file! */
699 Py_BEGIN_ALLOW_THREADS
700 errno = 0;
701 hFile = (HANDLE)_get_osfhandle(fd);
702 ret = hFile == (HANDLE)-1; /* testing for INVALID_HANDLE value */
703 if (ret == 0) {
704 ret = SetEndOfFile(hFile) == 0;
705 if (ret)
706 errno = EACCES;
707 }
708 Py_END_ALLOW_THREADS
709
710 /* we restore the file pointer position in any case */
711 tempposobj = portable_lseek(fd, oldposobj, 0);
712 Py_DECREF(oldposobj);
713 if (tempposobj == NULL) {
714 Py_DECREF(posobj);
715 return NULL;
716 }
717 Py_DECREF(tempposobj);
718 }
719#else
720
721#if defined(HAVE_LARGEFILE_SUPPORT)
722 pos = PyLong_AsLongLong(posobj);
723#else
724 pos = PyLong_AsLong(posobj);
725#endif
726 if (PyErr_Occurred()){
727 Py_DECREF(posobj);
728 return NULL;
729 }
730
731 Py_BEGIN_ALLOW_THREADS
732 errno = 0;
733 ret = ftruncate(fd, pos);
734 Py_END_ALLOW_THREADS
735
736#endif /* !MS_WINDOWS */
737
738 if (ret != 0) {
739 Py_DECREF(posobj);
740 PyErr_SetFromErrno(PyExc_IOError);
741 return NULL;
742 }
743
744 return posobj;
745}
746#endif /* HAVE_FTRUNCATE */
747
748static char *
749mode_string(PyFileIOObject *self)
750{
751 if (self->readable) {
752 if (self->writable)
753 return "rb+";
754 else
755 return "rb";
756 }
757 else
758 return "wb";
759}
760
761static PyObject *
762fileio_repr(PyFileIOObject *self)
763{
764 if (self->fd < 0)
765 return PyString_FromFormat("_fileio._FileIO(-1)");
766
767 return PyString_FromFormat("_fileio._FileIO(%d, '%s')",
768 self->fd, mode_string(self));
769}
770
771static PyObject *
772fileio_isatty(PyFileIOObject *self)
773{
774 long res;
775
776 if (self->fd < 0)
777 return err_closed();
778 Py_BEGIN_ALLOW_THREADS
779 res = isatty(self->fd);
780 Py_END_ALLOW_THREADS
781 return PyBool_FromLong(res);
782}
783
784
785PyDoc_STRVAR(fileio_doc,
786"file(name: str[, mode: str]) -> file IO object\n"
787"\n"
788"Open a file. The mode can be 'r', 'w' or 'a' for reading (default),\n"
789"writing or appending. The file will be created if it doesn't exist\n"
790"when opened for writing or appending; it will be truncated when\n"
791"opened for writing. Add a '+' to the mode to allow simultaneous\n"
792"reading and writing.");
793
794PyDoc_STRVAR(read_doc,
795"read(size: int) -> bytes. read at most size bytes, returned as bytes.\n"
796"\n"
797"Only makes one system call, so less data may be returned than requested\n"
798"In non-blocking mode, returns None if no data is available.\n"
799"On end-of-file, returns ''.");
800
801PyDoc_STRVAR(readall_doc,
802"readall() -> bytes. read all data from the file, returned as bytes.\n"
803"\n"
804"In non-blocking mode, returns as much as is immediately available,\n"
805"or None if no data is available. On end-of-file, returns ''.");
806
807PyDoc_STRVAR(write_doc,
808"write(b: bytes) -> int. Write bytes b to file, return number written.\n"
809"\n"
810"Only makes one system call, so not all of the data may be written.\n"
811"The number of bytes actually written is returned.");
812
813PyDoc_STRVAR(fileno_doc,
814"fileno() -> int. \"file descriptor\".\n"
815"\n"
816"This is needed for lower-level file interfaces, such the fcntl module.");
817
818PyDoc_STRVAR(seek_doc,
819"seek(offset: int[, whence: int]) -> None. Move to new file position.\n"
820"\n"
821"Argument offset is a byte count. Optional argument whence defaults to\n"
822"0 (offset from start of file, offset should be >= 0); other values are 1\n"
823"(move relative to current position, positive or negative), and 2 (move\n"
824"relative to end of file, usually negative, although many platforms allow\n"
825"seeking beyond the end of a file)."
826"\n"
827"Note that not all file objects are seekable.");
828
829#ifdef HAVE_FTRUNCATE
830PyDoc_STRVAR(truncate_doc,
831"truncate([size: int]) -> None. Truncate the file to at most size bytes.\n"
832"\n"
833"Size defaults to the current file position, as returned by tell()."
834"The current file position is changed to the value of size.");
835#endif
836
837PyDoc_STRVAR(tell_doc,
838"tell() -> int. Current file position");
839
840PyDoc_STRVAR(readinto_doc,
841"readinto() -> Undocumented. Don't use this; it may go away.");
842
843PyDoc_STRVAR(close_doc,
844"close() -> None. Close the file.\n"
845"\n"
846"A closed file cannot be used for further I/O operations. close() may be\n"
847"called more than once without error. Changes the fileno to -1.");
848
849PyDoc_STRVAR(isatty_doc,
850"isatty() -> bool. True if the file is connected to a tty device.");
851
852PyDoc_STRVAR(seekable_doc,
853"seekable() -> bool. True if file supports random-access.");
854
855PyDoc_STRVAR(readable_doc,
856"readable() -> bool. True if file was opened in a read mode.");
857
858PyDoc_STRVAR(writable_doc,
859"writable() -> bool. True if file was opened in a write mode.");
860
861static PyMethodDef fileio_methods[] = {
862 {"read", (PyCFunction)fileio_read, METH_VARARGS, read_doc},
863 {"readall", (PyCFunction)fileio_readall, METH_NOARGS, readall_doc},
864 {"readinto", (PyCFunction)fileio_readinto, METH_VARARGS, readinto_doc},
865 {"write", (PyCFunction)fileio_write, METH_VARARGS, write_doc},
866 {"seek", (PyCFunction)fileio_seek, METH_VARARGS, seek_doc},
867 {"tell", (PyCFunction)fileio_tell, METH_VARARGS, tell_doc},
868#ifdef HAVE_FTRUNCATE
869 {"truncate", (PyCFunction)fileio_truncate, METH_VARARGS, truncate_doc},
870#endif
871 {"close", (PyCFunction)fileio_close, METH_NOARGS, close_doc},
872 {"seekable", (PyCFunction)fileio_seekable, METH_NOARGS, seekable_doc},
873 {"readable", (PyCFunction)fileio_readable, METH_NOARGS, readable_doc},
874 {"writable", (PyCFunction)fileio_writable, METH_NOARGS, writable_doc},
875 {"fileno", (PyCFunction)fileio_fileno, METH_NOARGS, fileno_doc},
876 {"isatty", (PyCFunction)fileio_isatty, METH_NOARGS, isatty_doc},
877 {NULL, NULL} /* sentinel */
878};
879
880/* 'closed' and 'mode' are attributes for backwards compatibility reasons. */
881
882static PyObject *
883get_closed(PyFileIOObject *self, void *closure)
884{
885 return PyBool_FromLong((long)(self->fd < 0));
886}
887
888static PyObject *
889get_closefd(PyFileIOObject *self, void *closure)
890{
891 return PyBool_FromLong((long)(self->closefd));
892}
893
894static PyObject *
895get_mode(PyFileIOObject *self, void *closure)
896{
897 return PyString_FromString(mode_string(self));
898}
899
900static PyGetSetDef fileio_getsetlist[] = {
901 {"closed", (getter)get_closed, NULL, "True if the file is closed"},
902 {"closefd", (getter)get_closefd, NULL,
903 "True if the file descriptor will be closed"},
904 {"mode", (getter)get_mode, NULL, "String giving the file mode"},
905 {0},
906};
907
908PyTypeObject PyFileIO_Type = {
909 PyVarObject_HEAD_INIT(NULL, 0)
910 "_FileIO",
911 sizeof(PyFileIOObject),
912 0,
913 (destructor)fileio_dealloc, /* tp_dealloc */
914 0, /* tp_print */
915 0, /* tp_getattr */
916 0, /* tp_setattr */
917 0, /* tp_compare */
918 (reprfunc)fileio_repr, /* tp_repr */
919 0, /* tp_as_number */
920 0, /* tp_as_sequence */
921 0, /* tp_as_mapping */
922 0, /* tp_hash */
923 0, /* tp_call */
924 0, /* tp_str */
925 PyObject_GenericGetAttr, /* tp_getattro */
926 0, /* tp_setattro */
927 0, /* tp_as_buffer */
928 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
929 fileio_doc, /* tp_doc */
930 0, /* tp_traverse */
931 0, /* tp_clear */
932 0, /* tp_richcompare */
933 offsetof(PyFileIOObject, weakreflist), /* tp_weaklistoffset */
934 0, /* tp_iter */
935 0, /* tp_iternext */
936 fileio_methods, /* tp_methods */
937 0, /* tp_members */
938 fileio_getsetlist, /* tp_getset */
939 0, /* tp_base */
940 0, /* tp_dict */
941 0, /* tp_descr_get */
942 0, /* tp_descr_set */
943 0, /* tp_dictoffset */
944 fileio_init, /* tp_init */
945 PyType_GenericAlloc, /* tp_alloc */
946 fileio_new, /* tp_new */
947 PyObject_Del, /* tp_free */
948};
949
950static PyMethodDef module_methods[] = {
951 {NULL, NULL}
952};
953
954PyMODINIT_FUNC
955init_fileio(void)
956{
957 PyObject *m; /* a module object */
958
959 m = Py_InitModule3("_fileio", module_methods,
960 "Fast implementation of io.FileIO.");
961 if (m == NULL)
962 return;
963 if (PyType_Ready(&PyFileIO_Type) < 0)
964 return;
965 Py_INCREF(&PyFileIO_Type);
966 PyModule_AddObject(m, "_FileIO", (PyObject *) &PyFileIO_Type);
967}
Note: See TracBrowser for help on using the repository browser.