LCOV - code coverage report
Current view: top level - common - xreadline.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 20 47 42.6 %
Date: 2016-11-29 15:00:56 Functions: 1 1 100.0 %

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

Generated by: LCOV version 1.11