ยปCore Development>Code coverage>Objects/fileobject.c

Python code coverage for Objects/fileobject.c

#countcontent
1n/a/* File object implementation (what's left of it -- see io.py) */
2n/a
3n/a#define PY_SSIZE_T_CLEAN
4n/a#include "Python.h"
5n/a
6n/a#ifdef HAVE_GETC_UNLOCKED
7n/a#define GETC(f) getc_unlocked(f)
8n/a#define FLOCKFILE(f) flockfile(f)
9n/a#define FUNLOCKFILE(f) funlockfile(f)
10n/a#else
11n/a#define GETC(f) getc(f)
12n/a#define FLOCKFILE(f)
13n/a#define FUNLOCKFILE(f)
14n/a#endif
15n/a
16n/a/* Newline flags */
17n/a#define NEWLINE_UNKNOWN 0 /* No newline seen, yet */
18n/a#define NEWLINE_CR 1 /* \r newline seen */
19n/a#define NEWLINE_LF 2 /* \n newline seen */
20n/a#define NEWLINE_CRLF 4 /* \r\n newline seen */
21n/a
22n/a#ifdef __cplusplus
23n/aextern "C" {
24n/a#endif
25n/a
26n/a/* External C interface */
27n/a
28n/aPyObject *
29n/aPyFile_FromFd(int fd, const char *name, const char *mode, int buffering, const char *encoding,
30n/a const char *errors, const char *newline, int closefd)
31n/a{
32n/a PyObject *io, *stream;
33n/a _Py_IDENTIFIER(open);
34n/a
35n/a io = PyImport_ImportModule("io");
36n/a if (io == NULL)
37n/a return NULL;
38n/a stream = _PyObject_CallMethodId(io, &PyId_open, "isisssi", fd, mode,
39n/a buffering, encoding, errors,
40n/a newline, closefd);
41n/a Py_DECREF(io);
42n/a if (stream == NULL)
43n/a return NULL;
44n/a /* ignore name attribute because the name attribute of _BufferedIOMixin
45n/a and TextIOWrapper is read only */
46n/a return stream;
47n/a}
48n/a
49n/aPyObject *
50n/aPyFile_GetLine(PyObject *f, int n)
51n/a{
52n/a PyObject *result;
53n/a
54n/a if (f == NULL) {
55n/a PyErr_BadInternalCall();
56n/a return NULL;
57n/a }
58n/a
59n/a {
60n/a PyObject *reader;
61n/a PyObject *args;
62n/a _Py_IDENTIFIER(readline);
63n/a
64n/a reader = _PyObject_GetAttrId(f, &PyId_readline);
65n/a if (reader == NULL)
66n/a return NULL;
67n/a if (n <= 0)
68n/a args = PyTuple_New(0);
69n/a else
70n/a args = Py_BuildValue("(i)", n);
71n/a if (args == NULL) {
72n/a Py_DECREF(reader);
73n/a return NULL;
74n/a }
75n/a result = PyEval_CallObject(reader, args);
76n/a Py_DECREF(reader);
77n/a Py_DECREF(args);
78n/a if (result != NULL && !PyBytes_Check(result) &&
79n/a !PyUnicode_Check(result)) {
80n/a Py_DECREF(result);
81n/a result = NULL;
82n/a PyErr_SetString(PyExc_TypeError,
83n/a "object.readline() returned non-string");
84n/a }
85n/a }
86n/a
87n/a if (n < 0 && result != NULL && PyBytes_Check(result)) {
88n/a char *s = PyBytes_AS_STRING(result);
89n/a Py_ssize_t len = PyBytes_GET_SIZE(result);
90n/a if (len == 0) {
91n/a Py_DECREF(result);
92n/a result = NULL;
93n/a PyErr_SetString(PyExc_EOFError,
94n/a "EOF when reading a line");
95n/a }
96n/a else if (s[len-1] == '\n') {
97n/a if (result->ob_refcnt == 1)
98n/a _PyBytes_Resize(&result, len-1);
99n/a else {
100n/a PyObject *v;
101n/a v = PyBytes_FromStringAndSize(s, len-1);
102n/a Py_DECREF(result);
103n/a result = v;
104n/a }
105n/a }
106n/a }
107n/a if (n < 0 && result != NULL && PyUnicode_Check(result)) {
108n/a Py_ssize_t len = PyUnicode_GET_LENGTH(result);
109n/a if (len == 0) {
110n/a Py_DECREF(result);
111n/a result = NULL;
112n/a PyErr_SetString(PyExc_EOFError,
113n/a "EOF when reading a line");
114n/a }
115n/a else if (PyUnicode_READ_CHAR(result, len-1) == '\n') {
116n/a PyObject *v;
117n/a v = PyUnicode_Substring(result, 0, len-1);
118n/a Py_DECREF(result);
119n/a result = v;
120n/a }
121n/a }
122n/a return result;
123n/a}
124n/a
125n/a/* Interfaces to write objects/strings to file-like objects */
126n/a
127n/aint
128n/aPyFile_WriteObject(PyObject *v, PyObject *f, int flags)
129n/a{
130n/a PyObject *writer, *value, *result;
131n/a _Py_IDENTIFIER(write);
132n/a
133n/a if (f == NULL) {
134n/a PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
135n/a return -1;
136n/a }
137n/a writer = _PyObject_GetAttrId(f, &PyId_write);
138n/a if (writer == NULL)
139n/a return -1;
140n/a if (flags & Py_PRINT_RAW) {
141n/a value = PyObject_Str(v);
142n/a }
143n/a else
144n/a value = PyObject_Repr(v);
145n/a if (value == NULL) {
146n/a Py_DECREF(writer);
147n/a return -1;
148n/a }
149n/a result = PyObject_CallFunctionObjArgs(writer, value, NULL);
150n/a Py_DECREF(value);
151n/a Py_DECREF(writer);
152n/a if (result == NULL)
153n/a return -1;
154n/a Py_DECREF(result);
155n/a return 0;
156n/a}
157n/a
158n/aint
159n/aPyFile_WriteString(const char *s, PyObject *f)
160n/a{
161n/a if (f == NULL) {
162n/a /* Should be caused by a pre-existing error */
163n/a if (!PyErr_Occurred())
164n/a PyErr_SetString(PyExc_SystemError,
165n/a "null file for PyFile_WriteString");
166n/a return -1;
167n/a }
168n/a else if (!PyErr_Occurred()) {
169n/a PyObject *v = PyUnicode_FromString(s);
170n/a int err;
171n/a if (v == NULL)
172n/a return -1;
173n/a err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
174n/a Py_DECREF(v);
175n/a return err;
176n/a }
177n/a else
178n/a return -1;
179n/a}
180n/a
181n/a/* Try to get a file-descriptor from a Python object. If the object
182n/a is an integer, its value is returned. If not, the
183n/a object's fileno() method is called if it exists; the method must return
184n/a an integer, which is returned as the file descriptor value.
185n/a -1 is returned on failure.
186n/a*/
187n/a
188n/aint
189n/aPyObject_AsFileDescriptor(PyObject *o)
190n/a{
191n/a int fd;
192n/a PyObject *meth;
193n/a _Py_IDENTIFIER(fileno);
194n/a
195n/a if (PyLong_Check(o)) {
196n/a fd = _PyLong_AsInt(o);
197n/a }
198n/a else if ((meth = _PyObject_GetAttrId(o, &PyId_fileno)) != NULL)
199n/a {
200n/a PyObject *fno = PyEval_CallObject(meth, NULL);
201n/a Py_DECREF(meth);
202n/a if (fno == NULL)
203n/a return -1;
204n/a
205n/a if (PyLong_Check(fno)) {
206n/a fd = _PyLong_AsInt(fno);
207n/a Py_DECREF(fno);
208n/a }
209n/a else {
210n/a PyErr_SetString(PyExc_TypeError,
211n/a "fileno() returned a non-integer");
212n/a Py_DECREF(fno);
213n/a return -1;
214n/a }
215n/a }
216n/a else {
217n/a PyErr_SetString(PyExc_TypeError,
218n/a "argument must be an int, or have a fileno() method.");
219n/a return -1;
220n/a }
221n/a
222n/a if (fd == -1 && PyErr_Occurred())
223n/a return -1;
224n/a if (fd < 0) {
225n/a PyErr_Format(PyExc_ValueError,
226n/a "file descriptor cannot be a negative integer (%i)",
227n/a fd);
228n/a return -1;
229n/a }
230n/a return fd;
231n/a}
232n/a
233n/a/*
234n/a** Py_UniversalNewlineFgets is an fgets variation that understands
235n/a** all of \r, \n and \r\n conventions.
236n/a** The stream should be opened in binary mode.
237n/a** If fobj is NULL the routine always does newline conversion, and
238n/a** it may peek one char ahead to gobble the second char in \r\n.
239n/a** If fobj is non-NULL it must be a PyFileObject. In this case there
240n/a** is no readahead but in stead a flag is used to skip a following
241n/a** \n on the next read. Also, if the file is open in binary mode
242n/a** the whole conversion is skipped. Finally, the routine keeps track of
243n/a** the different types of newlines seen.
244n/a** Note that we need no error handling: fgets() treats error and eof
245n/a** identically.
246n/a*/
247n/achar *
248n/aPy_UniversalNewlineFgets(char *buf, int n, FILE *stream, PyObject *fobj)
249n/a{
250n/a char *p = buf;
251n/a int c;
252n/a int newlinetypes = 0;
253n/a int skipnextlf = 0;
254n/a
255n/a if (fobj) {
256n/a errno = ENXIO; /* What can you do... */
257n/a return NULL;
258n/a }
259n/a FLOCKFILE(stream);
260n/a c = 'x'; /* Shut up gcc warning */
261n/a while (--n > 0 && (c = GETC(stream)) != EOF ) {
262n/a if (skipnextlf ) {
263n/a skipnextlf = 0;
264n/a if (c == '\n') {
265n/a /* Seeing a \n here with skipnextlf true
266n/a ** means we saw a \r before.
267n/a */
268n/a newlinetypes |= NEWLINE_CRLF;
269n/a c = GETC(stream);
270n/a if (c == EOF) break;
271n/a } else {
272n/a /*
273n/a ** Note that c == EOF also brings us here,
274n/a ** so we're okay if the last char in the file
275n/a ** is a CR.
276n/a */
277n/a newlinetypes |= NEWLINE_CR;
278n/a }
279n/a }
280n/a if (c == '\r') {
281n/a /* A \r is translated into a \n, and we skip
282n/a ** an adjacent \n, if any. We don't set the
283n/a ** newlinetypes flag until we've seen the next char.
284n/a */
285n/a skipnextlf = 1;
286n/a c = '\n';
287n/a } else if ( c == '\n') {
288n/a newlinetypes |= NEWLINE_LF;
289n/a }
290n/a *p++ = c;
291n/a if (c == '\n') break;
292n/a }
293n/a /* if ( c == EOF && skipnextlf )
294n/a newlinetypes |= NEWLINE_CR; */
295n/a FUNLOCKFILE(stream);
296n/a *p = '\0';
297n/a if ( skipnextlf ) {
298n/a /* If we have no file object we cannot save the
299n/a ** skipnextlf flag. We have to readahead, which
300n/a ** will cause a pause if we're reading from an
301n/a ** interactive stream, but that is very unlikely
302n/a ** unless we're doing something silly like
303n/a ** exec(open("/dev/tty").read()).
304n/a */
305n/a c = GETC(stream);
306n/a if ( c != '\n' )
307n/a ungetc(c, stream);
308n/a }
309n/a if (p == buf)
310n/a return NULL;
311n/a return buf;
312n/a}
313n/a
314n/a/* **************************** std printer ****************************
315n/a * The stdprinter is used during the boot strapping phase as a preliminary
316n/a * file like object for sys.stderr.
317n/a */
318n/a
319n/atypedef struct {
320n/a PyObject_HEAD
321n/a int fd;
322n/a} PyStdPrinter_Object;
323n/a
324n/astatic PyObject *
325n/astdprinter_new(PyTypeObject *type, PyObject *args, PyObject *kews)
326n/a{
327n/a PyStdPrinter_Object *self;
328n/a
329n/a assert(type != NULL && type->tp_alloc != NULL);
330n/a
331n/a self = (PyStdPrinter_Object *) type->tp_alloc(type, 0);
332n/a if (self != NULL) {
333n/a self->fd = -1;
334n/a }
335n/a
336n/a return (PyObject *) self;
337n/a}
338n/a
339n/astatic int
340n/astdprinter_init(PyObject *self, PyObject *args, PyObject *kwds)
341n/a{
342n/a PyErr_SetString(PyExc_TypeError,
343n/a "cannot create 'stderrprinter' instances");
344n/a return -1;
345n/a}
346n/a
347n/aPyObject *
348n/aPyFile_NewStdPrinter(int fd)
349n/a{
350n/a PyStdPrinter_Object *self;
351n/a
352n/a if (fd != fileno(stdout) && fd != fileno(stderr)) {
353n/a /* not enough infrastructure for PyErr_BadInternalCall() */
354n/a return NULL;
355n/a }
356n/a
357n/a self = PyObject_New(PyStdPrinter_Object,
358n/a &PyStdPrinter_Type);
359n/a if (self != NULL) {
360n/a self->fd = fd;
361n/a }
362n/a return (PyObject*)self;
363n/a}
364n/a
365n/astatic PyObject *
366n/astdprinter_write(PyStdPrinter_Object *self, PyObject *args)
367n/a{
368n/a PyObject *unicode;
369n/a PyObject *bytes = NULL;
370n/a const char *str;
371n/a Py_ssize_t n;
372n/a int err;
373n/a
374n/a if (self->fd < 0) {
375n/a /* fd might be invalid on Windows
376n/a * I can't raise an exception here. It may lead to an
377n/a * unlimited recursion in the case stderr is invalid.
378n/a */
379n/a Py_RETURN_NONE;
380n/a }
381n/a
382n/a if (!PyArg_ParseTuple(args, "U", &unicode))
383n/a return NULL;
384n/a
385n/a /* encode Unicode to UTF-8 */
386n/a str = PyUnicode_AsUTF8AndSize(unicode, &n);
387n/a if (str == NULL) {
388n/a PyErr_Clear();
389n/a bytes = _PyUnicode_AsUTF8String(unicode, "backslashreplace");
390n/a if (bytes == NULL)
391n/a return NULL;
392n/a str = PyBytes_AS_STRING(bytes);
393n/a n = PyBytes_GET_SIZE(bytes);
394n/a }
395n/a
396n/a n = _Py_write(self->fd, str, n);
397n/a /* save errno, it can be modified indirectly by Py_XDECREF() */
398n/a err = errno;
399n/a
400n/a Py_XDECREF(bytes);
401n/a
402n/a if (n == -1) {
403n/a if (err == EAGAIN) {
404n/a PyErr_Clear();
405n/a Py_RETURN_NONE;
406n/a }
407n/a return NULL;
408n/a }
409n/a
410n/a return PyLong_FromSsize_t(n);
411n/a}
412n/a
413n/astatic PyObject *
414n/astdprinter_fileno(PyStdPrinter_Object *self)
415n/a{
416n/a return PyLong_FromLong((long) self->fd);
417n/a}
418n/a
419n/astatic PyObject *
420n/astdprinter_repr(PyStdPrinter_Object *self)
421n/a{
422n/a return PyUnicode_FromFormat("<stdprinter(fd=%d) object at 0x%x>",
423n/a self->fd, self);
424n/a}
425n/a
426n/astatic PyObject *
427n/astdprinter_noop(PyStdPrinter_Object *self)
428n/a{
429n/a Py_RETURN_NONE;
430n/a}
431n/a
432n/astatic PyObject *
433n/astdprinter_isatty(PyStdPrinter_Object *self)
434n/a{
435n/a long res;
436n/a if (self->fd < 0) {
437n/a Py_RETURN_FALSE;
438n/a }
439n/a
440n/a Py_BEGIN_ALLOW_THREADS
441n/a res = isatty(self->fd);
442n/a Py_END_ALLOW_THREADS
443n/a
444n/a return PyBool_FromLong(res);
445n/a}
446n/a
447n/astatic PyMethodDef stdprinter_methods[] = {
448n/a {"close", (PyCFunction)stdprinter_noop, METH_NOARGS, ""},
449n/a {"flush", (PyCFunction)stdprinter_noop, METH_NOARGS, ""},
450n/a {"fileno", (PyCFunction)stdprinter_fileno, METH_NOARGS, ""},
451n/a {"isatty", (PyCFunction)stdprinter_isatty, METH_NOARGS, ""},
452n/a {"write", (PyCFunction)stdprinter_write, METH_VARARGS, ""},
453n/a {NULL, NULL} /*sentinel */
454n/a};
455n/a
456n/astatic PyObject *
457n/aget_closed(PyStdPrinter_Object *self, void *closure)
458n/a{
459n/a Py_RETURN_FALSE;
460n/a}
461n/a
462n/astatic PyObject *
463n/aget_mode(PyStdPrinter_Object *self, void *closure)
464n/a{
465n/a return PyUnicode_FromString("w");
466n/a}
467n/a
468n/astatic PyObject *
469n/aget_encoding(PyStdPrinter_Object *self, void *closure)
470n/a{
471n/a Py_RETURN_NONE;
472n/a}
473n/a
474n/astatic PyGetSetDef stdprinter_getsetlist[] = {
475n/a {"closed", (getter)get_closed, NULL, "True if the file is closed"},
476n/a {"encoding", (getter)get_encoding, NULL, "Encoding of the file"},
477n/a {"mode", (getter)get_mode, NULL, "String giving the file mode"},
478n/a {0},
479n/a};
480n/a
481n/aPyTypeObject PyStdPrinter_Type = {
482n/a PyVarObject_HEAD_INIT(&PyType_Type, 0)
483n/a "stderrprinter", /* tp_name */
484n/a sizeof(PyStdPrinter_Object), /* tp_basicsize */
485n/a 0, /* tp_itemsize */
486n/a /* methods */
487n/a 0, /* tp_dealloc */
488n/a 0, /* tp_print */
489n/a 0, /* tp_getattr */
490n/a 0, /* tp_setattr */
491n/a 0, /* tp_reserved */
492n/a (reprfunc)stdprinter_repr, /* tp_repr */
493n/a 0, /* tp_as_number */
494n/a 0, /* tp_as_sequence */
495n/a 0, /* tp_as_mapping */
496n/a 0, /* tp_hash */
497n/a 0, /* tp_call */
498n/a 0, /* tp_str */
499n/a PyObject_GenericGetAttr, /* tp_getattro */
500n/a 0, /* tp_setattro */
501n/a 0, /* tp_as_buffer */
502n/a Py_TPFLAGS_DEFAULT, /* tp_flags */
503n/a 0, /* tp_doc */
504n/a 0, /* tp_traverse */
505n/a 0, /* tp_clear */
506n/a 0, /* tp_richcompare */
507n/a 0, /* tp_weaklistoffset */
508n/a 0, /* tp_iter */
509n/a 0, /* tp_iternext */
510n/a stdprinter_methods, /* tp_methods */
511n/a 0, /* tp_members */
512n/a stdprinter_getsetlist, /* tp_getset */
513n/a 0, /* tp_base */
514n/a 0, /* tp_dict */
515n/a 0, /* tp_descr_get */
516n/a 0, /* tp_descr_set */
517n/a 0, /* tp_dictoffset */
518n/a stdprinter_init, /* tp_init */
519n/a PyType_GenericAlloc, /* tp_alloc */
520n/a stdprinter_new, /* tp_new */
521n/a PyObject_Del, /* tp_free */
522n/a};
523n/a
524n/a
525n/a#ifdef __cplusplus
526n/a}
527n/a#endif