fileobject.c 15.4 KB
Newer Older
1
/* File object implementation (what's left of it -- see io.py) */
Guido van Rossum's avatar
Guido van Rossum committed
2

Martin v. Löwis's avatar
Martin v. Löwis committed
3
#define PY_SSIZE_T_CLEAN
4
#include "Python.h"
Guido van Rossum's avatar
Guido van Rossum committed
5

6 7 8 9 10 11 12
#ifdef HAVE_GETC_UNLOCKED
#define GETC(f) getc_unlocked(f)
#define FLOCKFILE(f) flockfile(f)
#define FUNLOCKFILE(f) funlockfile(f)
#else
#define GETC(f) getc(f)
#define FLOCKFILE(f)
13
#define FUNLOCKFILE(f)
14 15
#endif

16
/* Newline flags */
17 18 19 20
#define NEWLINE_UNKNOWN 0       /* No newline seen, yet */
#define NEWLINE_CR 1            /* \r newline seen */
#define NEWLINE_LF 2            /* \n newline seen */
#define NEWLINE_CRLF 4          /* \r\n newline seen */
21

22 23 24
#ifdef __cplusplus
extern "C" {
#endif
25

26
/* External C interface */
27

28
PyObject *
29 30
PyFile_FromFd(int fd, const char *name, const char *mode, int buffering, const char *encoding,
              const char *errors, const char *newline, int closefd)
Guido van Rossum's avatar
Guido van Rossum committed
31
{
32
    PyObject *io, *stream;
33
    _Py_IDENTIFIER(open);
34 35 36 37

    io = PyImport_ImportModule("io");
    if (io == NULL)
        return NULL;
38
    stream = _PyObject_CallMethodId(io, &PyId_open, "isisssi", fd, mode,
39 40 41 42 43
                                 buffering, encoding, errors,
                                 newline, closefd);
    Py_DECREF(io);
    if (stream == NULL)
        return NULL;
44 45
    /* ignore name attribute because the name attribute of _BufferedIOMixin
       and TextIOWrapper is read only */
46
    return stream;
Guido van Rossum's avatar
Guido van Rossum committed
47 48
}

49
PyObject *
50
PyFile_GetLine(PyObject *f, int n)
51
{
52 53 54 55 56 57 58 59 60 61
    PyObject *result;

    if (f == NULL) {
        PyErr_BadInternalCall();
        return NULL;
    }

    {
        PyObject *reader;
        PyObject *args;
62
        _Py_IDENTIFIER(readline);
63

64
        reader = _PyObject_GetAttrId(f, &PyId_readline);
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
        if (reader == NULL)
            return NULL;
        if (n <= 0)
            args = PyTuple_New(0);
        else
            args = Py_BuildValue("(i)", n);
        if (args == NULL) {
            Py_DECREF(reader);
            return NULL;
        }
        result = PyEval_CallObject(reader, args);
        Py_DECREF(reader);
        Py_DECREF(args);
        if (result != NULL && !PyBytes_Check(result) &&
            !PyUnicode_Check(result)) {
            Py_DECREF(result);
            result = NULL;
            PyErr_SetString(PyExc_TypeError,
                       "object.readline() returned non-string");
        }
    }

    if (n < 0 && result != NULL && PyBytes_Check(result)) {
        char *s = PyBytes_AS_STRING(result);
        Py_ssize_t len = PyBytes_GET_SIZE(result);
        if (len == 0) {
            Py_DECREF(result);
            result = NULL;
            PyErr_SetString(PyExc_EOFError,
                            "EOF when reading a line");
        }
        else if (s[len-1] == '\n') {
            if (result->ob_refcnt == 1)
                _PyBytes_Resize(&result, len-1);
            else {
                PyObject *v;
                v = PyBytes_FromStringAndSize(s, len-1);
                Py_DECREF(result);
                result = v;
            }
        }
    }
    if (n < 0 && result != NULL && PyUnicode_Check(result)) {
Martin v. Löwis's avatar
Martin v. Löwis committed
108
        Py_ssize_t len = PyUnicode_GET_LENGTH(result);
109 110 111 112 113 114
        if (len == 0) {
            Py_DECREF(result);
            result = NULL;
            PyErr_SetString(PyExc_EOFError,
                            "EOF when reading a line");
        }
Martin v. Löwis's avatar
Martin v. Löwis committed
115 116 117 118 119
        else if (PyUnicode_READ_CHAR(result, len-1) == '\n') {
            PyObject *v;
            v = PyUnicode_Substring(result, 0, len-1);
            Py_DECREF(result);
            result = v;
120 121 122
        }
    }
    return result;
123 124
}

125 126 127
/* Interfaces to write objects/strings to file-like objects */

int
128
PyFile_WriteObject(PyObject *v, PyObject *f, int flags)
129
{
130
    PyObject *writer, *value, *args, *result;
131
    _Py_IDENTIFIER(write);
132

133 134 135 136
    if (f == NULL) {
        PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
        return -1;
    }
137
    writer = _PyObject_GetAttrId(f, &PyId_write);
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
    if (writer == NULL)
        return -1;
    if (flags & Py_PRINT_RAW) {
        value = PyObject_Str(v);
    }
    else
        value = PyObject_Repr(v);
    if (value == NULL) {
        Py_DECREF(writer);
        return -1;
    }
    args = PyTuple_Pack(1, value);
    if (args == NULL) {
        Py_DECREF(value);
        Py_DECREF(writer);
        return -1;
    }
    result = PyEval_CallObject(writer, args);
    Py_DECREF(args);
    Py_DECREF(value);
    Py_DECREF(writer);
    if (result == NULL)
        return -1;
    Py_DECREF(result);
    return 0;
163 164
}

165
int
166
PyFile_WriteString(const char *s, PyObject *f)
167
{
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
    if (f == NULL) {
        /* Should be caused by a pre-existing error */
        if (!PyErr_Occurred())
            PyErr_SetString(PyExc_SystemError,
                            "null file for PyFile_WriteString");
        return -1;
    }
    else if (!PyErr_Occurred()) {
        PyObject *v = PyUnicode_FromString(s);
        int err;
        if (v == NULL)
            return -1;
        err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
        Py_DECREF(v);
        return err;
    }
    else
        return -1;
186
}
187 188

/* Try to get a file-descriptor from a Python object.  If the object
189
   is an integer, its value is returned.  If not, the
190
   object's fileno() method is called if it exists; the method must return
191
   an integer, which is returned as the file descriptor value.
192 193 194
   -1 is returned on failure.
*/

195 196
int
PyObject_AsFileDescriptor(PyObject *o)
197
{
198 199
    int fd;
    PyObject *meth;
200
    _Py_IDENTIFIER(fileno);
201 202

    if (PyLong_Check(o)) {
203
        fd = _PyLong_AsInt(o);
204
    }
205
    else if ((meth = _PyObject_GetAttrId(o, &PyId_fileno)) != NULL)
206 207 208 209 210 211 212
    {
        PyObject *fno = PyEval_CallObject(meth, NULL);
        Py_DECREF(meth);
        if (fno == NULL)
            return -1;

        if (PyLong_Check(fno)) {
213
            fd = _PyLong_AsInt(fno);
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
            Py_DECREF(fno);
        }
        else {
            PyErr_SetString(PyExc_TypeError,
                            "fileno() returned a non-integer");
            Py_DECREF(fno);
            return -1;
        }
    }
    else {
        PyErr_SetString(PyExc_TypeError,
                        "argument must be an int, or have a fileno() method.");
        return -1;
    }

    if (fd == -1 && PyErr_Occurred())
        return -1;
    if (fd < 0) {
        PyErr_Format(PyExc_ValueError,
                     "file descriptor cannot be a negative integer (%i)",
                     fd);
        return -1;
    }
    return fd;
238
}
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256

/*
** Py_UniversalNewlineFgets is an fgets variation that understands
** all of \r, \n and \r\n conventions.
** The stream should be opened in binary mode.
** If fobj is NULL the routine always does newline conversion, and
** it may peek one char ahead to gobble the second char in \r\n.
** If fobj is non-NULL it must be a PyFileObject. In this case there
** is no readahead but in stead a flag is used to skip a following
** \n on the next read. Also, if the file is open in binary mode
** the whole conversion is skipped. Finally, the routine keeps track of
** the different types of newlines seen.
** Note that we need no error handling: fgets() treats error and eof
** identically.
*/
char *
Py_UniversalNewlineFgets(char *buf, int n, FILE *stream, PyObject *fobj)
{
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299
    char *p = buf;
    int c;
    int newlinetypes = 0;
    int skipnextlf = 0;

    if (fobj) {
        errno = ENXIO;          /* What can you do... */
        return NULL;
    }
    FLOCKFILE(stream);
    c = 'x'; /* Shut up gcc warning */
    while (--n > 0 && (c = GETC(stream)) != EOF ) {
        if (skipnextlf ) {
            skipnextlf = 0;
            if (c == '\n') {
                /* Seeing a \n here with skipnextlf true
                ** means we saw a \r before.
                */
                newlinetypes |= NEWLINE_CRLF;
                c = GETC(stream);
                if (c == EOF) break;
            } else {
                /*
                ** Note that c == EOF also brings us here,
                ** so we're okay if the last char in the file
                ** is a CR.
                */
                newlinetypes |= NEWLINE_CR;
            }
        }
        if (c == '\r') {
            /* A \r is translated into a \n, and we skip
            ** an adjacent \n, if any. We don't set the
            ** newlinetypes flag until we've seen the next char.
            */
            skipnextlf = 1;
            c = '\n';
        } else if ( c == '\n') {
            newlinetypes |= NEWLINE_LF;
        }
        *p++ = c;
        if (c == '\n') break;
    }
300 301
    /* if ( c == EOF && skipnextlf )
        newlinetypes |= NEWLINE_CR; */
302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318
    FUNLOCKFILE(stream);
    *p = '\0';
    if ( skipnextlf ) {
        /* If we have no file object we cannot save the
        ** skipnextlf flag. We have to readahead, which
        ** will cause a pause if we're reading from an
        ** interactive stream, but that is very unlikely
        ** unless we're doing something silly like
        ** exec(open("/dev/tty").read()).
        */
        c = GETC(stream);
        if ( c != '\n' )
            ungetc(c, stream);
    }
    if (p == buf)
        return NULL;
    return buf;
319 320
}

321 322 323 324
/* **************************** std printer ****************************
 * The stdprinter is used during the boot strapping phase as a preliminary
 * file like object for sys.stderr.
 */
325 326

typedef struct {
327 328
    PyObject_HEAD
    int fd;
329 330 331 332 333
} PyStdPrinter_Object;

static PyObject *
stdprinter_new(PyTypeObject *type, PyObject *args, PyObject *kews)
{
334
    PyStdPrinter_Object *self;
335

336
    assert(type != NULL && type->tp_alloc != NULL);
337

338 339 340 341
    self = (PyStdPrinter_Object *) type->tp_alloc(type, 0);
    if (self != NULL) {
        self->fd = -1;
    }
342

343
    return (PyObject *) self;
344 345
}

346
static int
347
stdprinter_init(PyObject *self, PyObject *args, PyObject *kwds)
348
{
349 350 351
    PyErr_SetString(PyExc_TypeError,
                    "cannot create 'stderrprinter' instances");
    return -1;
352 353
}

354 355 356
PyObject *
PyFile_NewStdPrinter(int fd)
{
357 358 359 360 361 362 363 364 365 366 367 368 369
    PyStdPrinter_Object *self;

    if (fd != fileno(stdout) && fd != fileno(stderr)) {
        /* not enough infrastructure for PyErr_BadInternalCall() */
        return NULL;
    }

    self = PyObject_New(PyStdPrinter_Object,
                        &PyStdPrinter_Type);
    if (self != NULL) {
        self->fd = fd;
    }
    return (PyObject*)self;
370 371
}

372
static PyObject *
373 374
stdprinter_write(PyStdPrinter_Object *self, PyObject *args)
{
375 376
    PyObject *unicode;
    PyObject *bytes = NULL;
377
    char *str;
378
    Py_ssize_t n;
379
    int err;
380 381 382 383 384 385 386 387 388

    if (self->fd < 0) {
        /* fd might be invalid on Windows
         * I can't raise an exception here. It may lead to an
         * unlimited recursion in the case stderr is invalid.
         */
        Py_RETURN_NONE;
    }

389
    if (!PyArg_ParseTuple(args, "U", &unicode))
390 391
        return NULL;

392 393 394 395 396 397 398 399 400 401 402
    /* encode Unicode to UTF-8 */
    str = PyUnicode_AsUTF8AndSize(unicode, &n);
    if (str == NULL) {
        PyErr_Clear();
        bytes = _PyUnicode_AsUTF8String(unicode, "backslashreplace");
        if (bytes == NULL)
            return NULL;
        if (PyBytes_AsStringAndSize(bytes, &str, &n) < 0) {
            Py_DECREF(bytes);
            return NULL;
        }
403 404
    }

405
    n = _Py_write(self->fd, str, n);
406 407 408
    /* save errno, it can be modified indirectly by Py_XDECREF() */
    err = errno;

409
    Py_XDECREF(bytes);
410

411
    if (n == -1) {
412
        if (err == EAGAIN) {
413
            PyErr_Clear();
414
            Py_RETURN_NONE;
415
        }
416 417 418 419
        return NULL;
    }

    return PyLong_FromSsize_t(n);
420 421 422 423 424
}

static PyObject *
stdprinter_fileno(PyStdPrinter_Object *self)
{
425
    return PyLong_FromLong((long) self->fd);
426 427 428 429 430
}

static PyObject *
stdprinter_repr(PyStdPrinter_Object *self)
{
431 432
    return PyUnicode_FromFormat("<stdprinter(fd=%d) object at 0x%x>",
                                self->fd, self);
433 434 435 436 437
}

static PyObject *
stdprinter_noop(PyStdPrinter_Object *self)
{
438
    Py_RETURN_NONE;
439 440 441 442 443
}

static PyObject *
stdprinter_isatty(PyStdPrinter_Object *self)
{
444 445 446 447
    long res;
    if (self->fd < 0) {
        Py_RETURN_FALSE;
    }
448

449 450 451
    Py_BEGIN_ALLOW_THREADS
    res = isatty(self->fd);
    Py_END_ALLOW_THREADS
452

453
    return PyBool_FromLong(res);
454 455 456
}

static PyMethodDef stdprinter_methods[] = {
457 458 459 460 461 462
    {"close",           (PyCFunction)stdprinter_noop, METH_NOARGS, ""},
    {"flush",           (PyCFunction)stdprinter_noop, METH_NOARGS, ""},
    {"fileno",          (PyCFunction)stdprinter_fileno, METH_NOARGS, ""},
    {"isatty",          (PyCFunction)stdprinter_isatty, METH_NOARGS, ""},
    {"write",           (PyCFunction)stdprinter_write, METH_VARARGS, ""},
    {NULL,              NULL}  /*sentinel */
463 464 465 466 467
};

static PyObject *
get_closed(PyStdPrinter_Object *self, void *closure)
{
468 469
    Py_INCREF(Py_False);
    return Py_False;
470 471 472 473 474
}

static PyObject *
get_mode(PyStdPrinter_Object *self, void *closure)
{
475
    return PyUnicode_FromString("w");
476 477 478 479 480
}

static PyObject *
get_encoding(PyStdPrinter_Object *self, void *closure)
{
481
    Py_RETURN_NONE;
482 483 484
}

static PyGetSetDef stdprinter_getsetlist[] = {
485 486 487 488
    {"closed", (getter)get_closed, NULL, "True if the file is closed"},
    {"encoding", (getter)get_encoding, NULL, "Encoding of the file"},
    {"mode", (getter)get_mode, NULL, "String giving the file mode"},
    {0},
489 490 491
};

PyTypeObject PyStdPrinter_Type = {
492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "stderrprinter",                            /* tp_name */
    sizeof(PyStdPrinter_Object),                /* tp_basicsize */
    0,                                          /* tp_itemsize */
    /* methods */
    0,                                          /* tp_dealloc */
    0,                                          /* tp_print */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    0,                                          /* tp_reserved */
    (reprfunc)stdprinter_repr,                  /* tp_repr */
    0,                                          /* tp_as_number */
    0,                                          /* tp_as_sequence */
    0,                                          /* tp_as_mapping */
    0,                                          /* tp_hash */
    0,                                          /* tp_call */
    0,                                          /* tp_str */
    PyObject_GenericGetAttr,                    /* tp_getattro */
    0,                                          /* tp_setattro */
    0,                                          /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT,                         /* tp_flags */
    0,                                          /* tp_doc */
    0,                                          /* tp_traverse */
    0,                                          /* tp_clear */
    0,                                          /* tp_richcompare */
    0,                                          /* tp_weaklistoffset */
    0,                                          /* tp_iter */
    0,                                          /* tp_iternext */
    stdprinter_methods,                         /* tp_methods */
    0,                                          /* tp_members */
    stdprinter_getsetlist,                      /* tp_getset */
    0,                                          /* tp_base */
    0,                                          /* tp_dict */
    0,                                          /* tp_descr_get */
    0,                                          /* tp_descr_set */
    0,                                          /* tp_dictoffset */
528
    stdprinter_init,                            /* tp_init */
529 530 531
    PyType_GenericAlloc,                        /* tp_alloc */
    stdprinter_new,                             /* tp_new */
    PyObject_Del,                               /* tp_free */
532 533 534
};


535 536 537
#ifdef __cplusplus
}
#endif