2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: read.c /main/3 1995/11/01 16:29:22 rswiston $ */
24 /***************************************************************
26 * AT&T - PROPRIETARY *
28 * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF *
29 * AT&T BELL LABORATORIES *
30 * AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN *
31 * ACCORDANCE WITH APPLICABLE AGREEMENTS *
33 * Copyright (c) 1995 AT&T Corp. *
34 * Unpublished & Not for Publication *
35 * All Rights Reserved *
37 * The copyright notice above does not evidence any *
38 * actual or intended publication of such source code *
40 * This software was created by the *
41 * Advanced Software Technology Department *
42 * AT&T Bell Laboratories *
44 * For further information contact *
45 * {research,attmail}!dgk *
47 ***************************************************************/
49 /* : : generated by proto : : */
51 #if !defined(__PROTO__)
52 #if defined(__STDC__) || defined(__cplusplus) || defined(_proto) || defined(c_plusplus)
53 #if defined(__cplusplus)
54 #define __MANGLE__ "C"
59 #define __PROTO__(x) x
61 #define __PARAM__(n,o) n
62 #if !defined(__STDC__) && !defined(__cplusplus)
63 #if !defined(c_plusplus)
74 #define __PROTO__(x) ()
75 #define __OTORP__(x) x
76 #define __PARAM__(n,o) o
84 #if defined(__cplusplus) || defined(c_plusplus)
85 #define __VARARG__ ...
89 #if defined(__STDARG__)
90 #define __VA_START__(p,a) va_start(p,a)
92 #define __VA_START__(p,a) va_start(p)
99 #include "variables.h"
100 #include "lexstates.h"
103 #include "builtins.h"
105 #include "terminal.h"
106 #include "national.h"
108 #define R_FLAG 1 /* raw mode */
109 #define S_FLAG 2 /* save in history file */
110 #define A_FLAG 4 /* read into array */
111 #define D_FLAG 6 /* must be number of bits for all flags */
113 int b_read __PARAM__((int argc,char *argv[], __V_ *extra), (argc, argv, extra)) __OTORP__(int argc;char *argv[]; __V_ *extra;){
115 register int r, flags=0, fd=0;
116 long timeout = 1000*sh.tmout;
120 while((r = optget(argv,sh_optread))) switch(r)
126 timeout = 1000*opt_num;
129 if(opt_arg && *opt_arg!='\n')
130 flags |= ((*opt_arg)<< D_FLAG);
133 if((fd = sh.cpipe[0])<=0)
134 error(ERROR_exit(1),e_query);
140 /* save in history file */
152 error(ERROR_usage(2), opt_arg);
156 if(error_info.errors)
157 error(ERROR_usage(2),optusage((char*)0));
158 if(!((r=sh.fdstatus[fd])&IOREAD) || !(r&(IOSEEK|IONOSEEK)))
159 r = sh_iocheckfd(fd);
160 if(fd<0 || !(r&IOREAD))
161 error(ERROR_system(1),e_file+4);
162 /* look for prompt */
163 if((name = *argv) && (name=strchr(name,'?')) && (r&IOTTY))
165 r = strlen(++name)+1;
166 if(sh.prompt=(char*)sfreserve(sfstderr,r,1))
168 memcpy(sh.prompt,name,r);
169 sfwrite(sfstderr,sh.prompt,r);
173 save_prompt = sh.nextprompt;
175 r=sh_readline(argv,fd,flags,timeout);
176 sh.nextprompt = save_prompt;
177 if(r==0 && (r=(sfeof(sh.sftable[fd])||sferror(sh.sftable[fd]))))
179 if(fd == sh.cpipe[0])
185 sfclrerr(sh.sftable[fd]);
190 * here for read timeout
192 static void timedout __PARAM__((__V_ *handle), (handle)) __OTORP__(__V_ *handle;){
193 sfclrlock((Sfio_t*)handle);
198 * This is the code to read a line and to split it into tokens
199 * <names> is an array of variable names
200 * <fd> is the file descriptor
201 * <flags> is union of -A, -r, -s, and contains delimiter if not '\n'
202 * <timeout> is number of milli-seconds until timeout
205 int sh_readline __PARAM__((char **names, int fd, int flags,long timeout), (names, fd, flags, timeout)) __OTORP__(char **names; int fd; int flags;long timeout;){
207 register unsigned char *cp;
208 register Namval_t *np;
209 register char *name, *val;
210 register Sfio_t *iop;
212 unsigned char *cpmax;
216 long array_index = 0;
221 if(!(iop=sh.sftable[fd]) && !(iop=sh_iostream(fd)))
223 if(flags>>D_FLAG) /* delimiter not new-line */
225 delim = ((unsigned)flags)>>D_FLAG;
226 if(sh.fdstatus[fd]&IOTTY)
229 /* set up state table based on IFS */
230 ifs = nv_getval(np=nv_scoped(IFSNOD));
231 if((flags&R_FLAG) && sh.ifstable['\\']==S_ESC)
232 sh.ifstable['\\'] = 0;
233 else if(!(flags&R_FLAG) && sh.ifstable['\\']==0)
234 sh.ifstable['\\'] = S_ESC;
235 sh.ifstable[delim] = S_NL;
238 sh.ifstable['\n'] = 0;
239 nv_putval(np, ifs, NV_RDONLY);
241 sh.ifstable[0] = S_EOF;
242 if(names && (name = *names))
244 if(val= strchr(name,'?'))
246 np = nv_open(name,sh.var_tree,NV_NOASSIGN|NV_VARNAME);
252 nv_putsub(np,NIL(char*),0L);
262 if(hashscope(sh.var_tree))
263 np = nv_search((char*)REPLYNOD,sh.var_tree,HASH_BUCKET);
270 sh_pushcontext(&buff,1);
271 jmpval = sigsetjmp(buff.buff,0);
274 timeslot = (__V_*)timeradd(timeout,0,timedout,(__V_*)iop);
276 if(!(cp = (unsigned char*)sfgetr(iop,delim,0)))
277 cp = (unsigned char*)sfgetr(iop,delim,-1);
282 cpmax = cp + sfslen();
283 if(*(cpmax-1) != delim)
286 sfwrite(sh.hist_ptr->histfp,(char*)cp,sfslen());
287 c = sh.ifstable[*cp++];
288 #ifndef SHOPT_MULTIBYTE
289 if(!name && (flags&R_FLAG)) /* special case single argument */
291 /* skip over leading blanks */
293 c = sh.ifstable[*cp++];
294 /* strip trailing delimiters */
295 if(cpmax[-1] == '\n')
300 while((c=sh.ifstable[*--cpmax])==S_DELIM || c==S_SPACE);
303 nv_putval(np,(char*)cp-1,0);
306 #endif /* !SHOPT_MULTIBYTE */
312 /* val==0 at the start of a field */
318 #ifdef SHOPT_MULTIBYTE
320 if(sh_strchr(ifs,(char*)cp-1)>=0)
322 c = mblen((char*)cp-1,MB_CUR_MAX);
330 #endif /*SHOPT_MULTIBYTE */
332 /* process escape character */
333 if((c = sh.ifstable[*cp++]) == S_NL)
347 /* check for end of buffer */
359 /* eliminate null bytes */
360 c = sh.ifstable[*cp++];
361 if(!name && val && (c==S_SPACE||c==S_DELIM||c==S_MBYTE))
368 if((cp = (unsigned char*)sfgetr(iop,delim,0)) ||
369 (cp = (unsigned char*)sfgetr(iop,delim,-1)))
372 sfwrite(sh.hist_ptr->histfp,(char*)cp,sfslen());
373 cpmax = cp + sfslen();
374 c = sh.ifstable[*cp++];
376 if(!name && (c==S_SPACE || c==S_DELIM || c==S_MBYTE))
385 /* skip over blanks */
387 c = sh.ifstable[*cp++];
390 #ifdef SHOPT_MULTIBYTE
393 if(sh_strchr(ifs,(char*)cp-1)>=0)
395 c = mblen((char*)cp-1,MB_CUR_MAX);
402 #endif /* SHOPT_MULTIBYTE */
409 /* skip over trailing blanks */
410 while((c=sh.ifstable[*cp++])==S_SPACE);
417 /* skip over word characters */
420 while((c=sh.ifstable[*cp++])==0);
421 if(name || c==S_NL || c==S_ESC || c==S_EOF || c==S_MBYTE)
428 /* assign value and advance to next variable */
439 /* strip off trailing delimiters */
440 register char *cp = val + strlen(val);
442 while((n=sh.ifstable[*--cp])==S_DELIM || n==S_SPACE);
454 nv_putsub(np, NIL(char*), array_index++);
461 if(sh_isoption(SH_ALLEXPORT)&&!strchr(nv_name(np),'.'))
462 nv_onattr(np,NV_EXPORT);
466 np = nv_open(name,sh.var_tree,NV_NOASSIGN|NV_VARNAME);
475 nv_putval(np, "", 0);
481 sh_popcontext(&buff);
482 if((flags>>D_FLAG) && (sh.fdstatus[fd]&IOTTY))
485 hist_flush(sh.hist_ptr);