fileobject.c 11.8 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 17 18 19 20
/* Newline flags */
#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
PyFile_FromFd(int fd, char *name, char *mode, int buffering, char *encoding,
30
	      char *errors, char *newline, int closefd)
Guido van Rossum's avatar
Guido van Rossum committed
31
{
32
	PyObject *io, *stream, *nameobj = NULL;
33

34 35
	io = PyImport_ImportModule("io");
	if (io == NULL)
Guido van Rossum's avatar
Guido van Rossum committed
36
		return NULL;
37 38 39
	stream = PyObject_CallMethod(io, "open", "isisssi", fd, mode,
				     buffering, encoding, errors,
				     newline, closefd);
40
	Py_DECREF(io);
41 42
	if (stream == NULL)
		return NULL;
43 44 45
	if (name != NULL) {
		nameobj = PyUnicode_FromString(name);
		if (nameobj == NULL)
46
			PyErr_Clear();
47 48 49 50 51
		else {
			if (PyObject_SetAttrString(stream, "name", nameobj) < 0)
				PyErr_Clear();
			Py_DECREF(nameobj);
		}
Guido van Rossum's avatar
Guido van Rossum committed
52
	}
53
	return stream;
Guido van Rossum's avatar
Guido van Rossum committed
54 55
}

56
PyObject *
57
PyFile_GetLine(PyObject *f, int n)
58
{
59 60
	PyObject *result;

61
	if (f == NULL) {
62
		PyErr_BadInternalCall();
63 64
		return NULL;
	}
65

66
	{
67 68
		PyObject *reader;
		PyObject *args;
69

70
		reader = PyObject_GetAttrString(f, "readline");
71 72 73
		if (reader == NULL)
			return NULL;
		if (n <= 0)
74
			args = PyTuple_New(0);
75
		else
76
			args = Py_BuildValue("(i)", n);
77
		if (args == NULL) {
78
			Py_DECREF(reader);
79 80
			return NULL;
		}
81 82 83
		result = PyEval_CallObject(reader, args);
		Py_DECREF(reader);
		Py_DECREF(args);
84
		if (result != NULL && !PyBytes_Check(result) &&
85
		    !PyUnicode_Check(result)) {
86
			Py_DECREF(result);
87
			result = NULL;
88
			PyErr_SetString(PyExc_TypeError,
89 90
				   "object.readline() returned non-string");
		}
91 92
	}

93 94 95
	if (n < 0 && result != NULL && PyBytes_Check(result)) {
		char *s = PyBytes_AS_STRING(result);
		Py_ssize_t len = PyBytes_GET_SIZE(result);
96 97 98 99 100 101 102 103
		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)
104
				_PyBytes_Resize(&result, len-1);
105 106
			else {
				PyObject *v;
107
				v = PyBytes_FromStringAndSize(s, len-1);
108
				Py_DECREF(result);
109
				result = v;
110 111 112
			}
		}
	}
113 114
	if (n < 0 && result != NULL && PyUnicode_Check(result)) {
		Py_UNICODE *s = PyUnicode_AS_UNICODE(result);
Martin v. Löwis's avatar
Martin v. Löwis committed
115
		Py_ssize_t len = PyUnicode_GET_SIZE(result);
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
		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)
				PyUnicode_Resize(&result, len-1);
			else {
				PyObject *v;
				v = PyUnicode_FromUnicode(s, len-1);
				Py_DECREF(result);
				result = v;
			}
		}
	}
133
	return result;
134 135
}

136 137 138
/* Interfaces to write objects/strings to file-like objects */

int
139
PyFile_WriteObject(PyObject *v, PyObject *f, int flags)
140
{
141
	PyObject *writer, *value, *args, *result;
142
	if (f == NULL) {
143
		PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
144 145
		return -1;
	}
146
	writer = PyObject_GetAttrString(f, "write");
147 148
	if (writer == NULL)
		return -1;
149
	if (flags & Py_PRINT_RAW) {
150
		value = PyObject_Str(v);
151
	}
152
	else
153
		value = PyObject_Repr(v);
154
	if (value == NULL) {
155
		Py_DECREF(writer);
156
		return -1;
157
	}
158
	args = PyTuple_Pack(1, value);
159
	if (args == NULL) {
160 161
		Py_DECREF(value);
		Py_DECREF(writer);
162 163
		return -1;
	}
164 165 166 167
	result = PyEval_CallObject(writer, args);
	Py_DECREF(args);
	Py_DECREF(value);
	Py_DECREF(writer);
168 169
	if (result == NULL)
		return -1;
170
	Py_DECREF(result);
171 172 173
	return 0;
}

174
int
175
PyFile_WriteString(const char *s, PyObject *f)
176 177
{
	if (f == NULL) {
178
		/* Should be caused by a pre-existing error */
179
		if (!PyErr_Occurred())
180 181 182
			PyErr_SetString(PyExc_SystemError,
					"null file for PyFile_WriteString");
		return -1;
183
	}
184
	else if (!PyErr_Occurred()) {
185
		PyObject *v = PyUnicode_FromString(s);
186 187 188 189 190 191
		int err;
		if (v == NULL)
			return -1;
		err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
		Py_DECREF(v);
		return err;
192
	}
193 194
	else
		return -1;
195
}
196 197 198 199 200 201 202 203

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

