@@ -639,105 +639,95 @@ file_readinto(PyFileObject *f, PyObject *args)
639639 Size argument interpretation:
640640 > 0: max length;
641641 = 0: read arbitrary line;
642- < 0: strip trailing '\n', raise EOFError if EOF reached immediately
642+ < 0: illegal (use get_line_raw() instead)
643643*/
644644
645+ #ifdef HAVE_GETC_UNLOCKED
646+ #define GETC (f ) getc_unlocked(f)
647+ #define FLOCKFILE (f ) flockfile(f)
648+ #define FUNLOCKFILE (f ) funlockfile(f)
649+ #else
650+ #define GETC (f ) getc(f)
651+ #define FLOCKFILE (f )
652+ #define FUNLOCKFILE (f )
653+ #endif
654+
645655static PyObject *
646656get_line (PyFileObject * f , int n )
647657{
648- register FILE * fp = f -> f_fp ;
649- register int c ;
658+ FILE * fp = f -> f_fp ;
659+ int c ;
650660 char * buf , * end ;
651661 size_t n1 , n2 ;
652662 PyObject * v ;
653663
654- #if defined(HAVE_GETLINE ) && defined(_GNU_SOURCE )
655- /* Use GNU libc extension getline() for arbitrary-sized lines */
656- if (n == 0 ) {
657- size_t size = 0 ;
658- buf = NULL ;
659- Py_BEGIN_ALLOW_THREADS
660- n1 = getline (& buf , & size , fp );
661- Py_END_ALLOW_THREADS
662- if (n1 == -1 ) {
663- if (buf ){
664- free (buf );
665- }
666- clearerr (fp );
667- if (PyErr_CheckSignals ()) {
668- return NULL ;
669- }
670- if (n < 0 && feof (fp )) {
671- PyErr_SetString (PyExc_EOFError ,
672- "EOF when reading a line" );
673- return NULL ;
674- }
675- return PyString_FromStringAndSize (NULL , 0 );
676- }
677- /* No error */
678-
679- v = PyString_FromStringAndSize (buf , n1 );
680- free (buf );
681- return v ;
682- }
683- #endif
684-
685664 n2 = n > 0 ? n : 100 ;
686665 v = PyString_FromStringAndSize ((char * )NULL , n2 );
687666 if (v == NULL )
688667 return NULL ;
689668 buf = BUF (v );
690669 end = buf + n2 ;
691670
692- Py_BEGIN_ALLOW_THREADS
693671 for (;;) {
694- if ((c = getc (fp )) == EOF ) {
672+ Py_BEGIN_ALLOW_THREADS
673+ FLOCKFILE (fp );
674+ while ((c = GETC (fp )) != EOF &&
675+ (* buf ++ = c ) != '\n' &&
676+ buf != end )
677+ ;
678+ FUNLOCKFILE (fp );
679+ Py_END_ALLOW_THREADS
680+ if (c == '\n' )
681+ break ;
682+ if (c == EOF ) {
695683 clearerr (fp );
696- Py_BLOCK_THREADS
697684 if (PyErr_CheckSignals ()) {
698685 Py_DECREF (v );
699686 return NULL ;
700687 }
701- if (n < 0 && buf == BUF (v )) {
702- Py_DECREF (v );
703- PyErr_SetString (PyExc_EOFError ,
704- "EOF when reading a line" );
705- return NULL ;
706- }
707- Py_UNBLOCK_THREADS
708688 break ;
709689 }
710- if ((* buf ++ = c ) == '\n' ) {
711- if (n < 0 )
712- buf -- ;
690+ /* Must be because buf == end */
691+ if (n > 0 )
713692 break ;
693+ n1 = n2 ;
694+ n2 += 1000 ;
695+ if (n2 > INT_MAX ) {
696+ PyErr_SetString (PyExc_OverflowError ,
697+ "line is longer than a Python string can hold" );
698+ return NULL ;
714699 }
715- if (buf == end ) {
716- if (n > 0 )
717- break ;
718- n1 = n2 ;
719- n2 += 1000 ;
720- if (n2 > INT_MAX ) {
721- PyErr_SetString (PyExc_OverflowError ,
722- "line is longer than a Python string can hold" );
723- return NULL ;
724- }
725- Py_BLOCK_THREADS
726- if (_PyString_Resize (& v , n2 ) < 0 )
727- return NULL ;
728- Py_UNBLOCK_THREADS
729- buf = BUF (v ) + n1 ;
730- end = BUF (v ) + n2 ;
731- }
700+ if (_PyString_Resize (& v , n2 ) < 0 )
701+ return NULL ;
702+ buf = BUF (v ) + n1 ;
703+ end = BUF (v ) + n2 ;
732704 }
733- Py_END_ALLOW_THREADS
734705
735706 n1 = buf - BUF (v );
736707 if (n1 != n2 )
737708 _PyString_Resize (& v , n1 );
738709 return v ;
739710}
740711
712+ /* Internal routine to get a line for raw_input():
713+ strip trailing '\n', raise EOFError if EOF reached immediately
714+ */
715+
716+ static PyObject *
717+ get_line_raw (PyFileObject * f )
718+ {
719+ PyObject * line ;
720+
721+ line = get_line (f , 0 );
722+ if (line == NULL || PyString_GET_SIZE (line ) > 0 )
723+ return line ;
724+ else {
725+ Py_DECREF (line );
726+ PyErr_SetString (PyExc_EOFError , "EOF when reading a line" );
727+ return NULL ;
728+ }
729+ }
730+
741731/* External C interface */
742732
743733PyObject *
@@ -796,7 +786,10 @@ PyFile_GetLine(PyObject *f, int n)
796786 }
797787 if (((PyFileObject * )f )-> f_fp == NULL )
798788 return err_closed ();
799- return get_line ((PyFileObject * )f , n );
789+ if (n < 0 )
790+ return get_line_raw ((PyFileObject * )f );
791+ else
792+ return get_line ((PyFileObject * )f , n );
800793}
801794
802795/* Python method */
0 commit comments