fileobject.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. /* File object implementation (what's left of it -- see io.py) */
  2. #define PY_SSIZE_T_CLEAN
  3. #include "Python.h"
  4. #include "pycore_call.h" // _PyObject_CallNoArgs()
  5. #include "pycore_runtime.h" // _PyRuntime
  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. /* Newline flags */
  17. #define NEWLINE_UNKNOWN 0 /* No newline seen, yet */
  18. #define NEWLINE_CR 1 /* \r newline seen */
  19. #define NEWLINE_LF 2 /* \n newline seen */
  20. #define NEWLINE_CRLF 4 /* \r\n newline seen */
  21. #ifdef __cplusplus
  22. extern "C" {
  23. #endif
  24. /* External C interface */
  25. PyObject *
  26. PyFile_FromFd(int fd, const char *name, const char *mode, int buffering, const char *encoding,
  27. const char *errors, const char *newline, int closefd)
  28. {
  29. PyObject *open, *stream;
  30. /* import _io in case we are being used to open io.py */
  31. open = _PyImport_GetModuleAttrString("_io", "open");
  32. if (open == NULL)
  33. return NULL;
  34. stream = PyObject_CallFunction(open, "isisssO", fd, mode,
  35. buffering, encoding, errors,
  36. newline, closefd ? Py_True : Py_False);
  37. Py_DECREF(open);
  38. if (stream == NULL)
  39. return NULL;
  40. /* ignore name attribute because the name attribute of _BufferedIOMixin
  41. and TextIOWrapper is read only */
  42. return stream;
  43. }
  44. PyObject *
  45. PyFile_GetLine(PyObject *f, int n)
  46. {
  47. PyObject *result;
  48. if (f == NULL) {
  49. PyErr_BadInternalCall();
  50. return NULL;
  51. }
  52. if (n <= 0) {
  53. result = PyObject_CallMethodNoArgs(f, &_Py_ID(readline));
  54. }
  55. else {
  56. result = _PyObject_CallMethod(f, &_Py_ID(readline), "i", n);
  57. }
  58. if (result != NULL && !PyBytes_Check(result) &&
  59. !PyUnicode_Check(result)) {
  60. Py_SETREF(result, NULL);
  61. PyErr_SetString(PyExc_TypeError,
  62. "object.readline() returned non-string");
  63. }
  64. if (n < 0 && result != NULL && PyBytes_Check(result)) {
  65. const char *s = PyBytes_AS_STRING(result);
  66. Py_ssize_t len = PyBytes_GET_SIZE(result);
  67. if (len == 0) {
  68. Py_SETREF(result, NULL);
  69. PyErr_SetString(PyExc_EOFError,
  70. "EOF when reading a line");
  71. }
  72. else if (s[len-1] == '\n') {
  73. if (Py_REFCNT(result) == 1)
  74. _PyBytes_Resize(&result, len-1);
  75. else {
  76. PyObject *v;
  77. v = PyBytes_FromStringAndSize(s, len-1);
  78. Py_SETREF(result, v);
  79. }
  80. }
  81. }
  82. if (n < 0 && result != NULL && PyUnicode_Check(result)) {
  83. Py_ssize_t len = PyUnicode_GET_LENGTH(result);
  84. if (len == 0) {
  85. Py_SETREF(result, NULL);
  86. PyErr_SetString(PyExc_EOFError,
  87. "EOF when reading a line");
  88. }
  89. else if (PyUnicode_READ_CHAR(result, len-1) == '\n') {
  90. PyObject *v;
  91. v = PyUnicode_Substring(result, 0, len-1);
  92. Py_SETREF(result, v);
  93. }
  94. }
  95. return result;
  96. }
  97. /* Interfaces to write objects/strings to file-like objects */
  98. int
  99. PyFile_WriteObject(PyObject *v, PyObject *f, int flags)
  100. {
  101. PyObject *writer, *value, *result;
  102. if (f == NULL) {
  103. PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
  104. return -1;
  105. }
  106. writer = PyObject_GetAttr(f, &_Py_ID(write));
  107. if (writer == NULL)
  108. return -1;
  109. if (flags & Py_PRINT_RAW) {
  110. value = PyObject_Str(v);
  111. }
  112. else
  113. value = PyObject_Repr(v);
  114. if (value == NULL) {
  115. Py_DECREF(writer);
  116. return -1;
  117. }
  118. result = PyObject_CallOneArg(writer, value);
  119. Py_DECREF(value);
  120. Py_DECREF(writer);
  121. if (result == NULL)
  122. return -1;
  123. Py_DECREF(result);
  124. return 0;
  125. }
  126. int
  127. PyFile_WriteString(const char *s, PyObject *f)
  128. {
  129. if (f == NULL) {
  130. /* Should be caused by a pre-existing error */
  131. if (!PyErr_Occurred())
  132. PyErr_SetString(PyExc_SystemError,
  133. "null file for PyFile_WriteString");
  134. return -1;
  135. }
  136. else if (!PyErr_Occurred()) {
  137. PyObject *v = PyUnicode_FromString(s);
  138. int err;
  139. if (v == NULL)
  140. return -1;
  141. err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
  142. Py_DECREF(v);
  143. return err;
  144. }
  145. else
  146. return -1;
  147. }
  148. /* Try to get a file-descriptor from a Python object. If the object
  149. is an integer, its value is returned. If not, the
  150. object's fileno() method is called if it exists; the method must return
  151. an integer, which is returned as the file descriptor value.
  152. -1 is returned on failure.
  153. */
  154. int
  155. PyObject_AsFileDescriptor(PyObject *o)
  156. {
  157. int fd;
  158. PyObject *meth;
  159. if (PyLong_Check(o)) {
  160. fd = _PyLong_AsInt(o);
  161. }
  162. else if (_PyObject_LookupAttr(o, &_Py_ID(fileno), &meth) < 0) {
  163. return -1;
  164. }
  165. else if (meth != NULL) {
  166. PyObject *fno = _PyObject_CallNoArgs(meth);
  167. Py_DECREF(meth);
  168. if (fno == NULL)
  169. return -1;
  170. if (PyLong_Check(fno)) {
  171. fd = _PyLong_AsInt(fno);
  172. Py_DECREF(fno);
  173. }
  174. else {
  175. PyErr_SetString(PyExc_TypeError,
  176. "fileno() returned a non-integer");
  177. Py_DECREF(fno);
  178. return -1;
  179. }
  180. }
  181. else {
  182. PyErr_SetString(PyExc_TypeError,
  183. "argument must be an int, or have a fileno() method.");
  184. return -1;
  185. }
  186. if (fd == -1 && PyErr_Occurred())
  187. return -1;
  188. if (fd < 0) {
  189. PyErr_Format(PyExc_ValueError,
  190. "file descriptor cannot be a negative integer (%i)",
  191. fd);
  192. return -1;
  193. }
  194. return fd;
  195. }
  196. int
  197. _PyLong_FileDescriptor_Converter(PyObject *o, void *ptr)
  198. {
  199. int fd = PyObject_AsFileDescriptor(o);
  200. if (fd == -1) {
  201. return 0;
  202. }
  203. *(int *)ptr = fd;
  204. return 1;
  205. }
  206. char *
  207. _Py_UniversalNewlineFgetsWithSize(char *buf, int n, FILE *stream, PyObject *fobj, size_t* size)
  208. {
  209. char *p = buf;
  210. int c;
  211. if (fobj) {
  212. errno = ENXIO; /* What can you do... */
  213. return NULL;
  214. }
  215. FLOCKFILE(stream);
  216. while (--n > 0 && (c = GETC(stream)) != EOF ) {
  217. if (c == '\r') {
  218. // A \r is translated into a \n, and we skip an adjacent \n, if any.
  219. c = GETC(stream);
  220. if (c != '\n') {
  221. ungetc(c, stream);
  222. c = '\n';
  223. }
  224. }
  225. *p++ = c;
  226. if (c == '\n') {
  227. break;
  228. }
  229. }
  230. FUNLOCKFILE(stream);
  231. *p = '\0';
  232. if (p == buf) {
  233. return NULL;
  234. }
  235. *size = p - buf;
  236. return buf;
  237. }
  238. /*
  239. ** Py_UniversalNewlineFgets is an fgets variation that understands
  240. ** all of \r, \n and \r\n conventions.
  241. ** The stream should be opened in binary mode.
  242. ** The fobj parameter exists solely for legacy reasons and must be NULL.
  243. ** Note that we need no error handling: fgets() treats error and eof
  244. ** identically.
  245. */
  246. char *
  247. Py_UniversalNewlineFgets(char *buf, int n, FILE *stream, PyObject *fobj) {
  248. size_t size;
  249. return _Py_UniversalNewlineFgetsWithSize(buf, n, stream, fobj, &size);
  250. }
  251. /* **************************** std printer ****************************
  252. * The stdprinter is used during the boot strapping phase as a preliminary
  253. * file like object for sys.stderr.
  254. */
  255. typedef struct {
  256. PyObject_HEAD
  257. int fd;
  258. } PyStdPrinter_Object;
  259. PyObject *
  260. PyFile_NewStdPrinter(int fd)
  261. {
  262. PyStdPrinter_Object *self;
  263. if (fd != fileno(stdout) && fd != fileno(stderr)) {
  264. /* not enough infrastructure for PyErr_BadInternalCall() */
  265. return NULL;
  266. }
  267. self = PyObject_New(PyStdPrinter_Object,
  268. &PyStdPrinter_Type);
  269. if (self != NULL) {
  270. self->fd = fd;
  271. }
  272. return (PyObject*)self;
  273. }
  274. static PyObject *
  275. stdprinter_write(PyStdPrinter_Object *self, PyObject *args)
  276. {
  277. PyObject *unicode;
  278. PyObject *bytes = NULL;
  279. const char *str;
  280. Py_ssize_t n;
  281. int err;
  282. /* The function can clear the current exception */
  283. assert(!PyErr_Occurred());
  284. if (self->fd < 0) {
  285. /* fd might be invalid on Windows
  286. * I can't raise an exception here. It may lead to an
  287. * unlimited recursion in the case stderr is invalid.
  288. */
  289. Py_RETURN_NONE;
  290. }
  291. if (!PyArg_ParseTuple(args, "U", &unicode)) {
  292. return NULL;
  293. }
  294. /* Encode Unicode to UTF-8/backslashreplace */
  295. str = PyUnicode_AsUTF8AndSize(unicode, &n);
  296. if (str == NULL) {
  297. PyErr_Clear();
  298. bytes = _PyUnicode_AsUTF8String(unicode, "backslashreplace");
  299. if (bytes == NULL)
  300. return NULL;
  301. str = PyBytes_AS_STRING(bytes);
  302. n = PyBytes_GET_SIZE(bytes);
  303. }
  304. n = _Py_write(self->fd, str, n);
  305. /* save errno, it can be modified indirectly by Py_XDECREF() */
  306. err = errno;
  307. Py_XDECREF(bytes);
  308. if (n == -1) {
  309. if (err == EAGAIN) {
  310. PyErr_Clear();
  311. Py_RETURN_NONE;
  312. }
  313. return NULL;
  314. }
  315. return PyLong_FromSsize_t(n);
  316. }
  317. static PyObject *
  318. stdprinter_fileno(PyStdPrinter_Object *self, PyObject *Py_UNUSED(ignored))
  319. {
  320. return PyLong_FromLong((long) self->fd);
  321. }
  322. static PyObject *
  323. stdprinter_repr(PyStdPrinter_Object *self)
  324. {
  325. return PyUnicode_FromFormat("<stdprinter(fd=%d) object at %p>",
  326. self->fd, self);
  327. }
  328. static PyObject *
  329. stdprinter_noop(PyStdPrinter_Object *self, PyObject *Py_UNUSED(ignored))
  330. {
  331. Py_RETURN_NONE;
  332. }
  333. static PyObject *
  334. stdprinter_isatty(PyStdPrinter_Object *self, PyObject *Py_UNUSED(ignored))
  335. {
  336. long res;
  337. if (self->fd < 0) {
  338. Py_RETURN_FALSE;
  339. }
  340. Py_BEGIN_ALLOW_THREADS
  341. res = isatty(self->fd);
  342. Py_END_ALLOW_THREADS
  343. return PyBool_FromLong(res);
  344. }
  345. static PyMethodDef stdprinter_methods[] = {
  346. {"close", (PyCFunction)stdprinter_noop, METH_NOARGS, ""},
  347. {"flush", (PyCFunction)stdprinter_noop, METH_NOARGS, ""},
  348. {"fileno", (PyCFunction)stdprinter_fileno, METH_NOARGS, ""},
  349. {"isatty", (PyCFunction)stdprinter_isatty, METH_NOARGS, ""},
  350. {"write", (PyCFunction)stdprinter_write, METH_VARARGS, ""},
  351. {NULL, NULL} /*sentinel */
  352. };
  353. static PyObject *
  354. get_closed(PyStdPrinter_Object *self, void *closure)
  355. {
  356. Py_RETURN_FALSE;
  357. }
  358. static PyObject *
  359. get_mode(PyStdPrinter_Object *self, void *closure)
  360. {
  361. return PyUnicode_FromString("w");
  362. }
  363. static PyObject *
  364. get_encoding(PyStdPrinter_Object *self, void *closure)
  365. {
  366. Py_RETURN_NONE;
  367. }
  368. static PyGetSetDef stdprinter_getsetlist[] = {
  369. {"closed", (getter)get_closed, NULL, "True if the file is closed"},
  370. {"encoding", (getter)get_encoding, NULL, "Encoding of the file"},
  371. {"mode", (getter)get_mode, NULL, "String giving the file mode"},
  372. {0},
  373. };
  374. PyTypeObject PyStdPrinter_Type = {
  375. PyVarObject_HEAD_INIT(&PyType_Type, 0)
  376. "stderrprinter", /* tp_name */
  377. sizeof(PyStdPrinter_Object), /* tp_basicsize */
  378. 0, /* tp_itemsize */
  379. /* methods */
  380. 0, /* tp_dealloc */
  381. 0, /* tp_vectorcall_offset */
  382. 0, /* tp_getattr */
  383. 0, /* tp_setattr */
  384. 0, /* tp_as_async */
  385. (reprfunc)stdprinter_repr, /* tp_repr */
  386. 0, /* tp_as_number */
  387. 0, /* tp_as_sequence */
  388. 0, /* tp_as_mapping */
  389. 0, /* tp_hash */
  390. 0, /* tp_call */
  391. 0, /* tp_str */
  392. PyObject_GenericGetAttr, /* tp_getattro */
  393. 0, /* tp_setattro */
  394. 0, /* tp_as_buffer */
  395. Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, /* tp_flags */
  396. 0, /* tp_doc */
  397. 0, /* tp_traverse */
  398. 0, /* tp_clear */
  399. 0, /* tp_richcompare */
  400. 0, /* tp_weaklistoffset */
  401. 0, /* tp_iter */
  402. 0, /* tp_iternext */
  403. stdprinter_methods, /* tp_methods */
  404. 0, /* tp_members */
  405. stdprinter_getsetlist, /* tp_getset */
  406. 0, /* tp_base */
  407. 0, /* tp_dict */
  408. 0, /* tp_descr_get */
  409. 0, /* tp_descr_set */
  410. 0, /* tp_dictoffset */
  411. 0, /* tp_init */
  412. PyType_GenericAlloc, /* tp_alloc */
  413. 0, /* tp_new */
  414. PyObject_Del, /* tp_free */
  415. };
  416. /* ************************** open_code hook ***************************
  417. * The open_code hook allows embedders to override the method used to
  418. * open files that are going to be used by the runtime to execute code
  419. */
  420. int
  421. PyFile_SetOpenCodeHook(Py_OpenCodeHookFunction hook, void *userData) {
  422. if (Py_IsInitialized() &&
  423. PySys_Audit("setopencodehook", NULL) < 0) {
  424. return -1;
  425. }
  426. if (_PyRuntime.open_code_hook) {
  427. if (Py_IsInitialized()) {
  428. PyErr_SetString(PyExc_SystemError,
  429. "failed to change existing open_code hook");
  430. }
  431. return -1;
  432. }
  433. _PyRuntime.open_code_hook = hook;
  434. _PyRuntime.open_code_userdata = userData;
  435. return 0;
  436. }
  437. PyObject *
  438. PyFile_OpenCodeObject(PyObject *path)
  439. {
  440. PyObject *f = NULL;
  441. if (!PyUnicode_Check(path)) {
  442. PyErr_Format(PyExc_TypeError, "'path' must be 'str', not '%.200s'",
  443. Py_TYPE(path)->tp_name);
  444. return NULL;
  445. }
  446. Py_OpenCodeHookFunction hook = _PyRuntime.open_code_hook;
  447. if (hook) {
  448. f = hook(path, _PyRuntime.open_code_userdata);
  449. } else {
  450. PyObject *open = _PyImport_GetModuleAttrString("_io", "open");
  451. if (open) {
  452. f = PyObject_CallFunction(open, "Os", path, "rb");
  453. Py_DECREF(open);
  454. }
  455. }
  456. return f;
  457. }
  458. PyObject *
  459. PyFile_OpenCode(const char *utf8path)
  460. {
  461. PyObject *pathobj = PyUnicode_FromString(utf8path);
  462. PyObject *f;
  463. if (!pathobj) {
  464. return NULL;
  465. }
  466. f = PyFile_OpenCodeObject(pathobj);
  467. Py_DECREF(pathobj);
  468. return f;
  469. }
  470. #ifdef __cplusplus
  471. }
  472. #endif