xref: /titanic_44/usr/src/lib/libast/common/stdio/fgets.c (revision a776e90690d98f629ab57f6493ff5949af9d65bd)
1 /***********************************************************************
2 *                                                                      *
3 *               This software is part of the ast package               *
4 *           Copyright (c) 1985-2007 AT&T Knowledge Ventures            *
5 *                      and is licensed under the                       *
6 *                  Common Public License, Version 1.0                  *
7 *                      by AT&T Knowledge Ventures                      *
8 *                                                                      *
9 *                A copy of the License is available at                 *
10 *            http://www.opensource.org/licenses/cpl1.0.txt             *
11 *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
12 *                                                                      *
13 *              Information and Software Systems Research               *
14 *                            AT&T Research                             *
15 *                           Florham Park NJ                            *
16 *                                                                      *
17 *                 Glenn Fowler <gsf@research.att.com>                  *
18 *                  David Korn <dgk@research.att.com>                   *
19 *                   Phong Vo <kpv@research.att.com>                    *
20 *                                                                      *
21 ***********************************************************************/
22 #pragma prototyped
23 
24 #include "stdhdr.h"
25 
26 extern char*
27 _stdgets(Sfio_t* f, char* us, int n, int isgets)
28 {
29 	int		p;
30 	unsigned char*	is;
31 	unsigned char*	ps;
32 
33 	if(n <= 0 || !us || (f->mode != SF_READ && _sfmode(f,SF_READ,0) < 0))
34 		return NIL(char*);
35 
36 	SFLOCK(f,0);
37 
38 	n -= 1;
39 	is = (uchar*)us;
40 
41 	while(n)
42 	{	/* peek the read buffer for data */
43 		if((p = f->endb - (ps = f->next)) <= 0 )
44 		{	f->getr = '\n';
45 			f->mode |= SF_RC;
46 			if(SFRPEEK(f,ps,p) <= 0)
47 				break;
48 		}
49 
50 		if(p > n)
51 			p = n;
52 
53 #if _lib_memccpy
54 		if((ps = (uchar*)memccpy((char*)is,(char*)ps,'\n',p)) != NIL(uchar*))
55 			p = ps-is;
56 		is += p;
57 		ps  = f->next+p;
58 #else
59 		if(!(f->flags&(SF_BOTH|SF_MALLOC)))
60 		{	while(p-- && (*is++ = *ps++) != '\n')
61 				;
62 			p = ps-f->next;
63 		}
64 		else
65 		{	reg int	c = ps[p-1];
66 			if(c != '\n')
67 				ps[p-1] = '\n';
68 			while((*is++ = *ps++) != '\n')
69 				;
70 			if(c != '\n')
71 			{	f->next[p-1] = c;
72 				if((ps-f->next) >= p)
73 					is[-1] = c;
74 			}
75 		}
76 #endif
77 
78 		/* gobble up read data and continue */
79 		f->next = ps;
80 		if(is[-1] == '\n')
81 			break;
82 		else if(n > 0)
83 			n -= p;
84 	}
85 
86 	if((_Sfi = is - ((uchar*)us)) <= 0)
87 		us = NIL(char*);
88 	else if(isgets && is[-1] == '\n')
89 	{	is[-1] = '\0';
90 		_Sfi -= 1;
91 	}
92 	else	*is = '\0';
93 
94 	SFOPEN(f,0);
95 	return us;
96 }
97 
98 char*
99 fgets(char* s, int n, Sfio_t* f)
100 {
101 	STDIO_PTR(f, "fgets", char*, (char*, int, Sfio_t*), (s, n, f))
102 
103 	return _stdgets(f, s, n, 0);
104 }
105 
106 char*
107 gets(char* s)
108 {
109 	return _stdgets(sfstdin, s, BUFSIZ, 1);
110 }
111