bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: getline


From: Simon Josefsson
Subject: Re: getline
Date: Sun, 17 Jul 2005 12:13:37 +0200
User-agent: Gnus/5.110004 (No Gnus v0.4) Emacs/22.0.50 (gnu/linux)

This is a rough start, to let you see my thinking.  If this is OK,
I'll write ChangeLog entries for it.  The getdelim in glibc appear to
suffer from a missing overflow check in the realloc call, but I may be
mistaken.  I fixed that while porting the code below.

1. There are separate modules for getline and getdelim.
2. The getndelim2 module is not modified.
3. I'm not sure the M4 magic is kosher.
4. The M4 tests and building appear to work on GNU/Linux, NetBSD, DEC
   and HPUX.  I haven't tested that the implementation works.

Index: modules/getline
===================================================================
RCS file: /cvsroot/gnulib/gnulib/modules/getline,v
retrieving revision 1.9
diff -u -p -r1.9 getline
--- modules/getline     21 Mar 2005 22:07:25 -0000      1.9
+++ modules/getline     17 Jul 2005 10:09:58 -0000
@@ -4,25 +4,21 @@ Read a line from a stream.
 Files:
 lib/getline.h
 lib/getline.c
-lib/getndelim2.h
-lib/getndelim2.c
 m4/getline.m4
-m4/getndelim2.m4
-m4/ssize_t.m4
 
 Depends-on:
+getdelim
 
 configure.ac:
-AM_FUNC_GETLINE
+gl_FUNC_GETLINE
 
 Makefile.am:
-EXTRA_DIST += getndelim2.h getndelim2.c
 
 Include:
 "getline.h"
 
 License:
-GPL
+LGPL
 
 Maintainer:
-all
+Simon Josefsson
Index: modules/getdelim
===================================================================
RCS file: modules/getdelim
diff -N modules/getdelim
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ modules/getdelim    17 Jul 2005 10:09:58 -0000
@@ -0,0 +1,23 @@
+Description:
+Read character delimited data from a stream.
+
+Files:
+lib/getdelim.h
+lib/getdelim.c
+m4/getdelim.m4
+
+Depends-on:
+
+configure.ac:
+gl_FUNC_GETDELIM
+
+Makefile.am:
+
+Include:
+"getdelim.h"
+
+License:
+LGPL
+
+Maintainer:
+Simon Josefsson
Index: m4/getdelim.m4
===================================================================
RCS file: m4/getdelim.m4
diff -N m4/getdelim.m4
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ m4/getdelim.m4      17 Jul 2005 10:09:58 -0000
@@ -0,0 +1,30 @@
+# getdelim.m4 serial 1
+
+dnl Copyright (C) 2005 Free Software dnl Foundation, Inc.
+dnl
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_PREREQ(2.52)
+
+AC_DEFUN([gl_FUNC_GETDELIM],
+[
+  AC_LIBSOURCES([getdelim.c, getdelim.h])
+
+  dnl Persuade glibc <stdio.h> to declare getdelim().
+  AC_REQUIRE([AC_GNU_SOURCE])
+
+  AC_REPLACE_FUNCS(getdelim)
+  AC_CHECK_DECLS_ONCE(getdelim)
+
+  if test $ac_cv_func_getdelim = no; then
+    gl_PREREQ_GETDELIM
+  fi
+])
+
+# Prerequisites of lib/getdelim.c.
+AC_DEFUN([gl_PREREQ_GETDELIM],
+[
+  :
+])
Index: m4/getline.m4
===================================================================
RCS file: /cvsroot/gnulib/gnulib/m4/getline.m4,v
retrieving revision 1.15
diff -u -p -r1.15 getline.m4
--- m4/getline.m4       21 Mar 2005 22:06:27 -0000      1.15
+++ m4/getline.m4       17 Jul 2005 10:09:58 -0000
@@ -1,4 +1,4 @@
-# getline.m4 serial 12
+# getline.m4 serial 13
 
 dnl Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005 Free Software
 dnl Foundation, Inc.
@@ -13,19 +13,21 @@ dnl See if there's a working, system-sup
 dnl We can't just do AC_REPLACE_FUNCS(getline) because some systems
 dnl have a function by that name in -linet that doesn't have anything
 dnl to do with the function we need.
