1 /* 2 FUNCTION 3 <<getdelim>>---read a line up to a specified line delimeter 4 5 INDEX 6 getdelim 7 8 ANSI_SYNOPSIS 9 #include <stdio.h> 10 int getdelim(char **<[bufptr]>, size_t *<[n]>, 11 int <[delim]>, FILE *<[fp]>); 12 13 TRAD_SYNOPSIS 14 #include <stdio.h> 15 int getdelim(<[bufptr]>, <[n]>, <[delim]>, <[fp]>) 16 char **<[bufptr]>; 17 size_t *<[n]>; 18 int <[delim]>; 19 FILE *<[fp]>; 20 21 DESCRIPTION 22 <<getdelim>> reads a file <[fp]> up to and possibly including a specified 23 delimeter <[delim]>. The line is read into a buffer pointed to 24 by <[bufptr]> and designated with size *<[n]>. If the buffer is 25 not large enough, it will be dynamically grown by <<getdelim>>. 26 As the buffer is grown, the pointer to the size <[n]> will be 27 updated. 28 29 RETURNS 30 <<getdelim>> returns <<-1>> if no characters were successfully read, 31 otherwise, it returns the number of bytes successfully read. 32 at end of file, the result is nonzero. 33 34 PORTABILITY 35 <<getdelim>> is a glibc extension. 36 37 No supporting OS subroutines are directly required. 38 */ 39 40 /* Copyright 2002, Red Hat Inc. - all rights reserved */ 41 42 #include <stdio.h> 43 #include <stdlib.h> 44 #include <errno.h> 45 #include "local.h" 46 47 #define MIN_LINE_SIZE 4 48 #define DEFAULT_LINE_SIZE 128 49 50 ssize_t 51 __getdelim (bufptr, n, delim, fp) 52 char **bufptr; 53 size_t *n; 54 int delim; 55 FILE *fp; 56 { 57 char *buf; 58 char *ptr; 59 size_t newsize, numbytes; 60 int pos; 61 int ch; 62 int cont; 63 64 if (fp == NULL || bufptr == NULL || n == NULL) 65 { 66 errno = EINVAL; 67 return -1; 68 } 69 70 buf = *bufptr; 71 if (buf == NULL || *n < MIN_LINE_SIZE) 72 { 73 buf = (char *)realloc (*bufptr, DEFAULT_LINE_SIZE); 74 if (buf == NULL) 75 { 76 return -1; 77 } 78 *bufptr = buf; 79 *n = DEFAULT_LINE_SIZE; 80 } 81 82 _flockfile(fp); 83 84 CHECK_INIT(fp); 85 86 numbytes = *n; 87 ptr = buf; 88 89 cont = 1; 90 91 while (cont) 92 { 93 /* fill buffer - leaving room for nul-terminator */ 94 while (--numbytes > 0) 95 { 96 if ((ch = getc_unlocked (fp)) == EOF) 97 { 98 cont = 0; 99 break; 100 } 101 else 102 { 103 *ptr++ = ch; 104 if (ch == delim) 105 { 106 cont = 0; 107 break; 108 } 109 } 110 } 111 112 if (cont) 113 { 114 /* Buffer is too small so reallocate a larger buffer. */ 115 pos = ptr - buf; 116 newsize = (*n << 1); 117 buf = realloc (buf, newsize); 118 if (buf == NULL) 119 { 120 cont = 0; 121 break; 122 } 123 124 /* After reallocating, continue in new buffer */ 125 *bufptr = buf; 126 *n = newsize; 127 ptr = buf + pos; 128 numbytes = newsize - pos; 129 } 130 } 131 132 _funlockfile (fp); 133 134 /* if no input data, return failure */ 135 if (ptr == buf) 136 return -1; 137 138 /* otherwise, nul-terminate and return number of bytes read */ 139 *ptr = '\0'; 140 return (ssize_t)(ptr - buf); 141 } 142 143