Back to index

glibc  2.9
Functions
iogetdelim.c File Reference
#include "libioP.h"
#include <string.h>
#include <errno.h>

Go to the source code of this file.

Functions

_IO_ssize_t _IO_getdelim (char **lineptr, _IO_size_t *n, int delimiter, _IO_FILE *fp)

Function Documentation

_IO_ssize_t _IO_getdelim ( char **  lineptr,
_IO_size_t n,
int  delimiter,
_IO_FILE fp 
)

Definition at line 42 of file iogetdelim.c.

{
  _IO_ssize_t result;
  _IO_ssize_t cur_len = 0;
  _IO_ssize_t len;

  if (lineptr == NULL || n == NULL)
    {
      MAYBE_SET_EINVAL;
      return -1;
    }
  CHECK_FILE (fp, -1);
  _IO_acquire_lock (fp);
  if (_IO_ferror_unlocked (fp))
    {
      result = -1;
      goto unlock_return;
    }

  if (*lineptr == NULL || *n == 0)
    {
      *n = 120;
      *lineptr = (char *) malloc (*n);
      if (*lineptr == NULL)
       {
         result = -1;
         goto unlock_return;
       }
    }

  len = fp->_IO_read_end - fp->_IO_read_ptr;
  if (len <= 0)
    {
      if (__underflow (fp) == EOF)
       {
         result = -1;
         goto unlock_return;
       }
      len = fp->_IO_read_end - fp->_IO_read_ptr;
    }

  for (;;)
    {
      _IO_size_t needed;
      char *t;
      t = (char *) memchr ((void *) fp->_IO_read_ptr, delimiter, len);
      if (t != NULL)
       len = (t - fp->_IO_read_ptr) + 1;
      if (__builtin_expect (cur_len + len + 1 < 0, 0))
       {
         __set_errno (EOVERFLOW);
         result = -1;
         goto unlock_return;
       }
      /* Make enough space for len+1 (for final NUL) bytes.  */
      needed = cur_len + len + 1;
      if (needed > *n)
       {
         char *new_lineptr;

         if (needed < 2 * *n)
           needed = 2 * *n;  /* Be generous. */
         new_lineptr = (char *) realloc (*lineptr, needed);
         if (new_lineptr == NULL)
           {
             result = -1;
             goto unlock_return;
           }
         *lineptr = new_lineptr;
         *n = needed;
       }
      memcpy (*lineptr + cur_len, (void *) fp->_IO_read_ptr, len);
      fp->_IO_read_ptr += len;
      cur_len += len;
      if (t != NULL || __underflow (fp) == EOF)
       break;
      len = fp->_IO_read_end - fp->_IO_read_ptr;
    }
  (*lineptr)[cur_len] = '\0';
  result = cur_len;

unlock_return:
  _IO_release_lock (fp);
  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function: