xref: /haiku/src/libs/bsd/fgetln.c (revision 18bac98397348b42ee3537c508c7a1a05cc4d714)
1 /*
2  * Copyright 2006, Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Axel Dörfler, axeld@pinc-software.de
7  */
8 
9 
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 
14 
15 #define LINE_LENGTH 4096
16 
17 
18 char *
fgetln(FILE * stream,size_t * _length)19 fgetln(FILE *stream, size_t *_length)
20 {
21 	// TODO: this function is not thread-safe
22 	static size_t sBufferSize;
23 	static char *sBuffer;
24 
25 	size_t length, left;
26 	char *line;
27 
28 	if (sBuffer == NULL) {
29 		sBuffer = (char *)malloc(LINE_LENGTH);
30 		if (sBuffer == NULL)
31 			return NULL;
32 
33 		sBufferSize = LINE_LENGTH;
34 	}
35 
36 	line = sBuffer;
37 	left = sBufferSize;
38 	if (_length != NULL)
39 		*_length = 0;
40 
41 	for (;;) {
42 		line = fgets(line, left, stream);
43 		if (line == NULL) {
44 			free(sBuffer);
45 			sBuffer = NULL;
46 			return NULL;
47 		}
48 
49 		length = strlen(line);
50 		if (_length != NULL)
51 			*_length += length;
52 		if (line[length - 1] != '\n' && length == sBufferSize - 1) {
53 			// more data is following, enlarge buffer
54 			char *newBuffer = realloc(sBuffer, sBufferSize + LINE_LENGTH);
55 			if (newBuffer == NULL) {
56 				free(sBuffer);
57 				sBuffer = NULL;
58 				return NULL;
59 			}
60 
61 			sBuffer = newBuffer;
62 			sBufferSize += LINE_LENGTH;
63 			line = sBuffer + length;
64 			left += 1;
65 		} else
66 			break;
67 	}
68 
69 	return sBuffer;
70 }
71 
72