-AC_DEFUN([AM_FUNC_GETLINE],
+AC_DEFUN([gl_FUNC_GETLINE],
 [
   AC_LIBSOURCES([getline.c, getline.h])
 
-  dnl Persuade glibc <stdio.h> to declare getline() and getdelim().
+  dnl Persuade glibc <stdio.h> to declare getline().
   AC_REQUIRE([AC_GNU_SOURCE])
 
-  am_getline_needs_run_time_check=no
+  AC_CHECK_DECLS([getline])
+
+  gl_getline_needs_run_time_check=no
   AC_CHECK_FUNC(getline,
                dnl Found it in some library.  Verify that it works.
-               am_getline_needs_run_time_check=yes,
+               gl_getline_needs_run_time_check=yes,
                am_cv_func_working_getline=no)
-  if test $am_getline_needs_run_time_check = yes; then
+  if test $gl_getline_needs_run_time_check = yes; then
     AC_CACHE_CHECK([for working getline function], am_cv_func_working_getline,
     [echo fooN |tr -d '\012'|tr N '\012' > conftest.data
     AC_TRY_RUN([
@@ -57,20 +59,12 @@ AC_DEFUN([AM_FUNC_GETLINE],
       [Define to a replacement function name for getline().])
     AC_LIBOBJ(getline)
 
-    # Avoid multiple inclusions of getndelim2.o into LIBOBJS.
-    # This hack won't be needed after gnulib requires Autoconf 2.58 or later.
-    case " $LIB@&address@hidden " in
-    *" getndelim2.$ac_objext "* ) ;;
-    *) AC_LIBOBJ(getndelim2);;
-    esac
-
     gl_PREREQ_GETLINE
-    gl_PREREQ_GETNDELIM2
   fi
 ])
 
 # Prerequisites of lib/getline.c.
 AC_DEFUN([gl_PREREQ_GETLINE],
 [
-  AC_CHECK_FUNCS(getdelim)
+  gl_FUNC_GETDELIM
 ])
Index: lib/getdelim.c
===================================================================
RCS file: lib/getdelim.c
diff -N lib/getdelim.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ lib/getdelim.c      17 Jul 2005 10:09:58 -0000
@@ -0,0 +1,107 @@
+/* getdelim.c --- Implementation of replacement getdelim function.
+   Copyright (C) 1994, 1996, 1997, 1998, 2001, 2003, 2005 Free
+   Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+/* Ported from glibc by Simon Josefsson. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <errno.h>
+
+#include "getdelim.h"
+
+/* Read up to (and including) a DELIMITER from FP into *LINEPTR (and
+   NUL-terminate it).  *LINEPTR is a pointer returned from malloc (or
+   NULL), pointing to *N characters of space.  It is realloc'ed as
+   necessary.  Returns the number of characters read (not including
+   the null terminator), or -1 on error or EOF.  */
+
+ssize_t
+getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp)
+{
+  int result;
+  ssize_t cur_len = 0;
+  ssize_t len;
+
+  if (lineptr == NULL || n == NULL || fp == NULL)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  flockfile (fp);
+
+  if (*lineptr == NULL || *n == 0)
+    {
+      *n = 120;
+      *lineptr = (char *) malloc (*n);
+      if (*lineptr == NULL)
+       {
+         result = -1;
+         goto unlock_return;
+       }
+    }
+
+  for (;;)
+    {
+      char *t;
+      int i;
+
+      i = getc (fp);
+      if (i == EOF)
+       break;
+
+      /* Make enough space for len+1 (for final NUL) bytes.  */
+      if (cur_len + 1 >= *n)
+       {
+         size_t needed = 2 * (cur_len + 1) + 1;   /* Be generous. */
+         char *new_lineptr;
+
+         if (needed < cur_len)
+           {
+             result = -1;
+             goto unlock_return;
+           }
+
+         new_lineptr = (char *) realloc (*lineptr, needed);
+         if (new_lineptr == NULL)
+           {
+             result = -1;
+             goto unlock_return;
+           }
+
+         *lineptr = new_lineptr;
+         *n = needed;
+       }
+
+      (*lineptr)[cur_len] = i;
+      cur_len++;
+
+      if (i == delimiter)
+       break;
+    }
+  (*lineptr)[cur_len] = '\0';
+  result = cur_len;
+
+ unlock_return:
+  funlockfile (fp);
+  return result;
+}
Index: lib/getdelim.h
===================================================================
RCS file: lib/getdelim.h
diff -N lib/getdelim.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ lib/getdelim.h      17 Jul 2005 10:09:58 -0000
@@ -0,0 +1,28 @@
+/* getdelim.h --- Prototype for replacement getdelim function.
+   Copyright (C) 2005 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
+/* Written by Simon Josefsson. */
+
+/* Get size_t, FILE, ssize_t.  And getdelim, if available.  */
+# include <stddef.h>
+# include <stdio.h>
+# include <sys/types.h>
+
+#if !HAVE_DECL_GETDELIM
+ssize_t getdelim (char **lineptr, size_t *n, int delimiter, FILE *stream);
+#endif /* !HAVE_GETDELIM */
Index: lib/getline.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/getline.c,v
retrieving revision 1.18
diff -u -p -r1.18 getline.c
--- lib/getline.c       14 May 2005 06:03:58 -0000      1.18
+++ lib/getline.c       17 Jul 2005 10:09:58 -0000
@@ -1,44 +1,32 @@
-/* getline.c -- Replacement for GNU C library function getline
+/* getline.c --- Implementation of replacement getline function.
+   Copyright (C) 2005 Free Software Foundation, Inc.
 
-   Copyright (C) 1993, 1996, 1997, 1998, 2000, 2003, 2004 Free
-   Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
-   any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software Foundation,
-   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
 
-/* Written by Jan Brittenson, address@hidden  */
+/* Written by Simon Josefsson. */
 
 #if HAVE_CONFIG_H
 # include <config.h>
 #endif
 
+#include "getdelim.h"
 #include "getline.h"
 
-#if ! (defined __GNU_LIBRARY__ && HAVE_GETDELIM)
-
-# include "getndelim2.h"
-
-ssize_t
-getdelim (char **lineptr, size_t *linesize, int delimiter, FILE *stream)
-{
-  return getndelim2 (lineptr, linesize, 0, GETNLINE_NO_LIMIT, delimiter, EOF,
-                     stream);
-}
-#endif
-
 ssize_t
-getline (char **lineptr, size_t *linesize, FILE *stream)
+getline (char **lineptr, size_t *n, FILE *stream)
 {
-  return getdelim (lineptr, linesize, '\n', stream);
+  return getdelim (lineptr, n, '\n', stream);
 }
Index: lib/getline.h
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/getline.h,v
retrieving revision 1.15
diff -u -p -r1.15 getline.h
--- lib/getline.h       14 May 2005 06:03:58 -0000      1.15
+++ lib/getline.h       17 Jul 2005 10:09:58 -0000
@@ -1,39 +1,28 @@
-/* Replacement for GNU C library function getline
+/* getline.h --- Prototype for replacement getline function.
+   Copyright (C) 2005 Free Software Foundation, Inc.
 
-   Copyright (C) 1995, 1997, 1999, 2000, 2001, 2002, 2003 Free
-   Software Foundation, Inc.
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
 
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 
 */
-
-#ifndef GETLINE_H_
-# define GETLINE_H_ 1
+/* Written by Simon Josefsson. */
 
+/* Get size_t, FILE, ssize_t.  And getline, if available.  */
 # include <stddef.h>
 # include <stdio.h>
-
-/* Get ssize_t.  */
 # include <sys/types.h>
 
-/* glibc2 has these functions declared in <stdio.h>.  Avoid redeclarations.  */
-# if __GLIBC__ < 2
-
-extern ssize_t getline (char **_lineptr, size_t *_linesize, FILE *_stream);
-
-extern ssize_t getdelim (char **_lineptr, size_t *_linesize, int _delimiter,
-                         FILE *_stream);
-
-# endif
-
-#endif /* not GETLINE_H_ */
+#if !HAVE_DECL_GETLINE
+ssize_t getline (char **lineptr, size_t *n, FILE *stream);
+#endif /* !HAVE_GETLINE */




reply via email to

[Prev in Thread] Current Thread [Next in Thread]