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