1 /* 2 * pANS stdio -- rdline 3 * This is not a pANS routine. 4 */ 5 #include "iolib.h" 6 #include <string.h> 7 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