blob: 0faf7e70b5d87f061b8f55fd1adafbef5af51094 [file] [log] [blame]
Guido van Rossumda5b8f22007-06-12 23:30:11 +00001/* File object implementation (what's left of it -- see io.py) */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002
Martin v. Löwis18e16552006-02-15 17:27:45 +00003#define PY_SSIZE_T_CLEAN
Guido van Rossumc0b618a1997-05-02 03:12:38 +00004#include "Python.h"
Steve Dowerb82e17e2019-05-23 08:45:22 -07005#include "pycore_pystate.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006
Gregory P. Smith3015fb82018-11-12 22:01:22 -08007#if defined(HAVE_GETC_UNLOCKED) && !defined(_Py_MEMORY_SANITIZER)
Gregory P. Smithe6c77d82018-11-12 19:47:13 -08008/* clang MemorySanitizer doesn't yet understand getc_unlocked. */
Jack Jansen7b8c7542002-04-14 20:12:41 +00009#define GETC(f) getc_unlocked(f)
10#define FLOCKFILE(f) flockfile(f)
11#define FUNLOCKFILE(f) funlockfile(f)
12#else
13#define GETC(f) getc(f)
14#define FLOCKFILE(f)
15#define FUNLOCKFILE(f)
16#endif
17
Guido van Rossumda5b8f22007-06-12 23:30:11 +000018/* Newline flags */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000019#define NEWLINE_UNKNOWN 0 /* No newline seen, yet */
20#define NEWLINE_CR 1 /* \r newline seen */
21#define NEWLINE_LF 2 /* \n newline seen */
22#define NEWLINE_CRLF 4 /* \r\n newline seen */
Trent Mickf29f47b2000-08-11 19:02:59 +000023
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000024#ifdef __cplusplus
25extern "C" {
26#endif
27
Guido van Rossumda5b8f22007-06-12 23:30:11 +000028/* External C interface */
Tim Peters59c9a642001-09-13 05:38:56 +000029
30PyObject *
Serhiy Storchakac6792272013-10-19 21:03:34 +030031PyFile_FromFd(int fd, const char *name, const char *mode, int buffering, const char *encoding,
32 const char *errors, const char *newline, int closefd)
Tim Peters59c9a642001-09-13 05:38:56 +000033{
Victor Stinner3603cc52010-08-13 13:34:52 +000034 PyObject *io, *stream;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +020035 _Py_IDENTIFIER(open);
Guido van Rossum53970392007-06-12 00:28:30 +000036
Steve Dowerb82e17e2019-05-23 08:45:22 -070037 /* import _io in case we are being used to open io.py */
38 io = PyImport_ImportModule("_io");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000039 if (io == NULL)
40 return NULL;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +020041 stream = _PyObject_CallMethodId(io, &PyId_open, "isisssi", fd, mode,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000042 buffering, encoding, errors,
43 newline, closefd);
44 Py_DECREF(io);
45 if (stream == NULL)
46 return NULL;
Victor Stinner3603cc52010-08-13 13:34:52 +000047 /* ignore name attribute because the name attribute of _BufferedIOMixin
48 and TextIOWrapper is read only */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000049 return stream;
Tim Peters59c9a642001-09-13 05:38:56 +000050}
51
52PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +000053PyFile_GetLine(PyObject *f, int n)
Guido van Rossum0bd24411991-04-04 15:21:57 +000054{
INADA Naoki72dccde2017-02-16 09:26:01 +090055 _Py_IDENTIFIER(readline);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000056 PyObject *result;
Guido van Rossum4ddf0a02001-01-07 20:51:39 +000057
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000058 if (f == NULL) {
59 PyErr_BadInternalCall();
60 return NULL;
61 }
Guido van Rossum4ddf0a02001-01-07 20:51:39 +000062
INADA Naoki72dccde2017-02-16 09:26:01 +090063 if (n <= 0) {
Jeroen Demeyer762f93f2019-07-08 10:19:25 +020064 result = _PyObject_CallMethodIdNoArgs(f, &PyId_readline);
INADA Naoki72dccde2017-02-16 09:26:01 +090065 }
66 else {
67 result = _PyObject_CallMethodId(f, &PyId_readline, "i", n);
68 }
69 if (result != NULL && !PyBytes_Check(result) &&
70 !PyUnicode_Check(result)) {
71 Py_DECREF(result);
72 result = NULL;
73 PyErr_SetString(PyExc_TypeError,
74 "object.readline() returned non-string");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000075 }
Guido van Rossum4ddf0a02001-01-07 20:51:39 +000076
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000077 if (n < 0 && result != NULL && PyBytes_Check(result)) {
78 char *s = PyBytes_AS_STRING(result);
79 Py_ssize_t len = PyBytes_GET_SIZE(result);
80 if (len == 0) {
81 Py_DECREF(result);
82 result = NULL;
83 PyErr_SetString(PyExc_EOFError,
84 "EOF when reading a line");
85 }
86 else if (s[len-1] == '\n') {
87 if (result->ob_refcnt == 1)
88 _PyBytes_Resize(&result, len-1);
89 else {
90 PyObject *v;
91 v = PyBytes_FromStringAndSize(s, len-1);
92 Py_DECREF(result);
93 result = v;
94 }
95 }
96 }
97 if (n < 0 && result != NULL && PyUnicode_Check(result)) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020098 Py_ssize_t len = PyUnicode_GET_LENGTH(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000099 if (len == 0) {
100 Py_DECREF(result);
101 result = NULL;
102 PyErr_SetString(PyExc_EOFError,
103 "EOF when reading a line");
104 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200105 else if (PyUnicode_READ_CHAR(result, len-1) == '\n') {
106 PyObject *v;
107 v = PyUnicode_Substring(result, 0, len-1);
108 Py_DECREF(result);
109 result = v;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000110 }
111 }
112 return result;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000113}
114
Guido van Rossum3165fe61992-09-25 21:59:05 +0000115/* Interfaces to write objects/strings to file-like objects */
116
117int
Fred Drakefd99de62000-07-09 05:02:18 +0000118PyFile_WriteObject(PyObject *v, PyObject *f, int flags)
Guido van Rossum3165fe61992-09-25 21:59:05 +0000119{
Victor Stinner9def0902016-08-20 00:44:04 +0200120 PyObject *writer, *value, *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200121 _Py_IDENTIFIER(write);
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +0200122
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000123 if (f == NULL) {
124 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
125 return -1;
126 }
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +0200127 writer = _PyObject_GetAttrId(f, &PyId_write);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000128 if (writer == NULL)
129 return -1;
130 if (flags & Py_PRINT_RAW) {
131 value = PyObject_Str(v);
132 }
133 else
134 value = PyObject_Repr(v);
135 if (value == NULL) {
136 Py_DECREF(writer);
137 return -1;
138 }
Jeroen Demeyer196a5302019-07-04 12:31:34 +0200139 result = _PyObject_CallOneArg(writer, value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000140 Py_DECREF(value);
141 Py_DECREF(writer);
142 if (result == NULL)
143 return -1;
144 Py_DECREF(result);
145 return 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000146}
147
Guido van Rossum27a60b11997-05-22 22:25:11 +0000148int
Tim Petersc1bbcb82001-11-28 22:13:25 +0000149PyFile_WriteString(const char *s, PyObject *f)
Guido van Rossum3165fe61992-09-25 21:59:05 +0000150{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000151 if (f == NULL) {
152 /* Should be caused by a pre-existing error */
153 if (!PyErr_Occurred())
154 PyErr_SetString(PyExc_SystemError,
155 "null file for PyFile_WriteString");
156 return -1;
157 }
158 else if (!PyErr_Occurred()) {
159 PyObject *v = PyUnicode_FromString(s);
160 int err;
161 if (v == NULL)
162 return -1;
163 err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
164 Py_DECREF(v);
165 return err;
166 }
167 else
168 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000169}
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +0000170
171/* Try to get a file-descriptor from a Python object. If the object
Serhiy Storchaka95949422013-08-27 19:40:23 +0300172 is an integer, its value is returned. If not, the
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +0000173 object's fileno() method is called if it exists; the method must return
Serhiy Storchaka95949422013-08-27 19:40:23 +0300174 an integer, which is returned as the file descriptor value.
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +0000175 -1 is returned on failure.
176*/
177
Guido van Rossumda5b8f22007-06-12 23:30:11 +0000178int
179PyObject_AsFileDescriptor(PyObject *o)
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +0000180{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000181 int fd;
182 PyObject *meth;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200183 _Py_IDENTIFIER(fileno);
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +0000184
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000185 if (PyLong_Check(o)) {
Serhiy Storchaka78980432013-01-15 01:12:17 +0200186 fd = _PyLong_AsInt(o);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000187 }
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +0200188 else if ((meth = _PyObject_GetAttrId(o, &PyId_fileno)) != NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000189 {
INADA Naoki72dccde2017-02-16 09:26:01 +0900190 PyObject *fno = _PyObject_CallNoArg(meth);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000191 Py_DECREF(meth);
192 if (fno == NULL)
193 return -1;
Tim Peters86821b22001-01-07 21:19:34 +0000194
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000195 if (PyLong_Check(fno)) {
Serhiy Storchaka78980432013-01-15 01:12:17 +0200196 fd = _PyLong_AsInt(fno);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000197 Py_DECREF(fno);
198 }
199 else {
200 PyErr_SetString(PyExc_TypeError,
201 "fileno() returned a non-integer");
202 Py_DECREF(fno);
203 return -1;
204 }
205 }
206 else {
207 PyErr_SetString(PyExc_TypeError,
208 "argument must be an int, or have a fileno() method.");
209 return -1;
210 }
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +0000211
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000212 if (fd == -1 && PyErr_Occurred())
213 return -1;
214 if (fd < 0) {
215 PyErr_Format(PyExc_ValueError,
216 "file descriptor cannot be a negative integer (%i)",
217 fd);
218 return -1;
219 }
220 return fd;
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +0000221}
Jack Jansen7b8c7542002-04-14 20:12:41 +0000222
Jack Jansen7b8c7542002-04-14 20:12:41 +0000223/*
224** Py_UniversalNewlineFgets is an fgets variation that understands
225** all of \r, \n and \r\n conventions.
226** The stream should be opened in binary mode.
227** If fobj is NULL the routine always does newline conversion, and
228** it may peek one char ahead to gobble the second char in \r\n.
229** If fobj is non-NULL it must be a PyFileObject. In this case there
230** is no readahead but in stead a flag is used to skip a following
231** \n on the next read. Also, if the file is open in binary mode
232** the whole conversion is skipped. Finally, the routine keeps track of
233** the different types of newlines seen.
234** Note that we need no error handling: fgets() treats error and eof
235** identically.
236*/
237char *
238Py_UniversalNewlineFgets(char *buf, int n, FILE *stream, PyObject *fobj)
239{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000240 char *p = buf;
241 int c;
242 int newlinetypes = 0;
243 int skipnextlf = 0;
Tim Peters058b1412002-04-21 07:29:14 +0000244
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000245 if (fobj) {
246 errno = ENXIO; /* What can you do... */
247 return NULL;
248 }
249 FLOCKFILE(stream);
250 c = 'x'; /* Shut up gcc warning */
251 while (--n > 0 && (c = GETC(stream)) != EOF ) {
252 if (skipnextlf ) {
253 skipnextlf = 0;
254 if (c == '\n') {
255 /* Seeing a \n here with skipnextlf true
256 ** means we saw a \r before.
257 */
258 newlinetypes |= NEWLINE_CRLF;
259 c = GETC(stream);
260 if (c == EOF) break;
261 } else {
262 /*
263 ** Note that c == EOF also brings us here,
264 ** so we're okay if the last char in the file
265 ** is a CR.
266 */
267 newlinetypes |= NEWLINE_CR;
268 }
269 }
270 if (c == '\r') {
271 /* A \r is translated into a \n, and we skip
272 ** an adjacent \n, if any. We don't set the
273 ** newlinetypes flag until we've seen the next char.
274 */
275 skipnextlf = 1;
276 c = '\n';
277 } else if ( c == '\n') {
278 newlinetypes |= NEWLINE_LF;
279 }
280 *p++ = c;
281 if (c == '\n') break;
282 }
Brett Cannonb94767f2011-02-22 20:15:44 +0000283 /* if ( c == EOF && skipnextlf )
284 newlinetypes |= NEWLINE_CR; */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000285 FUNLOCKFILE(stream);
286 *p = '\0';
287 if ( skipnextlf ) {
288 /* If we have no file object we cannot save the
289 ** skipnextlf flag. We have to readahead, which
290 ** will cause a pause if we're reading from an
291 ** interactive stream, but that is very unlikely
292 ** unless we're doing something silly like
293 ** exec(open("/dev/tty").read()).
294 */
295 c = GETC(stream);
296 if ( c != '\n' )
297 ungetc(c, stream);
298 }
299 if (p == buf)
300 return NULL;
301 return buf;
Jack Jansen7b8c7542002-04-14 20:12:41 +0000302}
303
Christian Heimesaf935e32007-11-12 16:05:45 +0000304/* **************************** std printer ****************************
305 * The stdprinter is used during the boot strapping phase as a preliminary
306 * file like object for sys.stderr.
307 */
Guido van Rossum826d8972007-10-30 18:34:07 +0000308
309typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000310 PyObject_HEAD
311 int fd;
Guido van Rossum826d8972007-10-30 18:34:07 +0000312} PyStdPrinter_Object;
313
314static PyObject *
315stdprinter_new(PyTypeObject *type, PyObject *args, PyObject *kews)
316{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000317 PyStdPrinter_Object *self;
Guido van Rossum826d8972007-10-30 18:34:07 +0000318
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000319 assert(type != NULL && type->tp_alloc != NULL);
Guido van Rossum826d8972007-10-30 18:34:07 +0000320
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000321 self = (PyStdPrinter_Object *) type->tp_alloc(type, 0);
322 if (self != NULL) {
323 self->fd = -1;
324 }
Guido van Rossum826d8972007-10-30 18:34:07 +0000325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326 return (PyObject *) self;
Guido van Rossum826d8972007-10-30 18:34:07 +0000327}
328
Christian Heimesaf935e32007-11-12 16:05:45 +0000329static int
Victor Stinnerdc555402011-01-04 13:15:39 +0000330stdprinter_init(PyObject *self, PyObject *args, PyObject *kwds)
Christian Heimesaf935e32007-11-12 16:05:45 +0000331{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000332 PyErr_SetString(PyExc_TypeError,
333 "cannot create 'stderrprinter' instances");
334 return -1;
Christian Heimesaf935e32007-11-12 16:05:45 +0000335}
336
Guido van Rossum826d8972007-10-30 18:34:07 +0000337PyObject *
338PyFile_NewStdPrinter(int fd)
339{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000340 PyStdPrinter_Object *self;
Guido van Rossum826d8972007-10-30 18:34:07 +0000341
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000342 if (fd != fileno(stdout) && fd != fileno(stderr)) {
343 /* not enough infrastructure for PyErr_BadInternalCall() */
344 return NULL;
345 }
Guido van Rossum826d8972007-10-30 18:34:07 +0000346
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000347 self = PyObject_New(PyStdPrinter_Object,
348 &PyStdPrinter_Type);
349 if (self != NULL) {
350 self->fd = fd;
351 }
352 return (PyObject*)self;
Guido van Rossum826d8972007-10-30 18:34:07 +0000353}
354
Martin v. Löwisff649b42008-06-13 07:24:48 +0000355static PyObject *
Guido van Rossum826d8972007-10-30 18:34:07 +0000356stdprinter_write(PyStdPrinter_Object *self, PyObject *args)
357{
Serhiy Storchakaa59018c2015-09-30 15:46:53 +0300358 PyObject *unicode;
359 PyObject *bytes = NULL;
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +0200360 const char *str;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000361 Py_ssize_t n;
Victor Stinner89719e12015-09-30 15:01:34 +0200362 int err;
Guido van Rossum826d8972007-10-30 18:34:07 +0000363
Victor Stinner6d43f6f2019-01-22 21:18:05 +0100364 /* The function can clear the current exception */
365 assert(!PyErr_Occurred());
366
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000367 if (self->fd < 0) {
368 /* fd might be invalid on Windows
369 * I can't raise an exception here. It may lead to an
370 * unlimited recursion in the case stderr is invalid.
371 */
372 Py_RETURN_NONE;
373 }
Guido van Rossum826d8972007-10-30 18:34:07 +0000374
Victor Stinner6d43f6f2019-01-22 21:18:05 +0100375 if (!PyArg_ParseTuple(args, "U", &unicode)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000376 return NULL;
Victor Stinner6d43f6f2019-01-22 21:18:05 +0100377 }
Guido van Rossum826d8972007-10-30 18:34:07 +0000378
Victor Stinner6d43f6f2019-01-22 21:18:05 +0100379 /* Encode Unicode to UTF-8/surrogateescape */
Serhiy Storchakaa59018c2015-09-30 15:46:53 +0300380 str = PyUnicode_AsUTF8AndSize(unicode, &n);
381 if (str == NULL) {
382 PyErr_Clear();
383 bytes = _PyUnicode_AsUTF8String(unicode, "backslashreplace");
384 if (bytes == NULL)
385 return NULL;
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +0200386 str = PyBytes_AS_STRING(bytes);
387 n = PyBytes_GET_SIZE(bytes);
Guido van Rossum826d8972007-10-30 18:34:07 +0000388 }
Guido van Rossum826d8972007-10-30 18:34:07 +0000389
Serhiy Storchaka008fc772015-09-30 15:50:32 +0300390 n = _Py_write(self->fd, str, n);
Victor Stinner89719e12015-09-30 15:01:34 +0200391 /* save errno, it can be modified indirectly by Py_XDECREF() */
392 err = errno;
Victor Stinner89719e12015-09-30 15:01:34 +0200393
Serhiy Storchakaa59018c2015-09-30 15:46:53 +0300394 Py_XDECREF(bytes);
Guido van Rossum826d8972007-10-30 18:34:07 +0000395
Victor Stinner66aab0c2015-03-19 22:53:20 +0100396 if (n == -1) {
Victor Stinnerae86da92015-09-30 15:03:31 +0200397 if (err == EAGAIN) {
Victor Stinner66aab0c2015-03-19 22:53:20 +0100398 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000399 Py_RETURN_NONE;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100400 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000401 return NULL;
402 }
Guido van Rossum826d8972007-10-30 18:34:07 +0000403
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000404 return PyLong_FromSsize_t(n);
Christian Heimesaf935e32007-11-12 16:05:45 +0000405}
406
407static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530408stdprinter_fileno(PyStdPrinter_Object *self, PyObject *Py_UNUSED(ignored))
Christian Heimesaf935e32007-11-12 16:05:45 +0000409{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000410 return PyLong_FromLong((long) self->fd);
Christian Heimesaf935e32007-11-12 16:05:45 +0000411}
412
413static PyObject *
414stdprinter_repr(PyStdPrinter_Object *self)
415{
sth8b91eda2019-03-10 11:29:14 +0100416 return PyUnicode_FromFormat("<stdprinter(fd=%d) object at %p>",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000417 self->fd, self);
Christian Heimesaf935e32007-11-12 16:05:45 +0000418}
419
420static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530421stdprinter_noop(PyStdPrinter_Object *self, PyObject *Py_UNUSED(ignored))
Christian Heimesaf935e32007-11-12 16:05:45 +0000422{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000423 Py_RETURN_NONE;
Christian Heimesaf935e32007-11-12 16:05:45 +0000424}
425
426static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530427stdprinter_isatty(PyStdPrinter_Object *self, PyObject *Py_UNUSED(ignored))
Christian Heimesaf935e32007-11-12 16:05:45 +0000428{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000429 long res;
430 if (self->fd < 0) {
431 Py_RETURN_FALSE;
432 }
Christian Heimesaf935e32007-11-12 16:05:45 +0000433
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000434 Py_BEGIN_ALLOW_THREADS
435 res = isatty(self->fd);
436 Py_END_ALLOW_THREADS
Christian Heimesaf935e32007-11-12 16:05:45 +0000437
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000438 return PyBool_FromLong(res);
Guido van Rossum826d8972007-10-30 18:34:07 +0000439}
440
441static PyMethodDef stdprinter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000442 {"close", (PyCFunction)stdprinter_noop, METH_NOARGS, ""},
443 {"flush", (PyCFunction)stdprinter_noop, METH_NOARGS, ""},
444 {"fileno", (PyCFunction)stdprinter_fileno, METH_NOARGS, ""},
445 {"isatty", (PyCFunction)stdprinter_isatty, METH_NOARGS, ""},
446 {"write", (PyCFunction)stdprinter_write, METH_VARARGS, ""},
447 {NULL, NULL} /*sentinel */
Christian Heimesaf935e32007-11-12 16:05:45 +0000448};
449
450static PyObject *
451get_closed(PyStdPrinter_Object *self, void *closure)
452{
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200453 Py_RETURN_FALSE;
Christian Heimesaf935e32007-11-12 16:05:45 +0000454}
455
456static PyObject *
457get_mode(PyStdPrinter_Object *self, void *closure)
458{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000459 return PyUnicode_FromString("w");
Christian Heimesaf935e32007-11-12 16:05:45 +0000460}
461
462static PyObject *
463get_encoding(PyStdPrinter_Object *self, void *closure)
464{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000465 Py_RETURN_NONE;
Christian Heimesaf935e32007-11-12 16:05:45 +0000466}
467
468static PyGetSetDef stdprinter_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000469 {"closed", (getter)get_closed, NULL, "True if the file is closed"},
470 {"encoding", (getter)get_encoding, NULL, "Encoding of the file"},
471 {"mode", (getter)get_mode, NULL, "String giving the file mode"},
472 {0},
Guido van Rossum826d8972007-10-30 18:34:07 +0000473};
474
475PyTypeObject PyStdPrinter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000476 PyVarObject_HEAD_INIT(&PyType_Type, 0)
477 "stderrprinter", /* tp_name */
478 sizeof(PyStdPrinter_Object), /* tp_basicsize */
479 0, /* tp_itemsize */
480 /* methods */
481 0, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200482 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000483 0, /* tp_getattr */
484 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200485 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486 (reprfunc)stdprinter_repr, /* tp_repr */
487 0, /* tp_as_number */
488 0, /* tp_as_sequence */
489 0, /* tp_as_mapping */
490 0, /* tp_hash */
491 0, /* tp_call */
492 0, /* tp_str */
493 PyObject_GenericGetAttr, /* tp_getattro */
494 0, /* tp_setattro */
495 0, /* tp_as_buffer */
496 Py_TPFLAGS_DEFAULT, /* tp_flags */
497 0, /* tp_doc */
498 0, /* tp_traverse */
499 0, /* tp_clear */
500 0, /* tp_richcompare */
501 0, /* tp_weaklistoffset */
502 0, /* tp_iter */
503 0, /* tp_iternext */
504 stdprinter_methods, /* tp_methods */
505 0, /* tp_members */
506 stdprinter_getsetlist, /* tp_getset */
507 0, /* tp_base */
508 0, /* tp_dict */
509 0, /* tp_descr_get */
510 0, /* tp_descr_set */
511 0, /* tp_dictoffset */
Victor Stinnerdc555402011-01-04 13:15:39 +0000512 stdprinter_init, /* tp_init */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000513 PyType_GenericAlloc, /* tp_alloc */
514 stdprinter_new, /* tp_new */
515 PyObject_Del, /* tp_free */
Guido van Rossum826d8972007-10-30 18:34:07 +0000516};
517
518
Steve Dowerb82e17e2019-05-23 08:45:22 -0700519/* ************************** open_code hook ***************************
520 * The open_code hook allows embedders to override the method used to
521 * open files that are going to be used by the runtime to execute code
522 */
523
524int
525PyFile_SetOpenCodeHook(Py_OpenCodeHookFunction hook, void *userData) {
526 if (Py_IsInitialized() &&
527 PySys_Audit("setopencodehook", NULL) < 0) {
528 return -1;
529 }
530
531 if (_PyRuntime.open_code_hook) {
532 if (Py_IsInitialized()) {
533 PyErr_SetString(PyExc_SystemError,
534 "failed to change existing open_code hook");
535 }
536 return -1;
537 }
538
539 _PyRuntime.open_code_hook = hook;
540 _PyRuntime.open_code_userdata = userData;
541 return 0;
542}
543
544PyObject *
545PyFile_OpenCodeObject(PyObject *path)
546{
547 PyObject *iomod, *f = NULL;
548 _Py_IDENTIFIER(open);
549
550 if (!PyUnicode_Check(path)) {
551 PyErr_Format(PyExc_TypeError, "'path' must be 'str', not '%.200s'",
552 Py_TYPE(path)->tp_name);
553 return NULL;
554 }
555
556 Py_OpenCodeHookFunction hook = _PyRuntime.open_code_hook;
557 if (hook) {
558 f = hook(path, _PyRuntime.open_code_userdata);
559 } else {
560 iomod = PyImport_ImportModule("_io");
561 if (iomod) {
562 f = _PyObject_CallMethodId(iomod, &PyId_open, "Os",
563 path, "rb");
564 Py_DECREF(iomod);
565 }
566 }
567
568 return f;
569}
570
571PyObject *
572PyFile_OpenCode(const char *utf8path)
573{
574 PyObject *pathobj = PyUnicode_FromString(utf8path);
575 PyObject *f;
576 if (!pathobj) {
577 return NULL;
578 }
579 f = PyFile_OpenCodeObject(pathobj);
580 Py_DECREF(pathobj);
581 return f;
582}
583
584
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000585#ifdef __cplusplus
586}
587#endif