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
fgetline(f,buf,len)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
getline(buf,len)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
js_fgetline(f,buf,len)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
js_fgetline(f,buf,len)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
js_getline(buf,len)178 js_getline(buf, len)
179 char *buf;
180 int len;
181 {
182 return (js_fgetline(stdin, buf, len));
183 }
184