(linenum→info "unix/slp.c:2238")

glibc/2.7/libio/iogetdelim.c

    1: /* Copyright (C) 1994,1996-1998,2001,2003,2005 Free Software Foundation, Inc.
    2:    This file is part of the GNU C Library.
    3: 
    4:    The GNU C Library is free software; you can redistribute it and/or
    5:    modify it under the terms of the GNU Lesser General Public
    6:    License as published by the Free Software Foundation; either
    7:    version 2.1 of the License, or (at your option) any later version.
    8: 
    9:    The GNU C Library is distributed in the hope that it will be useful,
   10:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   11:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   12:    Lesser General Public License for more details.
   13: 
   14:    You should have received a copy of the GNU Lesser General Public
   15:    License along with the GNU C Library; if not, write to the Free
   16:    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   17:    02111-1307 USA.
   18: 
   19:    As a special exception, if you link the code in this file with
   20:    files compiled with a GNU compiler to produce an executable,
   21:    that does not cause the resulting executable to be covered by
   22:    the GNU Lesser General Public License.  This exception does not
   23:    however invalidate any other reasons why the executable file
   24:    might be covered by the GNU Lesser General Public License.
   25:    This exception applies to code released by its copyright holders
   26:    in files containing the exception.  */
   27: 
   28: #ifdef __STDC__
   29: #include <stdlib.h>
   30: #endif
   31: #include "libioP.h"
   32: #include <string.h>
   33: #include <errno.h>
   34: 
   35: /* Read up to (and including) a TERMINATOR from FP into *LINEPTR
   36:    (and null-terminate it).  *LINEPTR is a pointer returned from malloc (or
   37:    NULL), pointing to *N characters of space.  It is realloc'ed as
   38:    necessary.  Returns the number of characters read (not including the
   39:    null terminator), or -1 on error or EOF.  */
   40: 
   41: _IO_ssize_t
   42: _IO_getdelim (lineptr, n, delimiter, fp)
   43:      char **lineptr;
   44:      _IO_size_t *n;
   45:      int delimiter;
   46:      _IO_FILE *fp;
   47: {
   48:   _IO_ssize_t result;
   49:   _IO_ssize_t cur_len = 0;
   50:   _IO_ssize_t len;
   51: 
   52:   if (lineptr == NULL || n == NULL)
   53:     {
   54:       MAYBE_SET_EINVAL;
   55:       return -1;
   56:     }
   57:   CHECK_FILE (fp, -1);
   58:   _IO_acquire_lock (fp);
   59:   if (_IO_ferror_unlocked (fp))
   60:     {
   61:       result = -1;
   62:       goto unlock_return;
   63:     }
   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:   len = fp->_IO_read_end - fp->_IO_read_ptr;
   77:   if (len <= 0)
   78:     {
   79:       if (__underflow (fp) == EOF)
   80:         {
   81:           result = -1;
   82:           goto unlock_return;
   83:         }
   84:       len = fp->_IO_read_end - fp->_IO_read_ptr;
   85:     }
   86: 
   87:   for (;;)
   88:     {
   89:       _IO_size_t needed;
   90:       char *t;
   91:       t = (char *) memchr ((void *) fp->_IO_read_ptr, delimiter, len);
   92:       if (t != NULL)
   93:         len = (t - fp->_IO_read_ptr) + 1;
   94:       if (__builtin_expect (cur_len + len + 1 < 0, 0))
   95:         {
   96:           __set_errno (EOVERFLOW);
   97:           result = -1;
   98:           goto unlock_return;
   99:         }
  100:       /* Make enough space for len+1 (for final NUL) bytes.  */
  101:       needed = cur_len + len + 1;
  102:       if (needed > *n)
  103:         {
  104:           char *new_lineptr;
  105: 
  106:           if (needed < 2 * *n)
  107:             needed = 2 * *n;  /* Be generous. */
  108:           new_lineptr = (char *) realloc (*lineptr, needed);
  109:           if (new_lineptr == NULL)
  110:             {
  111:               result = -1;
  112:               goto unlock_return;
  113:             }
  114:           *lineptr = new_lineptr;
  115:           *n = needed;
  116:         }
  117:       memcpy (*lineptr + cur_len, (void *) fp->_IO_read_ptr, len);
  118:       fp->_IO_read_ptr += len;
  119:       cur_len += len;
  120:       if (t != NULL || __underflow (fp) == EOF)
  121:         break;
  122:       len = fp->_IO_read_end - fp->_IO_read_ptr;
  123:     }
  124:   (*lineptr)[cur_len] = '\0';
  125:   result = cur_len;
  126: 
  127: unlock_return:
  128:   _IO_release_lock (fp);
  129:   return result;
  130: }
  131: 
  132: #ifdef weak_alias
  133: weak_alias (_IO_getdelim, __getdelim)
  134: weak_alias (_IO_getdelim, getdelim)
  135: #endif
Syntax (Markdown)