xref: /haiku/src/libs/bsd/fgetln.c (revision 820dca4df6c7bf955c46e8f6521b9408f50b2900)
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 
13 
14 #define LINE_LENGTH 4096
15 
16 
17 char *
18 fgetln(FILE *stream, size_t *_length)
19 {
20 	// TODO: this function is not thread-safe
21 	static size_t sBufferSize;
22 	static char *sBuffer;
23 
24 	size_t length, left;
25 	char *line;
26 
27 	if (sBuffer == NULL) {
28 		sBuffer = (char *)malloc(LINE_LENGTH);
29 		if (sBuffer == NULL)
30 			return NULL;
31 
32 		sBufferSize = LINE_LENGTH;
33 	}
34 
35 	line = sBuffer;
36 	left = sBufferSize;
37 	if (_length != NULL)
38 		*_length = 0;
39 
40 	for (;;) {
41 		line = fgets(line, left, stream);
42 		if (line == NULL) {
43 			free(sBuffer);
44 			sBuffer = NULL;
45 			return NULL;
46 		}
47 
48 		length = strlen(line);
49 		if (_length != NULL)
50 			*_length += length;
51 		if (line[length - 1] != '\n' && length == sBufferSize - 1) {
52 			// more data is following, enlarge buffer
53 			char *newBuffer = realloc(sBuffer, sBufferSize + LINE_LENGTH);
54 			if (newBuffer == NULL) {
55 				free(sBuffer);
56 				sBuffer = NULL;
57 				return NULL;
58 			}
59 
60 			sBuffer = newBuffer;
61 			sBufferSize += LINE_LENGTH;
62 			line = sBuffer + length;
63 			left += 1;
64 		} else
65 			break;
66 	}
67 
68 	return sBuffer;
69 }
70 
71