da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1982-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * read [-ACprs] [-d delim] [-u filenum] [-t timeout] [-n n] [-N n] [name...]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * David Korn
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Labs
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define C_FLAG 0x40 /* read into compound variable */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define D_FLAG 8 /* must be number of bits for all flags */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Shell_t *shp = ((Shbltin_t*)extra)->shp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int save_prompt, fixargs=((Shbltin_t*)extra)->invariant;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz rp = (struct read_save*)(((Shbltin_t*)extra)->data);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errormsg(SH_DICT,ERROR_exit(1),e_overlimit,opt_info.name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* save in history file */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_usage(2), "%s", optusage((char*)0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!((r=shp->fdstatus[fd])&IOREAD) || !(r&(IOSEEK|IONOSEEK)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* look for prompt */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((name = *argv) && (name=strchr(name,'?')) && (r&IOTTY))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(argc==fixargs && (rp=newof(NIL(struct read_save*),struct read_save,1,0)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(r && (shp->prompt=(char*)sfreserve(sfstderr,r,SF_LOCKR)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(r==0 && (r=(sfeof(shp->sftable[fd])||sferror(shp->sftable[fd]))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(r);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * here for read timeout
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This is the code to read a line and to split it into tokens
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * <names> is an array of variable names
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * <fd> is the file descriptor
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * <flags> is union of -A, -r, -s, and contains delimiter if not '\n'
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * <timeout> is number of milli-seconds until timeout
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sh_readline(register Shell_t *shp,char **names, int fd, int flags,long timeout)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(iop=shp->sftable[fd]) && !(iop=sh_iostream(shp,fd)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = nv_open(name,shp->var_tree,NV_NOASSIGN|NV_VARNAME);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(np && nv_isarray(np) && (mp=nv_opensub(np)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags>>D_FLAG) /* delimiter not new-line or fixed size read */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* set up state table based on IFS */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin timeslot = (void*)sh_timeradd(timeout,0,timedout,(void*)iop);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* reserved buffer */
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner m = (cp = sfreserve(iop,c,0)) ? sfvalue(iop) : 0;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner m = (cp = sfreserve(iop,c,SF_LOCKR)) ? sfvalue(iop) : 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(m>0 && (flags&N_FLAG) && !binary && (v=memchr(cp,'\n',m)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz m = v-(char*)cp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((size -= x) > 0 && (up >= cur || z < 0) && ((flags & NN_FLAG) || z < 0 || m > c))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!binary && mbwide() && (up == var || (flags & NN_FLAG) && size))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(binary && !((size=nv_size(np)) && nv_isarray(np) && c!=size))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if((c==size) && np->nvalue.cp && !nv_isarray(np))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(!nv_isattr(np,NV_IMPORT|NV_EXPORT) && (mp=(Namval_t*)np->nvenv))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_CRNL */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!name && (flags&R_FLAG)) /* special case single argument */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* skip over leading blanks */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* strip trailing delimiters */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((c=shp->ifstable[*--cpmax])==S_DELIM || c==S_SPACE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_warn(0),e_readonly, nv_name(np));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* !SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* val==0 at the start of a field */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /*SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* process escape character */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for end of buffer */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* eliminate null bytes */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!name && val && (c==S_SPACE||c==S_DELIM||c==S_MBYTE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* skip over blanks */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* FALL THRU */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* skip over trailing blanks */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* FALL THRU */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* skip over word characters */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(name || c==S_NL || c==S_ESC || c==S_EOF || c==S_MBYTE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* assign value and advance to next variable */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* strip off trailing space delimiters */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned char *vp = (unsigned char*)val + strlen(val);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_warn(0),e_readonly, nv_name(np));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_ALLEXPORT)&&!strchr(nv_name(np),'.') && !nv_isattr(np,NV_EXPORT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = nv_open(name,shp->var_tree,NV_NOASSIGN|NV_VARNAME);