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