Re: getline incompatibility with Linux

From: David Schultz <das_at_FreeBSD.ORG>
Date: Tue, 31 Mar 2009 02:50:24 -0400
On Sun, Mar 29, 2009, Joe Marcus Clarke wrote:
> The new getline() function in FreeBSD is not completely compatible with
> Linux's implementation.  The result is that programs which assume Linux
> getline may enter a tight infinite loop.
> 
> According to the Linux getline(3) manpage, getline(3) returns -1 on
> error (including EOF).  Our implementation returns 0 on EOF.  Would it
> be possible to return -1 on EOF in our implementation?

Good catch; even POSIX says (in its usual roundabout way) that
getline() is supposed to return -1 on both error and EOF, and
never return 0. Of course POSIX merely inherited this braindeadness
from glibc...

The following patch should fix it. I'll commit this soonish, but
ENOTIME right now. Thanks for pointing this out.

Index: getline.3
===================================================================
--- getline.3	(revision 190425)
+++ getline.3	(working copy)
_at__at_ -24,7 +24,7 _at__at_
 .\"
 .\" $FreeBSD$
 .\"
-.Dd February 28, 2009
+.Dd March 29, 2009
 .Dt GETLINE 3
 .Os
 .Sh NAME
_at__at_ -79,7 +79,7 _at__at_
 functions return the number of characters written, excluding the
 terminating
 .Dv NUL .
-The value \-1 is returned if an error occurs.
+The value \-1 is returned if an error occurs, or if end-of-file is reached.
 .Sh EXAMPLES
 The following code fragment reads lines from a file and
 writes them to standard output.
Index: getdelim.c
===================================================================
--- getdelim.c	(revision 190425)
+++ getdelim.c	(working copy)
_at__at_ -120,7 +120,6 _at__at_
 		goto error;
 	}
 
-	linelen = 0;
 	if (*linecapp == 0)
 		*linep = NULL;
 
_at__at_ -128,9 +127,12 _at__at_
 		/* If fp is at EOF already, we just need space for the NUL. */
 		if (__sferror(fp) || expandtofit(linep, 1, linecapp))
 			goto error;
-		goto done;
+		FUNLOCKFILE(fp);
+		(*linep)[0] = '\0';
+		return (-1);
 	}
 
+	linelen = 0;
 	while ((endp = memchr(fp->_p, delim, fp->_r)) == NULL) {
 		if (sappend(linep, &linelen, linecapp, fp->_p, fp->_r))
 			goto error;
Received on Tue Mar 31 2009 - 05:10:47 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:45 UTC