Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 7445888659893398b01d014bc633b458 > files > 30

ksh-20100621-18.el5.src.rpm

diff -up ksh-20100621/src/cmd/ksh93/include/io.h.iotry1 ksh-20100621/src/cmd/ksh93/include/io.h
--- ksh-20100621/src/cmd/ksh93/include/io.h.iotry1	2009-04-12 10:05:46.000000000 +0200
+++ ksh-20100621/src/cmd/ksh93/include/io.h	2010-10-19 13:36:41.597091989 +0200
@@ -63,8 +63,6 @@
     struct ionod;
 #endif /* !ARG_RAW */
 
-#define sh_inuse(f2)	(sh.fdptrs[f2])
-
 extern int	sh_iocheckfd(Shell_t*,int);
 extern void 	sh_ioinit(Shell_t*);
 extern int 	sh_iomovefd(int);
@@ -77,6 +75,8 @@ extern void 	sh_iorestore(Shell_t*,int,i
 extern Sfio_t 	*sh_iostream(Shell_t*,int);
 extern int	sh_redirect(Shell_t*,struct ionod*,int);
 extern void 	sh_iosave(Shell_t *, int,int,char*);
+extern int 	sh_iovalidfd(Shell_t*, int);
+extern int 	sh_inuse(int);
 extern void 	sh_iounsave(Shell_t*);
 extern int	sh_chkopen(const char*);
 extern int	sh_ioaccess(int,int);
diff -up ksh-20100621/src/cmd/ksh93/sh/init.c.iotry1 ksh-20100621/src/cmd/ksh93/sh/init.c
--- ksh-20100621/src/cmd/ksh93/sh/init.c.iotry1	2010-10-19 16:01:31.124585914 +0200
+++ ksh-20100621/src/cmd/ksh93/sh/init.c	2010-10-19 16:02:19.813260073 +0200
@@ -1102,7 +1102,6 @@ Shell_t *sh_init(register int argc,regis
 	}
 	shp->lim.clk_tck = getconf("CLK_TCK");
 	shp->lim.arg_max = getconf("ARG_MAX");
-	shp->lim.open_max = getconf("OPEN_MAX");
 	shp->lim.child_max = getconf("CHILD_MAX");
 	shp->lim.ngroups_max = getconf("NGROUPS_MAX");
 	shp->lim.posix_version = getconf("VERSION");
diff -up ksh-20100621/src/cmd/ksh93/sh/io.c.iotry1 ksh-20100621/src/cmd/ksh93/sh/io.c
--- ksh-20100621/src/cmd/ksh93/sh/io.c.iotry1	2010-06-10 21:09:46.000000000 +0200
+++ ksh-20100621/src/cmd/ksh93/sh/io.c	2010-10-19 13:36:41.599091685 +0200
@@ -316,6 +316,12 @@ struct fdsave
 	char	*tname;		/* name used with >; */
 };
 
+struct Iodisc
+{
+	Sfdisc_t	disc;
+	Shell_t		*sh;
+};
+
 static int  	subexcept(Sfio_t*, int, void*, Sfdisc_t*);
 static int  	eval_exceptf(Sfio_t*, int, void*, Sfdisc_t*);
 static int  	slowexcept(Sfio_t*, int, void*, Sfdisc_t*);
