xref: /illumos-gate/usr/src/cmd/csh/sh.misc.c (revision 2a8bcb4e)
17c478bd9Sstevel@tonic-gate /*
26c02b4a4Smuffin  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
57c478bd9Sstevel@tonic-gate 
67c478bd9Sstevel@tonic-gate /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
77c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
87c478bd9Sstevel@tonic-gate 
97c478bd9Sstevel@tonic-gate /*
107c478bd9Sstevel@tonic-gate  * Copyright (c) 1980 Regents of the University of California.
117c478bd9Sstevel@tonic-gate  * All rights reserved.  The Berkeley Software License Agreement
127c478bd9Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
137c478bd9Sstevel@tonic-gate  */
147c478bd9Sstevel@tonic-gate 
157c478bd9Sstevel@tonic-gate #include "sh.h"
167c478bd9Sstevel@tonic-gate #include "sh.tconst.h"
177c478bd9Sstevel@tonic-gate #include <fcntl.h>
187c478bd9Sstevel@tonic-gate #include <unistd.h>
197c478bd9Sstevel@tonic-gate 
207c478bd9Sstevel@tonic-gate /*
217c478bd9Sstevel@tonic-gate  * C Shell
227c478bd9Sstevel@tonic-gate  */
236c02b4a4Smuffin tchar	**blkcat(tchar **, tchar **);
246c02b4a4Smuffin tchar	**blkend(tchar **);
257c478bd9Sstevel@tonic-gate 
266c02b4a4Smuffin int
any(int c,tchar * s)276c02b4a4Smuffin any(int c, tchar *s)
287c478bd9Sstevel@tonic-gate {
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate 	while (s && *s)
317c478bd9Sstevel@tonic-gate 		if (*s++ == c)
327c478bd9Sstevel@tonic-gate 			return (1);
337c478bd9Sstevel@tonic-gate 	return (0);
347c478bd9Sstevel@tonic-gate }
357c478bd9Sstevel@tonic-gate 
366c02b4a4Smuffin int
onlyread(tchar * cp)376c02b4a4Smuffin onlyread(tchar *cp)
387c478bd9Sstevel@tonic-gate {
397c478bd9Sstevel@tonic-gate 	extern char end[];
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate 	return ((char *)cp < end);
427c478bd9Sstevel@tonic-gate }
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate tchar *
savestr(tchar * s)456c02b4a4Smuffin savestr(tchar *s)
467c478bd9Sstevel@tonic-gate {
477c478bd9Sstevel@tonic-gate 	tchar *n;
486c02b4a4Smuffin 	tchar *p;
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate 	if (s == 0)
517c478bd9Sstevel@tonic-gate 		s = S_ /* "" */;
527c478bd9Sstevel@tonic-gate #ifndef m32
537c478bd9Sstevel@tonic-gate 	for (p = s; *p++; )
547c478bd9Sstevel@tonic-gate 		;
55*65b0c20eSnakanon 	n = p = (tchar *)xalloc((unsigned)(p - s)*sizeof (tchar));
567c478bd9Sstevel@tonic-gate 	while (*p++ = *s++)
577c478bd9Sstevel@tonic-gate 		;
587c478bd9Sstevel@tonic-gate 	return (n);
597c478bd9Sstevel@tonic-gate #else
607c478bd9Sstevel@tonic-gate 	p = (tchar *) xalloc((strlen_(s) + 1)*sizeof (tchar));
617c478bd9Sstevel@tonic-gate 	strcpy_(p, s);
627c478bd9Sstevel@tonic-gate 	return (p);
637c478bd9Sstevel@tonic-gate #endif
647c478bd9Sstevel@tonic-gate }
657c478bd9Sstevel@tonic-gate 
66*65b0c20eSnakanon static void *
nomem(size_t i)67*65b0c20eSnakanon nomem(size_t i)
687c478bd9Sstevel@tonic-gate {
697c478bd9Sstevel@tonic-gate #ifdef debug
707c478bd9Sstevel@tonic-gate 	static tchar *av[2] = {0, 0};
717c478bd9Sstevel@tonic-gate #endif
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate 	child++;
747c478bd9Sstevel@tonic-gate #ifndef debug
757c478bd9Sstevel@tonic-gate 	error("Out of memory");
767c478bd9Sstevel@tonic-gate #ifdef lint
777c478bd9Sstevel@tonic-gate 	i = i;
787c478bd9Sstevel@tonic-gate #endif
797c478bd9Sstevel@tonic-gate #else
807c478bd9Sstevel@tonic-gate 	showall(av);
817c478bd9Sstevel@tonic-gate 	printf("i=%d: Out of memory\n", i);
827c478bd9Sstevel@tonic-gate 	chdir("/usr/bill/cshcore");
837c478bd9Sstevel@tonic-gate 	abort();
847c478bd9Sstevel@tonic-gate #endif
857c478bd9Sstevel@tonic-gate 	return (0);		/* fool lint */
867c478bd9Sstevel@tonic-gate }
877c478bd9Sstevel@tonic-gate 
887c478bd9Sstevel@tonic-gate tchar **
blkend(tchar ** up)896c02b4a4Smuffin blkend(tchar **up)
907c478bd9Sstevel@tonic-gate {
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate 	while (*up)
937c478bd9Sstevel@tonic-gate 		up++;
947c478bd9Sstevel@tonic-gate 	return (up);
957c478bd9Sstevel@tonic-gate }
967c478bd9Sstevel@tonic-gate 
976c02b4a4Smuffin void
blkpr(tchar ** av)986c02b4a4Smuffin blkpr(tchar **av)
997c478bd9Sstevel@tonic-gate {
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate 	for (; *av; av++) {
1027c478bd9Sstevel@tonic-gate 		printf("%t", *av);
1037c478bd9Sstevel@tonic-gate 		if (av[1])
1047c478bd9Sstevel@tonic-gate 			printf(" ");
1057c478bd9Sstevel@tonic-gate 	}
1067c478bd9Sstevel@tonic-gate }
1077c478bd9Sstevel@tonic-gate 
1086c02b4a4Smuffin int
blklen(tchar ** av)1096c02b4a4Smuffin blklen(tchar **av)
1107c478bd9Sstevel@tonic-gate {
1116c02b4a4Smuffin 	int i = 0;
1127c478bd9Sstevel@tonic-gate 
1137c478bd9Sstevel@tonic-gate 	while (*av++)
1147c478bd9Sstevel@tonic-gate 		i++;
1157c478bd9Sstevel@tonic-gate 	return (i);
1167c478bd9Sstevel@tonic-gate }
1177c478bd9Sstevel@tonic-gate 
1187c478bd9Sstevel@tonic-gate tchar **
blkcpy(tchar ** oav,tchar ** bv)1196c02b4a4Smuffin blkcpy(tchar **oav, tchar **bv)
1207c478bd9Sstevel@tonic-gate {
1216c02b4a4Smuffin 	tchar **av = oav;
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate 	while (*av++ = *bv++)
1247c478bd9Sstevel@tonic-gate 		continue;
1257c478bd9Sstevel@tonic-gate 	return (oav);
1267c478bd9Sstevel@tonic-gate }
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate tchar **
blkcat(tchar ** up,tchar ** vp)1296c02b4a4Smuffin blkcat(tchar **up, tchar **vp)
1307c478bd9Sstevel@tonic-gate {
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate 	(void) blkcpy(blkend(up), vp);
1337c478bd9Sstevel@tonic-gate 	return (up);
1347c478bd9Sstevel@tonic-gate }
1357c478bd9Sstevel@tonic-gate 
1366c02b4a4Smuffin void
blkfree(tchar ** av0)1376c02b4a4Smuffin blkfree(tchar **av0)
1387c478bd9Sstevel@tonic-gate {
1396c02b4a4Smuffin 	tchar **av = av0;
1407c478bd9Sstevel@tonic-gate 
1417c478bd9Sstevel@tonic-gate 	for (; *av; av++)
142*65b0c20eSnakanon 		xfree(*av);
143*65b0c20eSnakanon 	xfree(av0);
1447c478bd9Sstevel@tonic-gate }
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate tchar **
saveblk(tchar ** v)1476c02b4a4Smuffin saveblk(tchar **v)
1487c478bd9Sstevel@tonic-gate {
1496c02b4a4Smuffin 	tchar **newv =
150*65b0c20eSnakanon 		(tchar **)xcalloc((unsigned)(blklen(v) + 1),
1517c478bd9Sstevel@tonic-gate 				sizeof (tchar **));
1527c478bd9Sstevel@tonic-gate 	tchar **onewv = newv;
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate 	while (*v)
1557c478bd9Sstevel@tonic-gate 		*newv++ = savestr(*v++);
1567c478bd9Sstevel@tonic-gate 	return (onewv);
1577c478bd9Sstevel@tonic-gate }
1587c478bd9Sstevel@tonic-gate 
1597c478bd9Sstevel@tonic-gate tchar *
strspl(tchar * cp,tchar * dp)1606c02b4a4Smuffin strspl(tchar *cp, tchar *dp)
1617c478bd9Sstevel@tonic-gate {
1627c478bd9Sstevel@tonic-gate 	tchar *ep;
1636c02b4a4Smuffin 	tchar *p, *q;
1647c478bd9Sstevel@tonic-gate 
1657c478bd9Sstevel@tonic-gate #ifndef m32
1667c478bd9Sstevel@tonic-gate 	for (p = cp; *p++; )
1677c478bd9Sstevel@tonic-gate 		;
1687c478bd9Sstevel@tonic-gate 	for (q = dp; *q++; )
1697c478bd9Sstevel@tonic-gate 		;
170*65b0c20eSnakanon 	ep = (tchar *) xalloc((unsigned)(((p - cp) +
1717c478bd9Sstevel@tonic-gate 			(q - dp) - 1))*sizeof (tchar));
1727c478bd9Sstevel@tonic-gate 	for (p = ep, q = cp; *p++ = *q++; )
1737c478bd9Sstevel@tonic-gate 		;
1747c478bd9Sstevel@tonic-gate 	for (p--, q = dp; *p++ = *q++; )
1757c478bd9Sstevel@tonic-gate 		;
1767c478bd9Sstevel@tonic-gate #else
1777c478bd9Sstevel@tonic-gate 	int	len1 = strlen_(cp);
1787c478bd9Sstevel@tonic-gate 	int	len2 = strlen_(dp);
1797c478bd9Sstevel@tonic-gate 
180*65b0c20eSnakanon 	ep = (tchar *)xalloc((unsigned)(len1 + len2 + 1)*sizeof (tchar));
1817c478bd9Sstevel@tonic-gate 	strcpy_(ep, cp);
1827c478bd9Sstevel@tonic-gate 	strcat_(ep, dp);
1837c478bd9Sstevel@tonic-gate #endif
1847c478bd9Sstevel@tonic-gate 	return (ep);
1857c478bd9Sstevel@tonic-gate }
1867c478bd9Sstevel@tonic-gate 
1877c478bd9Sstevel@tonic-gate tchar **
blkspl(tchar ** up,tchar ** vp)1886c02b4a4Smuffin blkspl(tchar **up, tchar **vp)
1897c478bd9Sstevel@tonic-gate {
1906c02b4a4Smuffin 	tchar **wp =
191*65b0c20eSnakanon 		(tchar **)xcalloc((unsigned)(blklen(up) + blklen(vp) + 1),
1927c478bd9Sstevel@tonic-gate 			sizeof (tchar **));
1937c478bd9Sstevel@tonic-gate 
1947c478bd9Sstevel@tonic-gate 	(void) blkcpy(wp, up);
1957c478bd9Sstevel@tonic-gate 	return (blkcat(wp, vp));
1967c478bd9Sstevel@tonic-gate }
1977c478bd9Sstevel@tonic-gate 
1986c02b4a4Smuffin int
lastchr(tchar * cp)1996c02b4a4Smuffin lastchr(tchar *cp)
2007c478bd9Sstevel@tonic-gate {
2017c478bd9Sstevel@tonic-gate 
2027c478bd9Sstevel@tonic-gate 	if (!*cp)
2037c478bd9Sstevel@tonic-gate 		return (0);
2047c478bd9Sstevel@tonic-gate 	while (cp[1])
2057c478bd9Sstevel@tonic-gate 		cp++;
2067c478bd9Sstevel@tonic-gate 	return (*cp);
2077c478bd9Sstevel@tonic-gate }
2087c478bd9Sstevel@tonic-gate 
2096c02b4a4Smuffin void
donefds(void)2106c02b4a4Smuffin donefds(void)
2117c478bd9Sstevel@tonic-gate {
2127c478bd9Sstevel@tonic-gate 	(void) close(0);
2137c478bd9Sstevel@tonic-gate 	(void) close(1);
2147c478bd9Sstevel@tonic-gate 	(void) close(2);
2157c478bd9Sstevel@tonic-gate 
2167c478bd9Sstevel@tonic-gate 	/*
2177c478bd9Sstevel@tonic-gate 	 * To avoid NIS+ functions to get hold of 0/1/2,
2187c478bd9Sstevel@tonic-gate 	 * use descriptor 0, and dup it to 1 and 2.
2197c478bd9Sstevel@tonic-gate 	 */
2207c478bd9Sstevel@tonic-gate 	open("/dev/null", 0);
2217c478bd9Sstevel@tonic-gate 	dup(0); dup(0);
2227c478bd9Sstevel@tonic-gate 	didfds = 0;
2237c478bd9Sstevel@tonic-gate }
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate /*
2267c478bd9Sstevel@tonic-gate  * Move descriptor i to j.
2277c478bd9Sstevel@tonic-gate  * If j is -1 then we just want to get i to a safe place,
2287c478bd9Sstevel@tonic-gate  * i.e. to a unit > 2.  This also happens in dcopy.
2297c478bd9Sstevel@tonic-gate  */
2306c02b4a4Smuffin int
dmove(int i,int j)2316c02b4a4Smuffin dmove(int i, int j)
2327c478bd9Sstevel@tonic-gate {
2337c478bd9Sstevel@tonic-gate 	int fd;
2347c478bd9Sstevel@tonic-gate 
2357c478bd9Sstevel@tonic-gate 	if (i == j || i < 0)
2367c478bd9Sstevel@tonic-gate 		return (i);
2377c478bd9Sstevel@tonic-gate 	if (j >= 0) {
2387c478bd9Sstevel@tonic-gate 		fd = dup2(i, j);
2397c478bd9Sstevel@tonic-gate 		if (fd != -1)
2407c478bd9Sstevel@tonic-gate 			setfd(fd);
2417c478bd9Sstevel@tonic-gate 	} else
2427c478bd9Sstevel@tonic-gate 		j = dcopy(i, j);
2437c478bd9Sstevel@tonic-gate 	if (j != i) {
2447c478bd9Sstevel@tonic-gate 		(void) close(i);
2457c478bd9Sstevel@tonic-gate 		unsetfd(i);
2467c478bd9Sstevel@tonic-gate 	}
2477c478bd9Sstevel@tonic-gate 	return (j);
2487c478bd9Sstevel@tonic-gate }
2497c478bd9Sstevel@tonic-gate 
2506c02b4a4Smuffin int
dcopy(int i,int j)2516c02b4a4Smuffin dcopy(int i, int j)
2527c478bd9Sstevel@tonic-gate {
2537c478bd9Sstevel@tonic-gate 
2547c478bd9Sstevel@tonic-gate 	int fd;
2557c478bd9Sstevel@tonic-gate 
2567c478bd9Sstevel@tonic-gate 	if (i == j || i < 0 || j < 0 && i > 2)
2577c478bd9Sstevel@tonic-gate 		return (i);
2587c478bd9Sstevel@tonic-gate 	if (j >= 0) {
2597c478bd9Sstevel@tonic-gate 		fd = dup2(i, j);
2607c478bd9Sstevel@tonic-gate 		if (fd != -1)
2617c478bd9Sstevel@tonic-gate 			setfd(fd);
2627c478bd9Sstevel@tonic-gate 		return (j);
2637c478bd9Sstevel@tonic-gate 	}
2647c478bd9Sstevel@tonic-gate 	(void) close(j);
2657c478bd9Sstevel@tonic-gate 	unsetfd(j);
2667c478bd9Sstevel@tonic-gate 	return (renum(i, j));
2677c478bd9Sstevel@tonic-gate }
2687c478bd9Sstevel@tonic-gate 
2696c02b4a4Smuffin int
renum(int i,int j)2706c02b4a4Smuffin renum(int i, int j)
2717c478bd9Sstevel@tonic-gate {
2726c02b4a4Smuffin 	int k = dup(i);
2737c478bd9Sstevel@tonic-gate 
2747c478bd9Sstevel@tonic-gate 	if (k < 0)
2757c478bd9Sstevel@tonic-gate 		return (-1);
2767c478bd9Sstevel@tonic-gate 	if (j == -1 && k > 2) {
2777c478bd9Sstevel@tonic-gate 		setfd(k);
2787c478bd9Sstevel@tonic-gate 		return (k);
2797c478bd9Sstevel@tonic-gate 	}
2807c478bd9Sstevel@tonic-gate 	if (k != j) {
2817c478bd9Sstevel@tonic-gate 		j = renum(k, j);
2827c478bd9Sstevel@tonic-gate 		(void) close(k);	/* no need ofr unsetfd() */
2837c478bd9Sstevel@tonic-gate 		return (j);
2847c478bd9Sstevel@tonic-gate 	}
2857c478bd9Sstevel@tonic-gate 	return (k);
2867c478bd9Sstevel@tonic-gate }
2877c478bd9Sstevel@tonic-gate 
2887c478bd9Sstevel@tonic-gate #ifndef copy
2896c02b4a4Smuffin void
copy(tchar * to,tchar * from,int size)2906c02b4a4Smuffin copy(tchar *to, tchar *from, int size)
2917c478bd9Sstevel@tonic-gate {
2927c478bd9Sstevel@tonic-gate 
2937c478bd9Sstevel@tonic-gate 	if (size)
2947c478bd9Sstevel@tonic-gate 		do
2957c478bd9Sstevel@tonic-gate 			*to++ = *from++;
2967c478bd9Sstevel@tonic-gate 		while (--size != 0);
2977c478bd9Sstevel@tonic-gate }
2987c478bd9Sstevel@tonic-gate #endif
2997c478bd9Sstevel@tonic-gate 
3007c478bd9Sstevel@tonic-gate /*
3017c478bd9Sstevel@tonic-gate  * Left shift a command argument list, discarding
3027c478bd9Sstevel@tonic-gate  * the first c arguments.  Used in "shift" commands
3037c478bd9Sstevel@tonic-gate  * as well as by commands like "repeat".
3047c478bd9Sstevel@tonic-gate  */
3056c02b4a4Smuffin void
lshift(tchar ** v,int c)3066c02b4a4Smuffin lshift(tchar **v, int c)
3077c478bd9Sstevel@tonic-gate {
3086c02b4a4Smuffin 	tchar **u = v;
3097c478bd9Sstevel@tonic-gate 
3107c478bd9Sstevel@tonic-gate 	while (*u && --c >= 0)
3116c02b4a4Smuffin 		xfree((char *)*u++);
3127c478bd9Sstevel@tonic-gate 	(void) blkcpy(v, u);
3137c478bd9Sstevel@tonic-gate }
3147c478bd9Sstevel@tonic-gate 
3156c02b4a4Smuffin int
number(tchar * cp)3166c02b4a4Smuffin number(tchar *cp)
3177c478bd9Sstevel@tonic-gate {
3187c478bd9Sstevel@tonic-gate 
3197c478bd9Sstevel@tonic-gate 	if (*cp == '-') {
3207c478bd9Sstevel@tonic-gate 		cp++;
3217c478bd9Sstevel@tonic-gate 		if (!digit(*cp++))
3227c478bd9Sstevel@tonic-gate 			return (0);
3237c478bd9Sstevel@tonic-gate 	}
3247c478bd9Sstevel@tonic-gate 	while (*cp && digit(*cp))
3257c478bd9Sstevel@tonic-gate 		cp++;
3267c478bd9Sstevel@tonic-gate 	return (*cp == 0);
3277c478bd9Sstevel@tonic-gate }
3287c478bd9Sstevel@tonic-gate 
3297c478bd9Sstevel@tonic-gate tchar **
copyblk(tchar ** v)3306c02b4a4Smuffin copyblk(tchar **v)
3317c478bd9Sstevel@tonic-gate {
3326c02b4a4Smuffin 	tchar **nv =
333*65b0c20eSnakanon 		(tchar **)xcalloc((unsigned)(blklen(v) + 1),
3347c478bd9Sstevel@tonic-gate 				sizeof (tchar **));
3357c478bd9Sstevel@tonic-gate 
3367c478bd9Sstevel@tonic-gate 	return (blkcpy(nv, v));
3377c478bd9Sstevel@tonic-gate }
3387c478bd9Sstevel@tonic-gate 
3397c478bd9Sstevel@tonic-gate tchar *
strend(tchar * cp)3406c02b4a4Smuffin strend(tchar *cp)
3417c478bd9Sstevel@tonic-gate {
3427c478bd9Sstevel@tonic-gate 
3437c478bd9Sstevel@tonic-gate 	while (*cp)
3447c478bd9Sstevel@tonic-gate 		cp++;
3457c478bd9Sstevel@tonic-gate 	return (cp);
3467c478bd9Sstevel@tonic-gate }
3477c478bd9Sstevel@tonic-gate 
3487c478bd9Sstevel@tonic-gate tchar *
strip(tchar * cp)3496c02b4a4Smuffin strip(tchar *cp)
3507c478bd9Sstevel@tonic-gate {
3516c02b4a4Smuffin 	tchar *dp = cp;
3527c478bd9Sstevel@tonic-gate 
3537c478bd9Sstevel@tonic-gate 	while (*dp++ &= TRIM)
3547c478bd9Sstevel@tonic-gate 		continue;
3557c478bd9Sstevel@tonic-gate 	return (cp);
3567c478bd9Sstevel@tonic-gate }
3577c478bd9Sstevel@tonic-gate 
3586c02b4a4Smuffin void
udvar(tchar * name)3596c02b4a4Smuffin udvar(tchar *name)
3607c478bd9Sstevel@tonic-gate {
3617c478bd9Sstevel@tonic-gate 
3627c478bd9Sstevel@tonic-gate 	setname(name);
3637c478bd9Sstevel@tonic-gate 	bferr("Undefined variable");
3647c478bd9Sstevel@tonic-gate }
3657c478bd9Sstevel@tonic-gate 
3666c02b4a4Smuffin int
prefix(tchar * sub,tchar * str)3676c02b4a4Smuffin prefix(tchar *sub, tchar *str)
3687c478bd9Sstevel@tonic-gate {
3697c478bd9Sstevel@tonic-gate 
3707c478bd9Sstevel@tonic-gate 	for (;;) {
3717c478bd9Sstevel@tonic-gate 		if (*sub == 0)
3727c478bd9Sstevel@tonic-gate 			return (1);
3737c478bd9Sstevel@tonic-gate 		if (*str == 0)
3747c478bd9Sstevel@tonic-gate 			return (0);
3757c478bd9Sstevel@tonic-gate 		if (*sub++ != *str++)
3767c478bd9Sstevel@tonic-gate 			return (0);
3777c478bd9Sstevel@tonic-gate 	}
3787c478bd9Sstevel@tonic-gate }
3797c478bd9Sstevel@tonic-gate 
3807c478bd9Sstevel@tonic-gate /*
3817c478bd9Sstevel@tonic-gate  * blk*_ routines
3827c478bd9Sstevel@tonic-gate  */
3837c478bd9Sstevel@tonic-gate 
3847c478bd9Sstevel@tonic-gate char **
blkend_(char ** up)3856c02b4a4Smuffin blkend_(char **up)
3867c478bd9Sstevel@tonic-gate {
3877c478bd9Sstevel@tonic-gate 
3887c478bd9Sstevel@tonic-gate 	while (*up)
3897c478bd9Sstevel@tonic-gate 		up++;
3907c478bd9Sstevel@tonic-gate 	return (up);
3917c478bd9Sstevel@tonic-gate }
3927c478bd9Sstevel@tonic-gate 
3936c02b4a4Smuffin int
blklen_(char ** av)3946c02b4a4Smuffin blklen_(char **av)
3957c478bd9Sstevel@tonic-gate {
3966c02b4a4Smuffin 	int i = 0;
3977c478bd9Sstevel@tonic-gate 
3987c478bd9Sstevel@tonic-gate 	while (*av++)
3997c478bd9Sstevel@tonic-gate 		i++;
4007c478bd9Sstevel@tonic-gate 	return (i);
4017c478bd9Sstevel@tonic-gate }
4027c478bd9Sstevel@tonic-gate 
4037c478bd9Sstevel@tonic-gate char **
blkcpy_(char ** oav,char ** bv)4046c02b4a4Smuffin blkcpy_(char **oav, char **bv)
4057c478bd9Sstevel@tonic-gate {
4066c02b4a4Smuffin 	char **av = oav;
4077c478bd9Sstevel@tonic-gate 
4087c478bd9Sstevel@tonic-gate 	while (*av++ = *bv++)
4097c478bd9Sstevel@tonic-gate 		continue;
4107c478bd9Sstevel@tonic-gate 	return (oav);
4117c478bd9Sstevel@tonic-gate }
4127c478bd9Sstevel@tonic-gate 
4137c478bd9Sstevel@tonic-gate char **
blkcat_(char ** up,char ** vp)4146c02b4a4Smuffin blkcat_(char **up, char **vp)
4157c478bd9Sstevel@tonic-gate {
4167c478bd9Sstevel@tonic-gate 
4177c478bd9Sstevel@tonic-gate 	(void) blkcpy_(blkend_(up), vp);
4187c478bd9Sstevel@tonic-gate 	return (up);
4197c478bd9Sstevel@tonic-gate }
4207c478bd9Sstevel@tonic-gate 
4217c478bd9Sstevel@tonic-gate char **
blkspl_(char ** up,char ** vp)4226c02b4a4Smuffin blkspl_(char **up, char **vp)
4237c478bd9Sstevel@tonic-gate {
4246c02b4a4Smuffin 	char **wp =
425*65b0c20eSnakanon 		(char **)xcalloc((unsigned)(blklen_(up) + blklen_(vp) + 1),
4267c478bd9Sstevel@tonic-gate 			sizeof (char **));
4277c478bd9Sstevel@tonic-gate 
4287c478bd9Sstevel@tonic-gate 	(void) blkcpy_(wp, up);
4297c478bd9Sstevel@tonic-gate 	return (blkcat_(wp, vp));
4307c478bd9Sstevel@tonic-gate }
431*65b0c20eSnakanon 
432*65b0c20eSnakanon /*
433*65b0c20eSnakanon  * If stack address was passed to free(), we have no good way to see if
434*65b0c20eSnakanon  * they are really in the stack. Therefore, we record the bottom of heap,
435*65b0c20eSnakanon  * and filter out the address not within heap's top(end) and bottom
436*65b0c20eSnakanon  * (xalloc_bottom).
437*65b0c20eSnakanon  */
438*65b0c20eSnakanon extern char	end[];
439*65b0c20eSnakanon static char	*xalloc_bottom;
440*65b0c20eSnakanon 
441*65b0c20eSnakanon void *
xalloc(size_t size)442*65b0c20eSnakanon xalloc(size_t size)
443*65b0c20eSnakanon {
444*65b0c20eSnakanon 	char	*rptr, *bp;
445*65b0c20eSnakanon 
446*65b0c20eSnakanon 	if ((rptr = malloc(size)) == NULL)
447*65b0c20eSnakanon 		return (nomem(size));
448*65b0c20eSnakanon 	bp = rptr + size;
449*65b0c20eSnakanon 	if (bp > xalloc_bottom)
450*65b0c20eSnakanon 		xalloc_bottom = bp;
451*65b0c20eSnakanon 	return (rptr);
452*65b0c20eSnakanon }
453*65b0c20eSnakanon 
454*65b0c20eSnakanon void *
xrealloc(void * ptr,size_t size)455*65b0c20eSnakanon xrealloc(void *ptr, size_t size)
456*65b0c20eSnakanon {
457*65b0c20eSnakanon 	char	*rptr = ptr, *bp;
458*65b0c20eSnakanon 
459*65b0c20eSnakanon 	if (ptr == NULL)
460*65b0c20eSnakanon 		return (xalloc(size));
461*65b0c20eSnakanon 	if (rptr < end) {
462*65b0c20eSnakanon 		/* data area, but not in heap area. don't touch it */
463*65b0c20eSnakanon oob:
464*65b0c20eSnakanon 		if (size == 0)
465*65b0c20eSnakanon 			return (NULL);
466*65b0c20eSnakanon 		rptr = xalloc(size);
467*65b0c20eSnakanon 		/* copy max size */
468*65b0c20eSnakanon 		(void) memcpy(rptr, ptr, size);
469*65b0c20eSnakanon 		return (rptr);
470*65b0c20eSnakanon 	}
471*65b0c20eSnakanon 	if (rptr < xalloc_bottom) {
472*65b0c20eSnakanon 		/* address in the heap */
473*65b0c20eSnakanon inb:
474*65b0c20eSnakanon 		if (size == 0) {
475*65b0c20eSnakanon 			free(ptr);
476*65b0c20eSnakanon 			return (NULL);
477*65b0c20eSnakanon 		}
478*65b0c20eSnakanon 		if ((rptr = realloc(ptr, size)) == NULL)
479*65b0c20eSnakanon 			return (nomem(size));
480*65b0c20eSnakanon 		bp = rptr + size;
481*65b0c20eSnakanon 		if (bp > xalloc_bottom)
482*65b0c20eSnakanon 			xalloc_bottom = bp;
483*65b0c20eSnakanon 		return (rptr);
484*65b0c20eSnakanon 	}
485*65b0c20eSnakanon #if defined(__sparc)
486*65b0c20eSnakanon 	if (rptr > (char *)&rptr) {
487*65b0c20eSnakanon 		/* in the stack frame */
488*65b0c20eSnakanon 		goto oob;
489*65b0c20eSnakanon 	}
490*65b0c20eSnakanon #endif
491*65b0c20eSnakanon 	/*
492*65b0c20eSnakanon 	 * can be a memory block returned indirectly from
493*65b0c20eSnakanon 	 * library functions. update bottom, and check it again.
494*65b0c20eSnakanon 	 */
495*65b0c20eSnakanon 	xalloc_bottom = sbrk(0);
496*65b0c20eSnakanon 	if (rptr <= xalloc_bottom)
497*65b0c20eSnakanon 		goto inb;
498*65b0c20eSnakanon 	else
499*65b0c20eSnakanon 		goto oob;
500*65b0c20eSnakanon 	/*NOTREACHED*/
501*65b0c20eSnakanon }
502*65b0c20eSnakanon 
503*65b0c20eSnakanon void
xfree(void * ptr)504*65b0c20eSnakanon xfree(void *ptr)
505*65b0c20eSnakanon {
506*65b0c20eSnakanon 	char	*rptr = ptr;
507*65b0c20eSnakanon 
508*65b0c20eSnakanon 	if (rptr < end) {
509*65b0c20eSnakanon 		return;
510*65b0c20eSnakanon 	}
511*65b0c20eSnakanon 	if (rptr < xalloc_bottom) {
512*65b0c20eSnakanon 		free(ptr);
513*65b0c20eSnakanon 		return;
514*65b0c20eSnakanon 	}
515*65b0c20eSnakanon #if defined(__sparc)
516*65b0c20eSnakanon 	if (rptr > (char *)&rptr) {
517*65b0c20eSnakanon 		/* in the stack frame */
518*65b0c20eSnakanon 		return;
519*65b0c20eSnakanon 	}
520*65b0c20eSnakanon #endif
521*65b0c20eSnakanon 	xalloc_bottom = sbrk(0);
522*65b0c20eSnakanon 	if (rptr <= xalloc_bottom) {
523*65b0c20eSnakanon 		free(ptr);
524*65b0c20eSnakanon 	}
525*65b0c20eSnakanon }
526*65b0c20eSnakanon 
527*65b0c20eSnakanon void *
xcalloc(size_t i,size_t j)528*65b0c20eSnakanon xcalloc(size_t i, size_t j)
529*65b0c20eSnakanon {
530*65b0c20eSnakanon 	char *cp;
531*65b0c20eSnakanon 
532*65b0c20eSnakanon 	i *= j;
533*65b0c20eSnakanon 	cp = xalloc(i);
534*65b0c20eSnakanon 	(void) memset(cp, '\0', i);
535*65b0c20eSnakanon 	return (cp);
536*65b0c20eSnakanon }
537