xref: /onnv-gate/usr/src/cmd/csh/sh.misc.c (revision 356)
10Sstevel@tonic-gate /*
2*356Smuffin  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
30Sstevel@tonic-gate  * Use is subject to license terms.
40Sstevel@tonic-gate  */
50Sstevel@tonic-gate 
60Sstevel@tonic-gate /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
70Sstevel@tonic-gate /*	  All Rights Reserved  	*/
80Sstevel@tonic-gate 
90Sstevel@tonic-gate /*
100Sstevel@tonic-gate  * Copyright (c) 1980 Regents of the University of California.
110Sstevel@tonic-gate  * All rights reserved.  The Berkeley Software License Agreement
120Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
130Sstevel@tonic-gate  */
140Sstevel@tonic-gate 
150Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
160Sstevel@tonic-gate 
170Sstevel@tonic-gate #include "sh.h"
180Sstevel@tonic-gate #include "sh.tconst.h"
190Sstevel@tonic-gate #include <fcntl.h>
200Sstevel@tonic-gate #include <unistd.h>
210Sstevel@tonic-gate 
220Sstevel@tonic-gate /*
230Sstevel@tonic-gate  * C Shell
240Sstevel@tonic-gate  */
25*356Smuffin tchar	**blkcat(tchar **, tchar **);
26*356Smuffin tchar	**blkend(tchar **);
270Sstevel@tonic-gate 
28*356Smuffin int
29*356Smuffin any(int c, tchar *s)
300Sstevel@tonic-gate {
310Sstevel@tonic-gate 
320Sstevel@tonic-gate 	while (s && *s)
330Sstevel@tonic-gate 		if (*s++ == c)
340Sstevel@tonic-gate 			return (1);
350Sstevel@tonic-gate 	return (0);
360Sstevel@tonic-gate }
370Sstevel@tonic-gate 
38*356Smuffin int
39*356Smuffin onlyread(tchar *cp)
400Sstevel@tonic-gate {
410Sstevel@tonic-gate 	extern char end[];
420Sstevel@tonic-gate 
430Sstevel@tonic-gate 	return ((char *)cp < end);
440Sstevel@tonic-gate }
450Sstevel@tonic-gate 
460Sstevel@tonic-gate 
470Sstevel@tonic-gate /*
480Sstevel@tonic-gate  * WARNING: changes here also need to occur in the XFREE macro in sh.h.
490Sstevel@tonic-gate  */
50*356Smuffin void
51*356Smuffin xfree(char *cp)
520Sstevel@tonic-gate {
530Sstevel@tonic-gate 	extern char end[];
540Sstevel@tonic-gate 
550Sstevel@tonic-gate #if defined(sparc)
560Sstevel@tonic-gate 	if ((char *)cp >= end && (char *)cp <  (char *)&cp)
570Sstevel@tonic-gate 		free(cp);
580Sstevel@tonic-gate #elif defined(i386)
590Sstevel@tonic-gate 	if ((char *)cp >= end)
600Sstevel@tonic-gate 		free(cp);
610Sstevel@tonic-gate #else
620Sstevel@tonic-gate #error xfree function is machine dependent and no machine type is recognized
630Sstevel@tonic-gate #endif
640Sstevel@tonic-gate }
650Sstevel@tonic-gate 
660Sstevel@tonic-gate tchar *
67*356Smuffin savestr(tchar *s)
680Sstevel@tonic-gate {
690Sstevel@tonic-gate 	tchar *n;
70*356Smuffin 	tchar *p;
710Sstevel@tonic-gate 
720Sstevel@tonic-gate 	if (s == 0)
730Sstevel@tonic-gate 		s = S_ /* "" */;
740Sstevel@tonic-gate #ifndef m32
750Sstevel@tonic-gate 	for (p = s; *p++; )
760Sstevel@tonic-gate 		;
770Sstevel@tonic-gate 	n = p = (tchar *)xalloc((unsigned) (p - s)*sizeof (tchar));
780Sstevel@tonic-gate 	while (*p++ = *s++)
790Sstevel@tonic-gate 		;
800Sstevel@tonic-gate 	return (n);
810Sstevel@tonic-gate #else
820Sstevel@tonic-gate 	p = (tchar *) xalloc((strlen_(s) + 1)*sizeof (tchar));
830Sstevel@tonic-gate 	strcpy_(p, s);
840Sstevel@tonic-gate 	return (p);
850Sstevel@tonic-gate #endif
860Sstevel@tonic-gate }
870Sstevel@tonic-gate 
880Sstevel@tonic-gate void *
89*356Smuffin calloc(size_t i, size_t j)
900Sstevel@tonic-gate {
91*356Smuffin 	char *cp;
920Sstevel@tonic-gate 
930Sstevel@tonic-gate 	i *= j;
940Sstevel@tonic-gate 	cp = (char *)xalloc(i);
950Sstevel@tonic-gate 	bzero(cp, (int)i);
960Sstevel@tonic-gate 	return (cp);
970Sstevel@tonic-gate }
980Sstevel@tonic-gate 
99*356Smuffin int
100*356Smuffin nomem(unsigned i)
1010Sstevel@tonic-gate {
1020Sstevel@tonic-gate #ifdef debug
1030Sstevel@tonic-gate 	static tchar *av[2] = {0, 0};
1040Sstevel@tonic-gate #endif
1050Sstevel@tonic-gate 
1060Sstevel@tonic-gate 	child++;
1070Sstevel@tonic-gate #ifndef debug
1080Sstevel@tonic-gate 	error("Out of memory");
1090Sstevel@tonic-gate #ifdef lint
1100Sstevel@tonic-gate 	i = i;
1110Sstevel@tonic-gate #endif
1120Sstevel@tonic-gate #else
1130Sstevel@tonic-gate 	showall(av);
1140Sstevel@tonic-gate 	printf("i=%d: Out of memory\n", i);
1150Sstevel@tonic-gate 	chdir("/usr/bill/cshcore");
1160Sstevel@tonic-gate 	abort();
1170Sstevel@tonic-gate #endif
1180Sstevel@tonic-gate 	return (0);		/* fool lint */
1190Sstevel@tonic-gate }
1200Sstevel@tonic-gate 
1210Sstevel@tonic-gate tchar **
122*356Smuffin blkend(tchar **up)
1230Sstevel@tonic-gate {
1240Sstevel@tonic-gate 
1250Sstevel@tonic-gate 	while (*up)
1260Sstevel@tonic-gate 		up++;
1270Sstevel@tonic-gate 	return (up);
1280Sstevel@tonic-gate }
1290Sstevel@tonic-gate 
130*356Smuffin void
131*356Smuffin blkpr(tchar **av)
1320Sstevel@tonic-gate {
1330Sstevel@tonic-gate 
1340Sstevel@tonic-gate 	for (; *av; av++) {
1350Sstevel@tonic-gate 		printf("%t", *av);
1360Sstevel@tonic-gate 		if (av[1])
1370Sstevel@tonic-gate 			printf(" ");
1380Sstevel@tonic-gate 	}
1390Sstevel@tonic-gate }
1400Sstevel@tonic-gate 
141*356Smuffin int
142*356Smuffin blklen(tchar **av)
1430Sstevel@tonic-gate {
144*356Smuffin 	int i = 0;
1450Sstevel@tonic-gate 
1460Sstevel@tonic-gate 	while (*av++)
1470Sstevel@tonic-gate 		i++;
1480Sstevel@tonic-gate 	return (i);
1490Sstevel@tonic-gate }
1500Sstevel@tonic-gate 
1510Sstevel@tonic-gate tchar **
152*356Smuffin blkcpy(tchar **oav, tchar **bv)
1530Sstevel@tonic-gate {
154*356Smuffin 	tchar **av = oav;
1550Sstevel@tonic-gate 
1560Sstevel@tonic-gate 	while (*av++ = *bv++)
1570Sstevel@tonic-gate 		continue;
1580Sstevel@tonic-gate 	return (oav);
1590Sstevel@tonic-gate }
1600Sstevel@tonic-gate 
1610Sstevel@tonic-gate tchar **
162*356Smuffin blkcat(tchar **up, tchar **vp)
1630Sstevel@tonic-gate {
1640Sstevel@tonic-gate 
1650Sstevel@tonic-gate 	(void) blkcpy(blkend(up), vp);
1660Sstevel@tonic-gate 	return (up);
1670Sstevel@tonic-gate }
1680Sstevel@tonic-gate 
169*356Smuffin void
170*356Smuffin blkfree(tchar **av0)
1710Sstevel@tonic-gate {
172*356Smuffin 	tchar **av = av0;
1730Sstevel@tonic-gate 
1740Sstevel@tonic-gate 	for (; *av; av++)
1750Sstevel@tonic-gate 		XFREE(*av)
1760Sstevel@tonic-gate 	XFREE((tchar *)av0)
1770Sstevel@tonic-gate }
1780Sstevel@tonic-gate 
1790Sstevel@tonic-gate tchar **
180*356Smuffin saveblk(tchar **v)
1810Sstevel@tonic-gate {
182*356Smuffin 	tchar **newv =
1830Sstevel@tonic-gate 		(tchar **) calloc((unsigned) (blklen(v) + 1),
1840Sstevel@tonic-gate 				sizeof (tchar **));
1850Sstevel@tonic-gate 	tchar **onewv = newv;
1860Sstevel@tonic-gate 
1870Sstevel@tonic-gate 	while (*v)
1880Sstevel@tonic-gate 		*newv++ = savestr(*v++);
1890Sstevel@tonic-gate 	return (onewv);
1900Sstevel@tonic-gate }
1910Sstevel@tonic-gate 
1920Sstevel@tonic-gate tchar *
193*356Smuffin strspl(tchar *cp, tchar *dp)
1940Sstevel@tonic-gate {
1950Sstevel@tonic-gate 	tchar *ep;
196*356Smuffin 	tchar *p, *q;
1970Sstevel@tonic-gate 
1980Sstevel@tonic-gate #ifndef m32
1990Sstevel@tonic-gate 	for (p = cp; *p++; )
2000Sstevel@tonic-gate 		;
2010Sstevel@tonic-gate 	for (q = dp; *q++; )
2020Sstevel@tonic-gate 		;
2030Sstevel@tonic-gate 	ep = (tchar *) xalloc((unsigned) (((p - cp) +
2040Sstevel@tonic-gate 			(q - dp) - 1))*sizeof (tchar));
2050Sstevel@tonic-gate 	for (p = ep, q = cp; *p++ = *q++; )
2060Sstevel@tonic-gate 		;
2070Sstevel@tonic-gate 	for (p--, q = dp; *p++ = *q++; )
2080Sstevel@tonic-gate 		;
2090Sstevel@tonic-gate #else
2100Sstevel@tonic-gate 	int	len1 = strlen_(cp);
2110Sstevel@tonic-gate 	int	len2 = strlen_(dp);
2120Sstevel@tonic-gate 
2130Sstevel@tonic-gate 	ep = (tchar *)xalloc((unsigned) (len1 + len2 + 1)*sizeof (tchar));
2140Sstevel@tonic-gate 	strcpy_(ep, cp);
2150Sstevel@tonic-gate 	strcat_(ep, dp);
2160Sstevel@tonic-gate #endif
2170Sstevel@tonic-gate 	return (ep);
2180Sstevel@tonic-gate }
2190Sstevel@tonic-gate 
2200Sstevel@tonic-gate tchar **
221*356Smuffin blkspl(tchar **up, tchar **vp)
2220Sstevel@tonic-gate {
223*356Smuffin 	tchar **wp =
2240Sstevel@tonic-gate 		(tchar **) calloc((unsigned) (blklen(up) + blklen(vp) + 1),
2250Sstevel@tonic-gate 			sizeof (tchar **));
2260Sstevel@tonic-gate 
2270Sstevel@tonic-gate 	(void) blkcpy(wp, up);
2280Sstevel@tonic-gate 	return (blkcat(wp, vp));
2290Sstevel@tonic-gate }
2300Sstevel@tonic-gate 
231*356Smuffin int
232*356Smuffin lastchr(tchar *cp)
2330Sstevel@tonic-gate {
2340Sstevel@tonic-gate 
2350Sstevel@tonic-gate 	if (!*cp)
2360Sstevel@tonic-gate 		return (0);
2370Sstevel@tonic-gate 	while (cp[1])
2380Sstevel@tonic-gate 		cp++;
2390Sstevel@tonic-gate 	return (*cp);
2400Sstevel@tonic-gate }
2410Sstevel@tonic-gate 
242*356Smuffin void
243*356Smuffin donefds(void)
2440Sstevel@tonic-gate {
2450Sstevel@tonic-gate 	(void) close(0);
2460Sstevel@tonic-gate 	(void) close(1);
2470Sstevel@tonic-gate 	(void) close(2);
2480Sstevel@tonic-gate 
2490Sstevel@tonic-gate 	/*
2500Sstevel@tonic-gate 	 * To avoid NIS+ functions to get hold of 0/1/2,
2510Sstevel@tonic-gate 	 * use descriptor 0, and dup it to 1 and 2.
2520Sstevel@tonic-gate 	 */
2530Sstevel@tonic-gate 	open("/dev/null", 0);
2540Sstevel@tonic-gate 	dup(0); dup(0);
2550Sstevel@tonic-gate 	didfds = 0;
2560Sstevel@tonic-gate }
2570Sstevel@tonic-gate 
2580Sstevel@tonic-gate /*
2590Sstevel@tonic-gate  * Move descriptor i to j.
2600Sstevel@tonic-gate  * If j is -1 then we just want to get i to a safe place,
2610Sstevel@tonic-gate  * i.e. to a unit > 2.  This also happens in dcopy.
2620Sstevel@tonic-gate  */
263*356Smuffin int
264*356Smuffin dmove(int i, int j)
2650Sstevel@tonic-gate {
2660Sstevel@tonic-gate 	int fd;
2670Sstevel@tonic-gate 
2680Sstevel@tonic-gate 	if (i == j || i < 0)
2690Sstevel@tonic-gate 		return (i);
2700Sstevel@tonic-gate 	if (j >= 0) {
2710Sstevel@tonic-gate 		fd = dup2(i, j);
2720Sstevel@tonic-gate 		if (fd != -1)
2730Sstevel@tonic-gate 			setfd(fd);
2740Sstevel@tonic-gate 	} else
2750Sstevel@tonic-gate 		j = dcopy(i, j);
2760Sstevel@tonic-gate 	if (j != i) {
2770Sstevel@tonic-gate 		(void) close(i);
2780Sstevel@tonic-gate 		unsetfd(i);
2790Sstevel@tonic-gate 	}
2800Sstevel@tonic-gate 	return (j);
2810Sstevel@tonic-gate }
2820Sstevel@tonic-gate 
283*356Smuffin int
284*356Smuffin dcopy(int i, int j)
2850Sstevel@tonic-gate {
2860Sstevel@tonic-gate 
2870Sstevel@tonic-gate 	int fd;
2880Sstevel@tonic-gate 
2890Sstevel@tonic-gate 	if (i == j || i < 0 || j < 0 && i > 2)
2900Sstevel@tonic-gate 		return (i);
2910Sstevel@tonic-gate 	if (j >= 0) {
2920Sstevel@tonic-gate 		fd = dup2(i, j);
2930Sstevel@tonic-gate 		if (fd != -1)
2940Sstevel@tonic-gate 			setfd(fd);
2950Sstevel@tonic-gate 		return (j);
2960Sstevel@tonic-gate 	}
2970Sstevel@tonic-gate 	(void) close(j);
2980Sstevel@tonic-gate 	unsetfd(j);
2990Sstevel@tonic-gate 	return (renum(i, j));
3000Sstevel@tonic-gate }
3010Sstevel@tonic-gate 
302*356Smuffin int
303*356Smuffin renum(int i, int j)
3040Sstevel@tonic-gate {
305*356Smuffin 	int k = dup(i);
3060Sstevel@tonic-gate 
3070Sstevel@tonic-gate 	if (k < 0)
3080Sstevel@tonic-gate 		return (-1);
3090Sstevel@tonic-gate 	if (j == -1 && k > 2) {
3100Sstevel@tonic-gate 		setfd(k);
3110Sstevel@tonic-gate 		return (k);
3120Sstevel@tonic-gate 	}
3130Sstevel@tonic-gate 	if (k != j) {
3140Sstevel@tonic-gate 		j = renum(k, j);
3150Sstevel@tonic-gate 		(void) close(k);	/* no need ofr unsetfd() */
3160Sstevel@tonic-gate 		return (j);
3170Sstevel@tonic-gate 	}
3180Sstevel@tonic-gate 	return (k);
3190Sstevel@tonic-gate }
3200Sstevel@tonic-gate 
3210Sstevel@tonic-gate #ifndef copy
322*356Smuffin void
323*356Smuffin copy(tchar *to, tchar *from, int size)
3240Sstevel@tonic-gate {
3250Sstevel@tonic-gate 
3260Sstevel@tonic-gate 	if (size)
3270Sstevel@tonic-gate 		do
3280Sstevel@tonic-gate 			*to++ = *from++;
3290Sstevel@tonic-gate 		while (--size != 0);
3300Sstevel@tonic-gate }
3310Sstevel@tonic-gate #endif
3320Sstevel@tonic-gate 
3330Sstevel@tonic-gate /*
3340Sstevel@tonic-gate  * Left shift a command argument list, discarding
3350Sstevel@tonic-gate  * the first c arguments.  Used in "shift" commands
3360Sstevel@tonic-gate  * as well as by commands like "repeat".
3370Sstevel@tonic-gate  */
338*356Smuffin void
339*356Smuffin lshift(tchar **v, int c)
3400Sstevel@tonic-gate {
341*356Smuffin 	tchar **u = v;
3420Sstevel@tonic-gate 
3430Sstevel@tonic-gate 	while (*u && --c >= 0)
344*356Smuffin 		xfree((char *)*u++);
3450Sstevel@tonic-gate 	(void) blkcpy(v, u);
3460Sstevel@tonic-gate }
3470Sstevel@tonic-gate 
348*356Smuffin int
349*356Smuffin number(tchar *cp)
3500Sstevel@tonic-gate {
3510Sstevel@tonic-gate 
3520Sstevel@tonic-gate 	if (*cp == '-') {
3530Sstevel@tonic-gate 		cp++;
3540Sstevel@tonic-gate 		if (!digit(*cp++))
3550Sstevel@tonic-gate 			return (0);
3560Sstevel@tonic-gate 	}
3570Sstevel@tonic-gate 	while (*cp && digit(*cp))
3580Sstevel@tonic-gate 		cp++;
3590Sstevel@tonic-gate 	return (*cp == 0);
3600Sstevel@tonic-gate }
3610Sstevel@tonic-gate 
3620Sstevel@tonic-gate tchar **
363*356Smuffin copyblk(tchar **v)
3640Sstevel@tonic-gate {
365*356Smuffin 	tchar **nv =
3660Sstevel@tonic-gate 		(tchar **) calloc((unsigned) (blklen(v) + 1),
3670Sstevel@tonic-gate 				sizeof (tchar **));
3680Sstevel@tonic-gate 
3690Sstevel@tonic-gate 	return (blkcpy(nv, v));
3700Sstevel@tonic-gate }
3710Sstevel@tonic-gate 
3720Sstevel@tonic-gate tchar *
373*356Smuffin strend(tchar *cp)
3740Sstevel@tonic-gate {
3750Sstevel@tonic-gate 
3760Sstevel@tonic-gate 	while (*cp)
3770Sstevel@tonic-gate 		cp++;
3780Sstevel@tonic-gate 	return (cp);
3790Sstevel@tonic-gate }
3800Sstevel@tonic-gate 
3810Sstevel@tonic-gate tchar *
382*356Smuffin strip(tchar *cp)
3830Sstevel@tonic-gate {
384*356Smuffin 	tchar *dp = cp;
3850Sstevel@tonic-gate 
3860Sstevel@tonic-gate 	while (*dp++ &= TRIM)
3870Sstevel@tonic-gate 		continue;
3880Sstevel@tonic-gate 	return (cp);
3890Sstevel@tonic-gate }
3900Sstevel@tonic-gate 
391*356Smuffin void
392*356Smuffin udvar(tchar *name)
3930Sstevel@tonic-gate {
3940Sstevel@tonic-gate 
3950Sstevel@tonic-gate 	setname(name);
3960Sstevel@tonic-gate 	bferr("Undefined variable");
3970Sstevel@tonic-gate }
3980Sstevel@tonic-gate 
399*356Smuffin int
400*356Smuffin prefix(tchar *sub, tchar *str)
4010Sstevel@tonic-gate {
4020Sstevel@tonic-gate 
4030Sstevel@tonic-gate 	for (;;) {
4040Sstevel@tonic-gate 		if (*sub == 0)
4050Sstevel@tonic-gate 			return (1);
4060Sstevel@tonic-gate 		if (*str == 0)
4070Sstevel@tonic-gate 			return (0);
4080Sstevel@tonic-gate 		if (*sub++ != *str++)
4090Sstevel@tonic-gate 			return (0);
4100Sstevel@tonic-gate 	}
4110Sstevel@tonic-gate }
4120Sstevel@tonic-gate 
4130Sstevel@tonic-gate /*
4140Sstevel@tonic-gate  * blk*_ routines
4150Sstevel@tonic-gate  */
4160Sstevel@tonic-gate 
4170Sstevel@tonic-gate char **
418*356Smuffin blkend_(char **up)
4190Sstevel@tonic-gate {
4200Sstevel@tonic-gate 
4210Sstevel@tonic-gate 	while (*up)
4220Sstevel@tonic-gate 		up++;
4230Sstevel@tonic-gate 	return (up);
4240Sstevel@tonic-gate }
4250Sstevel@tonic-gate 
426*356Smuffin int
427*356Smuffin blklen_(char **av)
4280Sstevel@tonic-gate {
429*356Smuffin 	int i = 0;
4300Sstevel@tonic-gate 
4310Sstevel@tonic-gate 	while (*av++)
4320Sstevel@tonic-gate 		i++;
4330Sstevel@tonic-gate 	return (i);
4340Sstevel@tonic-gate }
4350Sstevel@tonic-gate 
4360Sstevel@tonic-gate char **
437*356Smuffin blkcpy_(char **oav, char **bv)
4380Sstevel@tonic-gate {
439*356Smuffin 	char **av = oav;
4400Sstevel@tonic-gate 
4410Sstevel@tonic-gate 	while (*av++ = *bv++)
4420Sstevel@tonic-gate 		continue;
4430Sstevel@tonic-gate 	return (oav);
4440Sstevel@tonic-gate }
4450Sstevel@tonic-gate 
4460Sstevel@tonic-gate char **
447*356Smuffin blkcat_(char **up, char **vp)
4480Sstevel@tonic-gate {
4490Sstevel@tonic-gate 
4500Sstevel@tonic-gate 	(void) blkcpy_(blkend_(up), vp);
4510Sstevel@tonic-gate 	return (up);
4520Sstevel@tonic-gate }
4530Sstevel@tonic-gate 
4540Sstevel@tonic-gate char **
455*356Smuffin blkspl_(char **up, char **vp)
4560Sstevel@tonic-gate {
457*356Smuffin 	char **wp =
4580Sstevel@tonic-gate 		(char **) calloc((unsigned) (blklen_(up) + blklen_(vp) + 1),
4590Sstevel@tonic-gate 			sizeof (char **));
4600Sstevel@tonic-gate 
4610Sstevel@tonic-gate 	(void) blkcpy_(wp, up);
4620Sstevel@tonic-gate 	return (blkcat_(wp, vp));
4630Sstevel@tonic-gate }
464