@@ -380,29 +386,60 @@ static int matchf(void *handle, char *pt
 static struct fdsave	*filemap;
 static short		filemapsize;
 
+#define PSEUDOFD	(SHRT_MAX)
+
 /* ======== input output and file copying ======== */
 
+int  sh_iovalidfd(Shell_t *shp, int fd)
+{
+	Sfio_t		**sftable = shp->sftable;
+	int		max,n, **fdptrs = shp->fdptrs;
+	unsigned char	*fdstatus = shp->fdstatus;
+	if(fd<0)
+		return(0);
+	if(fd < sh.lim.open_max)
+		return(1);
+	max = strtol(astconf("OPEN_MAX",NiL,NiL),NiL,0);
+	if(fd >= max)
+	{
+		errno = EBADF;
+		return(0);
+	}
+	n = (fd+16)&~0xf;
+	if(n > max)
+		n = max;
+	max = sh.lim.open_max;
+	shp->sftable = (Sfio_t**)calloc(n*(sizeof(int*)+sizeof(Sfio_t*)+1),1);
+	if(max)
+		memcpy(shp->sftable,sftable,max*sizeof(Sfio_t*));
+	shp->fdptrs = (int**)(&shp->sftable[n]);
+	if(max)
+		memcpy(shp->fdptrs,fdptrs,max*sizeof(int*));
+	shp->fdstatus = (unsigned char*)(&shp->fdptrs[n]);
+	if(max)
+		memcpy(shp->fdstatus,fdstatus,max);
+	if(sftable)
+		free((void*)sftable);
+	sh.lim.open_max = n;
+	return(1);
+}
+
+int  sh_inuse(int fd)
+{
+	return(fd < sh.lim.open_max && sh.fdptrs[fd]);
+}
+
 void sh_ioinit(Shell_t *shp)
 {
-	register int n;
 	filemapsize = 8;
 	filemap = (struct fdsave*)malloc(filemapsize*sizeof(struct fdsave));
-#if SHOPT_FASTPIPE
-	n = shp->lim.open_max+2;
-#else
-	n = shp->lim.open_max;
-#endif /* SHOPT_FASTPIPE */
-	shp->fdstatus = (unsigned char*)malloc((unsigned)n);
-	memset((char*)shp->fdstatus,0,n);
-	shp->fdptrs = (int**)malloc(n*sizeof(int*));
-	memset((char*)shp->fdptrs,0,n*sizeof(int*));
-	shp->sftable = (Sfio_t**)malloc(n*sizeof(Sfio_t*));
-	memset((char*)shp->sftable,0,n*sizeof(Sfio_t*));
+	sh_iovalidfd(shp,16);
 	shp->sftable[0] = sfstdin;
 	shp->sftable[1] = sfstdout;
 	shp->sftable[2] = sfstderr;
 	sfnotify(sftrack);
 	sh_iostream(shp,0);
+	sh_iostream(shp,1);
 	/* 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+4);
@@ -471,11 +508,7 @@ Sfio_t *sh_iostream(Shell_t *shp, regist
 	register int status = sh_iocheckfd(shp,fd);
 	register int flags = SF_WRITE;
 	char *bp;
-	Sfdisc_t *dp;
-#if SHOPT_FASTPIPE
-	if(fd>=shp->lim.open_max)
-		return(shp->sftable[fd]);
-#endif /* SHOPT_FASTPIPE */
+	struct Iodisc *dp;
 	if(status==IOCLOSE)
 	{
 		switch(fd)
@@ -505,31 +538,35 @@ Sfio_t *sh_iostream(Shell_t *shp, regist
 		sfsetbuf(iop, bp, IOBSIZE);
 	else if(!(iop=sfnew((fd<=2?iop:0),bp,IOBSIZE,fd,flags)))
 		return(NIL(Sfio_t*));
-	dp = newof(0,Sfdisc_t,1,0);
+	dp = newof(0,struct Iodisc,1,0);
+	dp->sh = shp;
 	if(status&IOREAD)
 	{
 		sfset(iop,SF_MALLOC,1);
 		if(!(status&IOWRITE))
 			sfset(iop,SF_IOCHECK,1);
-		dp->exceptf = slowexcept;
+		dp->disc.exceptf = slowexcept;
 		if(status&IOTTY)
-			dp->readf = slowread;
+			dp->disc.readf = slowread;
 		else if(status&IONOSEEK)
 		{
-			dp->readf = piperead;
+			dp->disc.readf = piperead;
 			sfset(iop, SF_IOINTR,1);
 		}
 		else
-			dp->readf = 0;
-		dp->seekf = 0;
-		dp->writef = 0;
+			dp->disc.readf = 0;
+		dp->disc.seekf = 0;
+		dp->disc.writef = 0;
 	}
 	else
 	{
-		dp->exceptf = outexcept;
+		if((status&(IONOSEEK|IOTTY)) == IONOSEEK)
+			dp->disc.exceptf = pipeexcept;
+		else
+			dp->disc.exceptf = outexcept;
 		sfpool(iop,shp->outpool,SF_WRITE);
 	}
-	sfdisc(iop,dp);
+	sfdisc(iop,&dp->disc);
 	shp->sftable[fd] = iop;
 	return(iop);
 }
@@ -552,6 +589,8 @@ static void io_preserve(Shell_t* shp, re
 		((struct checkpt*)shp->jmplist)->mode = SH_JMPERREXIT;
 		errormsg(SH_DICT,ERROR_system(1),e_toomany);
 	}
+	if(f2 >= sh.lim.open_max)
+		sh_iovalidfd(shp,f2);
 	if(shp->fdptrs[fd]=shp->fdptrs[f2])
 	{
 		if(f2==job.fd)
@@ -610,6 +649,8 @@ int sh_iorenumber(Shell_t *shp, register
 			shp->sftable[f1] = 0;
 		sh_close(f1);
 	}
+	if(f2>=sh.lim.open_max)
+		sh_iovalidfd(shp,f2);
 	return(f2);
 }
 
@@ -618,11 +659,14 @@ int sh_iorenumber(Shell_t *shp, register
  */
 int sh_close(register int fd)
 {
+	Shell_t *shp = sh_getinterp();
 	register Sfio_t *sp;
 	register int r = 0;
 	if(fd<0)
 		return(-1);
-	if(!(sp=sh.sftable[fd]) || sfclose(sp) < 0)
+	if(fd >= sh.lim.open_max)
+		sh_iovalidfd(shp,fd);
+	if(!(sp=shp->sftable[fd]) || sfclose(sp) < 0)
 	{
 		if(fdnotify)
 			(*fdnotify)(fd,SH_FDCLOSE);
@@ -912,7 +956,7 @@ static char *io_usename(char *name, int 
 {
 	struct stat	statb;
 	char		*tname, *sp, *ep;
-	int		fd,len,n=0;
+	int		fd;
 	if(mode==0)
 	{
 		if((fd = sh_open(name,O_RDONLY,0)) > 0)
@@ -926,18 +970,25 @@ static char *io_usename(char *name, int 
 		else if(fd < 0  && errno!=ENOENT)
 			return(0);
 	}
-	tname = sp = (char*)stakalloc((len=strlen(name)) + 5);
-	if(ep = strrchr(name,'/'))
+	stakseek(1);
+	stakputs(name);
+	stakputc(0);
+	pathcanon(stakptr(1),PATH_PHYSICAL);
+	sp = ep = stakptr(1);
+	if(ep = strrchr(sp,'/'))
 	{
-		memcpy(sp,name,n=++ep-name);
-		len -=n;
-		sp += n;
+		memcpy(stakptr(0),sp,++ep-sp);
+		stakseek(ep-sp);
 	}
 	else
-		ep = name;
-	*sp++ = '.';
-	memcpy(sp,ep,len);
-	strcpy(sp+len,".tmp");
+	{
+		ep = sp;
+		stakseek(0);
+	}
+	stakputc('.');
+	stakputs(ep);
+	stakputs(".tmp");
+	tname = stakfreeze(1);
 	switch(mode)
 	{
 	    case 1:
@@ -1029,6 +1080,8 @@ int	sh_redirect(Shell_t *shp,struct iono
 			if((iof&IOLSEEK) || ((iof&IOMOV) && *fname=='-'))
 				fn = nv_getnum(np);
 		}
+		if(fn>=sh.lim.open_max && !sh_iovalidfd(shp,fn))
+			errormsg(SH_DICT,ERROR_system(1),e_file+4);
 		if(iof&IOLSEEK)
 		{
 			io_op[2] = '#';
@@ -1070,7 +1123,7 @@ int	sh_redirect(Shell_t *shp,struct iono
 						message = e_file;
 						goto fail;
 					}
-					if(shp->subshell && dupfd==1 && (sfset(sfstdout,0,0)&SF_STRING))
+					if(shp->subshell && dupfd==1)
 					{
 						if(sfset(sfstdout,0,0)&SF_STRING)
 							sh_subtmpfile(shp);
@@ -1103,6 +1156,8 @@ int	sh_redirect(Shell_t *shp,struct iono
 					goto traceit;
 				if((fd=sh_fcntl(dupfd,F_DUPFD,3))<0)
 					goto fail;
+				if(fd>= sh.lim.open_max)
+					sh_iovalidfd(shp,fd);
 				sh_iocheckfd(shp,dupfd);
 				shp->fdstatus[fd] = (shp->fdstatus[dupfd]&~IOCLEX);
 				if(toclose<0 && shp->fdstatus[fd]&IOREAD)
@@ -1159,7 +1214,7 @@ int	sh_redirect(Shell_t *shp,struct iono
 						{
 #if SHOPT_FS_3D
 							if(S_ISREG(sb.st_mode)&&
-						                (!shp->lim.fs3d || iview(&sb)==0))
+						                (!sh.lim.fs3d || iview(&sb)==0))
 #else
 							if(S_ISREG(sb.st_mode))
 #endif /* SHOPT_FS_3D */
@@ -1315,6 +1370,8 @@ int	sh_redirect(Shell_t *shp,struct iono
 					{
 						if((fn=fcntl(fd,F_DUPFD,10)) < 0)
 							goto fail;
+						if(fn>=sh.lim.open_max && !sh_iovalidfd(shp,fn))
+							goto fail;
 						shp->fdstatus[fn] = shp->fdstatus[fd];
 						sh_close(fd);
 						fd = fn;
@@ -1447,11 +1504,7 @@ void sh_iosave(Shell_t *shp, register in
 			errormsg(SH_DICT,ERROR_exit(4),e_nospace);
 		if(moved = (char*)filemap - oldptr)
 		{
-#if SHOPT_FASTPIPE
-			for(savefd=shp->lim.open_max+2; --savefd>=0; )
-#else
-			for(savefd=shp->lim.open_max; --savefd>=0; )
-#endif /* SHOPT_FASTPIPE */
+			for(savefd=sh.lim.open_max; --savefd>=0; )
 			{
 				cp = (char*)shp->fdptrs[savefd];
 				if(cp >= oldptr && cp < oldend)
@@ -1612,10 +1665,16 @@ int sh_ioaccess(int fd,register int mode
  */
 static int slowexcept(register Sfio_t *iop,int type,void *data,Sfdisc_t *handle)
 {
+	Shell_t *shp = sh_getinterp();
 	register int	n,fno;
 	NOT_USED(handle);
 	if(type==SF_DPOP || type==SF_FINAL)
 		free((void*)handle);
+	if(type==SF_WRITE && errno==EPIPE)
+	{
+		sfpurge(iop);
+		return(-1);
+	}
 	if(type!=SF_READ)
 		return(0);
 	if((sh.trapnote&(SH_SIGSET|SH_SIGTRAP)) && errno!=EIO && errno!=ENXIO)
@@ -1837,7 +1896,15 @@ int sh_iocheckfd(Shell_t *shp, register 
 			n |= IONOSEEK;
 #ifdef S_ISSOCK
 			if((fstat(fd,&statb)>=0) && S_ISSOCK(statb.st_mode))
+			{
 				n |= IOREAD|IOWRITE;
+#   if _socketpair_shutdown_mode
+				if(!(statb.st_mode&S_IRUSR))
+					n &= ~IOREAD;
+				else if(!(statb.st_mode&S_IWUSR))
+					n &= ~IOWRITE;
+#   endif
+			}
 #endif /* S_ISSOCK */
 		}
 		else if((fstat(fd,&statb)>=0) && (
@@ -1853,7 +1920,11 @@ int sh_iocheckfd(Shell_t *shp, register 
 		else
 			n |= IOSEEK;
 	}
-	sh.fdstatus[fd] = n;
+	if(fd==0)
+		n &= ~IOWRITE;
+	else if(fd==1)
+		n &= ~IOREAD;
+	shp->fdstatus[fd] = n;
 	return(n);
 }
 
@@ -1940,8 +2011,11 @@ static int pipeexcept(Sfio_t* iop, int m
 	NOT_USED(iop);
 	if(mode==SF_DPOP || mode==SF_FINAL)
 		free((void*)handle);
-	else if(mode==SF_WRITE && errno==EINTR)
+	else if(mode==SF_WRITE && errno==EPIPE)
+	{
+		sfpurge(iop);
 		return(-1);
+	}
 	return(0);
 }
 
@@ -1977,7 +2051,7 @@ static void	sftrack(Sfio_t* sp, int flag
 		return;
 	}
 #endif
-	if((unsigned)fd >= shp->lim.open_max)
+	if(fd<0 || (fd>=sh.lim.open_max && !sh_iovalidfd(shp,fd)))
 		return;
 	if(sh_isstate(SH_NOTRACK))
 		return;
@@ -2125,7 +2199,7 @@ static Sfio_t *subopen(Shell_t *shp,Sfio
 	disp->oldsp = sp;
 	disp->offset = offset;
 	disp->size = disp->left = size;
-	sp = sfnew(NIL(Sfio_t*),(char*)(disp+1),IOBSIZE,shp->lim.open_max,SF_READ);
+	sp = sfnew(NIL(Sfio_t*),(char*)(disp+1),IOBSIZE,PSEUDOFD,SF_READ);
 	sfdisc(sp,&disp->disc);
 	return(sp);
 }
@@ -2136,13 +2210,18 @@ static Sfio_t *subopen(Shell_t *shp,Sfio
 static ssize_t subread(Sfio_t* sp,void* buff,register size_t size,Sfdisc_t* handle)
 {
 	register struct subfile *disp = (struct subfile*)handle;
+	ssize_t	n;
 	NOT_USED(sp);
+	sfseek(disp->oldsp,disp->offset,SEEK_SET);
 	if(disp->left == 0)
 		return(0);
 	if(size > disp->left)
 		size = disp->left;
 	disp->left -= size;
-	return(sfread(disp->oldsp,buff,size));
+	n = sfread(disp->oldsp,buff,size);
+	if(size>0)
+		disp->offset += size;
+	return(n);
 }
 
 /*
@@ -2300,6 +2379,8 @@ int sh_fcntl(register int fd, int op, ..
 	    case F_DUPFD:
 		if(sh.fdstatus[fd] == IOCLOSE)
 			sh.fdstatus[fd] = 0;
+		if(newfd>=sh.lim.open_max)
+			sh_iovalidfd(&sh,newfd);
 		sh.fdstatus[newfd] = (sh.fdstatus[fd]&~IOCLEX);
 		if(fdnotify)
 			(*fdnotify)(fd,newfd);
@@ -2353,7 +2434,7 @@ Sfio_t *sh_iogetiop(int fd, int mode)
 			fd = shp->cpipe[0];
 		break;
 	    default:
-		if(fd<0 || fd >= shp->lim.open_max)
+		if(fd<0 || !sh_iovalidfd(shp,fd))
 			fd = -1;
 	}
 	if(fd<0)