1 /* @(#)fgetline.c	1.14 16/11/07 Copyright 1986, 1996-2016 J. Schilling */
2 /*
3  *	Copyright (c) 1986, 1996-2016 J. Schilling
4  *
5  *	This is an interface that exists in the public since 1982.
6  *	The POSIX.1-2008 standard did ignore POSIX rules not to
7  *	redefine existing public interfaces and redefined the interfaces
8  *	forcing us to add a js_*() prefix to the original functions.
9  */
10 /*
11  * The contents of this file are subject to the terms of the
12  * Common Development and Distribution License, Version 1.0 only
13  * (the "License").  You may not use this file except in compliance
14  * with the License.
15  *
16  * See the file CDDL.Schily.txt in this distribution for details.
17  * A copy of the CDDL is also available via the Internet at
18  * http://www.opensource.org/licenses/cddl1.txt
19  *
20  * When distributing Covered Code, include this CDDL HEADER in each
21  * file and include the License file CDDL.Schily.txt from this distribution.
22  */
23 
24 #define	fgetline	__no__fgetline__
25 #define	getline		__no__getline__
26 
27 #define	FAST_GETC_PUTC		/* Will be reset if not possible */
28 #include "schilyio.h"
29 
30 #ifdef	LIB_SHEDIT
31 #undef	HAVE_USG_STDIO
32 #undef	FAST_GETC_PUTC
33 #endif
34 
35 #ifndef	NO_GETLINE_COMPAT	/* Define to disable backward compatibility */
36 #undef	fgetline
37 #undef	getline
38 #ifdef	HAVE_PRAGMA_WEAK
39 #pragma	weak fgetline =	js_fgetline
40 #pragma	weak getline =	js_getline
41 #else
42 
43 EXPORT	int	fgetline	__PR((FILE *, char *, int));
44 EXPORT 	int	getline		__PR((char *, int));
45 
46 EXPORT int
47 fgetline(f, buf, len)
48 	FILE	*f;
49 	char	*buf;
50 	int	len;
51 {
52 	return (js_fgetline(f, buf, len));
53 }
54 
55 EXPORT int
56 getline(buf, len)
57 	char	*buf;
58 	int	len;
59 {
60 	return (js_fgetline(stdin, buf, len));
61 }
62 #endif
63 #endif
64 
65 #if !defined(getc) && defined(USE_FGETS_FOR_FGETLINE)
66 #include <schily/string.h>
67 
68 /*
69  * Warning: this prevents us from being able to have embedded null chars.
70  */
71 EXPORT int
72 js_fgetline(f, buf, len)
73 	register	FILE	*f;
74 			char	*buf;
75 	register	int	len;
76 {
77 	char	*bp = fgets(buf, len, f);
78 
79 	if (bp) {
80 		len = strlen(bp);
81 
82 		if (len > 0) {
83 			if (bp[len-1] == '\n')
84 				bp[--len] = '\0';
85 		}
86 		return (len);
87 	}
88 	buf[0] = '\0';
89 	return (-1);
90 }
91 
92 #else
93 EXPORT int
94 js_fgetline(f, buf, len)
95 	register	FILE	*f;
96 			char	*buf;
97 	register	int	len;
98 {
99 	register char	*bp	= buf;
100 #if	defined(HAVE_USG_STDIO) || defined(FAST_GETC_PUTC)
101 	register char	*p;
102 #else
103 	register int	nl	= '\n';
104 	register int	c	= '\0';
105 #endif
106 
107 	down2(f, _IOREAD, _IORW);
108 
109 	if (len <= 0)
110 		return (0);
111 
112 	*bp = '\0';
113 	for (;;) {
114 #if	defined(HAVE_USG_STDIO) || defined(FAST_GETC_PUTC)
115 		size_t	n;
116 
117 		if ((__c f)->_cnt <= 0) {
118 			if (usg_filbuf(f) == EOF) {
119 				/*
120 				 * If buffer is empty and we hit EOF, return EOF
121 				 */
122 				if (bp == buf)
123 					return (EOF);
124 				break;
125 			}
126 			(__c f)->_cnt++;
127 			(__c f)->_ptr--;
128 		}
129 
130 		n = len;
131 		if (n > (__c f)->_cnt)
132 			n = (__c f)->_cnt;
133 		p = movecbytes((__c f)->_ptr, bp, '\n', n);
134 		if (p) {
135 			n = p - bp;
136 		}
137 		(__c f)->_ptr += n;
138 		(__c f)->_cnt -= n;
139 		bp += n;
140 		len -= n;
141 		if (p != NULL) {
142 			bp--;		/* Remove '\n' */
143 			break;
144 		}
145 #else
146 		if ((c = getc(f)) < 0) {
147 			/*
148 			 * If buffer is empty and we hit EOF, return EOF
149 			 */
150 			if (bp == buf)
151 				return (c);
152 			break;
153 		}
154 		if (c == nl)
155 			break;
156 		if (--len > 0) {
157 			*bp++ = (char)c;
158 		} else {
159 #ifdef	__never__
160 			/*
161 			 * Read up to end of line
162 			 */
163 			while ((c = getc(f)) >= 0 && c != nl)
164 				/* LINTED */
165 				;
166 #endif
167 			break;
168 		}
169 #endif
170 	}
171 	*bp = '\0';
172 
173 	return (bp - buf);
174 }
175 #endif
176 
177 EXPORT int
178 js_getline(buf, len)
179 	char	*buf;
180 	int	len;
181 {
182 	return (js_fgetline(stdin, buf, len));
183 }
184