xref: /onnv-gate/usr/src/cmd/sh/io.c (revision 0)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
23*0Sstevel@tonic-gate /*	  All Rights Reserved  	*/
24*0Sstevel@tonic-gate 
25*0Sstevel@tonic-gate 
26*0Sstevel@tonic-gate /*
27*0Sstevel@tonic-gate  * Copyright (c) 1996, 2001 by Sun Microsystems, Inc.
28*0Sstevel@tonic-gate  * All rights reserved.
29*0Sstevel@tonic-gate  */
30*0Sstevel@tonic-gate 
31*0Sstevel@tonic-gate #ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.10.2.1	*/
32*0Sstevel@tonic-gate /*
33*0Sstevel@tonic-gate  * UNIX shell
34*0Sstevel@tonic-gate  */
35*0Sstevel@tonic-gate 
36*0Sstevel@tonic-gate #include	"defs.h"
37*0Sstevel@tonic-gate #include	"dup.h"
38*0Sstevel@tonic-gate #include	<fcntl.h>
39*0Sstevel@tonic-gate #include	<sys/types.h>
40*0Sstevel@tonic-gate #include	<sys/stat.h>
41*0Sstevel@tonic-gate #include	<errno.h>
42*0Sstevel@tonic-gate 
43*0Sstevel@tonic-gate short topfd;
44*0Sstevel@tonic-gate 
45*0Sstevel@tonic-gate /* ========	input output and file copying ======== */
46*0Sstevel@tonic-gate 
47*0Sstevel@tonic-gate initf(fd)
48*0Sstevel@tonic-gate int	fd;
49*0Sstevel@tonic-gate {
50*0Sstevel@tonic-gate 	register struct fileblk *f = standin;
51*0Sstevel@tonic-gate 
52*0Sstevel@tonic-gate 	f->fdes = fd;
53*0Sstevel@tonic-gate 	f->fsiz = ((flags & oneflg) == 0 ? BUFFERSIZE : 1);
54*0Sstevel@tonic-gate 	f->fnxt = f->fend = f->fbuf;
55*0Sstevel@tonic-gate 	f->nxtoff = f->endoff = 0;
56*0Sstevel@tonic-gate 	f->feval = 0;
57*0Sstevel@tonic-gate 	f->flin = 1;
58*0Sstevel@tonic-gate 	f->feof = FALSE;
59*0Sstevel@tonic-gate }
60*0Sstevel@tonic-gate 
61*0Sstevel@tonic-gate estabf(s)
62*0Sstevel@tonic-gate register unsigned char *s;
63*0Sstevel@tonic-gate {
64*0Sstevel@tonic-gate 	register struct fileblk *f;
65*0Sstevel@tonic-gate 
66*0Sstevel@tonic-gate 	(f = standin)->fdes = -1;
67*0Sstevel@tonic-gate 	f->fend = length(s) + (f->fnxt = s);
68*0Sstevel@tonic-gate 	f->nxtoff = 0;
69*0Sstevel@tonic-gate 	f->endoff = length(s);
70*0Sstevel@tonic-gate 	f->flin = 1;
71*0Sstevel@tonic-gate 	return (f->feof = (s == 0));
72*0Sstevel@tonic-gate }
73*0Sstevel@tonic-gate 
74*0Sstevel@tonic-gate push(af)
75*0Sstevel@tonic-gate struct fileblk *af;
76*0Sstevel@tonic-gate {
77*0Sstevel@tonic-gate 	register struct fileblk *f;
78*0Sstevel@tonic-gate 
79*0Sstevel@tonic-gate 	(f = af)->fstak = standin;
80*0Sstevel@tonic-gate 	f->feof = 0;
81*0Sstevel@tonic-gate 	f->feval = 0;
82*0Sstevel@tonic-gate 	standin = f;
83*0Sstevel@tonic-gate }
84*0Sstevel@tonic-gate 
85*0Sstevel@tonic-gate pop()
86*0Sstevel@tonic-gate {
87*0Sstevel@tonic-gate 	register struct fileblk *f;
88*0Sstevel@tonic-gate 
89*0Sstevel@tonic-gate 	if ((f = standin)->fstak)
90*0Sstevel@tonic-gate 	{
91*0Sstevel@tonic-gate 		if (f->fdes >= 0)
92*0Sstevel@tonic-gate 			close(f->fdes);
93*0Sstevel@tonic-gate 		standin = f->fstak;
94*0Sstevel@tonic-gate 		return (TRUE);
95*0Sstevel@tonic-gate 	}else
96*0Sstevel@tonic-gate 		return (FALSE);
97*0Sstevel@tonic-gate }
98*0Sstevel@tonic-gate 
99*0Sstevel@tonic-gate struct tempblk *tmpfptr;
100*0Sstevel@tonic-gate 
101*0Sstevel@tonic-gate pushtemp(fd, tb)
102*0Sstevel@tonic-gate 	int fd;
103*0Sstevel@tonic-gate 	struct tempblk *tb;
104*0Sstevel@tonic-gate {
105*0Sstevel@tonic-gate 	tb->fdes = fd;
106*0Sstevel@tonic-gate 	tb->fstak = tmpfptr;
107*0Sstevel@tonic-gate 	tmpfptr = tb;
108*0Sstevel@tonic-gate }
109*0Sstevel@tonic-gate 
110*0Sstevel@tonic-gate poptemp()
111*0Sstevel@tonic-gate {
112*0Sstevel@tonic-gate 	if (tmpfptr){
113*0Sstevel@tonic-gate 		close(tmpfptr->fdes);
114*0Sstevel@tonic-gate 		tmpfptr = tmpfptr->fstak;
115*0Sstevel@tonic-gate 		return (TRUE);
116*0Sstevel@tonic-gate 	}else
117*0Sstevel@tonic-gate 		return (FALSE);
118*0Sstevel@tonic-gate }
119*0Sstevel@tonic-gate 
120*0Sstevel@tonic-gate chkpipe(pv)
121*0Sstevel@tonic-gate int	*pv;
122*0Sstevel@tonic-gate {
123*0Sstevel@tonic-gate 	if (pipe(pv) < 0 || pv[INPIPE] < 0 || pv[OTPIPE] < 0)
124*0Sstevel@tonic-gate 		error(piperr);
125*0Sstevel@tonic-gate }
126*0Sstevel@tonic-gate 
127*0Sstevel@tonic-gate chkopen(idf, mode)
128*0Sstevel@tonic-gate unsigned char *idf;
129*0Sstevel@tonic-gate int mode;
130*0Sstevel@tonic-gate {
131*0Sstevel@tonic-gate 	register int	rc;
132*0Sstevel@tonic-gate 
133*0Sstevel@tonic-gate 	if ((rc = open((char *)idf, mode, 0666)) < 0)
134*0Sstevel@tonic-gate 		failed(idf, badopen);
135*0Sstevel@tonic-gate 	else
136*0Sstevel@tonic-gate 		return (rc);
137*0Sstevel@tonic-gate }
138*0Sstevel@tonic-gate 
139*0Sstevel@tonic-gate /*
140*0Sstevel@tonic-gate  * Make f2 be a synonym (including the close-on-exec flag) for f1, which is
141*0Sstevel@tonic-gate  * then closed.  If f2 is descriptor 0, modify the global ioset variable
142*0Sstevel@tonic-gate  * accordingly.
143*0Sstevel@tonic-gate  */
144*0Sstevel@tonic-gate renamef(f1, f2)
145*0Sstevel@tonic-gate register int	f1, f2;
146*0Sstevel@tonic-gate {
147*0Sstevel@tonic-gate #ifdef RES
148*0Sstevel@tonic-gate 	if (f1 != f2)
149*0Sstevel@tonic-gate 	{
150*0Sstevel@tonic-gate 		dup(f1 | DUPFLG, f2);
151*0Sstevel@tonic-gate 		close(f1);
152*0Sstevel@tonic-gate 		if (f2 == 0)
153*0Sstevel@tonic-gate 			ioset |= 1;
154*0Sstevel@tonic-gate 	}
155*0Sstevel@tonic-gate #else
156*0Sstevel@tonic-gate 	int	fs;
157*0Sstevel@tonic-gate 
158*0Sstevel@tonic-gate 	if (f1 != f2)
159*0Sstevel@tonic-gate 	{
160*0Sstevel@tonic-gate 		fs = fcntl(f2, 1, 0);
161*0Sstevel@tonic-gate 		close(f2);
162*0Sstevel@tonic-gate 		fcntl(f1, 0, f2);
163*0Sstevel@tonic-gate 		close(f1);
164*0Sstevel@tonic-gate 		if (fs == 1)
165*0Sstevel@tonic-gate 			fcntl(f2, 2, 1);
166*0Sstevel@tonic-gate 		if (f2 == 0)
167*0Sstevel@tonic-gate 			ioset |= 1;
168*0Sstevel@tonic-gate 	}
169*0Sstevel@tonic-gate #endif
170*0Sstevel@tonic-gate }
171*0Sstevel@tonic-gate 
172*0Sstevel@tonic-gate create(s)
173*0Sstevel@tonic-gate unsigned char *s;
174*0Sstevel@tonic-gate {
175*0Sstevel@tonic-gate 	register int	rc;
176*0Sstevel@tonic-gate 
177*0Sstevel@tonic-gate 	if ((rc = creat((char *)s, 0666)) < 0)
178*0Sstevel@tonic-gate 		failed(s, badcreate);
179*0Sstevel@tonic-gate 	else
180*0Sstevel@tonic-gate 		return (rc);
181*0Sstevel@tonic-gate }
182*0Sstevel@tonic-gate 
183*0Sstevel@tonic-gate 
184*0Sstevel@tonic-gate tmpfil(tb)
185*0Sstevel@tonic-gate 	struct tempblk *tb;
186*0Sstevel@tonic-gate {
187*0Sstevel@tonic-gate 	int fd;
188*0Sstevel@tonic-gate 
189*0Sstevel@tonic-gate 	/* make sure tmp file does not already exist. */
190*0Sstevel@tonic-gate 	do {
191*0Sstevel@tonic-gate 		itos(serial++);
192*0Sstevel@tonic-gate 		movstr(numbuf, tmpname);
193*0Sstevel@tonic-gate 		fd = open((char *)tmpout, O_RDWR|O_CREAT|O_EXCL, 0666);
194*0Sstevel@tonic-gate 	} while ((fd == -1) && (errno == EEXIST));
195*0Sstevel@tonic-gate 	if (fd != -1) {
196*0Sstevel@tonic-gate 		pushtemp(fd, tb);
197*0Sstevel@tonic-gate 		return (fd);
198*0Sstevel@tonic-gate 	}
199*0Sstevel@tonic-gate 	else
200*0Sstevel@tonic-gate 		failed(tmpout, badcreate);
201*0Sstevel@tonic-gate 
202*0Sstevel@tonic-gate }
203*0Sstevel@tonic-gate 
204*0Sstevel@tonic-gate /*
205*0Sstevel@tonic-gate  * set by trim
206*0Sstevel@tonic-gate  */
207*0Sstevel@tonic-gate extern BOOL		nosubst;
208*0Sstevel@tonic-gate #define			CPYSIZ		512
209*0Sstevel@tonic-gate 
210*0Sstevel@tonic-gate copy(ioparg)
211*0Sstevel@tonic-gate struct ionod	*ioparg;
212*0Sstevel@tonic-gate {
213*0Sstevel@tonic-gate 	register unsigned char	*cline;
214*0Sstevel@tonic-gate 	register unsigned char	*clinep;
215*0Sstevel@tonic-gate 	register struct ionod	*iop;
216*0Sstevel@tonic-gate 	unsigned int	c;
217*0Sstevel@tonic-gate 	unsigned char	*ends;
218*0Sstevel@tonic-gate 	unsigned char	*start;
219*0Sstevel@tonic-gate 	int		fd;
220*0Sstevel@tonic-gate 	int		i;
221*0Sstevel@tonic-gate 	int		stripflg;
222*0Sstevel@tonic-gate 	unsigned char	*pc;
223*0Sstevel@tonic-gate 
224*0Sstevel@tonic-gate 
225*0Sstevel@tonic-gate 	if (iop = ioparg)
226*0Sstevel@tonic-gate 	{
227*0Sstevel@tonic-gate 		struct tempblk tb;
228*0Sstevel@tonic-gate 		copy(iop->iolst);
229*0Sstevel@tonic-gate 		ends = mactrim(iop->ioname);
230*0Sstevel@tonic-gate 		stripflg = iop->iofile & IOSTRIP;
231*0Sstevel@tonic-gate 		if (nosubst)
232*0Sstevel@tonic-gate 			iop->iofile &= ~IODOC;
233*0Sstevel@tonic-gate 		fd = tmpfil(&tb);
234*0Sstevel@tonic-gate 
235*0Sstevel@tonic-gate 		if (fndef)
236*0Sstevel@tonic-gate 			iop->ioname = (char *) make(tmpout);
237*0Sstevel@tonic-gate 		else
238*0Sstevel@tonic-gate 			iop->ioname = (char *) cpystak(tmpout);
239*0Sstevel@tonic-gate 
240*0Sstevel@tonic-gate 		iop->iolst = iotemp;
241*0Sstevel@tonic-gate 		iotemp = iop;
242*0Sstevel@tonic-gate 
243*0Sstevel@tonic-gate 		cline = clinep = start = locstak();
244*0Sstevel@tonic-gate 		if (stripflg)
245*0Sstevel@tonic-gate 		{
246*0Sstevel@tonic-gate 			iop->iofile &= ~IOSTRIP;
247*0Sstevel@tonic-gate 			while (*ends == '\t')
248*0Sstevel@tonic-gate 				ends++;
249*0Sstevel@tonic-gate 		}
250*0Sstevel@tonic-gate 		for (;;)
251*0Sstevel@tonic-gate 		{
252*0Sstevel@tonic-gate 			chkpr();
253*0Sstevel@tonic-gate 			if (nosubst)
254*0Sstevel@tonic-gate 			{
255*0Sstevel@tonic-gate 				c = readwc();
256*0Sstevel@tonic-gate 				if (stripflg)
257*0Sstevel@tonic-gate 					while (c == '\t')
258*0Sstevel@tonic-gate 						c = readwc();
259*0Sstevel@tonic-gate 
260*0Sstevel@tonic-gate 				while (!eolchar(c))
261*0Sstevel@tonic-gate 				{
262*0Sstevel@tonic-gate 					pc = readw(c);
263*0Sstevel@tonic-gate 					while (*pc) {
264*0Sstevel@tonic-gate 						if (clinep >= brkend)
265*0Sstevel@tonic-gate 							growstak(clinep);
266*0Sstevel@tonic-gate 						*clinep++ = *pc++;
267*0Sstevel@tonic-gate 					}
268*0Sstevel@tonic-gate 					c = readwc();
269*0Sstevel@tonic-gate 				}
270*0Sstevel@tonic-gate 			}else{
271*0Sstevel@tonic-gate 				c = nextwc();
272*0Sstevel@tonic-gate 				if (stripflg)
273*0Sstevel@tonic-gate 					while (c == '\t')
274*0Sstevel@tonic-gate 						c = nextwc();
275*0Sstevel@tonic-gate 
276*0Sstevel@tonic-gate 				while (!eolchar(c))
277*0Sstevel@tonic-gate 				{
278*0Sstevel@tonic-gate 					pc = readw(c);
279*0Sstevel@tonic-gate 					while (*pc) {
280*0Sstevel@tonic-gate 						if (clinep >= brkend)
281*0Sstevel@tonic-gate 							growstak(clinep);
282*0Sstevel@tonic-gate 						*clinep++ = *pc++;
283*0Sstevel@tonic-gate 					}
284*0Sstevel@tonic-gate 					if (c == '\\')
285*0Sstevel@tonic-gate 					{
286*0Sstevel@tonic-gate 						pc = readw(readwc());
287*0Sstevel@tonic-gate 						/* *pc might be NULL */
288*0Sstevel@tonic-gate 						if (*pc) {
289*0Sstevel@tonic-gate 							while (*pc) {
290*0Sstevel@tonic-gate 								if (clinep >= brkend)
291*0Sstevel@tonic-gate 									growstak(clinep);
292*0Sstevel@tonic-gate 								*clinep++ = *pc++;
293*0Sstevel@tonic-gate 							}
294*0Sstevel@tonic-gate 						} else {
295*0Sstevel@tonic-gate 							if (clinep >= brkend)
296*0Sstevel@tonic-gate 								growstak(clinep);
297*0Sstevel@tonic-gate 							*clinep++ = *pc;
298*0Sstevel@tonic-gate 						}
299*0Sstevel@tonic-gate 					}
300*0Sstevel@tonic-gate 					c = nextwc();
301*0Sstevel@tonic-gate 				}
302*0Sstevel@tonic-gate 			}
303*0Sstevel@tonic-gate 
304*0Sstevel@tonic-gate 			if (clinep >= brkend)
305*0Sstevel@tonic-gate 				growstak(clinep);
306*0Sstevel@tonic-gate 			*clinep = 0;
307*0Sstevel@tonic-gate 			if (eof || eq(cline, ends))
308*0Sstevel@tonic-gate 			{
309*0Sstevel@tonic-gate 				if ((i = cline - start) > 0)
310*0Sstevel@tonic-gate 					write(fd, start, i);
311*0Sstevel@tonic-gate 				break;
312*0Sstevel@tonic-gate 			}else{
313*0Sstevel@tonic-gate 				if (clinep >= brkend)
314*0Sstevel@tonic-gate 					growstak(clinep);
315*0Sstevel@tonic-gate 				*clinep++ = NL;
316*0Sstevel@tonic-gate 			}
317*0Sstevel@tonic-gate 
318*0Sstevel@tonic-gate 			if ((i = clinep - start) < CPYSIZ)
319*0Sstevel@tonic-gate 				cline = clinep;
320*0Sstevel@tonic-gate 			else
321*0Sstevel@tonic-gate 			{
322*0Sstevel@tonic-gate 				write(fd, start, i);
323*0Sstevel@tonic-gate 				cline = clinep = start;
324*0Sstevel@tonic-gate 			}
325*0Sstevel@tonic-gate 		}
326*0Sstevel@tonic-gate 
327*0Sstevel@tonic-gate 		poptemp();	/*
328*0Sstevel@tonic-gate 				 * pushed in tmpfil -- bug fix for problem
329*0Sstevel@tonic-gate 				 * deleting in-line scripts
330*0Sstevel@tonic-gate 				 */
331*0Sstevel@tonic-gate 	}
332*0Sstevel@tonic-gate }
333*0Sstevel@tonic-gate 
334*0Sstevel@tonic-gate 
335*0Sstevel@tonic-gate link_iodocs(i)
336*0Sstevel@tonic-gate 	struct ionod	*i;
337*0Sstevel@tonic-gate {
338*0Sstevel@tonic-gate 	int r;
339*0Sstevel@tonic-gate 
340*0Sstevel@tonic-gate 	while (i)
341*0Sstevel@tonic-gate 	{
342*0Sstevel@tonic-gate 		free(i->iolink);
343*0Sstevel@tonic-gate 
344*0Sstevel@tonic-gate 		/* make sure tmp file does not already exist. */
345*0Sstevel@tonic-gate 		do {
346*0Sstevel@tonic-gate 			itos(serial++);
347*0Sstevel@tonic-gate 			movstr(numbuf, tmpname);
348*0Sstevel@tonic-gate 			r = link(i->ioname, (char *)tmpout);
349*0Sstevel@tonic-gate 		} while (r == -1 && errno == EEXIST);
350*0Sstevel@tonic-gate 
351*0Sstevel@tonic-gate 		if (r != -1) {
352*0Sstevel@tonic-gate 			i->iolink = (char *)make(tmpout);
353*0Sstevel@tonic-gate 			i = i->iolst;
354*0Sstevel@tonic-gate 		} else
355*0Sstevel@tonic-gate 			failed(tmpout, badcreate);
356*0Sstevel@tonic-gate 
357*0Sstevel@tonic-gate 	}
358*0Sstevel@tonic-gate }
359*0Sstevel@tonic-gate 
360*0Sstevel@tonic-gate 
361*0Sstevel@tonic-gate swap_iodoc_nm(i)
362*0Sstevel@tonic-gate 	struct ionod	*i;
363*0Sstevel@tonic-gate {
364*0Sstevel@tonic-gate 	while (i)
365*0Sstevel@tonic-gate 	{
366*0Sstevel@tonic-gate 		free(i->ioname);
367*0Sstevel@tonic-gate 		i->ioname = i->iolink;
368*0Sstevel@tonic-gate 		i->iolink = 0;
369*0Sstevel@tonic-gate 
370*0Sstevel@tonic-gate 		i = i->iolst;
371*0Sstevel@tonic-gate 	}
372*0Sstevel@tonic-gate }
373*0Sstevel@tonic-gate 
374*0Sstevel@tonic-gate 
375*0Sstevel@tonic-gate savefd(fd)
376*0Sstevel@tonic-gate 	int fd;
377*0Sstevel@tonic-gate {
378*0Sstevel@tonic-gate 	register int	f;
379*0Sstevel@tonic-gate 
380*0Sstevel@tonic-gate 	f = fcntl(fd, F_DUPFD, 10);
381*0Sstevel@tonic-gate 	return (f);
382*0Sstevel@tonic-gate }
383*0Sstevel@tonic-gate 
384*0Sstevel@tonic-gate 
385*0Sstevel@tonic-gate restore(last)
386*0Sstevel@tonic-gate 	register int	last;
387*0Sstevel@tonic-gate {
388*0Sstevel@tonic-gate 	register int 	i;
389*0Sstevel@tonic-gate 	register int	dupfd;
390*0Sstevel@tonic-gate 
391*0Sstevel@tonic-gate 	for (i = topfd - 1; i >= last; i--)
392*0Sstevel@tonic-gate 	{
393*0Sstevel@tonic-gate 		if ((dupfd = fdmap[i].dup_fd) > 0)
394*0Sstevel@tonic-gate 			renamef(dupfd, fdmap[i].org_fd);
395*0Sstevel@tonic-gate 		else
396*0Sstevel@tonic-gate 			close(fdmap[i].org_fd);
397*0Sstevel@tonic-gate 	}
398*0Sstevel@tonic-gate 	topfd = last;
399*0Sstevel@tonic-gate }
400