~ubuntu-branches/ubuntu/precise/parted/precise

« back to all changes in this revision

Viewing changes to gnulib/lib/getdelim.c

  • Committer: Bazaar Package Importer
  • Author(s): Otavio Salvador
  • Date: 2010-02-06 16:39:19 UTC
  • mfrom: (1.1.5 upstream)
  • mto: (7.3.2 experimental)
  • mto: This revision was merged to the branch mainline in revision 48.
  • Revision ID: james.westby@ubuntu.com-20100206163919-nsxr2vtchk0ecabf
Tags: upstream-2.1
ImportĀ upstreamĀ versionĀ 2.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* getdelim.c --- Implementation of replacement getdelim function.
2
 
   Copyright (C) 1994, 1996, 1997, 1998, 2001, 2003, 2005, 2006 Free
3
 
   Software Foundation, Inc.
4
 
 
5
 
   This program is free software; you can redistribute it and/or
6
 
   modify it under the terms of the GNU General Public License as
7
 
   published by the Free Software Foundation; either version 2, or (at
8
 
   your option) any later version.
9
 
 
10
 
   This program is distributed in the hope that it will be useful, but
11
 
   WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 
   General Public License for more details.
14
 
 
15
 
   You should have received a copy of the GNU General Public License
16
 
   along with this program; if not, write to the Free Software
17
 
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18
 
   02110-1301, USA.  */
19
 
 
20
 
/* Ported from glibc by Simon Josefsson. */
21
 
 
22
 
#include <config.h>
23
 
 
24
 
#include "getdelim.h"
25
 
 
26
 
#include <limits.h>
27
 
#include <stdlib.h>
28
 
#include <errno.h>
29
 
 
30
 
#ifndef SIZE_MAX
31
 
# define SIZE_MAX ((size_t) -1)
32
 
#endif
33
 
#ifndef SSIZE_MAX
34
 
# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
35
 
#endif
36
 
#if !HAVE_FLOCKFILE
37
 
# undef flockfile
38
 
# define flockfile(x) ((void) 0)
39
 
#endif
40
 
#if !HAVE_FUNLOCKFILE
41
 
# undef funlockfile
42
 
# define funlockfile(x) ((void) 0)
43
 
#endif
44
 
 
45
 
/* Read up to (and including) a DELIMITER from FP into *LINEPTR (and
46
 
   NUL-terminate it).  *LINEPTR is a pointer returned from malloc (or
47
 
   NULL), pointing to *N characters of space.  It is realloc'ed as
48
 
   necessary.  Returns the number of characters read (not including
49
 
   the null terminator), or -1 on error or EOF.  */
50
 
 
51
 
ssize_t
52
 
getdelim (char **lineptr, size_t *n, int delimiter, FILE *fp)
53
 
{
54
 
  ssize_t result;
55
 
  size_t cur_len = 0;
56
 
 
57
 
  if (lineptr == NULL || n == NULL || fp == NULL)
58
 
    {
59
 
      errno = EINVAL;
60
 
      return -1;
61
 
    }
62
 
 
63
 
  flockfile (fp);
64
 
 
65
 
  if (*lineptr == NULL || *n == 0)
66
 
    {
67
 
      *n = 120;
68
 
      *lineptr = (char *) malloc (*n);
69
 
      if (*lineptr == NULL)
70
 
        {
71
 
          result = -1;
72
 
          goto unlock_return;
73
 
        }
74
 
    }
75
 
 
76
 
  for (;;)
77
 
    {
78
 
      int i;
79
 
 
80
 
      i = getc (fp);
81
 
      if (i == EOF)
82
 
        {
83
 
          result = -1;
84
 
          break;
85
 
        }
86
 
 
87
 
      /* Make enough space for len+1 (for final NUL) bytes.  */
88
 
      if (cur_len + 1 >= *n)
89
 
        {
90
 
          size_t needed_max =
91
 
            SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX;
92
 
          size_t needed = 2 * *n + 1;   /* Be generous. */
93
 
          char *new_lineptr;
94
 
 
95
 
          if (needed_max < needed)
96
 
            needed = needed_max;
97
 
          if (cur_len + 1 >= needed)
98
 
            {
99
 
              result = -1;
100
 
              goto unlock_return;
101
 
            }
102
 
 
103
 
          new_lineptr = (char *) realloc (*lineptr, needed);
104
 
          if (new_lineptr == NULL)
105
 
            {
106
 
              result = -1;
107
 
              goto unlock_return;
108
 
            }
109
 
 
110
 
          *lineptr = new_lineptr;
111
 
          *n = needed;
112
 
        }
113
 
 
114
 
      (*lineptr)[cur_len] = i;
115
 
      cur_len++;
116
 
 
117
 
      if (i == delimiter)
118
 
        break;
119
 
    }
120
 
  (*lineptr)[cur_len] = '\0';
121
 
  result = cur_len ? cur_len : result;
122
 
 
123
 
 unlock_return:
124
 
  funlockfile (fp);
125
 
  return result;
126
 
}