Linux implementation in the Toolchain, so here directly copy the implementation of Apple, so for memory allocation processing is clear.
/* getline.c--replacement for GNU C library function Getlinecopyright (c) 1993 free software Foundation, Inc.this progra M is free software; You can redistribute it and/ormodify it under the terms of the GNU general public License aspublished by the free software Foundation; Either version 2 of Thelicense, or (at your option) any later version. Distributed in the hope that it'll be useful, butwithout any WARRANTY; Without even the implied warranty ofmerchantability or FITNESS for A particular PURPOSE. See the Gnugeneral public License for more details. *//* written by Jan Brittenson, [email protected] */#ifdef have_config_h#include <config.h> #endif # include & lt;sys/types.h> #include <stdio.h> #include <assert.h> #include <errno.h> #if stdc_headers# Include <stdlib.h> #elsechar *malloc (), *realloc (), #endif/* Always add @ least this many bytes when extending the Buffer. */#define MIN_CHUNK 64/* Read up to (and including) a TerminatoR from STREAM to *lineptr + OFFSET (and null-terminate it). *lineptr is a pointer returned from malloc (or NULL), pointing to *n characters of space. It is realloc ' d as necessary. Return the number of characters read (not including the null terminator), or-1 on Error or EOF. On A-1 return, the caller should check feof (), if not then errno have been set to indicate the error. */intgetstr (lineptr, N, Stream, terminator, offset) char **lineptr; size_t *n; FILE *stream; char Terminator; int offset; {int nchars_avail;/* allocated but unused chars in *lineptr. */char *read_pos;/* Where we ' re reading into *lineptr. */INT ret; if (!lineptr | |!n | |!stream) {errno = EINVAL; return-1; } if (!*lineptr) {*n = Min_chunk; *lineptr = malloc (*n); if (!*lineptr) {errno = Enomem; return-1;} } Nchars_avail = *n-offset; Read_pos = *lineptr + offset; for (;;) {int Save_errno; Register int c = GETC (stream); Save_errno = errno; /* We always want at least one char left in the buffer, since we always (unless we get a error while reading the first CH AR) nul-terminate the line buffer. */Assert ((*lineptr + *n) = = (Read_pos + nchars_avail)); if (Nchars_avail < 2) {if (*n > Min_chunk) *n *= 2; else *n + = Min_chunk; Nchars_avail = *n + *lineptr-read_pos; *lineptr = ReAlloc (*lineptr, *n); if (!*lineptr) {errno = Enomem; return-1; } Read_pos = *n-nchars_avail + *lineptr; ASSERT ((*lineptr + *n) = = (Read_pos + nchars_avail));} if (Ferror (stream)) {/* might like to return partial line, but there are no place for us to store errno. And we don ' t want to just lose errno. */errno = Save_errno; return-1;} if (c = = EOF) {/* Return partial line, if any. */if (Read_pos = = *lineptr) return-1; else break;} *read_pos++ = C; nchars_avail--; if (c = = Terminator)/* Return the line. */break; }/* Done-nul terminate and return the number of chars read. */*read_pos = ' + '; ret = Read_pos-(*lineptr + offset); return ret;} Intgetline (lineptr, N, Stream) char **lineptr; size_t *n; FILE *stream; {return getstr (lineptr, N, stream, ' \ n ', 0);}
Getline C Implementation