diff options
Diffstat (limited to 'usr/src/lib/libshell/common/sh/io.c')
-rw-r--r-- | usr/src/lib/libshell/common/sh/io.c | 88 |
1 files changed, 66 insertions, 22 deletions
diff --git a/usr/src/lib/libshell/common/sh/io.c b/usr/src/lib/libshell/common/sh/io.c index 50fa35561f..547a67aa27 100644 --- a/usr/src/lib/libshell/common/sh/io.c +++ b/usr/src/lib/libshell/common/sh/io.c @@ -1,7 +1,7 @@ /*********************************************************************** * * * This software is part of the ast package * -* Copyright (c) 1982-2008 AT&T Intellectual Property * +* Copyright (c) 1982-2009 AT&T Intellectual Property * * and is licensed under the * * Common Public License, Version 1.0 * * by AT&T Intellectual Property * @@ -31,7 +31,6 @@ #include <fcin.h> #include <ls.h> #include <stdarg.h> -#include <ctype.h> #include <regex.h> #include "variables.h" #include "path.h" @@ -406,7 +405,7 @@ void sh_ioinit(Shell_t *shp) sh_iostream(shp,0); /* all write steams are in the same pool and share outbuff */ shp->outpool = sfopen(NIL(Sfio_t*),NIL(char*),"sw"); /* pool identifier */ - shp->outbuff = (char*)malloc(IOBSIZE); + shp->outbuff = (char*)malloc(IOBSIZE+4); shp->errbuff = (char*)malloc(IOBSIZE/4); sfsetbuf(sfstderr,shp->errbuff,IOBSIZE/4); sfsetbuf(sfstdout,shp->outbuff,IOBSIZE); @@ -548,7 +547,11 @@ static void io_preserve(Shell_t* shp, register Sfio_t *sp, register int f2) if(f2==shp->infd) shp->infd = fd; if(fd<0) + { + shp->toomany = 1; + ((struct checkpt*)shp->jmplist)->mode = SH_JMPERREXIT; errormsg(SH_DICT,ERROR_system(1),e_toomany); + } if(shp->fdptrs[fd]=shp->fdptrs[f2]) { if(f2==job.fd) @@ -717,6 +720,20 @@ int sh_open(register const char *path, int flags, ...) } if (fd >= 0) { + int nfd= -1; + if (flags & O_CREAT) + { + struct stat st; + if (stat(path,&st) >=0) + nfd = open(path,flags,st.st_mode); + } + else + nfd = open(path,flags); + if(nfd>=0) + { + fd = nfd; + goto ok; + } if((mode=sh_iocheckfd(shp,fd))==IOCLOSE) return(-1); flags &= O_ACCMODE; @@ -727,12 +744,21 @@ int sh_open(register const char *path, int flags, ...) if((fd=dup(fd))<0) return(-1); } - else while((fd = open(path, flags, mode)) < 0) - if(errno!=EINTR || sh.trapnote) - return(-1); -#ifdef O_SERVICE - ok: + else + { +#if SHOPT_REGRESS + char buf[PATH_MAX]; + if(strncmp(path,"/etc/",5)==0) + { + sfsprintf(buf, sizeof(buf), "%s%s", sh_regress_etc(path, __LINE__, __FILE__), path+4); + path = buf; + } #endif + while((fd = open(path, flags, mode)) < 0) + if(errno!=EINTR || sh.trapnote) + return(-1); + } + ok: flags &= O_ACCMODE; if(flags==O_WRONLY) mode = IOWRITE; @@ -939,10 +965,11 @@ int sh_redirect(Shell_t *shp,struct ionod *iop, int flag) const char *message = e_open; int o_mode; /* mode flag for open */ static char io_op[7]; /* used for -x trace info */ - int clexec=0, fn, traceon; + int trunc=0, clexec=0, fn, traceon; int r, indx = shp->topfd, perm= -1; char *tname=0, *after="", *trace = shp->st.trap[SH_DEBUGTRAP]; Namval_t *np=0; + int isstring = shp->subshell?(sfset(sfstdout,0,0)&SF_STRING):0; if(flag==2) clexec = 1; if(iop) @@ -951,7 +978,7 @@ int sh_redirect(Shell_t *shp,struct ionod *iop, int flag) { iof=iop->iofile; fn = (iof&IOUFD); - if(fn==1 && shp->subshell && (flag==2 || (sfset(sfstdout,0,0)&SF_STRING))) + if(fn==1 && shp->subshell && !shp->subshare && (flag==2 || isstring)) sh_subfork(); io_op[0] = '0'+(iof&IOUFD); if(iof&IOPUT) @@ -978,6 +1005,16 @@ int sh_redirect(Shell_t *shp,struct ionod *iop, int flag) strcpy(ap->argval,iop->ioname); fname=sh_macpat(shp,ap,(iof&IOARITH)?ARG_ARITH:ARG_EXP); } + else if(iof&IOPROCSUB) + { + struct argnod *ap = (struct argnod*)stakalloc(ARGVAL+strlen(iop->ioname)); + memset(ap, 0, ARGVAL); + if(iof&IOPUT) + ap->argflag = ARG_RAW; + ap->argchn.ap = (struct argnod*)fname; + ap = sh_argprocsub(shp,ap); + fname = ap->argval; + } else fname=sh_mactrim(shp,fname,(!sh_isoption(SH_NOGLOB)&&sh_isoption(SH_INTERACTIVE))?2:0); } @@ -1033,7 +1070,7 @@ int sh_redirect(Shell_t *shp,struct ionod *iop, int flag) message = e_file; goto fail; } - if(shp->subshell && dupfd==1) + if(shp->subshell && dupfd==1 && (sfset(sfstdout,0,0)&SF_STRING)) { sh_subtmpfile(0); dupfd = sffileno(sfstdout); @@ -1083,6 +1120,8 @@ int sh_redirect(Shell_t *shp,struct ionod *iop, int flag) errormsg(SH_DICT,ERROR_exit(1),e_restricted,fname); io_op[2] = '>'; o_mode = O_RDWR|O_CREAT; + if(iof&IOREWRITE) + trunc = io_op[2] = ';'; goto openit; } else if(!(iof&IOPUT)) @@ -1197,7 +1236,10 @@ int sh_redirect(Shell_t *shp,struct ionod *iop, int flag) if((off = file_offset(shp,fn,fname))<0) goto fail; if(sp) + { off=sfseek(sp, off, SEEK_SET); + sfsync(sp); + } else off=lseek(fn, off, SEEK_SET); if(off<0) @@ -1245,7 +1287,7 @@ int sh_redirect(Shell_t *shp,struct ionod *iop, int flag) sh_close(fn); } } - sh_iosave(shp,fn,indx,tname?fname:0); + sh_iosave(shp,fn,indx,tname?fname:(trunc?Empty:0)); } else if(sh_subsavefd(fn)) sh_iosave(shp,fn,indx|IOSUBSHELL,tname?fname:0); @@ -1422,7 +1464,11 @@ void sh_iosave(Shell_t *shp, register int origfd, int oldtop, char *name) #endif /* SHOPT_DEVFD */ { if((savefd = sh_fcntl(origfd, F_DUPFD, 10)) < 0 && errno!=EBADF) + { + shp->toomany=1; + ((struct checkpt*)shp->jmplist)->mode = SH_JMPERREXIT; errormsg(SH_DICT,ERROR_system(1),e_toomany); + } } filemap[shp->topfd].tname = name; filemap[shp->topfd].subshell = flag; @@ -1492,7 +1538,9 @@ void sh_iorestore(Shell_t *shp, int last, int jmpval) continue; } origfd = filemap[fd].orig_fd; - if(filemap[fd].tname) + if(filemap[fd].tname == Empty && shp->exitval==0) + ftruncate(origfd,lseek(origfd,0,SEEK_CUR)); + else if(filemap[fd].tname) io_usename(filemap[fd].tname,(int*)0,shp->exitval?2:1); sh_close(origfd); if ((savefd = filemap[fd].save_fd) >= 0) @@ -1638,7 +1686,10 @@ static ssize_t piperead(Sfio_t *iop,void *buff,register size_t size,Sfdisc_t *ha int fd = sffileno(iop); NOT_USED(handle); if(job.waitsafe && job.savesig) - job_reap(job.savesig); + { + job_lock(); + job_unlock(); + } if(sh.trapnote) { errno = EINTR; @@ -1942,14 +1993,7 @@ static void sftrack(Sfio_t* sp, int flag, void* data) if(mode&SF_READ) flag |= IOREAD; shp->fdstatus[fd] = flag; -#if 0 - if(flag==IOWRITE) - sfpool(sp,shp->outpool,SF_WRITE); - else -#else - if(flag!=IOWRITE) -#endif - sh_iostream(shp,fd); + sh_iostream(shp,fd); } if((pp=(struct checkpt*)shp->jmplist) && pp->mode==SH_JMPCMD) { |