xref: /titanic_52/usr/src/cmd/sh/args.c (revision 965005c81e0f731867d47892b9fb677030b102df)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
22*965005c8Schin 
23*965005c8Schin /*
24*965005c8Schin  * Copyright 1995 Sun Microsystems, Inc.  All rights reserved.
25*965005c8Schin  * Use is subject to license terms.
26*965005c8Schin  */
27*965005c8Schin 
287c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
297c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
307c478bd9Sstevel@tonic-gate 
31*965005c8Schin #pragma ident	"%Z%%M%	%I%	%E% SMI"
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate /*
347c478bd9Sstevel@tonic-gate  *	UNIX shell
357c478bd9Sstevel@tonic-gate  */
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate #include	"defs.h"
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate static struct dolnod *copyargs();
40*965005c8Schin static void freedolh(void);
417c478bd9Sstevel@tonic-gate extern struct dolnod *freeargs();
427c478bd9Sstevel@tonic-gate static struct dolnod *dolh;
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate /* Used to save outermost positional parameters */
457c478bd9Sstevel@tonic-gate static struct dolnod *globdolh;
467c478bd9Sstevel@tonic-gate static unsigned char **globdolv;
477c478bd9Sstevel@tonic-gate static int globdolc;
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate unsigned char	flagadr[16];
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate unsigned char	flagchar[] =
527c478bd9Sstevel@tonic-gate {
537c478bd9Sstevel@tonic-gate 	'x',
547c478bd9Sstevel@tonic-gate 	'n',
557c478bd9Sstevel@tonic-gate 	'v',
567c478bd9Sstevel@tonic-gate 	't',
577c478bd9Sstevel@tonic-gate 	STDFLG,
587c478bd9Sstevel@tonic-gate 	'i',
597c478bd9Sstevel@tonic-gate 	'e',
607c478bd9Sstevel@tonic-gate 	'r',
617c478bd9Sstevel@tonic-gate 	'k',
627c478bd9Sstevel@tonic-gate 	'u',
637c478bd9Sstevel@tonic-gate 	'h',
647c478bd9Sstevel@tonic-gate 	'f',
657c478bd9Sstevel@tonic-gate 	'a',
667c478bd9Sstevel@tonic-gate 	'm',
677c478bd9Sstevel@tonic-gate 	'p',
687c478bd9Sstevel@tonic-gate 	 0
697c478bd9Sstevel@tonic-gate };
707c478bd9Sstevel@tonic-gate 
717c478bd9Sstevel@tonic-gate long	flagval[]  =
727c478bd9Sstevel@tonic-gate {
737c478bd9Sstevel@tonic-gate 	execpr,
747c478bd9Sstevel@tonic-gate 	noexec,
757c478bd9Sstevel@tonic-gate 	readpr,
767c478bd9Sstevel@tonic-gate 	oneflg,
777c478bd9Sstevel@tonic-gate 	stdflg,
787c478bd9Sstevel@tonic-gate 	intflg,
797c478bd9Sstevel@tonic-gate 	errflg,
807c478bd9Sstevel@tonic-gate 	rshflg,
817c478bd9Sstevel@tonic-gate 	keyflg,
827c478bd9Sstevel@tonic-gate 	setflg,
837c478bd9Sstevel@tonic-gate 	hashflg,
847c478bd9Sstevel@tonic-gate 	nofngflg,
857c478bd9Sstevel@tonic-gate 	exportflg,
867c478bd9Sstevel@tonic-gate 	monitorflg,
877c478bd9Sstevel@tonic-gate 	privflg,
887c478bd9Sstevel@tonic-gate 	  0
897c478bd9Sstevel@tonic-gate };
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate /* ========	option handling	======== */
927c478bd9Sstevel@tonic-gate 
937c478bd9Sstevel@tonic-gate 
94*965005c8Schin int
95*965005c8Schin options(int argc, unsigned char **argv)
967c478bd9Sstevel@tonic-gate {
97*965005c8Schin 	unsigned char *cp;
98*965005c8Schin 	unsigned char **argp = argv;
99*965005c8Schin 	unsigned char *flagc;
1007c478bd9Sstevel@tonic-gate 	unsigned char	*flagp;
1017c478bd9Sstevel@tonic-gate 	int		len;
1027c478bd9Sstevel@tonic-gate 	wchar_t		wc;
1037c478bd9Sstevel@tonic-gate 
1047c478bd9Sstevel@tonic-gate 	if (argc > 1 && *argp[1] == '-')
1057c478bd9Sstevel@tonic-gate 	{
1067c478bd9Sstevel@tonic-gate 		/*
1077c478bd9Sstevel@tonic-gate 		 * if first argument is "--" then options are not
1087c478bd9Sstevel@tonic-gate 		 * to be changed. Fix for problems getting
1097c478bd9Sstevel@tonic-gate 		 * $1 starting with a "-"
1107c478bd9Sstevel@tonic-gate 		 */
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate 		cp = argp[1];
1137c478bd9Sstevel@tonic-gate 		if (cp[1] == '-')
1147c478bd9Sstevel@tonic-gate 		{
1157c478bd9Sstevel@tonic-gate 			argp[1] = argp[0];
1167c478bd9Sstevel@tonic-gate 			argc--;
1177c478bd9Sstevel@tonic-gate 			return(argc);
1187c478bd9Sstevel@tonic-gate 		}
1197c478bd9Sstevel@tonic-gate 		if (cp[1] == '\0')
1207c478bd9Sstevel@tonic-gate 			flags &= ~(execpr|readpr);
1217c478bd9Sstevel@tonic-gate 
1227c478bd9Sstevel@tonic-gate 		/*
1237c478bd9Sstevel@tonic-gate 		 * Step along 'flagchar[]' looking for matches.
1247c478bd9Sstevel@tonic-gate 		 * 'sicrp' are not legal with 'set' command.
1257c478bd9Sstevel@tonic-gate 		 */
1267c478bd9Sstevel@tonic-gate 		cp++;
1277c478bd9Sstevel@tonic-gate 		while (*cp) {
1287c478bd9Sstevel@tonic-gate 			if ((len = mbtowc(&wc, (char *)cp, MB_LEN_MAX)) <= 0) {
1297c478bd9Sstevel@tonic-gate 				len = 1;
1307c478bd9Sstevel@tonic-gate 				wc = (unsigned char)*cp;
1317c478bd9Sstevel@tonic-gate 				failed(argv[1],badopt);
1327c478bd9Sstevel@tonic-gate 			}
1337c478bd9Sstevel@tonic-gate 			cp += len;
1347c478bd9Sstevel@tonic-gate 
1357c478bd9Sstevel@tonic-gate 			flagc = flagchar;
1367c478bd9Sstevel@tonic-gate 			while (*flagc && wc != *flagc)
1377c478bd9Sstevel@tonic-gate 				flagc++;
1387c478bd9Sstevel@tonic-gate 			if (wc == *flagc)
1397c478bd9Sstevel@tonic-gate 			{
1407c478bd9Sstevel@tonic-gate 				if (eq(argv[0], "set") && any(wc, "sicrp"))
1417c478bd9Sstevel@tonic-gate 					failed(argv[1], badopt);
1427c478bd9Sstevel@tonic-gate 				else
1437c478bd9Sstevel@tonic-gate 				{
1447c478bd9Sstevel@tonic-gate 					flags |= flagval[flagc-flagchar];
1457c478bd9Sstevel@tonic-gate 					if (flags & errflg)
1467c478bd9Sstevel@tonic-gate 						eflag = errflg;
1477c478bd9Sstevel@tonic-gate 				}
1487c478bd9Sstevel@tonic-gate 			}
1497c478bd9Sstevel@tonic-gate 			else if (wc == 'c' && argc > 2 && comdiv == 0)
1507c478bd9Sstevel@tonic-gate 			{
1517c478bd9Sstevel@tonic-gate 				comdiv = argp[2];
1527c478bd9Sstevel@tonic-gate 				argp[1] = argp[0];
1537c478bd9Sstevel@tonic-gate 				argp++;
1547c478bd9Sstevel@tonic-gate 				argc--;
1557c478bd9Sstevel@tonic-gate 			}
1567c478bd9Sstevel@tonic-gate 			else
1577c478bd9Sstevel@tonic-gate 				failed(argv[1],badopt);
1587c478bd9Sstevel@tonic-gate 		}
1597c478bd9Sstevel@tonic-gate 		argp[1] = argp[0];
1607c478bd9Sstevel@tonic-gate 		argc--;
1617c478bd9Sstevel@tonic-gate 	}
1627c478bd9Sstevel@tonic-gate 	else if (argc > 1 && *argp[1] == '+')	/* unset flags x, k, t, n, v, e, u */
1637c478bd9Sstevel@tonic-gate 	{
1647c478bd9Sstevel@tonic-gate 		cp = argp[1];
1657c478bd9Sstevel@tonic-gate 		cp++;
1667c478bd9Sstevel@tonic-gate 		while (*cp)
1677c478bd9Sstevel@tonic-gate 		{
1687c478bd9Sstevel@tonic-gate 			if ((len = mbtowc(&wc, (char *)cp, MB_LEN_MAX)) <= 0) {
1697c478bd9Sstevel@tonic-gate 				cp++;
1707c478bd9Sstevel@tonic-gate 				continue;
1717c478bd9Sstevel@tonic-gate 			}
1727c478bd9Sstevel@tonic-gate 
1737c478bd9Sstevel@tonic-gate 			flagc = flagchar;
1747c478bd9Sstevel@tonic-gate 			while (*flagc && wc != *flagc)
1757c478bd9Sstevel@tonic-gate 				flagc++;
1767c478bd9Sstevel@tonic-gate 			/*
1777c478bd9Sstevel@tonic-gate 			 * step through flags
1787c478bd9Sstevel@tonic-gate 			 */
1797c478bd9Sstevel@tonic-gate 			if (!any(wc, "sicrp") && wc == *flagc) {
1807c478bd9Sstevel@tonic-gate 				flags &= ~(flagval[flagc-flagchar]);
1817c478bd9Sstevel@tonic-gate 				if (wc == 'e')
1827c478bd9Sstevel@tonic-gate 					eflag = 0;
1837c478bd9Sstevel@tonic-gate 			}
1847c478bd9Sstevel@tonic-gate 			cp += len;
1857c478bd9Sstevel@tonic-gate 		}
1867c478bd9Sstevel@tonic-gate 		argp[1] = argp[0];
1877c478bd9Sstevel@tonic-gate 		argc--;
1887c478bd9Sstevel@tonic-gate 	}
1897c478bd9Sstevel@tonic-gate 	/*
1907c478bd9Sstevel@tonic-gate 	 * set up $-
1917c478bd9Sstevel@tonic-gate 	 */
1927c478bd9Sstevel@tonic-gate 	flagp = flagadr;
1937c478bd9Sstevel@tonic-gate 	if (flags)
1947c478bd9Sstevel@tonic-gate 	{
1957c478bd9Sstevel@tonic-gate 		flagc = flagchar;
1967c478bd9Sstevel@tonic-gate 		while (*flagc)
1977c478bd9Sstevel@tonic-gate 		{
1987c478bd9Sstevel@tonic-gate 			if (flags & flagval[flagc-flagchar])
1997c478bd9Sstevel@tonic-gate 				*flagp++ = *flagc;
2007c478bd9Sstevel@tonic-gate 			flagc++;
2017c478bd9Sstevel@tonic-gate 		}
2027c478bd9Sstevel@tonic-gate 	}
2037c478bd9Sstevel@tonic-gate 	*flagp = 0;
2047c478bd9Sstevel@tonic-gate 	return(argc);
2057c478bd9Sstevel@tonic-gate }
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate /*
2087c478bd9Sstevel@tonic-gate  * sets up positional parameters
2097c478bd9Sstevel@tonic-gate  */
210*965005c8Schin void
211*965005c8Schin setargs(unsigned char *argi[])
2127c478bd9Sstevel@tonic-gate {
213*965005c8Schin 	unsigned char **argp = argi;	/* count args */
214*965005c8Schin 	int argn = 0;
2157c478bd9Sstevel@tonic-gate 
2167c478bd9Sstevel@tonic-gate 	while (*argp++ != (unsigned char *)ENDARGS)
2177c478bd9Sstevel@tonic-gate 		argn++;
2187c478bd9Sstevel@tonic-gate 	/*
2197c478bd9Sstevel@tonic-gate 	 * free old ones unless on for loop chain
2207c478bd9Sstevel@tonic-gate 	 */
2217c478bd9Sstevel@tonic-gate 	freedolh();
2227c478bd9Sstevel@tonic-gate 	dolh = copyargs(argi, argn);
2237c478bd9Sstevel@tonic-gate 	dolc = argn - 1;
2247c478bd9Sstevel@tonic-gate }
2257c478bd9Sstevel@tonic-gate 
2267c478bd9Sstevel@tonic-gate 
227*965005c8Schin static void
228*965005c8Schin freedolh(void)
2297c478bd9Sstevel@tonic-gate {
230*965005c8Schin 	unsigned char **argp;
231*965005c8Schin 	struct dolnod *argblk;
2327c478bd9Sstevel@tonic-gate 
2337c478bd9Sstevel@tonic-gate 	if (argblk = dolh)
2347c478bd9Sstevel@tonic-gate 	{
2357c478bd9Sstevel@tonic-gate 		if ((--argblk->doluse) == 0)
2367c478bd9Sstevel@tonic-gate 		{
2377c478bd9Sstevel@tonic-gate 			for (argp = argblk->dolarg; *argp != (unsigned char *)ENDARGS; argp++)
2387c478bd9Sstevel@tonic-gate 				free(*argp);
2397c478bd9Sstevel@tonic-gate 			free(argblk->dolarg);
2407c478bd9Sstevel@tonic-gate 			free(argblk);
2417c478bd9Sstevel@tonic-gate 		}
2427c478bd9Sstevel@tonic-gate 	}
2437c478bd9Sstevel@tonic-gate }
2447c478bd9Sstevel@tonic-gate 
2457c478bd9Sstevel@tonic-gate struct dolnod *
2467c478bd9Sstevel@tonic-gate freeargs(blk)
2477c478bd9Sstevel@tonic-gate 	struct dolnod *blk;
2487c478bd9Sstevel@tonic-gate {
249*965005c8Schin 	unsigned char **argp;
250*965005c8Schin 	struct dolnod *argr = 0;
251*965005c8Schin 	struct dolnod *argblk;
2527c478bd9Sstevel@tonic-gate 	int cnt;
2537c478bd9Sstevel@tonic-gate 
2547c478bd9Sstevel@tonic-gate 	if (argblk = blk)
2557c478bd9Sstevel@tonic-gate 	{
2567c478bd9Sstevel@tonic-gate 		argr = argblk->dolnxt;
2577c478bd9Sstevel@tonic-gate 		cnt  = --argblk->doluse;
2587c478bd9Sstevel@tonic-gate 
2597c478bd9Sstevel@tonic-gate 		if (argblk == dolh)
2607c478bd9Sstevel@tonic-gate 		{
2617c478bd9Sstevel@tonic-gate 			if (cnt == 1)
2627c478bd9Sstevel@tonic-gate 				return(argr);
2637c478bd9Sstevel@tonic-gate 			else
2647c478bd9Sstevel@tonic-gate 				return(argblk);
2657c478bd9Sstevel@tonic-gate 		}
2667c478bd9Sstevel@tonic-gate 		else
2677c478bd9Sstevel@tonic-gate 		{
2687c478bd9Sstevel@tonic-gate 			if (cnt == 0)
2697c478bd9Sstevel@tonic-gate 			{
2707c478bd9Sstevel@tonic-gate 				for (argp = argblk->dolarg; *argp != (unsigned char *)ENDARGS; argp++)
2717c478bd9Sstevel@tonic-gate 					free(*argp);
2727c478bd9Sstevel@tonic-gate 				free(argblk->dolarg);
2737c478bd9Sstevel@tonic-gate 				free(argblk);
2747c478bd9Sstevel@tonic-gate 			}
2757c478bd9Sstevel@tonic-gate 		}
2767c478bd9Sstevel@tonic-gate 	}
2777c478bd9Sstevel@tonic-gate 	return(argr);
2787c478bd9Sstevel@tonic-gate }
2797c478bd9Sstevel@tonic-gate 
2807c478bd9Sstevel@tonic-gate static struct dolnod *
2817c478bd9Sstevel@tonic-gate copyargs(from, n)
2827c478bd9Sstevel@tonic-gate 	unsigned char	*from[];
2837c478bd9Sstevel@tonic-gate {
284*965005c8Schin 	struct dolnod *np = (struct dolnod *)alloc(sizeof (struct dolnod));
285*965005c8Schin 	unsigned char **fp = from;
286*965005c8Schin 	unsigned char **pp;
2877c478bd9Sstevel@tonic-gate 
2887c478bd9Sstevel@tonic-gate 	np -> dolnxt = 0;
2897c478bd9Sstevel@tonic-gate 	np->doluse = 1;	/* use count */
2907c478bd9Sstevel@tonic-gate 	pp = np->dolarg = (unsigned char **)alloc((n+1)*sizeof(char *));
2917c478bd9Sstevel@tonic-gate 	dolv = pp;
2927c478bd9Sstevel@tonic-gate 
2937c478bd9Sstevel@tonic-gate 	while (n--)
2947c478bd9Sstevel@tonic-gate 		*pp++ = make(*fp++);
2957c478bd9Sstevel@tonic-gate 	*pp++ = ENDARGS;
2967c478bd9Sstevel@tonic-gate 	return(np);
2977c478bd9Sstevel@tonic-gate }
2987c478bd9Sstevel@tonic-gate 
2997c478bd9Sstevel@tonic-gate 
3007c478bd9Sstevel@tonic-gate struct dolnod *
3017c478bd9Sstevel@tonic-gate clean_args(blk)
3027c478bd9Sstevel@tonic-gate 	struct dolnod *blk;
3037c478bd9Sstevel@tonic-gate {
304*965005c8Schin 	unsigned char **argp;
305*965005c8Schin 	struct dolnod *argr = 0;
306*965005c8Schin 	struct dolnod *argblk;
3077c478bd9Sstevel@tonic-gate 
3087c478bd9Sstevel@tonic-gate 	if (argblk = blk)
3097c478bd9Sstevel@tonic-gate 	{
3107c478bd9Sstevel@tonic-gate 		argr = argblk->dolnxt;
3117c478bd9Sstevel@tonic-gate 
3127c478bd9Sstevel@tonic-gate 		if (argblk == dolh)
3137c478bd9Sstevel@tonic-gate 			argblk->doluse = 1;
3147c478bd9Sstevel@tonic-gate 		else
3157c478bd9Sstevel@tonic-gate 		{
3167c478bd9Sstevel@tonic-gate 			for (argp = argblk->dolarg; *argp != (unsigned char *)ENDARGS; argp++)
3177c478bd9Sstevel@tonic-gate 				free(*argp);
3187c478bd9Sstevel@tonic-gate 			free(argblk->dolarg);
3197c478bd9Sstevel@tonic-gate 			free(argblk);
3207c478bd9Sstevel@tonic-gate 		}
3217c478bd9Sstevel@tonic-gate 	}
3227c478bd9Sstevel@tonic-gate 	return(argr);
3237c478bd9Sstevel@tonic-gate }
3247c478bd9Sstevel@tonic-gate 
325*965005c8Schin void
326*965005c8Schin clearup(void)
3277c478bd9Sstevel@tonic-gate {
3287c478bd9Sstevel@tonic-gate 	/*
3297c478bd9Sstevel@tonic-gate 	 * force `for' $* lists to go away
3307c478bd9Sstevel@tonic-gate 	 */
3317c478bd9Sstevel@tonic-gate 	if(globdolv)
3327c478bd9Sstevel@tonic-gate 		dolv = globdolv;
3337c478bd9Sstevel@tonic-gate 	if(globdolc)
3347c478bd9Sstevel@tonic-gate 		dolc = globdolc;
3357c478bd9Sstevel@tonic-gate 	if(globdolh)
3367c478bd9Sstevel@tonic-gate 		dolh = globdolh;
3377c478bd9Sstevel@tonic-gate 	globdolv = 0;
3387c478bd9Sstevel@tonic-gate 	globdolc = 0;
3397c478bd9Sstevel@tonic-gate 	globdolh = 0;
3407c478bd9Sstevel@tonic-gate 	while (argfor = clean_args(argfor))
3417c478bd9Sstevel@tonic-gate 		;
3427c478bd9Sstevel@tonic-gate 	/*
3437c478bd9Sstevel@tonic-gate 	 * clean up io files
3447c478bd9Sstevel@tonic-gate 	 */
3457c478bd9Sstevel@tonic-gate 	while (pop())
3467c478bd9Sstevel@tonic-gate 		;
3477c478bd9Sstevel@tonic-gate 
3487c478bd9Sstevel@tonic-gate 	/*
3497c478bd9Sstevel@tonic-gate 	 * Clean up pipe file descriptor
3507c478bd9Sstevel@tonic-gate 	 * from command substitution
3517c478bd9Sstevel@tonic-gate 	 */
3527c478bd9Sstevel@tonic-gate 
3537c478bd9Sstevel@tonic-gate 	if(savpipe != -1) {
3547c478bd9Sstevel@tonic-gate 		close(savpipe);
3557c478bd9Sstevel@tonic-gate 		savpipe = -1;
3567c478bd9Sstevel@tonic-gate 	}
3577c478bd9Sstevel@tonic-gate 
3587c478bd9Sstevel@tonic-gate 	/*
3597c478bd9Sstevel@tonic-gate 	 * clean up tmp files
3607c478bd9Sstevel@tonic-gate 	*/
3617c478bd9Sstevel@tonic-gate 	while (poptemp())
3627c478bd9Sstevel@tonic-gate 		;
3637c478bd9Sstevel@tonic-gate }
3647c478bd9Sstevel@tonic-gate 
3657c478bd9Sstevel@tonic-gate /*
3667c478bd9Sstevel@tonic-gate  * Save positiional parameters before outermost function invocation
3677c478bd9Sstevel@tonic-gate  * in case we are interrupted.
3687c478bd9Sstevel@tonic-gate  * Increment use count for current positional parameters so that they aren't thrown
3697c478bd9Sstevel@tonic-gate  * away.
3707c478bd9Sstevel@tonic-gate  */
3717c478bd9Sstevel@tonic-gate 
3727c478bd9Sstevel@tonic-gate struct dolnod *savargs(funcnt)
3737c478bd9Sstevel@tonic-gate int funcnt;
3747c478bd9Sstevel@tonic-gate {
3757c478bd9Sstevel@tonic-gate 	if (!funcnt) {
3767c478bd9Sstevel@tonic-gate 		globdolh = dolh;
3777c478bd9Sstevel@tonic-gate 		globdolv = dolv;
3787c478bd9Sstevel@tonic-gate 		globdolc = dolc;
3797c478bd9Sstevel@tonic-gate 	}
3807c478bd9Sstevel@tonic-gate 	useargs();
3817c478bd9Sstevel@tonic-gate 	return(dolh);
3827c478bd9Sstevel@tonic-gate }
3837c478bd9Sstevel@tonic-gate 
3847c478bd9Sstevel@tonic-gate /* After function invocation, free positional parameters,
3857c478bd9Sstevel@tonic-gate  * restore old positional parameters, and restore
3867c478bd9Sstevel@tonic-gate  * use count.
3877c478bd9Sstevel@tonic-gate  */
3887c478bd9Sstevel@tonic-gate 
3897c478bd9Sstevel@tonic-gate void restorargs(olddolh, funcnt)
3907c478bd9Sstevel@tonic-gate struct dolnod *olddolh;
3917c478bd9Sstevel@tonic-gate {
3927c478bd9Sstevel@tonic-gate 	if(argfor != olddolh)
3937c478bd9Sstevel@tonic-gate 		while ((argfor = clean_args(argfor)) != olddolh && argfor);
3947c478bd9Sstevel@tonic-gate 	if(!argfor)
3957c478bd9Sstevel@tonic-gate 		return;
3967c478bd9Sstevel@tonic-gate 	freedolh();
3977c478bd9Sstevel@tonic-gate 	dolh = olddolh;
3987c478bd9Sstevel@tonic-gate 	if(dolh)
3997c478bd9Sstevel@tonic-gate 		dolh -> doluse++; /* increment use count so arguments aren't freed */
4007c478bd9Sstevel@tonic-gate 	argfor = freeargs(dolh);
4017c478bd9Sstevel@tonic-gate 	if(funcnt == 1) {
4027c478bd9Sstevel@tonic-gate 		globdolh = 0;
4037c478bd9Sstevel@tonic-gate 		globdolv = 0;
4047c478bd9Sstevel@tonic-gate 		globdolc = 0;
4057c478bd9Sstevel@tonic-gate 	}
4067c478bd9Sstevel@tonic-gate }
4077c478bd9Sstevel@tonic-gate 
4087c478bd9Sstevel@tonic-gate struct dolnod *
4097c478bd9Sstevel@tonic-gate useargs()
4107c478bd9Sstevel@tonic-gate {
4117c478bd9Sstevel@tonic-gate 	if (dolh)
4127c478bd9Sstevel@tonic-gate 	{
4137c478bd9Sstevel@tonic-gate 		if (dolh->doluse++ == 1)
4147c478bd9Sstevel@tonic-gate 		{
4157c478bd9Sstevel@tonic-gate 			dolh->dolnxt = argfor;
4167c478bd9Sstevel@tonic-gate 			argfor = dolh;
4177c478bd9Sstevel@tonic-gate 		}
4187c478bd9Sstevel@tonic-gate 	}
4197c478bd9Sstevel@tonic-gate 	return(dolh);
4207c478bd9Sstevel@tonic-gate }
4217c478bd9Sstevel@tonic-gate 
422