summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libc/stdio/fgetln.335
-rw-r--r--lib/libc/stdio/fgets.346
2 files changed, 77 insertions, 4 deletions
diff --git a/lib/libc/stdio/fgetln.3 b/lib/libc/stdio/fgetln.3
index e859ae87882..c1298d11617 100644
--- a/lib/libc/stdio/fgetln.3
+++ b/lib/libc/stdio/fgetln.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: fgetln.3,v 1.4 1999/07/21 12:21:29 aaron Exp $
+.\" $OpenBSD: fgetln.3,v 1.5 1999/09/15 21:26:58 aaron Exp $
.\"
.\" Copyright (c) 1990, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -56,8 +56,7 @@ The length of the line, including the final newline,
is stored in the memory location to which
.Fa len
points.
-(Note, however, that if the line is the last
-in a file that does not end in a newline,
+(Note, however, that if the last line in the stream does not end in a newline,
the returned text will not contain a newline.)
.Sh RETURN VALUES
Upon successful completion a pointer is returned;
@@ -112,6 +111,36 @@ for any of the errors specified for the routines
.Xr stat 2 ,
or
.Xr realloc 3 .
+.Sh CAVEATS
+Since the returned buffer is not a C string (it is not null terminated), a
+common practice is to replace the newline character with
+.Sq \e0 .
+However, if the last line in a file does not contain a newline,
+the returned text won't contain a newline either.
+The following code demonstrates how to deal with this problem by allocating a
+temporary buffer:
+.Bd -literal
+ char *buf, *lbuf;
+ size_t len;
+
+ lbuf = NULL;
+ while ((buf = fgetln(fp, &len))) {
+ if (buf[len - 1] == '\en')
+ buf[len - 1] = '\e0';
+ else {
+ lbuf = (char *)malloc(len + 1);
+ memcpy(lbuf, buf, len);
+ lbuf[len] = '\e0';
+ buf = lbuf;
+ }
+ printf("%s\en", buf);
+
+ if (lbuf != NULL) {
+ free(lbuf);
+ lbuf = NULL;
+ }
+ }
+.Ed
.Sh SEE ALSO
.Xr ferror 3 ,
.Xr fgets 3 ,
diff --git a/lib/libc/stdio/fgets.3 b/lib/libc/stdio/fgets.3
index 5a64ff70208..ef0dbfd5692 100644
--- a/lib/libc/stdio/fgets.3
+++ b/lib/libc/stdio/fgets.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: fgets.3,v 1.6 1999/07/09 13:35:23 aaron Exp $
+.\" $OpenBSD: fgets.3,v 1.7 1999/09/15 21:26:58 aaron Exp $
.\"
.\" Copyright (c) 1990, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -124,6 +124,50 @@ may also fail and set
.Va errno
for any of the errors specified for the routine
.Xr getchar 3 .
+.Sh CAVEATS
+The following bit of code illustrates a case where the programmer assumes a
+string is too long if it does not contain a newline:
+.Bd -literal
+ char buf[1024], *p;
+
+ while (fgets(buf, sizeof(buf), fp)) {
+ if (!(p = strchr(buf, '\en')) {
+ fprintf(stderr, "input line too long.\n");
+ exit(1);
+ }
+ *p = '\e0';
+ printf("%s\en", p);
+ }
+.Ed
+.Pp
+While the error would be true if a line > 1023 characters were read, it would
+be false in two other cases:
+.Bl -enum -offset indent
+.It
+If the last line in a file does not contain a newline, the string returned by
+.Fn fgets
+will not contain a newline either. Thus
+.Fn strchr
+will return
+.Dv NULL
+and the program will terminate, even if the line was valid.
+.It
+All C string functions, including
+.Fn strchr ,
+correctly assume the end of the string is represented by a null
+.Pq Sq \e0
+character.
+If the first character of a line returned by
+.Fn fgets
+were null,
+.Fn strchr
+would immediately return without considering the rest of the returned text
+which may indeed include a newline.
+.El
+.Pp
+Consider using
+.Xr fgetln 3
+instead when dealing with untrusted input.
.Sh SEE ALSO
.Xr feof 3 ,
.Xr ferror 3 ,