blob: c0eff8bed5136a32b38e5fa158f78c1cd6e28998 [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
Hai Shi46874c22020-01-30 17:20:25 -060028_Py_IDENTIFIER(open);
29
Guido van Rossumda5b8f22007-06-12 23:30:11 +000030/* External C interface */
Tim Peters59c9a642001-09-13 05:38:56 +000031
32PyObject *
Serhiy Storchakac6792272013-10-19 21:03:34 +030033PyFile_FromFd(int fd, const char *name, const char *mode, int buffering, const char *encoding,
34 const char *errors, const char *newline, int closefd)
Tim Peters59c9a642001-09-13 05:38:56 +000035{
Victor Stinner3603cc52010-08-13 13:34:52 +000036 PyObject *io, *stream;
Guido van Rossum53970392007-06-12 00:28:30 +000037
Steve Dowerb82e17e2019-05-23 08:45:22 -070038 /* import _io in case we are being used to open io.py */
39 io = PyImport_ImportModule("_io");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000040 if (io == NULL)
41 return NULL;
Serhiy Storchaka1f21eaa2019-09-01 12:16:51 +030042 stream = _PyObject_CallMethodId(io, &PyId_open, "isisssO", fd, mode,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000043 buffering, encoding, errors,
Serhiy Storchaka1f21eaa2019-09-01 12:16:51 +030044 newline, closefd ? Py_True : Py_False);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000045 Py_DECREF(io);
46 if (stream == NULL)
47 return NULL;
Victor Stinner3603cc52010-08-13 13:34:52 +000048 /* ignore name attribute because the name attribute of _BufferedIOMixin
49 and TextIOWrapper is read only */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000050 return stream;
Tim Peters59c9a642001-09-13 05:38:56 +000051}
52
53PyObject *
Fred Drakefd99de62000-07-09 05:02:18 +000054PyFile_GetLine(PyObject *f, int n)
Guido van Rossum0bd24411991-04-04 15:21:57 +000055{
INADA Naoki72dccde2017-02-16 09:26:01 +090056 _Py_IDENTIFIER(readline);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000057 PyObject *result;
Guido van Rossum4ddf0a02001-01-07 20:51:39 +000058
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000059 if (f == NULL) {
60 PyErr_BadInternalCall();
61 return NULL;
62 }
Guido van Rossum4ddf0a02001-01-07 20:51:39 +000063
INADA Naoki72dccde2017-02-16 09:26:01 +090064 if (n <= 0) {
Jeroen Demeyer762f93f2019-07-08 10:19:25 +020065 result = _PyObject_CallMethodIdNoArgs(f, &PyId_readline);
INADA Naoki72dccde2017-02-16 09:26:01 +090066 }
67 else {
68 result = _PyObject_CallMethodId(f, &PyId_readline, "i", n);
69 }
70 if (result != NULL && !PyBytes_Check(result) &&
71 !PyUnicode_Check(result)) {
72 Py_DECREF(result);
73 result = NULL;
74 PyErr_SetString(PyExc_TypeError,
75 "object.readline() returned non-string");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000076 }
Guido van Rossum4ddf0a02001-01-07 20:51:39 +000077
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000078 if (n < 0 && result != NULL && PyBytes_Check(result)) {
79 char *s = PyBytes_AS_STRING(result);
80 Py_ssize_t len = PyBytes_GET_SIZE(result);
81 if (len == 0) {
82 Py_DECREF(result);
83 result = NULL;
84 PyErr_SetString(PyExc_EOFError,
85 "EOF when reading a line");
86 }
87 else if (s[len-1] == '\n') {
Victor Stinnera93c51e2020-02-07 00:38:59 +010088 if (Py_REFCNT(result) == 1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000089 _PyBytes_Resize(&result, len-1);
90 else {
91 PyObject *v;
92 v = PyBytes_FromStringAndSize(s, len-1);
93 Py_DECREF(result);
94 result = v;
95 }
96 }
97 }
98 if (n < 0 && result != NULL && PyUnicode_Check(result)) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020099 Py_ssize_t len = PyUnicode_GET_LENGTH(result);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000100 if (len == 0) {
101 Py_DECREF(result);
102 result = NULL;
103 PyErr_SetString(PyExc_EOFError,
104 "EOF when reading a line");
105 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200106 else if (PyUnicode_READ_CHAR(result, len-1) == '\n') {
107 PyObject *v;
108 v = PyUnicode_Substring(result, 0, len-1);
109 Py_DECREF(result);
110 result = v;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000111 }
112 }
113 return result;
Guido van Rossum0bd24411991-04-04 15:21:57 +0000114}
115
Guido van Rossum3165fe61992-09-25 21:59:05 +0000116/* Interfaces to write objects/strings to file-like objects */
117
118int
Fred Drakefd99de62000-07-09 05:02:18 +0000119PyFile_WriteObject(PyObject *v, PyObject *f, int flags)
Guido van Rossum3165fe61992-09-25 21:59:05 +0000120{
Victor Stinner9def0902016-08-20 00:44:04 +0200121 PyObject *writer, *value, *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200122 _Py_IDENTIFIER(write);
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +0200123
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000124 if (f == NULL) {
125 PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
126 return -1;
127 }
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +0200128 writer = _PyObject_GetAttrId(f, &PyId_write);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000129 if (writer == NULL)
130 return -1;
131 if (flags & Py_PRINT_RAW) {
132 value = PyObject_Str(v);
133 }
134 else
135 value = PyObject_Repr(v);
136 if (value == NULL) {
137 Py_DECREF(writer);
138 return -1;
139 }
Jeroen Demeyer196a5302019-07-04 12:31:34 +0200140 result = _PyObject_CallOneArg(writer, value);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000141 Py_DECREF(value);
142 Py_DECREF(writer);
143 if (result == NULL)
144 return -1;
145 Py_DECREF(result);
146 return 0;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000147}
148
Guido van Rossum27a60b11997-05-22 22:25:11 +0000149int
Tim Petersc1bbcb82001-11-28 22:13:25 +0000150PyFile_WriteString(const char *s, PyObject *f)
Guido van Rossum3165fe61992-09-25 21:59:05 +0000151{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000152 if (f == NULL) {
153 /* Should be caused by a pre-existing error */
154 if (!PyErr_Occurred())
155 PyErr_SetString(PyExc_SystemError,
156 "null file for PyFile_WriteString");
157 return -1;
158 }
159 else if (!PyErr_Occurred()) {
160 PyObject *v = PyUnicode_FromString(s);
161 int err;
162 if (v == NULL)
163 return -1;
164 err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
165 Py_DECREF(v);
166 return err;
167 }
168 else
169 return -1;
Guido van Rossum3165fe61992-09-25 21:59:05 +0000170}
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +0000171
172/* Try to get a file-descriptor from a Python object. If the object
Serhiy Storchaka95949422013-08-27 19:40:23 +0300173 is an integer, its value is returned. If not, the
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +0000174 object's fileno() method is called if it exists; the method must return
Serhiy Storchaka95949422013-08-27 19:40:23 +0300175 an integer, which is returned as the file descriptor value.
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +0000176 -1 is returned on failure.
177*/
178
Guido van Rossumda5b8f22007-06-12 23:30:11 +0000179int
180PyObject_AsFileDescriptor(PyObject *o)
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +0000181{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000182 int fd;
183 PyObject *meth;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200184 _Py_IDENTIFIER(fileno);
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +0000185
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000186 if (PyLong_Check(o)) {
Serhiy Storchaka78980432013-01-15 01:12:17 +0200187 fd = _PyLong_AsInt(o);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000188 }
Serhiy Storchaka41c57b32019-09-01 12:03:39 +0300189 else if (_PyObject_LookupAttrId(o, &PyId_fileno, &meth) < 0) {
190 return -1;
191 }
192 else if (meth != NULL) {
INADA Naoki72dccde2017-02-16 09:26:01 +0900193 PyObject *fno = _PyObject_CallNoArg(meth);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000194 Py_DECREF(meth);
195 if (fno == NULL)
196 return -1;
Tim Peters86821b22001-01-07 21:19:34 +0000197
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000198 if (PyLong_Check(fno)) {
Serhiy Storchaka78980432013-01-15 01:12:17 +0200199 fd = _PyLong_AsInt(fno);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000200 Py_DECREF(fno);
201 }
202 else {
203 PyErr_SetString(PyExc_TypeError,
204 "fileno() returned a non-integer");
205 Py_DECREF(fno);
206 return -1;
207 }
208 }
209 else {
210 PyErr_SetString(PyExc_TypeError,
211 "argument must be an int, or have a fileno() method.");
212 return -1;
213 }
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +0000214
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000215 if (fd == -1 && PyErr_Occurred())
216 return -1;
217 if (fd < 0) {
218 PyErr_Format(PyExc_ValueError,
219 "file descriptor cannot be a negative integer (%i)",
220 fd);
221 return -1;
222 }
223 return fd;
Andrew M. Kuchling06051ed2000-07-13 23:56:54 +0000224}
Jack Jansen7b8c7542002-04-14 20:12:41 +0000225
Jack Jansen7b8c7542002-04-14 20:12:41 +0000226/*
227** Py_UniversalNewlineFgets is an fgets variation that understands
228** all of \r, \n and \r\n conventions.
229** The stream should be opened in binary mode.
230** If fobj is NULL the routine always does newline conversion, and
231** it may peek one char ahead to gobble the second char in \r\n.
232** If fobj is non-NULL it must be a PyFileObject. In this case there
233** is no readahead but in stead a flag is used to skip a following
234** \n on the next read. Also, if the file is open in binary mode
235** the whole conversion is skipped. Finally, the routine keeps track of
236** the different types of newlines seen.
237** Note that we need no error handling: fgets() treats error and eof
238** identically.
239*/
240char *
241Py_UniversalNewlineFgets(char *buf, int n, FILE *stream, PyObject *fobj)
242{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000243 char *p = buf;
244 int c;
245 int newlinetypes = 0;
246 int skipnextlf = 0;
Tim Peters058b1412002-04-21 07:29:14 +0000247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000248 if (fobj) {
249 errno = ENXIO; /* What can you do... */
250 return NULL;
251 }
252 FLOCKFILE(stream);
253 c = 'x'; /* Shut up gcc warning */
254 while (--n > 0 && (c = GETC(stream)) != EOF ) {
255 if (skipnextlf ) {
256 skipnextlf = 0;
257 if (c == '\n') {
258 /* Seeing a \n here with skipnextlf true
259 ** means we saw a \r before.
260 */
261 newlinetypes |= NEWLINE_CRLF;
262 c = GETC(stream);
263 if (c == EOF) break;
264 } else {
265 /*
266 ** Note that c == EOF also brings us here,
267 ** so we're okay if the last char in the file
268 ** is a CR.
269 */
270 newlinetypes |= NEWLINE_CR;
271 }
272 }
273 if (c == '\r') {
274 /* A \r is translated into a \n, and we skip
275 ** an adjacent \n, if any. We don't set the
276 ** newlinetypes flag until we've seen the next char.
277 */
278 skipnextlf = 1;
279 c = '\n';
280 } else if ( c == '\n') {
281 newlinetypes |= NEWLINE_LF;
282 }
283 *p++ = c;
284 if (c == '\n') break;
285 }
Brett Cannonb94767f2011-02-22 20:15:44 +0000286 /* if ( c == EOF && skipnextlf )
287 newlinetypes |= NEWLINE_CR; */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 FUNLOCKFILE(stream);
289 *p = '\0';
290 if ( skipnextlf ) {
291 /* If we have no file object we cannot save the
292 ** skipnextlf flag. We have to readahead, which
293 ** will cause a pause if we're reading from an
294 ** interactive stream, but that is very unlikely
295 ** unless we're doing something silly like
296 ** exec(open("/dev/tty").read()).
297 */
298 c = GETC(stream);
299 if ( c != '\n' )
300 ungetc(c, stream);
301 }
302 if (p == buf)
303 return NULL;
304 return buf;
Jack Jansen7b8c7542002-04-14 20:12:41 +0000305}
306
Christian Heimesaf935e32007-11-12 16:05:45 +0000307/* **************************** std printer ****************************
308 * The stdprinter is used during the boot strapping phase as a preliminary
309 * file like object for sys.stderr.
310 */
Guido van Rossum826d8972007-10-30 18:34:07 +0000311
312typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313 PyObject_HEAD
314 int fd;
Guido van Rossum826d8972007-10-30 18:34:07 +0000315} PyStdPrinter_Object;
316
317static PyObject *
318stdprinter_new(PyTypeObject *type, PyObject *args, PyObject *kews)
319{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000320 PyStdPrinter_Object *self;
Guido van Rossum826d8972007-10-30 18:34:07 +0000321
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000322 assert(type != NULL && type->tp_alloc != NULL);
Guido van Rossum826d8972007-10-30 18:34:07 +0000323
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000324 self = (PyStdPrinter_Object *) type->tp_alloc(type, 0);
325 if (self != NULL) {
326 self->fd = -1;
327 }
Guido van Rossum826d8972007-10-30 18:34:07 +0000328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000329 return (PyObject *) self;
Guido van Rossum826d8972007-10-30 18:34:07 +0000330}
331
Christian Heimesaf935e32007-11-12 16:05:45 +0000332static int
Victor Stinnerdc555402011-01-04 13:15:39 +0000333stdprinter_init(PyObject *self, PyObject *args, PyObject *kwds)
Christian Heimesaf935e32007-11-12 16:05:45 +0000334{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000335 PyErr_SetString(PyExc_TypeError,
336 "cannot create 'stderrprinter' instances");
337 return -1;
Christian Heimesaf935e32007-11-12 16:05:45 +0000338}
339
Guido van Rossum826d8972007-10-30 18:34:07 +0000340PyObject *
341PyFile_NewStdPrinter(int fd)
342{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000343 PyStdPrinter_Object *self;
Guido van Rossum826d8972007-10-30 18:34:07 +0000344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000345 if (fd != fileno(stdout) && fd != fileno(stderr)) {
346 /* not enough infrastructure for PyErr_BadInternalCall() */
347 return NULL;
348 }
Guido van Rossum826d8972007-10-30 18:34:07 +0000349
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000350 self = PyObject_New(PyStdPrinter_Object,
351 &PyStdPrinter_Type);
352 if (self != NULL) {
353 self->fd = fd;
354 }
355 return (PyObject*)self;
Guido van Rossum826d8972007-10-30 18:34:07 +0000356}
357
Martin v. Löwisff649b42008-06-13 07:24:48 +0000358static PyObject *
Guido van Rossum826d8972007-10-30 18:34:07 +0000359stdprinter_write(PyStdPrinter_Object *self, PyObject *args)
360{
Serhiy Storchakaa59018c2015-09-30 15:46:53 +0300361 PyObject *unicode;
362 PyObject *bytes = NULL;
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +0200363 const char *str;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000364 Py_ssize_t n;
Victor Stinner89719e12015-09-30 15:01:34 +0200365 int err;
Guido van Rossum826d8972007-10-30 18:34:07 +0000366
Victor Stinner6d43f6f2019-01-22 21:18:05 +0100367 /* The function can clear the current exception */
368 assert(!PyErr_Occurred());
369
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000370 if (self->fd < 0) {
371 /* fd might be invalid on Windows
372 * I can't raise an exception here. It may lead to an
373 * unlimited recursion in the case stderr is invalid.
374 */
375 Py_RETURN_NONE;
376 }
Guido van Rossum826d8972007-10-30 18:34:07 +0000377
Victor Stinner6d43f6f2019-01-22 21:18:05 +0100378 if (!PyArg_ParseTuple(args, "U", &unicode)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000379 return NULL;
Victor Stinner6d43f6f2019-01-22 21:18:05 +0100380 }
Guido van Rossum826d8972007-10-30 18:34:07 +0000381
Victor Stinner6d43f6f2019-01-22 21:18:05 +0100382 /* Encode Unicode to UTF-8/surrogateescape */
Serhiy Storchakaa59018c2015-09-30 15:46:53 +0300383 str = PyUnicode_AsUTF8AndSize(unicode, &n);
384 if (str == NULL) {
385 PyErr_Clear();
386 bytes = _PyUnicode_AsUTF8String(unicode, "backslashreplace");
387 if (bytes == NULL)
388 return NULL;
Serhiy Storchaka85b0f5b2016-11-20 10:16:47 +0200389 str = PyBytes_AS_STRING(bytes);
390 n = PyBytes_GET_SIZE(bytes);
Guido van Rossum826d8972007-10-30 18:34:07 +0000391 }
Guido van Rossum826d8972007-10-30 18:34:07 +0000392
Serhiy Storchaka008fc772015-09-30 15:50:32 +0300393 n = _Py_write(self->fd, str, n);
Victor Stinner89719e12015-09-30 15:01:34 +0200394 /* save errno, it can be modified indirectly by Py_XDECREF() */
395 err = errno;
Victor Stinner89719e12015-09-30 15:01:34 +0200396
Serhiy Storchakaa59018c2015-09-30 15:46:53 +0300397 Py_XDECREF(bytes);
Guido van Rossum826d8972007-10-30 18:34:07 +0000398
Victor Stinner66aab0c2015-03-19 22:53:20 +0100399 if (n == -1) {
Victor Stinnerae86da92015-09-30 15:03:31 +0200400 if (err == EAGAIN) {
Victor Stinner66aab0c2015-03-19 22:53:20 +0100401 PyErr_Clear();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000402 Py_RETURN_NONE;
Victor Stinner66aab0c2015-03-19 22:53:20 +0100403 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000404 return NULL;
405 }
Guido van Rossum826d8972007-10-30 18:34:07 +0000406
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000407 return PyLong_FromSsize_t(n);
Christian Heimesaf935e32007-11-12 16:05:45 +0000408}
409
410static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530411stdprinter_fileno(PyStdPrinter_Object *self, PyObject *Py_UNUSED(ignored))
Christian Heimesaf935e32007-11-12 16:05:45 +0000412{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000413 return PyLong_FromLong((long) self->fd);
Christian Heimesaf935e32007-11-12 16:05:45 +0000414}
415
416static PyObject *
417stdprinter_repr(PyStdPrinter_Object *self)
418{
sth8b91eda2019-03-10 11:29:14 +0100419 return PyUnicode_FromFormat("<stdprinter(fd=%d) object at %p>",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000420 self->fd, self);
Christian Heimesaf935e32007-11-12 16:05:45 +0000421}
422
423static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530424stdprinter_noop(PyStdPrinter_Object *self, PyObject *Py_UNUSED(ignored))
Christian Heimesaf935e32007-11-12 16:05:45 +0000425{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000426 Py_RETURN_NONE;
Christian Heimesaf935e32007-11-12 16:05:45 +0000427}
428
429static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +0530430stdprinter_isatty(PyStdPrinter_Object *self, PyObject *Py_UNUSED(ignored))
Christian Heimesaf935e32007-11-12 16:05:45 +0000431{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000432 long res;
433 if (self->fd < 0) {
434 Py_RETURN_FALSE;
435 }
Christian Heimesaf935e32007-11-12 16:05:45 +0000436
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000437 Py_BEGIN_ALLOW_THREADS
438 res = isatty(self->fd);
439 Py_END_ALLOW_THREADS
Christian Heimesaf935e32007-11-12 16:05:45 +0000440
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000441 return PyBool_FromLong(res);
Guido van Rossum826d8972007-10-30 18:34:07 +0000442}
443
444static PyMethodDef stdprinter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000445 {"close", (PyCFunction)stdprinter_noop, METH_NOARGS, ""},
446 {"flush", (PyCFunction)stdprinter_noop, METH_NOARGS, ""},
447 {"fileno", (PyCFunction)stdprinter_fileno, METH_NOARGS, ""},
448 {"isatty", (PyCFunction)stdprinter_isatty, METH_NOARGS, ""},
449 {"write", (PyCFunction)stdprinter_write, METH_VARARGS, ""},
450 {NULL, NULL} /*sentinel */
Christian Heimesaf935e32007-11-12 16:05:45 +0000451};
452
453static PyObject *
454get_closed(PyStdPrinter_Object *self, void *closure)
455{
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200456 Py_RETURN_FALSE;
Christian Heimesaf935e32007-11-12 16:05:45 +0000457}
458
459static PyObject *
460get_mode(PyStdPrinter_Object *self, void *closure)
461{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000462 return PyUnicode_FromString("w");
Christian Heimesaf935e32007-11-12 16:05:45 +0000463}
464
465static PyObject *
466get_encoding(PyStdPrinter_Object *self, void *closure)
467{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000468 Py_RETURN_NONE;
Christian Heimesaf935e32007-11-12 16:05:45 +0000469}
470
471static PyGetSetDef stdprinter_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000472 {"closed", (getter)get_closed, NULL, "True if the file is closed"},
473 {"encoding", (getter)get_encoding, NULL, "Encoding of the file"},
474 {"mode", (getter)get_mode, NULL, "String giving the file mode"},
475 {0},
Guido van Rossum826d8972007-10-30 18:34:07 +0000476};
477
478PyTypeObject PyStdPrinter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000479 PyVarObject_HEAD_INIT(&PyType_Type, 0)
480 "stderrprinter", /* tp_name */
481 sizeof(PyStdPrinter_Object), /* tp_basicsize */
482 0, /* tp_itemsize */
483 /* methods */
484 0, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200485 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486 0, /* tp_getattr */
487 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200488 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000489 (reprfunc)stdprinter_repr, /* tp_repr */
490 0, /* tp_as_number */
491 0, /* tp_as_sequence */
492 0, /* tp_as_mapping */
493 0, /* tp_hash */
494 0, /* tp_call */
495 0, /* tp_str */
496 PyObject_GenericGetAttr, /* tp_getattro */
497 0, /* tp_setattro */
498 0, /* tp_as_buffer */
499 Py_TPFLAGS_DEFAULT, /* tp_flags */
500 0, /* tp_doc */
501 0, /* tp_traverse */
502 0, /* tp_clear */
503 0, /* tp_richcompare */
504 0, /* tp_weaklistoffset */
505 0, /* tp_iter */
506 0, /* tp_iternext */
507 stdprinter_methods, /* tp_methods */
508 0, /* tp_members */
509 stdprinter_getsetlist, /* tp_getset */
510 0, /* tp_base */
511 0, /* tp_dict */
512 0, /* tp_descr_get */
513 0, /* tp_descr_set */
514 0, /* tp_dictoffset */
Victor Stinnerdc555402011-01-04 13:15:39 +0000515 stdprinter_init, /* tp_init */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000516 PyType_GenericAlloc, /* tp_alloc */
517 stdprinter_new, /* tp_new */
518 PyObject_Del, /* tp_free */
Guido van Rossum826d8972007-10-30 18:34:07 +0000519};
520
521
Steve Dowerb82e17e2019-05-23 08:45:22 -0700522/* ************************** open_code hook ***************************
523 * The open_code hook allows embedders to override the method used to
524 * open files that are going to be used by the runtime to execute code
525 */
526
527int
528PyFile_SetOpenCodeHook(Py_OpenCodeHookFunction hook, void *userData) {
529 if (Py_IsInitialized() &&
530 PySys_Audit("setopencodehook", NULL) < 0) {
531 return -1;
532 }
533
534 if (_PyRuntime.open_code_hook) {
535 if (Py_IsInitialized()) {
536 PyErr_SetString(PyExc_SystemError,
537 "failed to change existing open_code hook");
538 }
539 return -1;
540 }
541
542 _PyRuntime.open_code_hook = hook;
543 _PyRuntime.open_code_userdata = userData;
544 return 0;
545}
546
547PyObject *
548PyFile_OpenCodeObject(PyObject *path)
549{
550 PyObject *iomod, *f = NULL;
Steve Dowerb82e17e2019-05-23 08:45:22 -0700551
552 if (!PyUnicode_Check(path)) {
553 PyErr_Format(PyExc_TypeError, "'path' must be 'str', not '%.200s'",
554 Py_TYPE(path)->tp_name);
555 return NULL;
556 }
557
558 Py_OpenCodeHookFunction hook = _PyRuntime.open_code_hook;
559 if (hook) {
560 f = hook(path, _PyRuntime.open_code_userdata);
561 } else {
562 iomod = PyImport_ImportModule("_io");
563 if (iomod) {
564 f = _PyObject_CallMethodId(iomod, &PyId_open, "Os",
565 path, "rb");
566 Py_DECREF(iomod);
567 }
568 }
569
570 return f;
571}
572
573PyObject *
574PyFile_OpenCode(const char *utf8path)
575{
576 PyObject *pathobj = PyUnicode_FromString(utf8path);
577 PyObject *f;
578 if (!pathobj) {
579 return NULL;
580 }
581 f = PyFile_OpenCodeObject(pathobj);
582 Py_DECREF(pathobj);
583 return f;
584}
585
586
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000587#ifdef __cplusplus
588}
589#endif