fileio.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230
  1. /* Author: Daniel Stutzbach */
  2. #define PY_SSIZE_T_CLEAN
  3. #include "Python.h"
  4. #include "pycore_fileutils.h" // _Py_BEGIN_SUPPRESS_IPH
  5. #include "pycore_object.h" // _PyObject_GC_UNTRACK()
  6. #include "structmember.h" // PyMemberDef
  7. #include <stdbool.h>
  8. #ifdef HAVE_SYS_TYPES_H
  9. #include <sys/types.h>
  10. #endif
  11. #ifdef HAVE_SYS_STAT_H
  12. #include <sys/stat.h>
  13. #endif
  14. #ifdef HAVE_IO_H
  15. #include <io.h>
  16. #endif
  17. #ifdef HAVE_FCNTL_H
  18. #include <fcntl.h>
  19. #endif
  20. #include <stddef.h> /* For offsetof */
  21. #include "_iomodule.h"
  22. /*
  23. * Known likely problems:
  24. *
  25. * - Files larger then 2**32-1
  26. * - Files with unicode filenames
  27. * - Passing numbers greater than 2**32-1 when an integer is expected
  28. * - Making it work on Windows and other oddball platforms
  29. *
  30. * To Do:
  31. *
  32. * - autoconfify header file inclusion
  33. */
  34. #ifdef MS_WINDOWS
  35. /* can simulate truncate with Win32 API functions; see file_truncate */
  36. #define HAVE_FTRUNCATE
  37. #ifndef WIN32_LEAN_AND_MEAN
  38. #define WIN32_LEAN_AND_MEAN
  39. #endif
  40. #include <windows.h>
  41. #endif
  42. #if BUFSIZ < (8*1024)
  43. #define SMALLCHUNK (8*1024)
  44. #elif (BUFSIZ >= (2 << 25))
  45. #error "unreasonable BUFSIZ > 64 MiB defined"
  46. #else
  47. #define SMALLCHUNK BUFSIZ
  48. #endif
  49. /*[clinic input]
  50. module _io
  51. class _io.FileIO "fileio *" "clinic_state()->PyFileIO_Type"
  52. [clinic start generated code]*/
  53. /*[clinic end generated code: output=da39a3ee5e6b4b0d input=ac25ec278f4d6703]*/
  54. typedef struct {
  55. PyObject_HEAD
  56. int fd;
  57. unsigned int created : 1;
  58. unsigned int readable : 1;
  59. unsigned int writable : 1;
  60. unsigned int appending : 1;
  61. signed int seekable : 2; /* -1 means unknown */
  62. unsigned int closefd : 1;
  63. char finalizing;
  64. unsigned int blksize;
  65. PyObject *weakreflist;
  66. PyObject *dict;
  67. } fileio;
  68. #define PyFileIO_Check(state, op) (PyObject_TypeCheck((op), state->PyFileIO_Type))
  69. /* Forward declarations */
  70. static PyObject* portable_lseek(fileio *self, PyObject *posobj, int whence, bool suppress_pipe_error);
  71. int
  72. _PyFileIO_closed(PyObject *self)
  73. {
  74. return ((fileio *)self)->fd < 0;
  75. }
  76. /* Because this can call arbitrary code, it shouldn't be called when
  77. the refcount is 0 (that is, not directly from tp_dealloc unless
  78. the refcount has been temporarily re-incremented). */
  79. static PyObject *
  80. fileio_dealloc_warn(fileio *self, PyObject *source)
  81. {
  82. if (self->fd >= 0 && self->closefd) {
  83. PyObject *exc = PyErr_GetRaisedException();
  84. if (PyErr_ResourceWarning(source, 1, "unclosed file %R", source)) {
  85. /* Spurious errors can appear at shutdown */
  86. if (PyErr_ExceptionMatches(PyExc_Warning))
  87. PyErr_WriteUnraisable((PyObject *) self);
  88. }
  89. PyErr_SetRaisedException(exc);
  90. }
  91. Py_RETURN_NONE;
  92. }
  93. /* Returns 0 on success, -1 with exception set on failure. */
  94. static int
  95. internal_close(fileio *self)
  96. {
  97. int err = 0;
  98. int save_errno = 0;
  99. if (self->fd >= 0) {
  100. int fd = self->fd;
  101. self->fd = -1;
  102. /* fd is accessible and someone else may have closed it */
  103. Py_BEGIN_ALLOW_THREADS
  104. _Py_BEGIN_SUPPRESS_IPH
  105. err = close(fd);
  106. if (err < 0)
  107. save_errno = errno;
  108. _Py_END_SUPPRESS_IPH
  109. Py_END_ALLOW_THREADS
  110. }
  111. if (err < 0) {
  112. errno = save_errno;
  113. PyErr_SetFromErrno(PyExc_OSError);
  114. return -1;
  115. }
  116. return 0;
  117. }
  118. /*[clinic input]
  119. _io.FileIO.close
  120. cls: defining_class
  121. /
  122. Close the file.
  123. A closed file cannot be used for further I/O operations. close() may be
  124. called more than once without error.
  125. [clinic start generated code]*/
  126. static PyObject *
  127. _io_FileIO_close_impl(fileio *self, PyTypeObject *cls)
  128. /*[clinic end generated code: output=c30cbe9d1f23ca58 input=70da49e63db7c64d]*/
  129. {
  130. PyObject *res;
  131. int rc;
  132. _PyIO_State *state = get_io_state_by_cls(cls);
  133. res = PyObject_CallMethodOneArg((PyObject*)state->PyRawIOBase_Type,
  134. &_Py_ID(close), (PyObject *)self);
  135. if (!self->closefd) {
  136. self->fd = -1;
  137. return res;
  138. }
  139. PyObject *exc = NULL;
  140. if (res == NULL) {
  141. exc = PyErr_GetRaisedException();
  142. }
  143. if (self->finalizing) {
  144. PyObject *r = fileio_dealloc_warn(self, (PyObject *) self);
  145. if (r) {
  146. Py_DECREF(r);
  147. }
  148. else {
  149. PyErr_Clear();
  150. }
  151. }
  152. rc = internal_close(self);
  153. if (res == NULL) {
  154. _PyErr_ChainExceptions1(exc);
  155. }
  156. if (rc < 0) {
  157. Py_CLEAR(res);
  158. }
  159. return res;
  160. }
  161. static PyObject *
  162. fileio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
  163. {
  164. fileio *self;
  165. assert(type != NULL && type->tp_alloc != NULL);
  166. self = (fileio *) type->tp_alloc(type, 0);
  167. if (self != NULL) {
  168. self->fd = -1;
  169. self->created = 0;
  170. self->readable = 0;
  171. self->writable = 0;
  172. self->appending = 0;
  173. self->seekable = -1;
  174. self->blksize = 0;
  175. self->closefd = 1;
  176. self->weakreflist = NULL;
  177. }
  178. return (PyObject *) self;
  179. }
  180. #ifdef O_CLOEXEC
  181. extern int _Py_open_cloexec_works;
  182. #endif
  183. /*[clinic input]
  184. _io.FileIO.__init__
  185. file as nameobj: object
  186. mode: str = "r"
  187. closefd: bool = True
  188. opener: object = None
  189. Open a file.
  190. The mode can be 'r' (default), 'w', 'x' or 'a' for reading,
  191. writing, exclusive creation or appending. The file will be created if it
  192. doesn't exist when opened for writing or appending; it will be truncated
  193. when opened for writing. A FileExistsError will be raised if it already
  194. exists when opened for creating. Opening a file for creating implies
  195. writing so this mode behaves in a similar way to 'w'.Add a '+' to the mode
  196. to allow simultaneous reading and writing. A custom opener can be used by
  197. passing a callable as *opener*. The underlying file descriptor for the file
  198. object is then obtained by calling opener with (*name*, *flags*).
  199. *opener* must return an open file descriptor (passing os.open as *opener*
  200. results in functionality similar to passing None).
  201. [clinic start generated code]*/
  202. static int
  203. _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode,
  204. int closefd, PyObject *opener)
  205. /*[clinic end generated code: output=23413f68e6484bbd input=588aac967e0ba74b]*/
  206. {
  207. #ifdef MS_WINDOWS
  208. Py_UNICODE *widename = NULL;
  209. #else
  210. const char *name = NULL;
  211. #endif
  212. PyObject *stringobj = NULL;
  213. const char *s;
  214. int ret = 0;
  215. int rwa = 0, plus = 0;
  216. int flags = 0;
  217. int fd = -1;
  218. int fd_is_own = 0;
  219. #ifdef O_CLOEXEC
  220. int *atomic_flag_works = &_Py_open_cloexec_works;
  221. #elif !defined(MS_WINDOWS)
  222. int *atomic_flag_works = NULL;
  223. #endif
  224. struct _Py_stat_struct fdfstat;
  225. int fstat_result;
  226. int async_err = 0;
  227. #ifdef Py_DEBUG
  228. _PyIO_State *state = find_io_state_by_def(Py_TYPE(self));
  229. assert(PyFileIO_Check(state, self));
  230. #endif
  231. if (self->fd >= 0) {
  232. if (self->closefd) {
  233. /* Have to close the existing file first. */
  234. if (internal_close(self) < 0)
  235. return -1;
  236. }
  237. else
  238. self->fd = -1;
  239. }
  240. fd = _PyLong_AsInt(nameobj);
  241. if (fd < 0) {
  242. if (!PyErr_Occurred()) {
  243. PyErr_SetString(PyExc_ValueError,
  244. "negative file descriptor");
  245. return -1;
  246. }
  247. PyErr_Clear();
  248. }
  249. if (fd < 0) {
  250. #ifdef MS_WINDOWS
  251. if (!PyUnicode_FSDecoder(nameobj, &stringobj)) {
  252. return -1;
  253. }
  254. widename = PyUnicode_AsWideCharString(stringobj, NULL);
  255. if (widename == NULL)
  256. return -1;
  257. #else
  258. if (!PyUnicode_FSConverter(nameobj, &stringobj)) {
  259. return -1;
  260. }
  261. name = PyBytes_AS_STRING(stringobj);
  262. #endif
  263. }
  264. s = mode;
  265. while (*s) {
  266. switch (*s++) {
  267. case 'x':
  268. if (rwa) {
  269. bad_mode:
  270. PyErr_SetString(PyExc_ValueError,
  271. "Must have exactly one of create/read/write/append "
  272. "mode and at most one plus");
  273. goto error;
  274. }
  275. rwa = 1;
  276. self->created = 1;
  277. self->writable = 1;
  278. flags |= O_EXCL | O_CREAT;
  279. break;
  280. case 'r':
  281. if (rwa)
  282. goto bad_mode;
  283. rwa = 1;
  284. self->readable = 1;
  285. break;
  286. case 'w':
  287. if (rwa)
  288. goto bad_mode;
  289. rwa = 1;
  290. self->writable = 1;
  291. flags |= O_CREAT | O_TRUNC;
  292. break;
  293. case 'a':
  294. if (rwa)
  295. goto bad_mode;
  296. rwa = 1;
  297. self->writable = 1;
  298. self->appending = 1;
  299. flags |= O_APPEND | O_CREAT;
  300. break;
  301. case 'b':
  302. break;
  303. case '+':
  304. if (plus)
  305. goto bad_mode;
  306. self->readable = self->writable = 1;
  307. plus = 1;
  308. break;
  309. default:
  310. PyErr_Format(PyExc_ValueError,
  311. "invalid mode: %.200s", mode);
  312. goto error;
  313. }
  314. }
  315. if (!rwa)
  316. goto bad_mode;
  317. if (self->readable && self->writable)
  318. flags |= O_RDWR;
  319. else if (self->readable)
  320. flags |= O_RDONLY;
  321. else
  322. flags |= O_WRONLY;
  323. #ifdef O_BINARY
  324. flags |= O_BINARY;
  325. #endif
  326. #ifdef MS_WINDOWS
  327. flags |= O_NOINHERIT;
  328. #elif defined(O_CLOEXEC)
  329. flags |= O_CLOEXEC;
  330. #endif
  331. if (PySys_Audit("open", "Osi", nameobj, mode, flags) < 0) {
  332. goto error;
  333. }
  334. if (fd >= 0) {
  335. self->fd = fd;
  336. self->closefd = closefd;
  337. }
  338. else {
  339. self->closefd = 1;
  340. if (!closefd) {
  341. PyErr_SetString(PyExc_ValueError,
  342. "Cannot use closefd=False with file name");
  343. goto error;
  344. }
  345. errno = 0;
  346. if (opener == Py_None) {
  347. do {
  348. Py_BEGIN_ALLOW_THREADS
  349. #ifdef MS_WINDOWS
  350. self->fd = _wopen(widename, flags, 0666);
  351. #else
  352. self->fd = open(name, flags, 0666);
  353. #endif
  354. Py_END_ALLOW_THREADS
  355. } while (self->fd < 0 && errno == EINTR &&
  356. !(async_err = PyErr_CheckSignals()));
  357. if (async_err)
  358. goto error;
  359. if (self->fd < 0) {
  360. PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj);
  361. goto error;
  362. }
  363. }
  364. else {
  365. PyObject *fdobj;
  366. #ifndef MS_WINDOWS
  367. /* the opener may clear the atomic flag */
  368. atomic_flag_works = NULL;
  369. #endif
  370. fdobj = PyObject_CallFunction(opener, "Oi", nameobj, flags);
  371. if (fdobj == NULL)
  372. goto error;
  373. if (!PyLong_Check(fdobj)) {
  374. Py_DECREF(fdobj);
  375. PyErr_SetString(PyExc_TypeError,
  376. "expected integer from opener");
  377. goto error;
  378. }
  379. self->fd = _PyLong_AsInt(fdobj);
  380. Py_DECREF(fdobj);
  381. if (self->fd < 0) {
  382. if (!PyErr_Occurred()) {
  383. /* The opener returned a negative but didn't set an
  384. exception. See issue #27066 */
  385. PyErr_Format(PyExc_ValueError,
  386. "opener returned %d", self->fd);
  387. }
  388. goto error;
  389. }
  390. }
  391. fd_is_own = 1;
  392. #ifndef MS_WINDOWS
  393. if (_Py_set_inheritable(self->fd, 0, atomic_flag_works) < 0)
  394. goto error;
  395. #endif
  396. }
  397. self->blksize = DEFAULT_BUFFER_SIZE;
  398. Py_BEGIN_ALLOW_THREADS
  399. fstat_result = _Py_fstat_noraise(self->fd, &fdfstat);
  400. Py_END_ALLOW_THREADS
  401. if (fstat_result < 0) {
  402. /* Tolerate fstat() errors other than EBADF. See Issue #25717, where
  403. an anonymous file on a Virtual Box shared folder filesystem would
  404. raise ENOENT. */
  405. #ifdef MS_WINDOWS
  406. if (GetLastError() == ERROR_INVALID_HANDLE) {
  407. PyErr_SetFromWindowsErr(0);
  408. #else
  409. if (errno == EBADF) {
  410. PyErr_SetFromErrno(PyExc_OSError);
  411. #endif
  412. goto error;
  413. }
  414. }
  415. else {
  416. #if defined(S_ISDIR) && defined(EISDIR)
  417. /* On Unix, open will succeed for directories.
  418. In Python, there should be no file objects referring to
  419. directories, so we need a check. */
  420. if (S_ISDIR(fdfstat.st_mode)) {
  421. errno = EISDIR;
  422. PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj);
  423. goto error;
  424. }
  425. #endif /* defined(S_ISDIR) */
  426. #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
  427. if (fdfstat.st_blksize > 1)
  428. self->blksize = fdfstat.st_blksize;
  429. #endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
  430. }
  431. #if defined(MS_WINDOWS) || defined(__CYGWIN__)
  432. /* don't translate newlines (\r\n <=> \n) */
  433. _setmode(self->fd, O_BINARY);
  434. #endif
  435. if (PyObject_SetAttr((PyObject *)self, &_Py_ID(name), nameobj) < 0)
  436. goto error;
  437. if (self->appending) {
  438. /* For consistent behaviour, we explicitly seek to the
  439. end of file (otherwise, it might be done only on the
  440. first write()). */
  441. PyObject *pos = portable_lseek(self, NULL, 2, true);
  442. if (pos == NULL)
  443. goto error;
  444. Py_DECREF(pos);
  445. }
  446. goto done;
  447. error:
  448. ret = -1;
  449. if (!fd_is_own)
  450. self->fd = -1;
  451. if (self->fd >= 0) {
  452. PyObject *exc = PyErr_GetRaisedException();
  453. internal_close(self);
  454. _PyErr_ChainExceptions1(exc);
  455. }
  456. done:
  457. #ifdef MS_WINDOWS
  458. PyMem_Free(widename);
  459. #endif
  460. Py_CLEAR(stringobj);
  461. return ret;
  462. }
  463. static int
  464. fileio_traverse(fileio *self, visitproc visit, void *arg)
  465. {
  466. Py_VISIT(Py_TYPE(self));
  467. Py_VISIT(self->dict);
  468. return 0;
  469. }
  470. static int
  471. fileio_clear(fileio *self)
  472. {
  473. Py_CLEAR(self->dict);
  474. return 0;
  475. }
  476. static void
  477. fileio_dealloc(fileio *self)
  478. {
  479. PyTypeObject *tp = Py_TYPE(self);
  480. self->finalizing = 1;
  481. if (_PyIOBase_finalize((PyObject *) self) < 0)
  482. return;
  483. _PyObject_GC_UNTRACK(self);
  484. if (self->weakreflist != NULL)
  485. PyObject_ClearWeakRefs((PyObject *) self);
  486. (void)fileio_clear(self);
  487. tp->tp_free((PyObject *)self);
  488. Py_DECREF(tp);
  489. }
  490. static PyObject *
  491. err_closed(void)
  492. {
  493. PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
  494. return NULL;
  495. }
  496. static PyObject *
  497. err_mode(_PyIO_State *state, const char *action)
  498. {
  499. return PyErr_Format(state->unsupported_operation,
  500. "File not open for %s", action);
  501. }
  502. /*[clinic input]
  503. _io.FileIO.fileno
  504. Return the underlying file descriptor (an integer).
  505. [clinic start generated code]*/
  506. static PyObject *
  507. _io_FileIO_fileno_impl(fileio *self)
  508. /*[clinic end generated code: output=a9626ce5398ece90 input=0b9b2de67335ada3]*/
  509. {
  510. if (self->fd < 0)
  511. return err_closed();
  512. return PyLong_FromLong((long) self->fd);
  513. }
  514. /*[clinic input]
  515. _io.FileIO.readable
  516. True if file was opened in a read mode.
  517. [clinic start generated code]*/
  518. static PyObject *
  519. _io_FileIO_readable_impl(fileio *self)
  520. /*[clinic end generated code: output=640744a6150fe9ba input=a3fdfed6eea721c5]*/
  521. {
  522. if (self->fd < 0)
  523. return err_closed();
  524. return PyBool_FromLong((long) self->readable);
  525. }
  526. /*[clinic input]
  527. _io.FileIO.writable
  528. True if file was opened in a write mode.
  529. [clinic start generated code]*/
  530. static PyObject *
  531. _io_FileIO_writable_impl(fileio *self)
  532. /*[clinic end generated code: output=96cefc5446e89977 input=c204a808ca2e1748]*/
  533. {
  534. if (self->fd < 0)
  535. return err_closed();
  536. return PyBool_FromLong((long) self->writable);
  537. }
  538. /*[clinic input]
  539. _io.FileIO.seekable
  540. True if file supports random-access.
  541. [clinic start generated code]*/
  542. static PyObject *
  543. _io_FileIO_seekable_impl(fileio *self)
  544. /*[clinic end generated code: output=47909ca0a42e9287 input=c8e5554d2fd63c7f]*/
  545. {
  546. if (self->fd < 0)
  547. return err_closed();
  548. if (self->seekable < 0) {
  549. /* portable_lseek() sets the seekable attribute */
  550. PyObject *pos = portable_lseek(self, NULL, SEEK_CUR, false);
  551. assert(self->seekable >= 0);
  552. if (pos == NULL) {
  553. PyErr_Clear();
  554. }
  555. else {
  556. Py_DECREF(pos);
  557. }
  558. }
  559. return PyBool_FromLong((long) self->seekable);
  560. }
  561. /*[clinic input]
  562. _io.FileIO.readinto
  563. cls: defining_class
  564. buffer: Py_buffer(accept={rwbuffer})
  565. /
  566. Same as RawIOBase.readinto().
  567. [clinic start generated code]*/
  568. static PyObject *
  569. _io_FileIO_readinto_impl(fileio *self, PyTypeObject *cls, Py_buffer *buffer)
  570. /*[clinic end generated code: output=97f0f3d69534db34 input=fd20323e18ce1ec8]*/
  571. {
  572. Py_ssize_t n;
  573. int err;
  574. if (self->fd < 0)
  575. return err_closed();
  576. if (!self->readable) {
  577. _PyIO_State *state = get_io_state_by_cls(cls);
  578. return err_mode(state, "reading");
  579. }
  580. n = _Py_read(self->fd, buffer->buf, buffer->len);
  581. /* copy errno because PyBuffer_Release() can indirectly modify it */
  582. err = errno;
  583. if (n == -1) {
  584. if (err == EAGAIN) {
  585. PyErr_Clear();
  586. Py_RETURN_NONE;
  587. }
  588. return NULL;
  589. }
  590. return PyLong_FromSsize_t(n);
  591. }
  592. static size_t
  593. new_buffersize(fileio *self, size_t currentsize)
  594. {
  595. size_t addend;
  596. /* Expand the buffer by an amount proportional to the current size,
  597. giving us amortized linear-time behavior. For bigger sizes, use a
  598. less-than-double growth factor to avoid excessive allocation. */
  599. assert(currentsize <= PY_SSIZE_T_MAX);
  600. if (currentsize > 65536)
  601. addend = currentsize >> 3;
  602. else
  603. addend = 256 + currentsize;
  604. if (addend < SMALLCHUNK)
  605. /* Avoid tiny read() calls. */
  606. addend = SMALLCHUNK;
  607. return addend + currentsize;
  608. }
  609. /*[clinic input]
  610. _io.FileIO.readall
  611. Read all data from the file, returned as bytes.
  612. In non-blocking mode, returns as much as is immediately available,
  613. or None if no data is available. Return an empty bytes object at EOF.
  614. [clinic start generated code]*/
  615. static PyObject *
  616. _io_FileIO_readall_impl(fileio *self)
  617. /*[clinic end generated code: output=faa0292b213b4022 input=dbdc137f55602834]*/
  618. {
  619. struct _Py_stat_struct status;
  620. Py_off_t pos, end;
  621. PyObject *result;
  622. Py_ssize_t bytes_read = 0;
  623. Py_ssize_t n;
  624. size_t bufsize;
  625. int fstat_result;
  626. if (self->fd < 0)
  627. return err_closed();
  628. Py_BEGIN_ALLOW_THREADS
  629. _Py_BEGIN_SUPPRESS_IPH
  630. #ifdef MS_WINDOWS
  631. pos = _lseeki64(self->fd, 0L, SEEK_CUR);
  632. #else
  633. pos = lseek(self->fd, 0L, SEEK_CUR);
  634. #endif
  635. _Py_END_SUPPRESS_IPH
  636. fstat_result = _Py_fstat_noraise(self->fd, &status);
  637. Py_END_ALLOW_THREADS
  638. if (fstat_result == 0)
  639. end = status.st_size;
  640. else
  641. end = (Py_off_t)-1;
  642. if (end > 0 && end >= pos && pos >= 0 && end - pos < PY_SSIZE_T_MAX) {
  643. /* This is probably a real file, so we try to allocate a
  644. buffer one byte larger than the rest of the file. If the
  645. calculation is right then we should get EOF without having
  646. to enlarge the buffer. */
  647. bufsize = (size_t)(end - pos + 1);
  648. } else {
  649. bufsize = SMALLCHUNK;
  650. }
  651. result = PyBytes_FromStringAndSize(NULL, bufsize);
  652. if (result == NULL)
  653. return NULL;
  654. while (1) {
  655. if (bytes_read >= (Py_ssize_t)bufsize) {
  656. bufsize = new_buffersize(self, bytes_read);
  657. if (bufsize > PY_SSIZE_T_MAX || bufsize <= 0) {
  658. PyErr_SetString(PyExc_OverflowError,
  659. "unbounded read returned more bytes "
  660. "than a Python bytes object can hold");
  661. Py_DECREF(result);
  662. return NULL;
  663. }
  664. if (PyBytes_GET_SIZE(result) < (Py_ssize_t)bufsize) {
  665. if (_PyBytes_Resize(&result, bufsize) < 0)
  666. return NULL;
  667. }
  668. }
  669. n = _Py_read(self->fd,
  670. PyBytes_AS_STRING(result) + bytes_read,
  671. bufsize - bytes_read);
  672. if (n == 0)
  673. break;
  674. if (n == -1) {
  675. if (errno == EAGAIN) {
  676. PyErr_Clear();
  677. if (bytes_read > 0)
  678. break;
  679. Py_DECREF(result);
  680. Py_RETURN_NONE;
  681. }
  682. Py_DECREF(result);
  683. return NULL;
  684. }
  685. bytes_read += n;
  686. pos += n;
  687. }
  688. if (PyBytes_GET_SIZE(result) > bytes_read) {
  689. if (_PyBytes_Resize(&result, bytes_read) < 0)
  690. return NULL;
  691. }
  692. return result;
  693. }
  694. /*[clinic input]
  695. _io.FileIO.read
  696. cls: defining_class
  697. size: Py_ssize_t(accept={int, NoneType}) = -1
  698. /
  699. Read at most size bytes, returned as bytes.
  700. Only makes one system call, so less data may be returned than requested.
  701. In non-blocking mode, returns None if no data is available.
  702. Return an empty bytes object at EOF.
  703. [clinic start generated code]*/
  704. static PyObject *
  705. _io_FileIO_read_impl(fileio *self, PyTypeObject *cls, Py_ssize_t size)
  706. /*[clinic end generated code: output=bbd749c7c224143e input=f613d2057e4a1918]*/
  707. {
  708. char *ptr;
  709. Py_ssize_t n;
  710. PyObject *bytes;
  711. if (self->fd < 0)
  712. return err_closed();
  713. if (!self->readable) {
  714. _PyIO_State *state = get_io_state_by_cls(cls);
  715. return err_mode(state, "reading");
  716. }
  717. if (size < 0)
  718. return _io_FileIO_readall_impl(self);
  719. if (size > _PY_READ_MAX) {
  720. size = _PY_READ_MAX;
  721. }
  722. bytes = PyBytes_FromStringAndSize(NULL, size);
  723. if (bytes == NULL)
  724. return NULL;
  725. ptr = PyBytes_AS_STRING(bytes);
  726. n = _Py_read(self->fd, ptr, size);
  727. if (n == -1) {
  728. /* copy errno because Py_DECREF() can indirectly modify it */
  729. int err = errno;
  730. Py_DECREF(bytes);
  731. if (err == EAGAIN) {
  732. PyErr_Clear();
  733. Py_RETURN_NONE;
  734. }
  735. return NULL;
  736. }
  737. if (n != size) {
  738. if (_PyBytes_Resize(&bytes, n) < 0) {
  739. Py_CLEAR(bytes);
  740. return NULL;
  741. }
  742. }
  743. return (PyObject *) bytes;
  744. }
  745. /*[clinic input]
  746. _io.FileIO.write
  747. cls: defining_class
  748. b: Py_buffer
  749. /
  750. Write buffer b to file, return number of bytes written.
  751. Only makes one system call, so not all of the data may be written.
  752. The number of bytes actually written is returned. In non-blocking mode,
  753. returns None if the write would block.
  754. [clinic start generated code]*/
  755. static PyObject *
  756. _io_FileIO_write_impl(fileio *self, PyTypeObject *cls, Py_buffer *b)
  757. /*[clinic end generated code: output=927e25be80f3b77b input=2776314f043088f5]*/
  758. {
  759. Py_ssize_t n;
  760. int err;
  761. if (self->fd < 0)
  762. return err_closed();
  763. if (!self->writable) {
  764. _PyIO_State *state = get_io_state_by_cls(cls);
  765. return err_mode(state, "writing");
  766. }
  767. n = _Py_write(self->fd, b->buf, b->len);
  768. /* copy errno because PyBuffer_Release() can indirectly modify it */
  769. err = errno;
  770. if (n < 0) {
  771. if (err == EAGAIN) {
  772. PyErr_Clear();
  773. Py_RETURN_NONE;
  774. }
  775. return NULL;
  776. }
  777. return PyLong_FromSsize_t(n);
  778. }
  779. /* XXX Windows support below is likely incomplete */
  780. /* Cribbed from posix_lseek() */
  781. static PyObject *
  782. portable_lseek(fileio *self, PyObject *posobj, int whence, bool suppress_pipe_error)
  783. {
  784. Py_off_t pos, res;
  785. int fd = self->fd;
  786. #ifdef SEEK_SET
  787. /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
  788. switch (whence) {
  789. #if SEEK_SET != 0
  790. case 0: whence = SEEK_SET; break;
  791. #endif
  792. #if SEEK_CUR != 1
  793. case 1: whence = SEEK_CUR; break;
  794. #endif
  795. #if SEEK_END != 2
  796. case 2: whence = SEEK_END; break;
  797. #endif
  798. }
  799. #endif /* SEEK_SET */
  800. if (posobj == NULL) {
  801. pos = 0;
  802. }
  803. else {
  804. #if defined(HAVE_LARGEFILE_SUPPORT)
  805. pos = PyLong_AsLongLong(posobj);
  806. #else
  807. pos = PyLong_AsLong(posobj);
  808. #endif
  809. if (PyErr_Occurred())
  810. return NULL;
  811. }
  812. Py_BEGIN_ALLOW_THREADS
  813. _Py_BEGIN_SUPPRESS_IPH
  814. #ifdef MS_WINDOWS
  815. res = _lseeki64(fd, pos, whence);
  816. #else
  817. res = lseek(fd, pos, whence);
  818. #endif
  819. _Py_END_SUPPRESS_IPH
  820. Py_END_ALLOW_THREADS
  821. if (self->seekable < 0) {
  822. self->seekable = (res >= 0);
  823. }
  824. if (res < 0) {
  825. if (suppress_pipe_error && errno == ESPIPE) {
  826. res = 0;
  827. } else {
  828. return PyErr_SetFromErrno(PyExc_OSError);
  829. }
  830. }
  831. #if defined(HAVE_LARGEFILE_SUPPORT)
  832. return PyLong_FromLongLong(res);
  833. #else
  834. return PyLong_FromLong(res);
  835. #endif
  836. }
  837. /*[clinic input]
  838. _io.FileIO.seek
  839. pos: object
  840. whence: int = 0
  841. /
  842. Move to new file position and return the file position.
  843. Argument offset is a byte count. Optional argument whence defaults to
  844. SEEK_SET or 0 (offset from start of file, offset should be >= 0); other values
  845. are SEEK_CUR or 1 (move relative to current position, positive or negative),
  846. and SEEK_END or 2 (move relative to end of file, usually negative, although
  847. many platforms allow seeking beyond the end of a file).
  848. Note that not all file objects are seekable.
  849. [clinic start generated code]*/
  850. static PyObject *
  851. _io_FileIO_seek_impl(fileio *self, PyObject *pos, int whence)
  852. /*[clinic end generated code: output=c976acdf054e6655 input=0439194b0774d454]*/
  853. {
  854. if (self->fd < 0)
  855. return err_closed();
  856. return portable_lseek(self, pos, whence, false);
  857. }
  858. /*[clinic input]
  859. _io.FileIO.tell
  860. Current file position.
  861. Can raise OSError for non seekable files.
  862. [clinic start generated code]*/
  863. static PyObject *
  864. _io_FileIO_tell_impl(fileio *self)
  865. /*[clinic end generated code: output=ffe2147058809d0b input=807e24ead4cec2f9]*/
  866. {
  867. if (self->fd < 0)
  868. return err_closed();
  869. return portable_lseek(self, NULL, 1, false);
  870. }
  871. #ifdef HAVE_FTRUNCATE
  872. /*[clinic input]
  873. _io.FileIO.truncate
  874. cls: defining_class
  875. size as posobj: object = None
  876. /
  877. Truncate the file to at most size bytes and return the truncated size.
  878. Size defaults to the current file position, as returned by tell().
  879. The current file position is changed to the value of size.
  880. [clinic start generated code]*/
  881. static PyObject *
  882. _io_FileIO_truncate_impl(fileio *self, PyTypeObject *cls, PyObject *posobj)
  883. /*[clinic end generated code: output=d936732a49e8d5a2 input=c367fb45d6bb2c18]*/
  884. {
  885. Py_off_t pos;
  886. int ret;
  887. int fd;
  888. fd = self->fd;
  889. if (fd < 0)
  890. return err_closed();
  891. if (!self->writable) {
  892. _PyIO_State *state = get_io_state_by_cls(cls);
  893. return err_mode(state, "writing");
  894. }
  895. if (posobj == Py_None) {
  896. /* Get the current position. */
  897. posobj = portable_lseek(self, NULL, 1, false);
  898. if (posobj == NULL)
  899. return NULL;
  900. }
  901. else {
  902. Py_INCREF(posobj);
  903. }
  904. #if defined(HAVE_LARGEFILE_SUPPORT)
  905. pos = PyLong_AsLongLong(posobj);
  906. #else
  907. pos = PyLong_AsLong(posobj);
  908. #endif
  909. if (PyErr_Occurred()){
  910. Py_DECREF(posobj);
  911. return NULL;
  912. }
  913. Py_BEGIN_ALLOW_THREADS
  914. _Py_BEGIN_SUPPRESS_IPH
  915. errno = 0;
  916. #ifdef MS_WINDOWS
  917. ret = _chsize_s(fd, pos);
  918. #else
  919. ret = ftruncate(fd, pos);
  920. #endif
  921. _Py_END_SUPPRESS_IPH
  922. Py_END_ALLOW_THREADS
  923. if (ret != 0) {
  924. PyErr_SetFromErrno(PyExc_OSError);
  925. Py_DECREF(posobj);
  926. return NULL;
  927. }
  928. return posobj;
  929. }
  930. #endif /* HAVE_FTRUNCATE */
  931. static const char *
  932. mode_string(fileio *self)
  933. {
  934. if (self->created) {
  935. if (self->readable)
  936. return "xb+";
  937. else
  938. return "xb";
  939. }
  940. if (self->appending) {
  941. if (self->readable)
  942. return "ab+";
  943. else
  944. return "ab";
  945. }
  946. else if (self->readable) {
  947. if (self->writable)
  948. return "rb+";
  949. else
  950. return "rb";
  951. }
  952. else
  953. return "wb";
  954. }
  955. static PyObject *
  956. fileio_repr(fileio *self)
  957. {
  958. PyObject *nameobj, *res;
  959. if (self->fd < 0)
  960. return PyUnicode_FromFormat("<_io.FileIO [closed]>");
  961. if (_PyObject_LookupAttr((PyObject *) self, &_Py_ID(name), &nameobj) < 0) {
  962. return NULL;
  963. }
  964. if (nameobj == NULL) {
  965. res = PyUnicode_FromFormat(
  966. "<_io.FileIO fd=%d mode='%s' closefd=%s>",
  967. self->fd, mode_string(self), self->closefd ? "True" : "False");
  968. }
  969. else {
  970. int status = Py_ReprEnter((PyObject *)self);
  971. res = NULL;
  972. if (status == 0) {
  973. res = PyUnicode_FromFormat(
  974. "<_io.FileIO name=%R mode='%s' closefd=%s>",
  975. nameobj, mode_string(self), self->closefd ? "True" : "False");
  976. Py_ReprLeave((PyObject *)self);
  977. }
  978. else if (status > 0) {
  979. PyErr_Format(PyExc_RuntimeError,
  980. "reentrant call inside %s.__repr__",
  981. Py_TYPE(self)->tp_name);
  982. }
  983. Py_DECREF(nameobj);
  984. }
  985. return res;
  986. }
  987. /*[clinic input]
  988. _io.FileIO.isatty
  989. True if the file is connected to a TTY device.
  990. [clinic start generated code]*/
  991. static PyObject *
  992. _io_FileIO_isatty_impl(fileio *self)
  993. /*[clinic end generated code: output=932c39924e9a8070 input=cd94ca1f5e95e843]*/
  994. {
  995. long res;
  996. if (self->fd < 0)
  997. return err_closed();
  998. Py_BEGIN_ALLOW_THREADS
  999. _Py_BEGIN_SUPPRESS_IPH
  1000. res = isatty(self->fd);
  1001. _Py_END_SUPPRESS_IPH
  1002. Py_END_ALLOW_THREADS
  1003. return PyBool_FromLong(res);
  1004. }
  1005. #include "clinic/fileio.c.h"
  1006. static PyMethodDef fileio_methods[] = {
  1007. _IO_FILEIO_READ_METHODDEF
  1008. _IO_FILEIO_READALL_METHODDEF
  1009. _IO_FILEIO_READINTO_METHODDEF
  1010. _IO_FILEIO_WRITE_METHODDEF
  1011. _IO_FILEIO_SEEK_METHODDEF
  1012. _IO_FILEIO_TELL_METHODDEF
  1013. _IO_FILEIO_TRUNCATE_METHODDEF
  1014. _IO_FILEIO_CLOSE_METHODDEF
  1015. _IO_FILEIO_SEEKABLE_METHODDEF
  1016. _IO_FILEIO_READABLE_METHODDEF
  1017. _IO_FILEIO_WRITABLE_METHODDEF
  1018. _IO_FILEIO_FILENO_METHODDEF
  1019. _IO_FILEIO_ISATTY_METHODDEF
  1020. {"_dealloc_warn", (PyCFunction)fileio_dealloc_warn, METH_O, NULL},
  1021. {"__reduce__", _PyIOBase_cannot_pickle, METH_VARARGS},
  1022. {"__reduce_ex__", _PyIOBase_cannot_pickle, METH_VARARGS},
  1023. {NULL, NULL} /* sentinel */
  1024. };
  1025. /* 'closed' and 'mode' are attributes for backwards compatibility reasons. */
  1026. static PyObject *
  1027. get_closed(fileio *self, void *closure)
  1028. {
  1029. return PyBool_FromLong((long)(self->fd < 0));
  1030. }
  1031. static PyObject *
  1032. get_closefd(fileio *self, void *closure)
  1033. {
  1034. return PyBool_FromLong((long)(self->closefd));
  1035. }
  1036. static PyObject *
  1037. get_mode(fileio *self, void *closure)
  1038. {
  1039. return PyUnicode_FromString(mode_string(self));
  1040. }
  1041. static PyGetSetDef fileio_getsetlist[] = {
  1042. {"closed", (getter)get_closed, NULL, "True if the file is closed"},
  1043. {"closefd", (getter)get_closefd, NULL,
  1044. "True if the file descriptor will be closed by close()."},
  1045. {"mode", (getter)get_mode, NULL, "String giving the file mode"},
  1046. {NULL},
  1047. };
  1048. static PyMemberDef fileio_members[] = {
  1049. {"_blksize", T_UINT, offsetof(fileio, blksize), 0},
  1050. {"_finalizing", T_BOOL, offsetof(fileio, finalizing), 0},
  1051. {"__weaklistoffset__", T_PYSSIZET, offsetof(fileio, weakreflist), READONLY},
  1052. {"__dictoffset__", T_PYSSIZET, offsetof(fileio, dict), READONLY},
  1053. {NULL}
  1054. };
  1055. static PyType_Slot fileio_slots[] = {
  1056. {Py_tp_dealloc, fileio_dealloc},
  1057. {Py_tp_repr, fileio_repr},
  1058. {Py_tp_doc, (void *)_io_FileIO___init____doc__},
  1059. {Py_tp_traverse, fileio_traverse},
  1060. {Py_tp_clear, fileio_clear},
  1061. {Py_tp_methods, fileio_methods},
  1062. {Py_tp_members, fileio_members},
  1063. {Py_tp_getset, fileio_getsetlist},
  1064. {Py_tp_init, _io_FileIO___init__},
  1065. {Py_tp_new, fileio_new},
  1066. {0, NULL},
  1067. };
  1068. PyType_Spec fileio_spec = {
  1069. .name = "_io.FileIO",
  1070. .basicsize = sizeof(fileio),
  1071. .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
  1072. Py_TPFLAGS_IMMUTABLETYPE),
  1073. .slots = fileio_slots,
  1074. };