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