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