| OLD | NEW |
| 1 /* File object implementation */ | 1 /* File object implementation */ |
| 2 | 2 |
| 3 #define PY_SSIZE_T_CLEAN | 3 #define PY_SSIZE_T_CLEAN |
| 4 #include "Python.h" | 4 #include "Python.h" |
| 5 #include "structmember.h" | 5 #include "structmember.h" |
| 6 | 6 |
| 7 #ifdef HAVE_SYS_TYPES_H | 7 #ifdef HAVE_SYS_TYPES_H |
| 8 #include <sys/types.h> | 8 #include <sys/types.h> |
| 9 #endif /* HAVE_SYS_TYPES_H */ | 9 #endif /* HAVE_SYS_TYPES_H */ |
| 10 | 10 |
| (...skipping 853 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 864 if (v == NULL) | 864 if (v == NULL) |
| 865 return NULL; | 865 return NULL; |
| 866 bytesread = 0; | 866 bytesread = 0; |
| 867 for (;;) { | 867 for (;;) { |
| 868 Py_BEGIN_ALLOW_THREADS | 868 Py_BEGIN_ALLOW_THREADS |
| 869 errno = 0; | 869 errno = 0; |
| 870 chunksize = Py_UniversalNewlineFread(BUF(v) + bytesread, | 870 chunksize = Py_UniversalNewlineFread(BUF(v) + bytesread, |
| 871 buffersize - bytesread, f->f_fp, (PyObject *)f); | 871 buffersize - bytesread, f->f_fp, (PyObject *)f); |
| 872 Py_END_ALLOW_THREADS | 872 Py_END_ALLOW_THREADS |
| 873 if (chunksize == 0) { | 873 if (chunksize == 0) { |
| 874 » » » if (!ferror(f->f_fp)) | 874 » » » if (!PyErr_ExceptionMatches(PyExc_IOError)) |
| 875 break; | 875 break; |
| 876 clearerr(f->f_fp); | |
| 877 /* When in non-blocking mode, data shouldn't | 876 /* When in non-blocking mode, data shouldn't |
| 878 * be discarded if a blocking signal was | 877 * be discarded if a blocking signal was |
| 879 * received. That will also happen if | 878 * received. That will also happen if |
| 880 * chunksize != 0, but bytesread < buffersize. */ | 879 * chunksize != 0, but bytesread < buffersize. */ |
| 881 » » » if (bytesread > 0 && BLOCKED_ERRNO(errno)) | 880 » » » if (bytesread > 0 && BLOCKED_ERRNO(errno)) { |
| 881 » » » » PyErr_Clear(); |
| 882 break; | 882 break; |
| 883 » » » PyErr_SetFromErrno(PyExc_IOError); | 883 » » » } |
| 884 Py_DECREF(v); | 884 Py_DECREF(v); |
| 885 return NULL; | 885 return NULL; |
| 886 } | 886 } |
| 887 bytesread += chunksize; | 887 bytesread += chunksize; |
| 888 if (bytesread < buffersize) { | 888 if (bytesread < buffersize) { |
| 889 clearerr(f->f_fp); | 889 clearerr(f->f_fp); |
| 890 break; | 890 break; |
| 891 } | 891 } |
| 892 if (bytesrequested < 0) { | 892 if (bytesrequested < 0) { |
| 893 buffersize = new_buffersize(f, buffersize); | 893 buffersize = new_buffersize(f, buffersize); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 920 if (!PyArg_ParseTuple(args, "w#", &ptr, &ntodo)) | 920 if (!PyArg_ParseTuple(args, "w#", &ptr, &ntodo)) |
| 921 return NULL; | 921 return NULL; |
| 922 ndone = 0; | 922 ndone = 0; |
| 923 while (ntodo > 0) { | 923 while (ntodo > 0) { |
| 924 Py_BEGIN_ALLOW_THREADS | 924 Py_BEGIN_ALLOW_THREADS |
| 925 errno = 0; | 925 errno = 0; |
| 926 nnow = Py_UniversalNewlineFread(ptr+ndone, ntodo, f->f_fp, | 926 nnow = Py_UniversalNewlineFread(ptr+ndone, ntodo, f->f_fp, |
| 927 (PyObject *)f); | 927 (PyObject *)f); |
| 928 Py_END_ALLOW_THREADS | 928 Py_END_ALLOW_THREADS |
| 929 if (nnow == 0) { | 929 if (nnow == 0) { |
| 930 » » » if (!ferror(f->f_fp)) | 930 » » » if (!PyErr_ExceptionMatches(PyExc_IOError)) |
| 931 break; | 931 break; |
| 932 PyErr_SetFromErrno(PyExc_IOError); | |
| 933 clearerr(f->f_fp); | |
| 934 return NULL; | 932 return NULL; |
| 935 } | 933 } |
| 936 ndone += nnow; | 934 ndone += nnow; |
| 937 ntodo -= nnow; | 935 ntodo -= nnow; |
| 938 } | 936 } |
| 939 return PyInt_FromSsize_t(ndone); | 937 return PyInt_FromSsize_t(ndone); |
| 940 } | 938 } |
| 941 | 939 |
| 942 /************************************************************************** | 940 /************************************************************************** |
| 943 Routine to get next line using platform fgets(). | 941 Routine to get next line using platform fgets(). |
| (...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1415 else { | 1413 else { |
| 1416 Py_BEGIN_ALLOW_THREADS | 1414 Py_BEGIN_ALLOW_THREADS |
| 1417 errno = 0; | 1415 errno = 0; |
| 1418 nread = Py_UniversalNewlineFread(buffer+nfilled, | 1416 nread = Py_UniversalNewlineFread(buffer+nfilled, |
| 1419 buffersize-nfilled, f->f_fp, (PyObject *)f); | 1417 buffersize-nfilled, f->f_fp, (PyObject *)f); |
| 1420 Py_END_ALLOW_THREADS | 1418 Py_END_ALLOW_THREADS |
| 1421 shortread = (nread < buffersize-nfilled); | 1419 shortread = (nread < buffersize-nfilled); |
| 1422 } | 1420 } |
| 1423 if (nread == 0) { | 1421 if (nread == 0) { |
| 1424 sizehint = 0; | 1422 sizehint = 0; |
| 1425 » » » if (!ferror(f->f_fp)) | 1423 » » » if (!PyErr_ExceptionMatches(PyExc_IOError)) |
| 1426 break; | 1424 break; |
| 1427 PyErr_SetFromErrno(PyExc_IOError); | |
| 1428 clearerr(f->f_fp); | |
| 1429 error: | 1425 error: |
| 1430 Py_DECREF(list); | 1426 Py_DECREF(list); |
| 1431 list = NULL; | 1427 list = NULL; |
| 1432 goto cleanup; | 1428 goto cleanup; |
| 1433 } | 1429 } |
| 1434 totalread += nread; | 1430 totalread += nread; |
| 1435 p = (char *)memchr(buffer+nfilled, '\n', nread); | 1431 p = (char *)memchr(buffer+nfilled, '\n', nread); |
| 1436 if (p == NULL) { | 1432 if (p == NULL) { |
| 1437 /* Need a larger buffer to fit this line */ | 1433 /* Need a larger buffer to fit this line */ |
| 1438 nfilled += nread; | 1434 nfilled += nread; |
| (...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1866 if ((f->f_buf = (char *)PyMem_Malloc(bufsize)) == NULL) { | 1862 if ((f->f_buf = (char *)PyMem_Malloc(bufsize)) == NULL) { |
| 1867 PyErr_NoMemory(); | 1863 PyErr_NoMemory(); |
| 1868 return -1; | 1864 return -1; |
| 1869 } | 1865 } |
| 1870 Py_BEGIN_ALLOW_THREADS | 1866 Py_BEGIN_ALLOW_THREADS |
| 1871 errno = 0; | 1867 errno = 0; |
| 1872 chunksize = Py_UniversalNewlineFread( | 1868 chunksize = Py_UniversalNewlineFread( |
| 1873 f->f_buf, bufsize, f->f_fp, (PyObject *)f); | 1869 f->f_buf, bufsize, f->f_fp, (PyObject *)f); |
| 1874 Py_END_ALLOW_THREADS | 1870 Py_END_ALLOW_THREADS |
| 1875 if (chunksize == 0) { | 1871 if (chunksize == 0) { |
| 1876 » » if (ferror(f->f_fp)) { | 1872 » » if (PyErr_ExceptionMatches(PyExc_IOError)) { |
| 1877 » » » PyErr_SetFromErrno(PyExc_IOError); | |
| 1878 » » » clearerr(f->f_fp); | |
| 1879 drop_readahead(f); | 1873 drop_readahead(f); |
| 1880 return -1; | 1874 return -1; |
| 1881 } | 1875 } |
| 1882 } | 1876 } |
| 1883 f->f_bufptr = f->f_buf; | 1877 f->f_bufptr = f->f_buf; |
| 1884 f->f_bufend = f->f_buf + chunksize; | 1878 f->f_bufend = f->f_buf + chunksize; |
| 1885 return 0; | 1879 return 0; |
| 1886 } | 1880 } |
| 1887 | 1881 |
| 1888 /* Used by file_iternext. The returned string will start with 'skip' | 1882 /* Used by file_iternext. The returned string will start with 'skip' |
| (...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2419 ** the whole conversion is skipped. Finally, the routine keeps track of | 2413 ** the whole conversion is skipped. Finally, the routine keeps track of |
| 2420 ** the different types of newlines seen. | 2414 ** the different types of newlines seen. |
| 2421 */ | 2415 */ |
| 2422 size_t | 2416 size_t |
| 2423 Py_UniversalNewlineFread(char *buf, size_t n, | 2417 Py_UniversalNewlineFread(char *buf, size_t n, |
| 2424 FILE *stream, PyObject *fobj) | 2418 FILE *stream, PyObject *fobj) |
| 2425 { | 2419 { |
| 2426 char *dst = buf; | 2420 char *dst = buf; |
| 2427 PyFileObject *f = (PyFileObject *)fobj; | 2421 PyFileObject *f = (PyFileObject *)fobj; |
| 2428 int newlinetypes, skipnextlf; | 2422 int newlinetypes, skipnextlf; |
| 2423 size_t nread; |
| 2429 | 2424 |
| 2430 assert(buf != NULL); | 2425 assert(buf != NULL); |
| 2431 assert(stream != NULL); | 2426 assert(stream != NULL); |
| 2432 | 2427 |
| 2433 if (!fobj || !PyFile_Check(fobj)) { | 2428 if (!fobj || !PyFile_Check(fobj)) { |
| 2434 errno = ENXIO; /* What can you do... */ | 2429 errno = ENXIO; /* What can you do... */ |
| 2435 return 0; | 2430 return 0; |
| 2436 } | 2431 } |
| 2437 » if (!f->f_univ_newline) | 2432 » if (!f->f_univ_newline) { |
| 2438 » » return fread(buf, 1, n, stream); | 2433 » » nread = fread(buf, 1, n, stream); |
| 2434 » » if (nread == 0) { |
| 2435 » » » if (ferror(stream)) |
| 2436 » » » » PyErr_SetFromErrno(PyExc_IOError); |
| 2437 » » » clearerr(stream); |
| 2438 » » } |
| 2439 » » return nread; |
| 2440 » } |
| 2439 newlinetypes = f->f_newlinetypes; | 2441 newlinetypes = f->f_newlinetypes; |
| 2440 skipnextlf = f->f_skipnextlf; | 2442 skipnextlf = f->f_skipnextlf; |
| 2441 /* Invariant: n is the number of bytes remaining to be filled | 2443 /* Invariant: n is the number of bytes remaining to be filled |
| 2442 * in the buffer. | 2444 * in the buffer. |
| 2443 */ | 2445 */ |
| 2444 while (n) { | 2446 while (n) { |
| 2445 size_t nread; | |
| 2446 int shortread; | 2447 int shortread; |
| 2447 char *src = dst; | 2448 char *src = dst; |
| 2448 | 2449 |
| 2449 nread = fread(dst, 1, n, stream); | 2450 nread = fread(dst, 1, n, stream); |
| 2450 assert(nread <= n); | 2451 assert(nread <= n); |
| 2451 » » if (nread == 0) | 2452 » » if (nread == 0) { |
| 2453 » » » if (ferror(stream)) { |
| 2454 » » » » clearerr(stream); |
| 2455 » » » » PyErr_SetFromErrno(PyExc_IOError); |
| 2456 » » » » return 0; |
| 2457 » » » } |
| 2458 » » » clearerr(stream); |
| 2452 break; | 2459 break; |
| 2460 } |
| 2453 | 2461 |
| 2454 n -= nread; /* assuming 1 byte out for each in; will adjust */ | 2462 n -= nread; /* assuming 1 byte out for each in; will adjust */ |
| 2455 shortread = n != 0; /* true iff EOF or error */ | 2463 shortread = n != 0; /* true iff EOF or error */ |
| 2456 while (nread--) { | 2464 while (nread--) { |
| 2457 char c = *src++; | 2465 char c = *src++; |
| 2458 if (c == '\r') { | 2466 if (c == '\r') { |
| 2459 /* Save as LF and set flag to skip next LF. */ | 2467 /* Save as LF and set flag to skip next LF. */ |
| 2460 *dst++ = '\n'; | 2468 *dst++ = '\n'; |
| 2461 skipnextlf = 1; | 2469 skipnextlf = 1; |
| 2462 } | 2470 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2487 } | 2495 } |
| 2488 } | 2496 } |
| 2489 f->f_newlinetypes = newlinetypes; | 2497 f->f_newlinetypes = newlinetypes; |
| 2490 f->f_skipnextlf = skipnextlf; | 2498 f->f_skipnextlf = skipnextlf; |
| 2491 return dst - buf; | 2499 return dst - buf; |
| 2492 } | 2500 } |
| 2493 | 2501 |
| 2494 #ifdef __cplusplus | 2502 #ifdef __cplusplus |
| 2495 } | 2503 } |
| 2496 #endif | 2504 #endif |
| OLD | NEW |