1 /*
2 * pANS stdio -- rdline
3 * This is not a pANS routine.
4 */
5 #include "iolib.h"
6 #include <string.h>
7
rdline(FILE * f,char ** ep)8 char *rdline(FILE *f, char **ep){
9 int cnt;
10 char *nlp, *vp;
11 switch(f->state){
12 default: /* CLOSED, WR, ERR, EOF */
13 return NULL;
14 case OPEN:
15 _IO_setvbuf(f);
16 case RDWR:
17 f->state=RD;
18 case RD:
19 if(f->bufl==0){ /* Called by a comedian! */
20 f->state=ERR;
21 return NULL;
22 }
23 vp=f->rp;
24 for(;;){
25 /*
26 * Look for a newline.
27 * If none found, slide the partial line to the beginning
28 * of the buffer, read some more and keep looking.
29 */
30 nlp=memchr(f->rp, '\n', f->wp-f->rp);
31 if(nlp!=0) break;
32 if(f->flags&STRING){
33 f->rp=f->wp;
34 if(ep) *ep=f->wp;
35 return vp;
36 }
37 if(f->rp!=f->buf){
38 memmove(f->buf, f->rp, f->wp-f->rp);
39 f->wp-=f->rp-f->buf;
40 f->rp=f->buf;
41 vp=f->rp;
42 }
43 cnt=f->bufl-(f->wp-f->buf);
44 if(cnt==0){ /* no room left */
45 nlp=f->wp-1;
46 break;
47 }
48 cnt=read(f->fd, f->wp, cnt);
49 if(cnt==-1){
50 f->state=ERR;
51 return NULL;
52 }
53 if(cnt==0){ /* is this ok? */
54 f->state=EOF;
55 return NULL;
56 }
57 f->rp=f->wp;
58 f->wp+=cnt;
59 }
60 *nlp='\0';
61 f->rp=nlp+1;
62 if(ep) *ep=nlp;
63 return vp;
64 }
65 }
66