204 205
int
PyObject_AsFileDescriptor(PyObject *o)
206 207 208 209
{
	int fd;
	PyObject *meth;

210
	if (PyLong_Check(o)) {
211 212 213 214 215 216 217 218
		fd = PyLong_AsLong(o);
	}
	else if ((meth = PyObject_GetAttrString(o, "fileno")) != NULL)
	{
		PyObject *fno = PyEval_CallObject(meth, NULL);
		Py_DECREF(meth);
		if (fno == NULL)
			return -1;
219

220
		if (PyLong_Check(fno)) {
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236
			fd = PyLong_AsLong(fno);
			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;
	}

237 238
	if (fd == -1 && PyErr_Occurred())
		return -1;
239 240 241 242 243 244 245 246
	if (fd < 0) {
		PyErr_Format(PyExc_ValueError,
			     "file descriptor cannot be a negative integer (%i)",
			     fd);
		return -1;
	}
	return fd;
}
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268

/*
** 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)
{
	char *p = buf;
	int c;
	int newlinetypes = 0;
	int skipnextlf = 0;
269

270
	if (fobj) {
271 272
		errno = ENXIO;	/* What can you do... */
		return NULL;
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 300 301 302 303 304 305 306 307 308 309 310 311
	}
	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;
	}
	if ( c == EOF && skipnextlf )
		newlinetypes |= NEWLINE_CR;
	FUNLOCKFILE(stream);
	*p = '\0';
312
	if ( skipnextlf ) {
313 314 315 316 317
		/* 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
318
		** exec(open("/dev/tty").read()).
319 320 321 322 323 324 325 326 327 328
		*/
		c = GETC(stream);
		if ( c != '\n' )
			ungetc(c, stream);
	}
	if (p == buf)
		return NULL;
	return buf;
}

329 330 331 332
/* **************************** std printer ****************************
 * The stdprinter is used during the boot strapping phase as a preliminary
 * file like object for sys.stderr.
 */
333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353

typedef struct {
	PyObject_HEAD
	int fd;
} PyStdPrinter_Object;

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

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

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

	return (PyObject *) self;
}

354 355 356 357 358 359 360 361
static int
fileio_init(PyObject *self, PyObject *args, PyObject *kwds)
{
	PyErr_SetString(PyExc_TypeError,
			"cannot create 'stderrprinter' instances");
	return -1;
}

362 363 364 365 366
PyObject *
PyFile_NewStdPrinter(int fd)
{
	PyStdPrinter_Object *self;

367
	if (fd != fileno(stdout) && fd != fileno(stderr)) {
Christian Heimes's avatar
Christian Heimes committed
368
		/* not enough infrastructure for PyErr_BadInternalCall() */
369 370 371 372 373
		return NULL;
	}

	self = PyObject_New(PyStdPrinter_Object,
			    &PyStdPrinter_Type);
374 375 376
        if (self != NULL) {
		self->fd = fd;
	}
377 378 379
	return (PyObject*)self;
}

380
static PyObject *
381 382 383 384 385 386
stdprinter_write(PyStdPrinter_Object *self, PyObject *args)
{
	char *c;
	Py_ssize_t n;

	if (self->fd < 0) {
387 388 389 390
		/* 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.
		 */
391
		Py_RETURN_NONE;
392 393
	}

394
	if (!PyArg_ParseTuple(args, "s", &c)) {
395 396
		return NULL;
	}
397
	n = strlen(c);
398 399 400 401 402 403 404 405 406 407 408 409 410

	Py_BEGIN_ALLOW_THREADS
	errno = 0;
	n = write(self->fd, c, n);
	Py_END_ALLOW_THREADS

	if (n < 0) {
		if (errno == EAGAIN)
			Py_RETURN_NONE;
		PyErr_SetFromErrno(PyExc_IOError);
		return NULL;
	}

411 412 413 414 415 416
	return PyLong_FromSsize_t(n);
}

static PyObject *
stdprinter_fileno(PyStdPrinter_Object *self)
{
417
	return PyLong_FromLong((long) self->fd);
418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437
}

static PyObject *
stdprinter_repr(PyStdPrinter_Object *self)
{
	return PyUnicode_FromFormat("<stdprinter(fd=%d) object at 0x%x>",
				    self->fd, self);
}

static PyObject *
stdprinter_noop(PyStdPrinter_Object *self)
{
	Py_RETURN_NONE;
}

static PyObject *
stdprinter_isatty(PyStdPrinter_Object *self)
{
	long res;
	if (self->fd < 0) {
438
		Py_RETURN_FALSE;
439 440 441 442 443 444 445
	}

	Py_BEGIN_ALLOW_THREADS
	res = isatty(self->fd);
	Py_END_ALLOW_THREADS

	return PyBool_FromLong(res);
446 447 448
}

static PyMethodDef stdprinter_methods[] = {
449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480
	{"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 */
};

static PyObject *
get_closed(PyStdPrinter_Object *self, void *closure)
{
	Py_INCREF(Py_False);
	return Py_False;
}

static PyObject *
get_mode(PyStdPrinter_Object *self, void *closure)
{
	return PyUnicode_FromString("w");
}

static PyObject *
get_encoding(PyStdPrinter_Object *self, void *closure)
{
	Py_RETURN_NONE;
}

static PyGetSetDef stdprinter_getsetlist[] = {
	{"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},
481 482 483 484 485 486 487 488 489 490 491 492 493
};

PyTypeObject PyStdPrinter_Type = {
	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_compare */
494
	(reprfunc)stdprinter_repr,		/* tp_repr */
495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513
	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 */
514
	stdprinter_getsetlist,			/* tp_getset */
515 516 517 518 519
	0,					/* tp_base */
	0,					/* tp_dict */
	0,					/* tp_descr_get */
	0,					/* tp_descr_set */
	0,					/* tp_dictoffset */
520
	fileio_init,				/* tp_init */
521 522 523 524 525 526
	PyType_GenericAlloc,			/* tp_alloc */
	stdprinter_new,				/* tp_new */
	PyObject_Del,				/* tp_free */
};


527 528 529
#ifdef __cplusplus
}
#endif