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
any(int c,tchar * s)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
onlyread(tchar * cp)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 *
savestr(tchar * s)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 *
nomem(size_t i)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 **
blkend(tchar ** up)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
blkpr(tchar ** av)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
blklen(tchar ** av)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 **
blkcpy(tchar ** oav,tchar ** bv)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 **
blkcat(tchar ** up,tchar ** vp)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
blkfree(tchar ** av0)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 **
saveblk(tchar ** v)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 *
strspl(tchar * cp,tchar * dp)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 **
blkspl(tchar ** up,tchar ** vp)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
lastchr(tchar * cp)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
donefds(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
dmove(int i,int j)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
dcopy(int i,int j)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
renum(int i,int j)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
copy(tchar * to,tchar * from,int size)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
lshift(tchar ** v,int c)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
number(tchar * cp)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 **
copyblk(tchar ** v)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 *
strend(tchar * cp)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 *
strip(tchar * cp)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
udvar(tchar * name)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
prefix(tchar * sub,tchar * str)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 **
blkend_(char ** up)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
blklen_(char ** av)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 **
blkcpy_(char ** oav,char ** bv)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 **
blkcat_(char ** up,char ** vp)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 **
blkspl_(char ** up,char ** vp)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 *
xalloc(size_t size)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 *
xrealloc(void * ptr,size_t size)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
xfree(void * ptr)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 *
xcalloc(size_t i,size_t j)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