~ubuntu-branches/ubuntu/precise/gnupg2/precise-proposed

« back to all changes in this revision

Viewing changes to common/xreadline.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Mueller
  • Date: 2005-03-29 10:30:32 UTC
  • Revision ID: james.westby@ubuntu.com-20050329103032-sj42n2ain3ipx310
Tags: upstream-1.9.15
ImportĀ upstreamĀ versionĀ 1.9.15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* xreadline.c - fgets replacement function
 
2
 * Copyright (C) 1999, 2004 Free Software Foundation, Inc.
 
3
 *
 
4
 * This file is part of GnuPG.
 
5
 *
 
6
 * GnuPG is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; either version 2 of the License, or
 
9
 * (at your option) any later version.
 
10
 *
 
11
 * GnuPG is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program; if not, write to the Free Software
 
18
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
19
 */
 
20
 
 
21
#include <config.h>
 
22
#include <stdio.h>
 
23
#include <stdlib.h>
 
24
#include <errno.h>
 
25
 
 
26
#include "util.h"
 
27
 
 
28
 
 
29
/* Same as fgets() but if the provided buffer is too short a larger
 
30
   one will be allocated.  This is similar to getline. A line is
 
31
   considered a byte stream ending in a LF.
 
32
 
 
33
   If MAX_LENGTH is not NULL, it shall point to a value with the
 
34
   maximum allowed allocation.  
 
35
 
 
36
   Returns the length of the line. EOF is indicated by a line of
 
37
   length zero. A truncated line is indicated my setting the value at
 
38
   MAX_LENGTH to 0.  If the returned value is less then 0 not enough
 
39
   memory was enable and ERRNO is set accordingly.
 
40
 
 
41
   If a line has been truncated, the file pointer is moved forward to
 
42
   the end of the line so that the next read start with tghe next
 
43
   line.  Note that MAX_LENGTH must be re-initialzied in this case..
 
44
 
 
45
   Note: The returned buffer is allocated with enough extra space to
 
46
   append a CR,LF,Nul
 
47
 */
 
48
ssize_t
 
49
read_line (FILE *fp, 
 
50
           char **addr_of_buffer, size_t *length_of_buffer,
 
51
           size_t *max_length)
 
52
{
 
53
  int c;
 
54
  char  *buffer = *addr_of_buffer;
 
55
  size_t length = *length_of_buffer;
 
56
  size_t nbytes = 0;
 
57
  size_t maxlen = max_length? *max_length : 0;
 
58
  char *p;
 
59
 
 
60
  if (!buffer)
 
61
    { /* No buffer given - allocate a new one. */
 
62
      length = 256;
 
63
      buffer = xtrymalloc (length);
 
64
      *addr_of_buffer = buffer;
 
65
      if (!buffer)
 
66
        {
 
67
          *length_of_buffer = 0;
 
68
          if (max_length)
 
69
            *max_length = 0;
 
70
          return -1;
 
71
        }
 
72
      *length_of_buffer = length;
 
73
    }
 
74
 
 
75
  length -= 3; /* Reserve 3 bytes for CR,LF,EOL. */
 
76
  p = buffer;
 
77
  while  ((c = getc (fp)) != EOF)
 
78
    {
 
79
      if (nbytes == length)
 
80
        { /* Enlarge the buffer. */
 
81
          if (maxlen && length > maxlen) /* But not beyond our limit. */
 
82
            {
 
83
              /* Skip the rest of the line. */
 
84
              while (c != '\n' && (c=getc (fp)) != EOF)
 
85
                ;
 
86
              *p++ = '\n'; /* Always append a LF (we reserved some space). */
 
87
              nbytes++;
 
88
              if (max_length)
 
89
                *max_length = 0; /* Indicate truncation. */
 
90
              break; /* the while loop. */
 
91
            }
 
92
          length += 3; /* Adjust for the reserved bytes. */
 
93
          length += length < 1024? 256 : 1024;
 
94
          *addr_of_buffer = xtryrealloc (buffer, length);
 
95
          if (!*addr_of_buffer)
 
96
            {
 
97
              int save_errno = errno;
 
98
              xfree (buffer); 
 
99
              *length_of_buffer = *max_length = 0;
 
100
              errno = save_errno;
 
101
              return -1;
 
102
            }
 
103
          buffer = *addr_of_buffer;
 
104
          *length_of_buffer = length;
 
105
          length -= 3; 
 
106
          p = buffer + nbytes;
 
107
        }
 
108
      *p++ = c;
 
109
      nbytes++;
 
110
      if (c == '\n')
 
111
        break;
 
112
    }
 
113
  *p = 0; /* Make sure the line is a string. */
 
114
 
 
115
  return nbytes;
 
116
}