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