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