You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

527 lines
15 KiB

36 years ago
36 years ago
36 years ago
36 years ago
  1. /* File object implementation (what's left of it -- see io.py) */
  2. #define PY_SSIZE_T_CLEAN
  3. #include "Python.h"
  4. #ifdef HAVE_GETC_UNLOCKED
  5. #define GETC(f) getc_unlocked(f)
  6. #define FLOCKFILE(f) flockfile(f)
  7. #define FUNLOCKFILE(f) funlockfile(f)
  8. #else
  9. #define GETC(f) getc(f)
  10. #define FLOCKFILE(f)
  11. #define FUNLOCKFILE(f)
  12. #endif
  13. /* Newline flags */
  14. #define NEWLINE_UNKNOWN 0 /* No newline seen, yet */
  15. #define NEWLINE_CR 1 /* \r newline seen */
  16. #define NEWLINE_LF 2 /* \n newline seen */
  17. #define NEWLINE_CRLF 4 /* \r\n newline seen */
  18. #ifdef __cplusplus
  19. extern "C" {
  20. #endif
  21. /* External C interface */
  22. PyObject *
  23. PyFile_FromFd(int fd, char *name, char *mode, int buffering, char *encoding,
  24. char *errors, char *newline, int closefd)
  25. {
  26. PyObject *io, *stream;
  27. io = PyImport_ImportModule("io");
  28. if (io == NULL)
  29. return NULL;
  30. stream = PyObject_CallMethod(io, "open", "isisssi", fd, mode,
  31. buffering, encoding, errors,
  32. newline, closefd);
  33. Py_DECREF(io);
  34. if (stream == NULL)
  35. return NULL;
  36. /* ignore name attribute because the name attribute of _BufferedIOMixin
  37. and TextIOWrapper is read only */
  38. return stream;
  39. }
  40. PyObject *
  41. PyFile_GetLine(PyObject *f, int n)
  42. {
  43. PyObject *result;
  44. if (f == NULL) {
  45. PyErr_BadInternalCall();
  46. return NULL;
  47. }
  48. {
  49. PyObject *reader;
  50. PyObject *args;
  51. reader = PyObject_GetAttrString(f, "readline");
  52. if (reader == NULL)
  53. return NULL;
  54. if (n <= 0)
  55. args = PyTuple_New(0);
  56. else
  57. args = Py_BuildValue("(i)", n);
  58. if (args == NULL) {
  59. Py_DECREF(reader);
  60. return NULL;
  61. }
  62. result = PyEval_CallObject(reader, args);
  63. Py_DECREF(reader);
  64. Py_DECREF(args);
  65. if (result != NULL && !PyBytes_Check(result) &&
  66. !PyUnicode_Check(result)) {
  67. Py_DECREF(result);
  68. result = NULL;
  69. PyErr_SetString(PyExc_TypeError,
  70. "object.readline() returned non-string");
  71. }
  72. }
  73. if (n < 0 && result != NULL && PyBytes_Check(result)) {
  74. char *s = PyBytes_AS_STRING(result);
  75. Py_ssize_t len = PyBytes_GET_SIZE(result);
  76. if (len == 0) {
  77. Py_DECREF(result);
  78. result = NULL;
  79. PyErr_SetString(PyExc_EOFError,
  80. "EOF when reading a line");
  81. }
  82. else if (s[len-1] == '\n') {
  83. if (result->ob_refcnt == 1)
  84. _PyBytes_Resize(&result, len-1);
  85. else {
  86. PyObject *v;
  87. v = PyBytes_FromStringAndSize(s, len-1);
  88. Py_DECREF(result);
  89. result = v;
  90. }
  91. }
  92. }
  93. if (n < 0 && result != NULL && PyUnicode_Check(result)) {
  94. Py_UNICODE *s = PyUnicode_AS_UNICODE(result);
  95. Py_ssize_t len = PyUnicode_GET_SIZE(result);
  96. if (len == 0) {
  97. Py_DECREF(result);
  98. result = NULL;
  99. PyErr_SetString(PyExc_EOFError,
  100. "EOF when reading a line");
  101. }
  102. else if (s[len-1] == '\n') {
  103. if (result->ob_refcnt == 1)
  104. PyUnicode_Resize(&result, len-1);
  105. else {
  106. PyObject *v;
  107. v = PyUnicode_FromUnicode(s, len-1);
  108. Py_DECREF(result);
  109. result = v;
  110. }
  111. }
  112. }
  113. return result;
  114. }
  115. /* Interfaces to write objects/strings to file-like objects */
  116. int
  117. PyFile_WriteObject(PyObject *v, PyObject *f, int flags)
  118. {
  119. PyObject *writer, *value, *args, *result;
  120. if (f == NULL) {
  121. PyErr_SetString(PyExc_TypeError, "writeobject with NULL file");
  122. return -1;
  123. }
  124. writer = PyObject_GetAttrString(f, "write");
  125. if (writer == NULL)
  126. return -1;
  127. if (flags & Py_PRINT_RAW) {
  128. value = PyObject_Str(v);
  129. }
  130. else
  131. value = PyObject_Repr(v);
  132. if (value == NULL) {
  133. Py_DECREF(writer);
  134. return -1;
  135. }
  136. args = PyTuple_Pack(1, value);
  137. if (args == NULL) {
  138. Py_DECREF(value);
  139. Py_DECREF(writer);
  140. return -1;
  141. }
  142. result = PyEval_CallObject(writer, args);
  143. Py_DECREF(args);
  144. Py_DECREF(value);
  145. Py_DECREF(writer);
  146. if (result == NULL)
  147. return -1;
  148. Py_DECREF(result);
  149. return 0;
  150. }
  151. int
  152. PyFile_WriteString(const char *s, PyObject *f)
  153. {
  154. if (f == NULL) {
  155. /* Should be caused by a pre-existing error */
  156. if (!PyErr_Occurred())
  157. PyErr_SetString(PyExc_SystemError,
  158. "null file for PyFile_WriteString");
  159. return -1;
  160. }
  161. else if (!PyErr_Occurred()) {
  162. PyObject *v = PyUnicode_FromString(s);
  163. int err;
  164. if (v == NULL)
  165. return -1;
  166. err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
  167. Py_DECREF(v);
  168. return err;
  169. }
  170. else
  171. return -1;
  172. }
  173. /* Try to get a file-descriptor from a Python object. If the object
  174. is an integer or long integer, its value is returned. If not, the
  175. object's fileno() method is called if it exists; the method must return
  176. an integer or long integer, which is returned as the file descriptor value.
  177. -1 is returned on failure.
  178. */
  179. int
  180. PyObject_AsFileDescriptor(PyObject *o)
  181. {
  182. int fd;
  183. PyObject *meth;
  184. if (PyLong_Check(o)) {
  185. fd = PyLong_AsLong(o);
  186. }
  187. else if ((meth = PyObject_GetAttrString(o, "fileno")) != NULL)
  188. {
  189. PyObject *fno = PyEval_CallObject(meth, NULL);
  190. Py_DECREF(meth);
  191. if (fno == NULL)
  192. return -1;
  193. if (PyLong_Check(fno)) {
  194. fd = PyLong_AsLong(fno);
  195. Py_DECREF(fno);
  196. }
  197. else {
  198. PyErr_SetString(PyExc_TypeError,
  199. "fileno() returned a non-integer");
  200. Py_DECREF(fno);
  201. return -1;
  202. }
  203. }
  204. else {
  205. PyErr_SetString(PyExc_TypeError,
  206. "argument must be an int, or have a fileno() method.");
  207. return -1;
  208. }
  209. if (fd == -1 && PyErr_Occurred())
  210. return -1;
  211. if (fd < 0) {
  212. PyErr_Format(PyExc_ValueError,
  213. "file descriptor cannot be a negative integer (%i)",
  214. fd);
  215. return -1;
  216. }
  217. return fd;
  218. }
  219. /*
  220. ** Py_UniversalNewlineFgets is an fgets variation that understands
  221. ** all of \r, \n and \r\n conventions.
  222. ** The stream should be opened in binary mode.
  223. ** If fobj is NULL the routine always does newline conversion, and
  224. ** it may peek one char ahead to gobble the second char in \r\n.
  225. ** If fobj is non-NULL it must be a PyFileObject. In this case there
  226. ** is no readahead but in stead a flag is used to skip a following
  227. ** \n on the next read. Also, if the file is open in binary mode
  228. ** the whole conversion is skipped. Finally, the routine keeps track of
  229. ** the different types of newlines seen.
  230. ** Note that we need no error handling: fgets() treats error and eof
  231. ** identically.
  232. */
  233. char *
  234. Py_UniversalNewlineFgets(char *buf, int n, FILE *stream, PyObject *fobj)
  235. {
  236. char *p = buf;
  237. int c;
  238. int newlinetypes = 0;
  239. int skipnextlf = 0;
  240. if (fobj) {
  241. errno = ENXIO; /* What can you do... */
  242. return NULL;
  243. }
  244. FLOCKFILE(stream);
  245. c = 'x'; /* Shut up gcc warning */
  246. while (--n > 0 && (c = GETC(stream)) != EOF ) {
  247. if (skipnextlf ) {
  248. skipnextlf = 0;
  249. if (c == '\n') {
  250. /* Seeing a \n here with skipnextlf true
  251. ** means we saw a \r before.
  252. */
  253. newlinetypes |= NEWLINE_CRLF;
  254. c = GETC(stream);
  255. if (c == EOF) break;
  256. } else {
  257. /*
  258. ** Note that c == EOF also brings us here,
  259. ** so we're okay if the last char in the file
  260. ** is a CR.
  261. */
  262. newlinetypes |= NEWLINE_CR;
  263. }
  264. }
  265. if (c == '\r') {
  266. /* A \r is translated into a \n, and we skip
  267. ** an adjacent \n, if any. We don't set the
  268. ** newlinetypes flag until we've seen the next char.
  269. */
  270. skipnextlf = 1;
  271. c = '\n';
  272. } else if ( c == '\n') {
  273. newlinetypes |= NEWLINE_LF;
  274. }
  275. *p++ = c;
  276. if (c == '\n') break;
  277. }
  278. if ( c == EOF && skipnextlf )
  279. newlinetypes |= NEWLINE_CR;
  280. FUNLOCKFILE(stream);
  281. *p = '\0';
  282. if ( skipnextlf ) {
  283. /* If we have no file object we cannot save the
  284. ** skipnextlf flag. We have to readahead, which
  285. ** will cause a pause if we're reading from an
  286. ** interactive stream, but that is very unlikely
  287. ** unless we're doing something silly like
  288. ** exec(open("/dev/tty").read()).
  289. */
  290. c = GETC(stream);
  291. if ( c != '\n' )
  292. ungetc(c, stream);
  293. }
  294. if (p == buf)
  295. return NULL;
  296. return buf;
  297. }
  298. /* **************************** std printer ****************************
  299. * The stdprinter is used during the boot strapping phase as a preliminary
  300. * file like object for sys.stderr.
  301. */
  302. typedef struct {
  303. PyObject_HEAD
  304. int fd;
  305. } PyStdPrinter_Object;
  306. static PyObject *
  307. stdprinter_new(PyTypeObject *type, PyObject *args, PyObject *kews)
  308. {
  309. PyStdPrinter_Object *self;
  310. assert(type != NULL && type->tp_alloc != NULL);
  311. self = (PyStdPrinter_Object *) type->tp_alloc(type, 0);
  312. if (self != NULL) {
  313. self->fd = -1;
  314. }
  315. return (PyObject *) self;
  316. }
  317. static int
  318. stdprinter_init(PyObject *self, PyObject *args, PyObject *kwds)
  319. {
  320. PyErr_SetString(PyExc_TypeError,
  321. "cannot create 'stderrprinter' instances");
  322. return -1;
  323. }
  324. PyObject *
  325. PyFile_NewStdPrinter(int fd)
  326. {
  327. PyStdPrinter_Object *self;
  328. if (fd != fileno(stdout) && fd != fileno(stderr)) {
  329. /* not enough infrastructure for PyErr_BadInternalCall() */
  330. return NULL;
  331. }
  332. self = PyObject_New(PyStdPrinter_Object,
  333. &PyStdPrinter_Type);
  334. if (self != NULL) {
  335. self->fd = fd;
  336. }
  337. return (PyObject*)self;
  338. }
  339. static PyObject *
  340. stdprinter_write(PyStdPrinter_Object *self, PyObject *args)
  341. {
  342. char *c;
  343. Py_ssize_t n;
  344. if (self->fd < 0) {
  345. /* fd might be invalid on Windows
  346. * I can't raise an exception here. It may lead to an
  347. * unlimited recursion in the case stderr is invalid.
  348. */
  349. Py_RETURN_NONE;
  350. }
  351. if (!PyArg_ParseTuple(args, "s", &c)) {
  352. return NULL;
  353. }
  354. n = strlen(c);
  355. Py_BEGIN_ALLOW_THREADS
  356. errno = 0;
  357. #if defined(MS_WIN64) || defined(MS_WINDOWS)
  358. if (n > INT_MAX)
  359. n = INT_MAX;
  360. n = write(self->fd, c, (int)n);
  361. #else
  362. n = write(self->fd, c, n);
  363. #endif
  364. Py_END_ALLOW_THREADS
  365. if (n < 0) {
  366. if (errno == EAGAIN)
  367. Py_RETURN_NONE;
  368. PyErr_SetFromErrno(PyExc_IOError);
  369. return NULL;
  370. }
  371. return PyLong_FromSsize_t(n);
  372. }
  373. static PyObject *
  374. stdprinter_fileno(PyStdPrinter_Object *self)
  375. {
  376. return PyLong_FromLong((long) self->fd);
  377. }
  378. static PyObject *
  379. stdprinter_repr(PyStdPrinter_Object *self)
  380. {
  381. return PyUnicode_FromFormat("<stdprinter(fd=%d) object at 0x%x>",
  382. self->fd, self);
  383. }
  384. static PyObject *
  385. stdprinter_noop(PyStdPrinter_Object *self)
  386. {
  387. Py_RETURN_NONE;
  388. }
  389. static PyObject *
  390. stdprinter_isatty(PyStdPrinter_Object *self)
  391. {
  392. long res;
  393. if (self->fd < 0) {
  394. Py_RETURN_FALSE;
  395. }
  396. Py_BEGIN_ALLOW_THREADS
  397. res = isatty(self->fd);
  398. Py_END_ALLOW_THREADS
  399. return PyBool_FromLong(res);
  400. }
  401. static PyMethodDef stdprinter_methods[] = {
  402. {"close", (PyCFunction)stdprinter_noop, METH_NOARGS, ""},
  403. {"flush", (PyCFunction)stdprinter_noop, METH_NOARGS, ""},
  404. {"fileno", (PyCFunction)stdprinter_fileno, METH_NOARGS, ""},
  405. {"isatty", (PyCFunction)stdprinter_isatty, METH_NOARGS, ""},
  406. {"write", (PyCFunction)stdprinter_write, METH_VARARGS, ""},
  407. {NULL, NULL} /*sentinel */
  408. };
  409. static PyObject *
  410. get_closed(PyStdPrinter_Object *self, void *closure)
  411. {
  412. Py_INCREF(Py_False);
  413. return Py_False;
  414. }
  415. static PyObject *
  416. get_mode(PyStdPrinter_Object *self, void *closure)
  417. {
  418. return PyUnicode_FromString("w");
  419. }
  420. static PyObject *
  421. get_encoding(PyStdPrinter_Object *self, void *closure)
  422. {
  423. Py_RETURN_NONE;
  424. }
  425. static PyGetSetDef stdprinter_getsetlist[] = {
  426. {"closed", (getter)get_closed, NULL, "True if the file is closed"},
  427. {"encoding", (getter)get_encoding, NULL, "Encoding of the file"},
  428. {"mode", (getter)get_mode, NULL, "String giving the file mode"},
  429. {0},
  430. };
  431. PyTypeObject PyStdPrinter_Type = {
  432. PyVarObject_HEAD_INIT(&PyType_Type, 0)
  433. "stderrprinter", /* tp_name */
  434. sizeof(PyStdPrinter_Object), /* tp_basicsize */
  435. 0, /* tp_itemsize */
  436. /* methods */
  437. 0, /* tp_dealloc */
  438. 0, /* tp_print */
  439. 0, /* tp_getattr */
  440. 0, /* tp_setattr */
  441. 0, /* tp_reserved */
  442. (reprfunc)stdprinter_repr, /* tp_repr */
  443. 0, /* tp_as_number */
  444. 0, /* tp_as_sequence */
  445. 0, /* tp_as_mapping */
  446. 0, /* tp_hash */
  447. 0, /* tp_call */
  448. 0, /* tp_str */
  449. PyObject_GenericGetAttr, /* tp_getattro */
  450. 0, /* tp_setattro */
  451. 0, /* tp_as_buffer */
  452. Py_TPFLAGS_DEFAULT, /* tp_flags */
  453. 0, /* tp_doc */
  454. 0, /* tp_traverse */
  455. 0, /* tp_clear */
  456. 0, /* tp_richcompare */
  457. 0, /* tp_weaklistoffset */
  458. 0, /* tp_iter */
  459. 0, /* tp_iternext */
  460. stdprinter_methods, /* tp_methods */
  461. 0, /* tp_members */
  462. stdprinter_getsetlist, /* tp_getset */
  463. 0, /* tp_base */
  464. 0, /* tp_dict */
  465. 0, /* tp_descr_get */
  466. 0, /* tp_descr_set */
  467. 0, /* tp_dictoffset */
  468. stdprinter_init, /* tp_init */
  469. PyType_GenericAlloc, /* tp_alloc */
  470. stdprinter_new, /* tp_new */
  471. PyObject_Del, /* tp_free */
  472. };
  473. #ifdef __cplusplus
  474. }
  475. #endif