xref: /onnv-gate/usr/src/cmd/csh/sh.misc.c (revision 559:4933e3c7324c)
10Sstevel@tonic-gate /*
2356Smuffin  * 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  */
25356Smuffin tchar	**blkcat(tchar **, tchar **);
26356Smuffin tchar	**blkend(tchar **);
270Sstevel@tonic-gate 
28356Smuffin int
any(int c,tchar * s)29356Smuffin 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 
38356Smuffin int
onlyread(tchar * cp)39356Smuffin 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 tchar *
savestr(tchar * s)47356Smuffin savestr(tchar *s)
480Sstevel@tonic-gate {
490Sstevel@tonic-gate 	tchar *n;
50356Smuffin 	tchar *p;
510Sstevel@tonic-gate 
520Sstevel@tonic-gate 	if (s == 0)
530Sstevel@tonic-gate 		s = S_ /* "" */;
540Sstevel@tonic-gate #ifndef m32
550Sstevel@tonic-gate 	for (p = s; *p++; )
560Sstevel@tonic-gate 		;
57*559Snakanon 	n = p = (tchar *)xalloc((unsigned)(p - s)*sizeof (tchar));
580Sstevel@tonic-gate 	while (*p++ = *s++)
590Sstevel@tonic-gate 		;
600Sstevel@tonic-gate 	return (n);
610Sstevel@tonic-gate #else
620Sstevel@tonic-gate 	p = (tchar *) xalloc((strlen_(s) + 1)*sizeof (tchar));
630Sstevel@tonic-gate 	strcpy_(p, s);
640Sstevel@tonic-gate 	return (p);
650Sstevel@tonic-gate #endif
660Sstevel@tonic-gate }
670Sstevel@tonic-gate 
68*559Snakanon static void *
nomem(size_t i)69*559Snakanon nomem(size_t i)
700Sstevel@tonic-gate {
710Sstevel@tonic-gate #ifdef debug
720Sstevel@tonic-gate 	static tchar *av[2] = {0, 0};
730Sstevel@tonic-gate #endif
740Sstevel@tonic-gate 
750Sstevel@tonic-gate 	child++;
760Sstevel@tonic-gate #ifndef debug
770Sstevel@tonic-gate 	error("Out of memory");
780Sstevel@tonic-gate #ifdef lint
790Sstevel@tonic-gate 	i = i;
800Sstevel@tonic-gate #endif
810Sstevel@tonic-gate #else
820Sstevel@tonic-gate 	showall(av);
830Sstevel@tonic-gate 	printf("i=%d: Out of memory\n", i);
840Sstevel@tonic-gate 	chdir("/usr/bill/cshcore");
850Sstevel@tonic-gate 	abort();
860Sstevel@tonic-gate #endif
870Sstevel@tonic-gate 	return (0);		/* fool lint */
880Sstevel@tonic-gate }
890Sstevel@tonic-gate 
900Sstevel@tonic-gate tchar **
blkend(tchar ** up)91356Smuffin blkend(tchar **up)
920Sstevel@tonic-gate {
930Sstevel@tonic-gate 
940Sstevel@tonic-gate 	while (*up)
950Sstevel@tonic-gate 		up++;
960Sstevel@tonic-gate 	return (up);
970Sstevel@tonic-gate }
980Sstevel@tonic-gate 
99356Smuffin void
blkpr(tchar ** av)100356Smuffin blkpr(tchar **av)
1010Sstevel@tonic-gate {
1020Sstevel@tonic-gate 
1030Sstevel@tonic-gate 	for (; *av; av++) {
1040Sstevel@tonic-gate 		printf("%t", *av);
1050Sstevel@tonic-gate 		if (av[1])
1060Sstevel@tonic-gate 			printf(" ");
1070Sstevel@tonic-gate 	}
1080Sstevel@tonic-gate }
1090Sstevel@tonic-gate 
110356Smuffin int
blklen(tchar ** av)111356Smuffin blklen(tchar **av)
1120Sstevel@tonic-gate {
113356Smuffin 	int i = 0;
1140Sstevel@tonic-gate 
1150Sstevel@tonic-gate 	while (*av++)
1160Sstevel@tonic-gate 		i++;
1170Sstevel@tonic-gate 	return (i);
1180Sstevel@tonic-gate }
1190Sstevel@tonic-gate 
1200Sstevel@tonic-gate tchar **
blkcpy(tchar ** oav,tchar ** bv)121356Smuffin blkcpy(tchar **oav, tchar **bv)
1220Sstevel@tonic-gate {
123356Smuffin 	tchar **av = oav;
1240Sstevel@tonic-gate 
1250Sstevel@tonic-gate 	while (*av++ = *bv++)
1260Sstevel@tonic-gate 		continue;
1270Sstevel@tonic-gate 	return (oav);
1280Sstevel@tonic-gate }
1290Sstevel@tonic-gate 
1300Sstevel@tonic-gate tchar **
blkcat(tchar ** up,tchar ** vp)131356Smuffin blkcat(tchar **up, tchar **vp)
1320Sstevel@tonic-gate {
1330Sstevel@tonic-gate 
1340Sstevel@tonic-gate 	(void) blkcpy(blkend(up), vp);
1350Sstevel@tonic-gate 	return (up);
1360Sstevel@tonic-gate }
1370Sstevel@tonic-gate 
138356Smuffin void
blkfree(tchar ** av0)139356Smuffin blkfree(tchar **av0)
1400Sstevel@tonic-gate {
141356Smuffin 	tchar **av = av0;
1420Sstevel@tonic-gate 
1430Sstevel@tonic-gate 	for (; *av; av++)
144*559Snakanon 		xfree(*av);
145*559Snakanon 	xfree(av0);
1460Sstevel@tonic-gate }
1470Sstevel@tonic-gate 
1480Sstevel@tonic-gate tchar **
saveblk(tchar ** v)149356Smuffin saveblk(tchar **v)
1500Sstevel@tonic-gate {
151356Smuffin 	tchar **newv =
152*559Snakanon 		(tchar **)xcalloc((unsigned)(blklen(v) + 1),
1530Sstevel@tonic-gate 				sizeof (tchar **));
1540Sstevel@tonic-gate 	tchar **onewv = newv;
1550Sstevel@tonic-gate 
1560Sstevel@tonic-gate 	while (*v)
1570Sstevel@tonic-gate 		*newv++ = savestr(*v++);
1580Sstevel@tonic-gate 	return (onewv);
1590Sstevel@tonic-gate }
1600Sstevel@tonic-gate 
1610Sstevel@tonic-gate tchar *
strspl(tchar * cp,tchar * dp)162356Smuffin strspl(tchar *cp, tchar *dp)
1630Sstevel@tonic-gate {
1640Sstevel@tonic-gate 	tchar *ep;
165356Smuffin 	tchar *p, *q;
1660Sstevel@tonic-gate 
1670Sstevel@tonic-gate #ifndef m32
1680Sstevel@tonic-gate 	for (p = cp; *p++; )
1690Sstevel@tonic-gate 		;
1700Sstevel@tonic-gate 	for (q = dp; *q++; )
1710Sstevel@tonic-gate 		;
172*559Snakanon 	ep = (tchar *) xalloc((unsigned)(((p - cp) +
1730Sstevel@tonic-gate 			(q - dp) - 1))*sizeof (tchar));
1740Sstevel@tonic-gate 	for (p = ep, q = cp; *p++ = *q++; )
1750Sstevel@tonic-gate 		;
1760Sstevel@tonic-gate 	for (p--, q = dp; *p++ = *q++; )
1770Sstevel@tonic-gate 		;
1780Sstevel@tonic-gate #else
1790Sstevel@tonic-gate 	int	len1 = strlen_(cp);
1800Sstevel@tonic-gate 	int	len2 = strlen_(dp);
1810Sstevel@tonic-gate 
182*559Snakanon 	ep = (tchar *)xalloc((unsigned)(len1 + len2 + 1)*sizeof (tchar));
1830Sstevel@tonic-gate 	strcpy_(ep, cp);
1840Sstevel@tonic-gate 	strcat_(ep, dp);
1850Sstevel@tonic-gate #endif
1860Sstevel@tonic-gate 	return (ep);
1870Sstevel@tonic-gate }
1880Sstevel@tonic-gate 
1890Sstevel@tonic-gate tchar **
blkspl(tchar ** up,tchar ** vp)190356Smuffin blkspl(tchar **up, tchar **vp)
1910Sstevel@tonic-gate {
192356Smuffin 	tchar **wp =
193*559Snakanon 		(tchar **)xcalloc((unsigned)(blklen(up) + blklen(vp) + 1),
1940Sstevel@tonic-gate 			sizeof (tchar **));
1950Sstevel@tonic-gate 
1960Sstevel@tonic-gate 	(void) blkcpy(wp, up);
1970Sstevel@tonic-gate 	return (blkcat(wp, vp));
1980Sstevel@tonic-gate }
1990Sstevel@tonic-gate 
200356Smuffin int
lastchr(tchar * cp)201356Smuffin lastchr(tchar *cp)
2020Sstevel@tonic-gate {
2030Sstevel@tonic-gate 
2040Sstevel@tonic-gate 	if (!*cp)
2050Sstevel@tonic-gate 		return (0);
2060Sstevel@tonic-gate 	while (cp[1])
2070Sstevel@tonic-gate 		cp++;
2080Sstevel@tonic-gate 	return (*cp);
2090Sstevel@tonic-gate }
2100Sstevel@tonic-gate 
211356Smuffin void
donefds(void)212356Smuffin donefds(void)
2130Sstevel@tonic-gate {
2140Sstevel@tonic-gate 	(void) close(0);
2150Sstevel@tonic-gate 	(void) close(1);
2160Sstevel@tonic-gate 	(void) close(2);
2170Sstevel@tonic-gate 
2180Sstevel@tonic-gate 	/*
2190Sstevel@tonic-gate 	 * To avoid NIS+ functions to get hold of 0/1/2,
2200Sstevel@tonic-gate 	 * use descriptor 0, and dup it to 1 and 2.
2210Sstevel@tonic-gate 	 */
2220Sstevel@tonic-gate 	open("/dev/null", 0);
2230Sstevel@tonic-gate 	dup(0); dup(0);
2240Sstevel@tonic-gate 	didfds = 0;
2250Sstevel@tonic-gate }
2260Sstevel@tonic-gate 
2270Sstevel@tonic-gate /*
2280Sstevel@tonic-gate  * Move descriptor i to j.
2290Sstevel@tonic-gate  * If j is -1 then we just want to get i to a safe place,
2300Sstevel@tonic-gate  * i.e. to a unit > 2.  This also happens in dcopy.
2310Sstevel@tonic-gate  */
232356Smuffin int
dmove(int i,int j)233356Smuffin dmove(int i, int j)
2340Sstevel@tonic-gate {
2350Sstevel@tonic-gate 	int fd;
2360Sstevel@tonic-gate 
2370Sstevel@tonic-gate 	if (i == j || i < 0)
2380Sstevel@tonic-gate 		return (i);
2390Sstevel@tonic-gate 	if (j >= 0) {
2400Sstevel@tonic-gate 		fd = dup2(i, j);
2410Sstevel@tonic-gate 		if (fd != -1)
2420Sstevel@tonic-gate 			setfd(fd);
2430Sstevel@tonic-gate 	} else
2440Sstevel@tonic-gate 		j = dcopy(i, j);
2450Sstevel@tonic-gate 	if (j != i) {
2460Sstevel@tonic-gate 		(void) close(i);
2470Sstevel@tonic-gate 		unsetfd(i);
2480Sstevel@tonic-gate 	}
2490Sstevel@tonic-gate 	return (j);
2500Sstevel@tonic-gate }
2510Sstevel@tonic-gate 
252356Smuffin int
dcopy(int i,int j)253356Smuffin dcopy(int i, int j)
2540Sstevel@tonic-gate {
2550Sstevel@tonic-gate 
2560Sstevel@tonic-gate 	int fd;
2570Sstevel@tonic-gate 
2580Sstevel@tonic-gate 	if (i == j || i < 0 || j < 0 && i > 2)
2590Sstevel@tonic-gate 		return (i);
2600Sstevel@tonic-gate 	if (j >= 0) {
2610Sstevel@tonic-gate 		fd = dup2(i, j);
2620Sstevel@tonic-gate 		if (fd != -1)
2630Sstevel@tonic-gate 			setfd(fd);
2640Sstevel@tonic-gate 		return (j);
2650Sstevel@tonic-gate 	}
2660Sstevel@tonic-gate 	(void) close(j);
2670Sstevel@tonic-gate 	unsetfd(j);
2680Sstevel@tonic-gate 	return (renum(i, j));
2690Sstevel@tonic-gate }
2700Sstevel@tonic-gate 
271356Smuffin int
renum(int i,int j)272356Smuffin renum(int i, int j)
2730Sstevel@tonic-gate {
274356Smuffin 	int k = dup(i);
2750Sstevel@tonic-gate 
2760Sstevel@tonic-gate 	if (k < 0)
2770Sstevel@tonic-gate 		return (-1);
2780Sstevel@tonic-gate 	if (j == -1 && k > 2) {
2790Sstevel@tonic-gate 		setfd(k);
2800Sstevel@tonic-gate 		return (k);
2810Sstevel@tonic-gate 	}
2820Sstevel@tonic-gate 	if (k != j) {
2830Sstevel@tonic-gate 		j = renum(k, j);
2840Sstevel@tonic-gate 		(void) close(k);	/* no need ofr unsetfd() */
2850Sstevel@tonic-gate 		return (j);
2860Sstevel@tonic-gate 	}
2870Sstevel@tonic-gate 	return (k);
2880Sstevel@tonic-gate }
2890Sstevel@tonic-gate 
2900Sstevel@tonic-gate #ifndef copy
291356Smuffin void
copy(tchar * to,tchar * from,int size)292356Smuffin copy(tchar *to, tchar *from, int size)
2930Sstevel@tonic-gate {
2940Sstevel@tonic-gate 
2950Sstevel@tonic-gate 	if (size)
2960Sstevel@tonic-gate 		do
2970Sstevel@tonic-gate 			*to++ = *from++;
2980Sstevel@tonic-gate 		while (--size != 0);
2990Sstevel@tonic-gate }
3000Sstevel@tonic-gate #endif
3010Sstevel@tonic-gate 
3020Sstevel@tonic-gate /*
3030Sstevel@tonic-gate  * Left shift a command argument list, discarding
3040Sstevel@tonic-gate  * the first c arguments.  Used in "shift" commands
3050Sstevel@tonic-gate  * as well as by commands like "repeat".
3060Sstevel@tonic-gate  */
307356Smuffin void
lshift(tchar ** v,int c)308356Smuffin lshift(tchar **v, int c)
3090Sstevel@tonic-gate {
310356Smuffin 	tchar **u = v;
3110Sstevel@tonic-gate 
3120Sstevel@tonic-gate 	while (*u && --c >= 0)
313356Smuffin 		xfree((char *)*u++);
3140Sstevel@tonic-gate 	(void) blkcpy(v, u);
3150Sstevel@tonic-gate }
3160Sstevel@tonic-gate 
317356Smuffin int
number(tchar * cp)318356Smuffin number(tchar *cp)
3190Sstevel@tonic-gate {
3200Sstevel@tonic-gate 
3210Sstevel@tonic-gate 	if (*cp == '-') {
3220Sstevel@tonic-gate 		cp++;
3230Sstevel@tonic-gate 		if (!digit(*cp++))
3240Sstevel@tonic-gate 			return (0);
3250Sstevel@tonic-gate 	}
3260Sstevel@tonic-gate 	while (*cp && digit(*cp))
3270Sstevel@tonic-gate 		cp++;
3280Sstevel@tonic-gate 	return (*cp == 0);
3290Sstevel@tonic-gate }
3300Sstevel@tonic-gate 
3310Sstevel@tonic-gate tchar **
copyblk(tchar ** v)332356Smuffin copyblk(tchar **v)
3330Sstevel@tonic-gate {
334356Smuffin 	tchar **nv =
335*559Snakanon 		(tchar **)xcalloc((unsigned)(blklen(v) + 1),
3360Sstevel@tonic-gate 				sizeof (tchar **));
3370Sstevel@tonic-gate 
3380Sstevel@tonic-gate 	return (blkcpy(nv, v));
3390Sstevel@tonic-gate }
3400Sstevel@tonic-gate 
3410Sstevel@tonic-gate tchar *
strend(tchar * cp)342356Smuffin strend(tchar *cp)
3430Sstevel@tonic-gate {
3440Sstevel@tonic-gate 
3450Sstevel@tonic-gate 	while (*cp)
3460Sstevel@tonic-gate 		cp++;
3470Sstevel@tonic-gate 	return (cp);
3480Sstevel@tonic-gate }
3490Sstevel@tonic-gate 
3500Sstevel@tonic-gate tchar *
strip(tchar * cp)351356Smuffin strip(tchar *cp)
3520Sstevel@tonic-gate {
353356Smuffin 	tchar *dp = cp;
3540Sstevel@tonic-gate 
3550Sstevel@tonic-gate 	while (*dp++ &= TRIM)
3560Sstevel@tonic-gate 		continue;
3570Sstevel@tonic-gate 	return (cp);
3580Sstevel@tonic-gate }
3590Sstevel@tonic-gate 
360356Smuffin void
udvar(tchar * name)361356Smuffin udvar(tchar *name)
3620Sstevel@tonic-gate {
3630Sstevel@tonic-gate 
3640Sstevel@tonic-gate 	setname(name);
3650Sstevel@tonic-gate 	bferr("Undefined variable");
3660Sstevel@tonic-gate }
3670Sstevel@tonic-gate 
368356Smuffin int
prefix(tchar * sub,tchar * str)369356Smuffin prefix(tchar *sub, tchar *str)
3700Sstevel@tonic-gate {
3710Sstevel@tonic-gate 
3720Sstevel@tonic-gate 	for (;;) {
3730Sstevel@tonic-gate 		if (*sub == 0)
3740Sstevel@tonic-gate 			return (1);
3750Sstevel@tonic-gate 		if (*str == 0)
3760Sstevel@tonic-gate 			return (0);
3770Sstevel@tonic-gate 		if (*sub++ != *str++)
3780Sstevel@tonic-gate 			return (0);
3790Sstevel@tonic-gate 	}
3800Sstevel@tonic-gate }
3810Sstevel@tonic-gate 
3820Sstevel@tonic-gate /*
3830Sstevel@tonic-gate  * blk*_ routines
3840Sstevel@tonic-gate  */
3850Sstevel@tonic-gate 
3860Sstevel@tonic-gate char **
blkend_(char ** up)387356Smuffin blkend_(char **up)
3880Sstevel@tonic-gate {
3890Sstevel@tonic-gate 
3900Sstevel@tonic-gate 	while (*up)
3910Sstevel@tonic-gate 		up++;
3920Sstevel@tonic-gate 	return (up);
3930Sstevel@tonic-gate }
3940Sstevel@tonic-gate 
395356Smuffin int
blklen_(char ** av)396356Smuffin blklen_(char **av)
3970Sstevel@tonic-gate {
398356Smuffin 	int i = 0;
3990Sstevel@tonic-gate 
4000Sstevel@tonic-gate 	while (*av++)
4010Sstevel@tonic-gate 		i++;
4020Sstevel@tonic-gate 	return (i);
4030Sstevel@tonic-gate }
4040Sstevel@tonic-gate 
4050Sstevel@tonic-gate char **
blkcpy_(char ** oav,char ** bv)406356Smuffin blkcpy_(char **oav, char **bv)
4070Sstevel@tonic-gate {
408356Smuffin 	char **av = oav;
4090Sstevel@tonic-gate 
4100Sstevel@tonic-gate 	while (*av++ = *bv++)
4110Sstevel@tonic-gate 		continue;
4120Sstevel@tonic-gate 	return (oav);
4130Sstevel@tonic-gate }
4140Sstevel@tonic-gate 
4150Sstevel@tonic-gate char **
blkcat_(char ** up,char ** vp)416356Smuffin blkcat_(char **up, char **vp)
4170Sstevel@tonic-gate {
4180Sstevel@tonic-gate 
4190Sstevel@tonic-gate 	(void) blkcpy_(blkend_(up), vp);
4200Sstevel@tonic-gate 	return (up);
4210Sstevel@tonic-gate }
4220Sstevel@tonic-gate 
4230Sstevel@tonic-gate char **
blkspl_(char ** up,char ** vp)424356Smuffin blkspl_(char **up, char **vp)
4250Sstevel@tonic-gate {
426356Smuffin 	char **wp =
427*559Snakanon 		(char **)xcalloc((unsigned)(blklen_(up) + blklen_(vp) + 1),
4280Sstevel@tonic-gate 			sizeof (char **));
4290Sstevel@tonic-gate 
4300Sstevel@tonic-gate 	(void) blkcpy_(wp, up);
4310Sstevel@tonic-gate 	return (blkcat_(wp, vp));
4320Sstevel@tonic-gate }
433*559Snakanon 
434*559Snakanon /*
435*559Snakanon  * If stack address was passed to free(), we have no good way to see if
436*559Snakanon  * they are really in the stack. Therefore, we record the bottom of heap,
437*559Snakanon  * and filter out the address not within heap's top(end) and bottom
438*559Snakanon  * (xalloc_bottom).
439*559Snakanon  */
440*559Snakanon extern char	end[];
441*559Snakanon static char	*xalloc_bottom;
442*559Snakanon 
443*559Snakanon void *
xalloc(size_t size)444*559Snakanon xalloc(size_t size)
445*559Snakanon {
446*559Snakanon 	char	*rptr, *bp;
447*559Snakanon 
448*559Snakanon 	if ((rptr = malloc(size)) == NULL)
449*559Snakanon 		return (nomem(size));
450*559Snakanon 	bp = rptr + size;
451*559Snakanon 	if (bp > xalloc_bottom)
452*559Snakanon 		xalloc_bottom = bp;
453*559Snakanon 	return (rptr);
454*559Snakanon }
455*559Snakanon 
456*559Snakanon void *
xrealloc(void * ptr,size_t size)457*559Snakanon xrealloc(void *ptr, size_t size)
458*559Snakanon {
459*559Snakanon 	char	*rptr = ptr, *bp;
460*559Snakanon 
461*559Snakanon 	if (ptr == NULL)
462*559Snakanon 		return (xalloc(size));
463*559Snakanon 	if (rptr < end) {
464*559Snakanon 		/* data area, but not in heap area. don't touch it */
465*559Snakanon oob:
466*559Snakanon 		if (size == 0)
467*559Snakanon 			return (NULL);
468*559Snakanon 		rptr = xalloc(size);
469*559Snakanon 		/* copy max size */
470*559Snakanon 		(void) memcpy(rptr, ptr, size);
471*559Snakanon 		return (rptr);
472*559Snakanon 	}
473*559Snakanon 	if (rptr < xalloc_bottom) {
474*559Snakanon 		/* address in the heap */
475*559Snakanon inb:
476*559Snakanon 		if (size == 0) {
477*559Snakanon 			free(ptr);
478*559Snakanon 			return (NULL);
479*559Snakanon 		}
480*559Snakanon 		if ((rptr = realloc(ptr, size)) == NULL)
481*559Snakanon 			return (nomem(size));
482*559Snakanon 		bp = rptr + size;
483*559Snakanon 		if (bp > xalloc_bottom)
484*559Snakanon 			xalloc_bottom = bp;
485*559Snakanon 		return (rptr);
486*559Snakanon 	}
487*559Snakanon #if defined(__sparc)
488*559Snakanon 	if (rptr > (char *)&rptr) {
489*559Snakanon 		/* in the stack frame */
490*559Snakanon 		goto oob;
491*559Snakanon 	}
492*559Snakanon #endif
493*559Snakanon 	/*
494*559Snakanon 	 * can be a memory block returned indirectly from
495*559Snakanon 	 * library functions. update bottom, and check it again.
496*559Snakanon 	 */
497*559Snakanon 	xalloc_bottom = sbrk(0);
498*559Snakanon 	if (rptr <= xalloc_bottom)
499*559Snakanon 		goto inb;
500*559Snakanon 	else
501*559Snakanon 		goto oob;
502*559Snakanon 	/*NOTREACHED*/
503*559Snakanon }
504*559Snakanon 
505*559Snakanon void
xfree(void * ptr)506*559Snakanon xfree(void *ptr)
507*559Snakanon {
508*559Snakanon 	char	*rptr = ptr;
509*559Snakanon 
510*559Snakanon 	if (rptr < end) {
511*559Snakanon 		return;
512*559Snakanon 	}
513*559Snakanon 	if (rptr < xalloc_bottom) {
514*559Snakanon 		free(ptr);
515*559Snakanon 		return;
516*559Snakanon 	}
517*559Snakanon #if defined(__sparc)
518*559Snakanon 	if (rptr > (char *)&rptr) {
519*559Snakanon 		/* in the stack frame */
520*559Snakanon 		return;
521*559Snakanon 	}
522*559Snakanon #endif
523*559Snakanon 	xalloc_bottom = sbrk(0);
524*559Snakanon 	if (rptr <= xalloc_bottom) {
525*559Snakanon 		free(ptr);
526*559Snakanon 	}
527*559Snakanon }
528*559Snakanon 
529*559Snakanon void *
xcalloc(size_t i,size_t j)530*559Snakanon xcalloc(size_t i, size_t j)
531*559Snakanon {
532*559Snakanon 	char *cp;
533*559Snakanon 
534*559Snakanon 	i *= j;
535*559Snakanon 	cp = xalloc(i);
536*559Snakanon 	(void) memset(cp, '\0', i);
537*559Snakanon 	return (cp);
538*559Snakanon }
539