xref: /titanic_51/usr/src/cmd/csh/sh.misc.c (revision 65b0c20e9bbaf87a200ce20a4decf18585e61a25)
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 #pragma ident	"%Z%%M%	%I%	%E% SMI"
167c478bd9Sstevel@tonic-gate 
177c478bd9Sstevel@tonic-gate #include "sh.h"
187c478bd9Sstevel@tonic-gate #include "sh.tconst.h"
197c478bd9Sstevel@tonic-gate #include <fcntl.h>
207c478bd9Sstevel@tonic-gate #include <unistd.h>
217c478bd9Sstevel@tonic-gate 
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate  * C Shell
247c478bd9Sstevel@tonic-gate  */
256c02b4a4Smuffin tchar	**blkcat(tchar **, tchar **);
266c02b4a4Smuffin tchar	**blkend(tchar **);
277c478bd9Sstevel@tonic-gate 
286c02b4a4Smuffin int
296c02b4a4Smuffin any(int c, tchar *s)
307c478bd9Sstevel@tonic-gate {
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate 	while (s && *s)
337c478bd9Sstevel@tonic-gate 		if (*s++ == c)
347c478bd9Sstevel@tonic-gate 			return (1);
357c478bd9Sstevel@tonic-gate 	return (0);
367c478bd9Sstevel@tonic-gate }
377c478bd9Sstevel@tonic-gate 
386c02b4a4Smuffin int
396c02b4a4Smuffin onlyread(tchar *cp)
407c478bd9Sstevel@tonic-gate {
417c478bd9Sstevel@tonic-gate 	extern char end[];
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate 	return ((char *)cp < end);
447c478bd9Sstevel@tonic-gate }
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate tchar *
476c02b4a4Smuffin savestr(tchar *s)
487c478bd9Sstevel@tonic-gate {
497c478bd9Sstevel@tonic-gate 	tchar *n;
506c02b4a4Smuffin 	tchar *p;
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate 	if (s == 0)
537c478bd9Sstevel@tonic-gate 		s = S_ /* "" */;
547c478bd9Sstevel@tonic-gate #ifndef m32
557c478bd9Sstevel@tonic-gate 	for (p = s; *p++; )
567c478bd9Sstevel@tonic-gate 		;
577c478bd9Sstevel@tonic-gate 	n = p = (tchar *)xalloc((unsigned)(p - s)*sizeof (tchar));
587c478bd9Sstevel@tonic-gate 	while (*p++ = *s++)
597c478bd9Sstevel@tonic-gate 		;
607c478bd9Sstevel@tonic-gate 	return (n);
617c478bd9Sstevel@tonic-gate #else
627c478bd9Sstevel@tonic-gate 	p = (tchar *) xalloc((strlen_(s) + 1)*sizeof (tchar));
637c478bd9Sstevel@tonic-gate 	strcpy_(p, s);
647c478bd9Sstevel@tonic-gate 	return (p);
657c478bd9Sstevel@tonic-gate #endif
667c478bd9Sstevel@tonic-gate }
677c478bd9Sstevel@tonic-gate 
68*65b0c20eSnakanon static void *
69*65b0c20eSnakanon nomem(size_t i)
707c478bd9Sstevel@tonic-gate {
717c478bd9Sstevel@tonic-gate #ifdef debug
727c478bd9Sstevel@tonic-gate 	static tchar *av[2] = {0, 0};
737c478bd9Sstevel@tonic-gate #endif
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate 	child++;
767c478bd9Sstevel@tonic-gate #ifndef debug
777c478bd9Sstevel@tonic-gate 	error("Out of memory");
787c478bd9Sstevel@tonic-gate #ifdef lint
797c478bd9Sstevel@tonic-gate 	i = i;
807c478bd9Sstevel@tonic-gate #endif
817c478bd9Sstevel@tonic-gate #else
827c478bd9Sstevel@tonic-gate 	showall(av);
837c478bd9Sstevel@tonic-gate 	printf("i=%d: Out of memory\n", i);
847c478bd9Sstevel@tonic-gate 	chdir("/usr/bill/cshcore");
857c478bd9Sstevel@tonic-gate 	abort();
867c478bd9Sstevel@tonic-gate #endif
877c478bd9Sstevel@tonic-gate 	return (0);		/* fool lint */
887c478bd9Sstevel@tonic-gate }
897c478bd9Sstevel@tonic-gate 
907c478bd9Sstevel@tonic-gate tchar **
916c02b4a4Smuffin blkend(tchar **up)
927c478bd9Sstevel@tonic-gate {
937c478bd9Sstevel@tonic-gate 
947c478bd9Sstevel@tonic-gate 	while (*up)
957c478bd9Sstevel@tonic-gate 		up++;
967c478bd9Sstevel@tonic-gate 	return (up);
977c478bd9Sstevel@tonic-gate }
987c478bd9Sstevel@tonic-gate 
996c02b4a4Smuffin void
1006c02b4a4Smuffin blkpr(tchar **av)
1017c478bd9Sstevel@tonic-gate {
1027c478bd9Sstevel@tonic-gate 
1037c478bd9Sstevel@tonic-gate 	for (; *av; av++) {
1047c478bd9Sstevel@tonic-gate 		printf("%t", *av);
1057c478bd9Sstevel@tonic-gate 		if (av[1])
1067c478bd9Sstevel@tonic-gate 			printf(" ");
1077c478bd9Sstevel@tonic-gate 	}
1087c478bd9Sstevel@tonic-gate }
1097c478bd9Sstevel@tonic-gate 
1106c02b4a4Smuffin int
1116c02b4a4Smuffin blklen(tchar **av)
1127c478bd9Sstevel@tonic-gate {
1136c02b4a4Smuffin 	int i = 0;
1147c478bd9Sstevel@tonic-gate 
1157c478bd9Sstevel@tonic-gate 	while (*av++)
1167c478bd9Sstevel@tonic-gate 		i++;
1177c478bd9Sstevel@tonic-gate 	return (i);
1187c478bd9Sstevel@tonic-gate }
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate tchar **
1216c02b4a4Smuffin blkcpy(tchar **oav, tchar **bv)
1227c478bd9Sstevel@tonic-gate {
1236c02b4a4Smuffin 	tchar **av = oav;
1247c478bd9Sstevel@tonic-gate 
1257c478bd9Sstevel@tonic-gate 	while (*av++ = *bv++)
1267c478bd9Sstevel@tonic-gate 		continue;
1277c478bd9Sstevel@tonic-gate 	return (oav);
1287c478bd9Sstevel@tonic-gate }
1297c478bd9Sstevel@tonic-gate 
1307c478bd9Sstevel@tonic-gate tchar **
1316c02b4a4Smuffin blkcat(tchar **up, tchar **vp)
1327c478bd9Sstevel@tonic-gate {
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate 	(void) blkcpy(blkend(up), vp);
1357c478bd9Sstevel@tonic-gate 	return (up);
1367c478bd9Sstevel@tonic-gate }
1377c478bd9Sstevel@tonic-gate 
1386c02b4a4Smuffin void
1396c02b4a4Smuffin blkfree(tchar **av0)
1407c478bd9Sstevel@tonic-gate {
1416c02b4a4Smuffin 	tchar **av = av0;
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate 	for (; *av; av++)
144*65b0c20eSnakanon 		xfree(*av);
145*65b0c20eSnakanon 	xfree(av0);
1467c478bd9Sstevel@tonic-gate }
1477c478bd9Sstevel@tonic-gate 
1487c478bd9Sstevel@tonic-gate tchar **
1496c02b4a4Smuffin saveblk(tchar **v)
1507c478bd9Sstevel@tonic-gate {
1516c02b4a4Smuffin 	tchar **newv =
152*65b0c20eSnakanon 		(tchar **)xcalloc((unsigned)(blklen(v) + 1),
1537c478bd9Sstevel@tonic-gate 				sizeof (tchar **));
1547c478bd9Sstevel@tonic-gate 	tchar **onewv = newv;
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate 	while (*v)
1577c478bd9Sstevel@tonic-gate 		*newv++ = savestr(*v++);
1587c478bd9Sstevel@tonic-gate 	return (onewv);
1597c478bd9Sstevel@tonic-gate }
1607c478bd9Sstevel@tonic-gate 
1617c478bd9Sstevel@tonic-gate tchar *
1626c02b4a4Smuffin strspl(tchar *cp, tchar *dp)
1637c478bd9Sstevel@tonic-gate {
1647c478bd9Sstevel@tonic-gate 	tchar *ep;
1656c02b4a4Smuffin 	tchar *p, *q;
1667c478bd9Sstevel@tonic-gate 
1677c478bd9Sstevel@tonic-gate #ifndef m32
1687c478bd9Sstevel@tonic-gate 	for (p = cp; *p++; )
1697c478bd9Sstevel@tonic-gate 		;
1707c478bd9Sstevel@tonic-gate 	for (q = dp; *q++; )
1717c478bd9Sstevel@tonic-gate 		;
1727c478bd9Sstevel@tonic-gate 	ep = (tchar *) xalloc((unsigned)(((p - cp) +
1737c478bd9Sstevel@tonic-gate 			(q - dp) - 1))*sizeof (tchar));
1747c478bd9Sstevel@tonic-gate 	for (p = ep, q = cp; *p++ = *q++; )
1757c478bd9Sstevel@tonic-gate 		;
1767c478bd9Sstevel@tonic-gate 	for (p--, q = dp; *p++ = *q++; )
1777c478bd9Sstevel@tonic-gate 		;
1787c478bd9Sstevel@tonic-gate #else
1797c478bd9Sstevel@tonic-gate 	int	len1 = strlen_(cp);
1807c478bd9Sstevel@tonic-gate 	int	len2 = strlen_(dp);
1817c478bd9Sstevel@tonic-gate 
1827c478bd9Sstevel@tonic-gate 	ep = (tchar *)xalloc((unsigned)(len1 + len2 + 1)*sizeof (tchar));
1837c478bd9Sstevel@tonic-gate 	strcpy_(ep, cp);
1847c478bd9Sstevel@tonic-gate 	strcat_(ep, dp);
1857c478bd9Sstevel@tonic-gate #endif
1867c478bd9Sstevel@tonic-gate 	return (ep);
1877c478bd9Sstevel@tonic-gate }
1887c478bd9Sstevel@tonic-gate 
1897c478bd9Sstevel@tonic-gate tchar **
1906c02b4a4Smuffin blkspl(tchar **up, tchar **vp)
1917c478bd9Sstevel@tonic-gate {
1926c02b4a4Smuffin 	tchar **wp =
193*65b0c20eSnakanon 		(tchar **)xcalloc((unsigned)(blklen(up) + blklen(vp) + 1),
1947c478bd9Sstevel@tonic-gate 			sizeof (tchar **));
1957c478bd9Sstevel@tonic-gate 
1967c478bd9Sstevel@tonic-gate 	(void) blkcpy(wp, up);
1977c478bd9Sstevel@tonic-gate 	return (blkcat(wp, vp));
1987c478bd9Sstevel@tonic-gate }
1997c478bd9Sstevel@tonic-gate 
2006c02b4a4Smuffin int
2016c02b4a4Smuffin lastchr(tchar *cp)
2027c478bd9Sstevel@tonic-gate {
2037c478bd9Sstevel@tonic-gate 
2047c478bd9Sstevel@tonic-gate 	if (!*cp)
2057c478bd9Sstevel@tonic-gate 		return (0);
2067c478bd9Sstevel@tonic-gate 	while (cp[1])
2077c478bd9Sstevel@tonic-gate 		cp++;
2087c478bd9Sstevel@tonic-gate 	return (*cp);
2097c478bd9Sstevel@tonic-gate }
2107c478bd9Sstevel@tonic-gate 
2116c02b4a4Smuffin void
2126c02b4a4Smuffin donefds(void)
2137c478bd9Sstevel@tonic-gate {
2147c478bd9Sstevel@tonic-gate 	(void) close(0);
2157c478bd9Sstevel@tonic-gate 	(void) close(1);
2167c478bd9Sstevel@tonic-gate 	(void) close(2);
2177c478bd9Sstevel@tonic-gate 
2187c478bd9Sstevel@tonic-gate 	/*
2197c478bd9Sstevel@tonic-gate 	 * To avoid NIS+ functions to get hold of 0/1/2,
2207c478bd9Sstevel@tonic-gate 	 * use descriptor 0, and dup it to 1 and 2.
2217c478bd9Sstevel@tonic-gate 	 */
2227c478bd9Sstevel@tonic-gate 	open("/dev/null", 0);
2237c478bd9Sstevel@tonic-gate 	dup(0); dup(0);
2247c478bd9Sstevel@tonic-gate 	didfds = 0;
2257c478bd9Sstevel@tonic-gate }
2267c478bd9Sstevel@tonic-gate 
2277c478bd9Sstevel@tonic-gate /*
2287c478bd9Sstevel@tonic-gate  * Move descriptor i to j.
2297c478bd9Sstevel@tonic-gate  * If j is -1 then we just want to get i to a safe place,
2307c478bd9Sstevel@tonic-gate  * i.e. to a unit > 2.  This also happens in dcopy.
2317c478bd9Sstevel@tonic-gate  */
2326c02b4a4Smuffin int
2336c02b4a4Smuffin dmove(int i, int j)
2347c478bd9Sstevel@tonic-gate {
2357c478bd9Sstevel@tonic-gate 	int fd;
2367c478bd9Sstevel@tonic-gate 
2377c478bd9Sstevel@tonic-gate 	if (i == j || i < 0)
2387c478bd9Sstevel@tonic-gate 		return (i);
2397c478bd9Sstevel@tonic-gate 	if (j >= 0) {
2407c478bd9Sstevel@tonic-gate 		fd = dup2(i, j);
2417c478bd9Sstevel@tonic-gate 		if (fd != -1)
2427c478bd9Sstevel@tonic-gate 			setfd(fd);
2437c478bd9Sstevel@tonic-gate 	} else
2447c478bd9Sstevel@tonic-gate 		j = dcopy(i, j);
2457c478bd9Sstevel@tonic-gate 	if (j != i) {
2467c478bd9Sstevel@tonic-gate 		(void) close(i);
2477c478bd9Sstevel@tonic-gate 		unsetfd(i);
2487c478bd9Sstevel@tonic-gate 	}
2497c478bd9Sstevel@tonic-gate 	return (j);
2507c478bd9Sstevel@tonic-gate }
2517c478bd9Sstevel@tonic-gate 
2526c02b4a4Smuffin int
2536c02b4a4Smuffin dcopy(int i, int j)
2547c478bd9Sstevel@tonic-gate {
2557c478bd9Sstevel@tonic-gate 
2567c478bd9Sstevel@tonic-gate 	int fd;
2577c478bd9Sstevel@tonic-gate 
2587c478bd9Sstevel@tonic-gate 	if (i == j || i < 0 || j < 0 && i > 2)
2597c478bd9Sstevel@tonic-gate 		return (i);
2607c478bd9Sstevel@tonic-gate 	if (j >= 0) {
2617c478bd9Sstevel@tonic-gate 		fd = dup2(i, j);
2627c478bd9Sstevel@tonic-gate 		if (fd != -1)
2637c478bd9Sstevel@tonic-gate 			setfd(fd);
2647c478bd9Sstevel@tonic-gate 		return (j);
2657c478bd9Sstevel@tonic-gate 	}
2667c478bd9Sstevel@tonic-gate 	(void) close(j);
2677c478bd9Sstevel@tonic-gate 	unsetfd(j);
2687c478bd9Sstevel@tonic-gate 	return (renum(i, j));
2697c478bd9Sstevel@tonic-gate }
2707c478bd9Sstevel@tonic-gate 
2716c02b4a4Smuffin int
2726c02b4a4Smuffin renum(int i, int j)
2737c478bd9Sstevel@tonic-gate {
2746c02b4a4Smuffin 	int k = dup(i);
2757c478bd9Sstevel@tonic-gate 
2767c478bd9Sstevel@tonic-gate 	if (k < 0)
2777c478bd9Sstevel@tonic-gate 		return (-1);
2787c478bd9Sstevel@tonic-gate 	if (j == -1 && k > 2) {
2797c478bd9Sstevel@tonic-gate 		setfd(k);
2807c478bd9Sstevel@tonic-gate 		return (k);
2817c478bd9Sstevel@tonic-gate 	}
2827c478bd9Sstevel@tonic-gate 	if (k != j) {
2837c478bd9Sstevel@tonic-gate 		j = renum(k, j);
2847c478bd9Sstevel@tonic-gate 		(void) close(k);	/* no need ofr unsetfd() */
2857c478bd9Sstevel@tonic-gate 		return (j);
2867c478bd9Sstevel@tonic-gate 	}
2877c478bd9Sstevel@tonic-gate 	return (k);
2887c478bd9Sstevel@tonic-gate }
2897c478bd9Sstevel@tonic-gate 
2907c478bd9Sstevel@tonic-gate #ifndef copy
2916c02b4a4Smuffin void
2926c02b4a4Smuffin copy(tchar *to, tchar *from, int size)
2937c478bd9Sstevel@tonic-gate {
2947c478bd9Sstevel@tonic-gate 
2957c478bd9Sstevel@tonic-gate 	if (size)
2967c478bd9Sstevel@tonic-gate 		do
2977c478bd9Sstevel@tonic-gate 			*to++ = *from++;
2987c478bd9Sstevel@tonic-gate 		while (--size != 0);
2997c478bd9Sstevel@tonic-gate }
3007c478bd9Sstevel@tonic-gate #endif
3017c478bd9Sstevel@tonic-gate 
3027c478bd9Sstevel@tonic-gate /*
3037c478bd9Sstevel@tonic-gate  * Left shift a command argument list, discarding
3047c478bd9Sstevel@tonic-gate  * the first c arguments.  Used in "shift" commands
3057c478bd9Sstevel@tonic-gate  * as well as by commands like "repeat".
3067c478bd9Sstevel@tonic-gate  */
3076c02b4a4Smuffin void
3086c02b4a4Smuffin lshift(tchar **v, int c)
3097c478bd9Sstevel@tonic-gate {
3106c02b4a4Smuffin 	tchar **u = v;
3117c478bd9Sstevel@tonic-gate 
3127c478bd9Sstevel@tonic-gate 	while (*u && --c >= 0)
3136c02b4a4Smuffin 		xfree((char *)*u++);
3147c478bd9Sstevel@tonic-gate 	(void) blkcpy(v, u);
3157c478bd9Sstevel@tonic-gate }
3167c478bd9Sstevel@tonic-gate 
3176c02b4a4Smuffin int
3186c02b4a4Smuffin number(tchar *cp)
3197c478bd9Sstevel@tonic-gate {
3207c478bd9Sstevel@tonic-gate 
3217c478bd9Sstevel@tonic-gate 	if (*cp == '-') {
3227c478bd9Sstevel@tonic-gate 		cp++;
3237c478bd9Sstevel@tonic-gate 		if (!digit(*cp++))
3247c478bd9Sstevel@tonic-gate 			return (0);
3257c478bd9Sstevel@tonic-gate 	}
3267c478bd9Sstevel@tonic-gate 	while (*cp && digit(*cp))
3277c478bd9Sstevel@tonic-gate 		cp++;
3287c478bd9Sstevel@tonic-gate 	return (*cp == 0);
3297c478bd9Sstevel@tonic-gate }
3307c478bd9Sstevel@tonic-gate 
3317c478bd9Sstevel@tonic-gate tchar **
3326c02b4a4Smuffin copyblk(tchar **v)
3337c478bd9Sstevel@tonic-gate {
3346c02b4a4Smuffin 	tchar **nv =
335*65b0c20eSnakanon 		(tchar **)xcalloc((unsigned)(blklen(v) + 1),
3367c478bd9Sstevel@tonic-gate 				sizeof (tchar **));
3377c478bd9Sstevel@tonic-gate 
3387c478bd9Sstevel@tonic-gate 	return (blkcpy(nv, v));
3397c478bd9Sstevel@tonic-gate }
3407c478bd9Sstevel@tonic-gate 
3417c478bd9Sstevel@tonic-gate tchar *
3426c02b4a4Smuffin strend(tchar *cp)
3437c478bd9Sstevel@tonic-gate {
3447c478bd9Sstevel@tonic-gate 
3457c478bd9Sstevel@tonic-gate 	while (*cp)
3467c478bd9Sstevel@tonic-gate 		cp++;
3477c478bd9Sstevel@tonic-gate 	return (cp);
3487c478bd9Sstevel@tonic-gate }
3497c478bd9Sstevel@tonic-gate 
3507c478bd9Sstevel@tonic-gate tchar *
3516c02b4a4Smuffin strip(tchar *cp)
3527c478bd9Sstevel@tonic-gate {
3536c02b4a4Smuffin 	tchar *dp = cp;
3547c478bd9Sstevel@tonic-gate 
3557c478bd9Sstevel@tonic-gate 	while (*dp++ &= TRIM)
3567c478bd9Sstevel@tonic-gate 		continue;
3577c478bd9Sstevel@tonic-gate 	return (cp);
3587c478bd9Sstevel@tonic-gate }
3597c478bd9Sstevel@tonic-gate 
3606c02b4a4Smuffin void
3616c02b4a4Smuffin udvar(tchar *name)
3627c478bd9Sstevel@tonic-gate {
3637c478bd9Sstevel@tonic-gate 
3647c478bd9Sstevel@tonic-gate 	setname(name);
3657c478bd9Sstevel@tonic-gate 	bferr("Undefined variable");
3667c478bd9Sstevel@tonic-gate }
3677c478bd9Sstevel@tonic-gate 
3686c02b4a4Smuffin int
3696c02b4a4Smuffin prefix(tchar *sub, tchar *str)
3707c478bd9Sstevel@tonic-gate {
3717c478bd9Sstevel@tonic-gate 
3727c478bd9Sstevel@tonic-gate 	for (;;) {
3737c478bd9Sstevel@tonic-gate 		if (*sub == 0)
3747c478bd9Sstevel@tonic-gate 			return (1);
3757c478bd9Sstevel@tonic-gate 		if (*str == 0)
3767c478bd9Sstevel@tonic-gate 			return (0);
3777c478bd9Sstevel@tonic-gate 		if (*sub++ != *str++)
3787c478bd9Sstevel@tonic-gate 			return (0);
3797c478bd9Sstevel@tonic-gate 	}
3807c478bd9Sstevel@tonic-gate }
3817c478bd9Sstevel@tonic-gate 
3827c478bd9Sstevel@tonic-gate /*
3837c478bd9Sstevel@tonic-gate  * blk*_ routines
3847c478bd9Sstevel@tonic-gate  */
3857c478bd9Sstevel@tonic-gate 
3867c478bd9Sstevel@tonic-gate char **
3876c02b4a4Smuffin blkend_(char **up)
3887c478bd9Sstevel@tonic-gate {
3897c478bd9Sstevel@tonic-gate 
3907c478bd9Sstevel@tonic-gate 	while (*up)
3917c478bd9Sstevel@tonic-gate 		up++;
3927c478bd9Sstevel@tonic-gate 	return (up);
3937c478bd9Sstevel@tonic-gate }
3947c478bd9Sstevel@tonic-gate 
3956c02b4a4Smuffin int
3966c02b4a4Smuffin blklen_(char **av)
3977c478bd9Sstevel@tonic-gate {
3986c02b4a4Smuffin 	int i = 0;
3997c478bd9Sstevel@tonic-gate 
4007c478bd9Sstevel@tonic-gate 	while (*av++)
4017c478bd9Sstevel@tonic-gate 		i++;
4027c478bd9Sstevel@tonic-gate 	return (i);
4037c478bd9Sstevel@tonic-gate }
4047c478bd9Sstevel@tonic-gate 
4057c478bd9Sstevel@tonic-gate char **
4066c02b4a4Smuffin blkcpy_(char **oav, char **bv)
4077c478bd9Sstevel@tonic-gate {
4086c02b4a4Smuffin 	char **av = oav;
4097c478bd9Sstevel@tonic-gate 
4107c478bd9Sstevel@tonic-gate 	while (*av++ = *bv++)
4117c478bd9Sstevel@tonic-gate 		continue;
4127c478bd9Sstevel@tonic-gate 	return (oav);
4137c478bd9Sstevel@tonic-gate }
4147c478bd9Sstevel@tonic-gate 
4157c478bd9Sstevel@tonic-gate char **
4166c02b4a4Smuffin blkcat_(char **up, char **vp)
4177c478bd9Sstevel@tonic-gate {
4187c478bd9Sstevel@tonic-gate 
4197c478bd9Sstevel@tonic-gate 	(void) blkcpy_(blkend_(up), vp);
4207c478bd9Sstevel@tonic-gate 	return (up);
4217c478bd9Sstevel@tonic-gate }
4227c478bd9Sstevel@tonic-gate 
4237c478bd9Sstevel@tonic-gate char **
4246c02b4a4Smuffin blkspl_(char **up, char **vp)
4257c478bd9Sstevel@tonic-gate {
4266c02b4a4Smuffin 	char **wp =
427*65b0c20eSnakanon 		(char **)xcalloc((unsigned)(blklen_(up) + blklen_(vp) + 1),
4287c478bd9Sstevel@tonic-gate 			sizeof (char **));
4297c478bd9Sstevel@tonic-gate 
4307c478bd9Sstevel@tonic-gate 	(void) blkcpy_(wp, up);
4317c478bd9Sstevel@tonic-gate 	return (blkcat_(wp, vp));
4327c478bd9Sstevel@tonic-gate }
433*65b0c20eSnakanon 
434*65b0c20eSnakanon /*
435*65b0c20eSnakanon  * If stack address was passed to free(), we have no good way to see if
436*65b0c20eSnakanon  * they are really in the stack. Therefore, we record the bottom of heap,
437*65b0c20eSnakanon  * and filter out the address not within heap's top(end) and bottom
438*65b0c20eSnakanon  * (xalloc_bottom).
439*65b0c20eSnakanon  */
440*65b0c20eSnakanon extern char	end[];
441*65b0c20eSnakanon static char	*xalloc_bottom;
442*65b0c20eSnakanon 
443*65b0c20eSnakanon void *
444*65b0c20eSnakanon xalloc(size_t size)
445*65b0c20eSnakanon {
446*65b0c20eSnakanon 	char	*rptr, *bp;
447*65b0c20eSnakanon 
448*65b0c20eSnakanon 	if ((rptr = malloc(size)) == NULL)
449*65b0c20eSnakanon 		return (nomem(size));
450*65b0c20eSnakanon 	bp = rptr + size;
451*65b0c20eSnakanon 	if (bp > xalloc_bottom)
452*65b0c20eSnakanon 		xalloc_bottom = bp;
453*65b0c20eSnakanon 	return (rptr);
454*65b0c20eSnakanon }
455*65b0c20eSnakanon 
456*65b0c20eSnakanon void *
457*65b0c20eSnakanon xrealloc(void *ptr, size_t size)
458*65b0c20eSnakanon {
459*65b0c20eSnakanon 	char	*rptr = ptr, *bp;
460*65b0c20eSnakanon 
461*65b0c20eSnakanon 	if (ptr == NULL)
462*65b0c20eSnakanon 		return (xalloc(size));
463*65b0c20eSnakanon 	if (rptr < end) {
464*65b0c20eSnakanon 		/* data area, but not in heap area. don't touch it */
465*65b0c20eSnakanon oob:
466*65b0c20eSnakanon 		if (size == 0)
467*65b0c20eSnakanon 			return (NULL);
468*65b0c20eSnakanon 		rptr = xalloc(size);
469*65b0c20eSnakanon 		/* copy max size */
470*65b0c20eSnakanon 		(void) memcpy(rptr, ptr, size);
471*65b0c20eSnakanon 		return (rptr);
472*65b0c20eSnakanon 	}
473*65b0c20eSnakanon 	if (rptr < xalloc_bottom) {
474*65b0c20eSnakanon 		/* address in the heap */
475*65b0c20eSnakanon inb:
476*65b0c20eSnakanon 		if (size == 0) {
477*65b0c20eSnakanon 			free(ptr);
478*65b0c20eSnakanon 			return (NULL);
479*65b0c20eSnakanon 		}
480*65b0c20eSnakanon 		if ((rptr = realloc(ptr, size)) == NULL)
481*65b0c20eSnakanon 			return (nomem(size));
482*65b0c20eSnakanon 		bp = rptr + size;
483*65b0c20eSnakanon 		if (bp > xalloc_bottom)
484*65b0c20eSnakanon 			xalloc_bottom = bp;
485*65b0c20eSnakanon 		return (rptr);
486*65b0c20eSnakanon 	}
487*65b0c20eSnakanon #if defined(__sparc)
488*65b0c20eSnakanon 	if (rptr > (char *)&rptr) {
489*65b0c20eSnakanon 		/* in the stack frame */
490*65b0c20eSnakanon 		goto oob;
491*65b0c20eSnakanon 	}
492*65b0c20eSnakanon #endif
493*65b0c20eSnakanon 	/*
494*65b0c20eSnakanon 	 * can be a memory block returned indirectly from
495*65b0c20eSnakanon 	 * library functions. update bottom, and check it again.
496*65b0c20eSnakanon 	 */
497*65b0c20eSnakanon 	xalloc_bottom = sbrk(0);
498*65b0c20eSnakanon 	if (rptr <= xalloc_bottom)
499*65b0c20eSnakanon 		goto inb;
500*65b0c20eSnakanon 	else
501*65b0c20eSnakanon 		goto oob;
502*65b0c20eSnakanon 	/*NOTREACHED*/
503*65b0c20eSnakanon }
504*65b0c20eSnakanon 
505*65b0c20eSnakanon void
506*65b0c20eSnakanon xfree(void *ptr)
507*65b0c20eSnakanon {
508*65b0c20eSnakanon 	char	*rptr = ptr;
509*65b0c20eSnakanon 
510*65b0c20eSnakanon 	if (rptr < end) {
511*65b0c20eSnakanon 		return;
512*65b0c20eSnakanon 	}
513*65b0c20eSnakanon 	if (rptr < xalloc_bottom) {
514*65b0c20eSnakanon 		free(ptr);
515*65b0c20eSnakanon 		return;
516*65b0c20eSnakanon 	}
517*65b0c20eSnakanon #if defined(__sparc)
518*65b0c20eSnakanon 	if (rptr > (char *)&rptr) {
519*65b0c20eSnakanon 		/* in the stack frame */
520*65b0c20eSnakanon 		return;
521*65b0c20eSnakanon 	}
522*65b0c20eSnakanon #endif
523*65b0c20eSnakanon 	xalloc_bottom = sbrk(0);
524*65b0c20eSnakanon 	if (rptr <= xalloc_bottom) {
525*65b0c20eSnakanon 		free(ptr);
526*65b0c20eSnakanon 	}
527*65b0c20eSnakanon }
528*65b0c20eSnakanon 
529*65b0c20eSnakanon void *
530*65b0c20eSnakanon xcalloc(size_t i, size_t j)
531*65b0c20eSnakanon {
532*65b0c20eSnakanon 	char *cp;
533*65b0c20eSnakanon 
534*65b0c20eSnakanon 	i *= j;
535*65b0c20eSnakanon 	cp = xalloc(i);
536*65b0c20eSnakanon 	(void) memset(cp, '\0', i);
537*65b0c20eSnakanon 	return (cp);
538*65b0c20eSnakanon }
539