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.

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