1 0 stevel /* 2 356 muffin * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 3 0 stevel * Use is subject to license terms. 4 0 stevel */ 5 0 stevel 6 0 stevel /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 7 0 stevel /* All Rights Reserved */ 8 0 stevel 9 0 stevel /* 10 0 stevel * Copyright (c) 1980 Regents of the University of California. 11 0 stevel * All rights reserved. The Berkeley Software License Agreement 12 0 stevel * specifies the terms and conditions for redistribution. 13 0 stevel */ 14 0 stevel 15 0 stevel #pragma ident "%Z%%M% %I% %E% SMI" 16 0 stevel 17 0 stevel #include "sh.h" 18 0 stevel #include "sh.tconst.h" 19 0 stevel #include <fcntl.h> 20 0 stevel #include <unistd.h> 21 0 stevel 22 0 stevel /* 23 0 stevel * C Shell 24 0 stevel */ 25 356 muffin tchar **blkcat(tchar **, tchar **); 26 356 muffin tchar **blkend(tchar **); 27 0 stevel 28 356 muffin int 29 356 muffin any(int c, tchar *s) 30 0 stevel { 31 0 stevel 32 0 stevel while (s && *s) 33 0 stevel if (*s++ == c) 34 0 stevel return (1); 35 0 stevel return (0); 36 0 stevel } 37 0 stevel 38 356 muffin int 39 356 muffin onlyread(tchar *cp) 40 0 stevel { 41 0 stevel extern char end[]; 42 0 stevel 43 0 stevel return ((char *)cp < end); 44 0 stevel } 45 0 stevel 46 0 stevel tchar * 47 356 muffin savestr(tchar *s) 48 0 stevel { 49 0 stevel tchar *n; 50 356 muffin tchar *p; 51 0 stevel 52 0 stevel if (s == 0) 53 0 stevel s = S_ /* "" */; 54 0 stevel #ifndef m32 55 0 stevel for (p = s; *p++; ) 56 0 stevel ; 57 559 nakanon n = p = (tchar *)xalloc((unsigned)(p - s)*sizeof (tchar)); 58 0 stevel while (*p++ = *s++) 59 0 stevel ; 60 0 stevel return (n); 61 0 stevel #else 62 0 stevel p = (tchar *) xalloc((strlen_(s) + 1)*sizeof (tchar)); 63 0 stevel strcpy_(p, s); 64 0 stevel return (p); 65 0 stevel #endif 66 0 stevel } 67 0 stevel 68 559 nakanon static void * 69 559 nakanon nomem(size_t i) 70 0 stevel { 71 0 stevel #ifdef debug 72 0 stevel static tchar *av[2] = {0, 0}; 73 0 stevel #endif 74 0 stevel 75 0 stevel child++; 76 0 stevel #ifndef debug 77 0 stevel error("Out of memory"); 78 0 stevel #ifdef lint 79 0 stevel i = i; 80 0 stevel #endif 81 0 stevel #else 82 0 stevel showall(av); 83 0 stevel printf("i=%d: Out of memory\n", i); 84 0 stevel chdir("/usr/bill/cshcore"); 85 0 stevel abort(); 86 0 stevel #endif 87 0 stevel return (0); /* fool lint */ 88 0 stevel } 89 0 stevel 90 0 stevel tchar ** 91 356 muffin blkend(tchar **up) 92 0 stevel { 93 0 stevel 94 0 stevel while (*up) 95 0 stevel up++; 96 0 stevel return (up); 97 0 stevel } 98 0 stevel 99 356 muffin void 100 356 muffin blkpr(tchar **av) 101 0 stevel { 102 0 stevel 103 0 stevel for (; *av; av++) { 104 0 stevel printf("%t", *av); 105 0 stevel if (av[1]) 106 0 stevel printf(" "); 107 0 stevel } 108 0 stevel } 109 0 stevel 110 356 muffin int 111 356 muffin blklen(tchar **av) 112 0 stevel { 113 356 muffin int i = 0; 114 0 stevel 115 0 stevel while (*av++) 116 0 stevel i++; 117 0 stevel return (i); 118 0 stevel } 119 0 stevel 120 0 stevel tchar ** 121 356 muffin blkcpy(tchar **oav, tchar **bv) 122 0 stevel { 123 356 muffin tchar **av = oav; 124 0 stevel 125 0 stevel while (*av++ = *bv++) 126 0 stevel continue; 127 0 stevel return (oav); 128 0 stevel } 129 0 stevel 130 0 stevel tchar ** 131 356 muffin blkcat(tchar **up, tchar **vp) 132 0 stevel { 133 0 stevel 134 0 stevel (void) blkcpy(blkend(up), vp); 135 0 stevel return (up); 136 0 stevel } 137 0 stevel 138 356 muffin void 139 356 muffin blkfree(tchar **av0) 140 0 stevel { 141 356 muffin tchar **av = av0; 142 0 stevel 143 0 stevel for (; *av; av++) 144 559 nakanon xfree(*av); 145 559 nakanon xfree(av0); 146 0 stevel } 147 0 stevel 148 0 stevel tchar ** 149 356 muffin saveblk(tchar **v) 150 0 stevel { 151 356 muffin tchar **newv = 152 559 nakanon (tchar **)xcalloc((unsigned)(blklen(v) + 1), 153 0 stevel sizeof (tchar **)); 154 0 stevel tchar **onewv = newv; 155 0 stevel 156 0 stevel while (*v) 157 0 stevel *newv++ = savestr(*v++); 158 0 stevel return (onewv); 159 0 stevel } 160 0 stevel 161 0 stevel tchar * 162 356 muffin strspl(tchar *cp, tchar *dp) 163 0 stevel { 164 0 stevel tchar *ep; 165 356 muffin tchar *p, *q; 166 0 stevel 167 0 stevel #ifndef m32 168 0 stevel for (p = cp; *p++; ) 169 0 stevel ; 170 0 stevel for (q = dp; *q++; ) 171 0 stevel ; 172 559 nakanon ep = (tchar *) xalloc((unsigned)(((p - cp) + 173 0 stevel (q - dp) - 1))*sizeof (tchar)); 174 0 stevel for (p = ep, q = cp; *p++ = *q++; ) 175 0 stevel ; 176 0 stevel for (p--, q = dp; *p++ = *q++; ) 177 0 stevel ; 178 0 stevel #else 179 0 stevel int len1 = strlen_(cp); 180 0 stevel int len2 = strlen_(dp); 181 0 stevel 182 559 nakanon ep = (tchar *)xalloc((unsigned)(len1 + len2 + 1)*sizeof (tchar)); 183 0 stevel strcpy_(ep, cp); 184 0 stevel strcat_(ep, dp); 185 0 stevel #endif 186 0 stevel return (ep); 187 0 stevel } 188 0 stevel 189 0 stevel tchar ** 190 356 muffin blkspl(tchar **up, tchar **vp) 191 0 stevel { 192 356 muffin tchar **wp = 193 559 nakanon (tchar **)xcalloc((unsigned)(blklen(up) + blklen(vp) + 1), 194 0 stevel sizeof (tchar **)); 195 0 stevel 196 0 stevel (void) blkcpy(wp, up); 197 0 stevel return (blkcat(wp, vp)); 198 0 stevel } 199 0 stevel 200 356 muffin int 201 356 muffin lastchr(tchar *cp) 202 0 stevel { 203 0 stevel 204 0 stevel if (!*cp) 205 0 stevel return (0); 206 0 stevel while (cp[1]) 207 0 stevel cp++; 208 0 stevel return (*cp); 209 0 stevel } 210 0 stevel 211 356 muffin void 212 356 muffin donefds(void) 213 0 stevel { 214 0 stevel (void) close(0); 215 0 stevel (void) close(1); 216 0 stevel (void) close(2); 217 0 stevel 218 0 stevel /* 219 0 stevel * To avoid NIS+ functions to get hold of 0/1/2, 220 0 stevel * use descriptor 0, and dup it to 1 and 2. 221 0 stevel */ 222 0 stevel open("/dev/null", 0); 223 0 stevel dup(0); dup(0); 224 0 stevel didfds = 0; 225 0 stevel } 226 0 stevel 227 0 stevel /* 228 0 stevel * Move descriptor i to j. 229 0 stevel * If j is -1 then we just want to get i to a safe place, 230 0 stevel * i.e. to a unit > 2. This also happens in dcopy. 231 0 stevel */ 232 356 muffin int 233 356 muffin dmove(int i, int j) 234 0 stevel { 235 0 stevel int fd; 236 0 stevel 237 0 stevel if (i == j || i < 0) 238 0 stevel return (i); 239 0 stevel if (j >= 0) { 240 0 stevel fd = dup2(i, j); 241 0 stevel if (fd != -1) 242 0 stevel setfd(fd); 243 0 stevel } else 244 0 stevel j = dcopy(i, j); 245 0 stevel if (j != i) { 246 0 stevel (void) close(i); 247 0 stevel unsetfd(i); 248 0 stevel } 249 0 stevel return (j); 250 0 stevel } 251 0 stevel 252 356 muffin int 253 356 muffin dcopy(int i, int j) 254 0 stevel { 255 0 stevel 256 0 stevel int fd; 257 0 stevel 258 0 stevel if (i == j || i < 0 || j < 0 && i > 2) 259 0 stevel return (i); 260 0 stevel if (j >= 0) { 261 0 stevel fd = dup2(i, j); 262 0 stevel if (fd != -1) 263 0 stevel setfd(fd); 264 0 stevel return (j); 265 0 stevel } 266 0 stevel (void) close(j); 267 0 stevel unsetfd(j); 268 0 stevel return (renum(i, j)); 269 0 stevel } 270 0 stevel 271 356 muffin int 272 356 muffin renum(int i, int j) 273 0 stevel { 274 356 muffin int k = dup(i); 275 0 stevel 276 0 stevel if (k < 0) 277 0 stevel return (-1); 278 0 stevel if (j == -1 && k > 2) { 279 0 stevel setfd(k); 280 0 stevel return (k); 281 0 stevel } 282 0 stevel if (k != j) { 283 0 stevel j = renum(k, j); 284 0 stevel (void) close(k); /* no need ofr unsetfd() */ 285 0 stevel return (j); 286 0 stevel } 287 0 stevel return (k); 288 0 stevel } 289 0 stevel 290 0 stevel #ifndef copy 291 356 muffin void 292 356 muffin copy(tchar *to, tchar *from, int size) 293 0 stevel { 294 0 stevel 295 0 stevel if (size) 296 0 stevel do 297 0 stevel *to++ = *from++; 298 0 stevel while (--size != 0); 299 0 stevel } 300 0 stevel #endif 301 0 stevel 302 0 stevel /* 303 0 stevel * Left shift a command argument list, discarding 304 0 stevel * the first c arguments. Used in "shift" commands 305 0 stevel * as well as by commands like "repeat". 306 0 stevel */ 307 356 muffin void 308 356 muffin lshift(tchar **v, int c) 309 0 stevel { 310 356 muffin tchar **u = v; 311 0 stevel 312 0 stevel while (*u && --c >= 0) 313 356 muffin xfree((char *)*u++); 314 0 stevel (void) blkcpy(v, u); 315 0 stevel } 316 0 stevel 317 356 muffin int 318 356 muffin number(tchar *cp) 319 0 stevel { 320 0 stevel 321 0 stevel if (*cp == '-') { 322 0 stevel cp++; 323 0 stevel if (!digit(*cp++)) 324 0 stevel return (0); 325 0 stevel } 326 0 stevel while (*cp && digit(*cp)) 327 0 stevel cp++; 328 0 stevel return (*cp == 0); 329 0 stevel } 330 0 stevel 331 0 stevel tchar ** 332 356 muffin copyblk(tchar **v) 333 0 stevel { 334 356 muffin tchar **nv = 335 559 nakanon (tchar **)xcalloc((unsigned)(blklen(v) + 1), 336 0 stevel sizeof (tchar **)); 337 0 stevel 338 0 stevel return (blkcpy(nv, v)); 339 0 stevel } 340 0 stevel 341 0 stevel tchar * 342 356 muffin strend(tchar *cp) 343 0 stevel { 344 0 stevel 345 0 stevel while (*cp) 346 0 stevel cp++; 347 0 stevel return (cp); 348 0 stevel } 349 0 stevel 350 0 stevel tchar * 351 356 muffin strip(tchar *cp) 352 0 stevel { 353 356 muffin tchar *dp = cp; 354 0 stevel 355 0 stevel while (*dp++ &= TRIM) 356 0 stevel continue; 357 0 stevel return (cp); 358 0 stevel } 359 0 stevel 360 356 muffin void 361 356 muffin udvar(tchar *name) 362 0 stevel { 363 0 stevel 364 0 stevel setname(name); 365 0 stevel bferr("Undefined variable"); 366 0 stevel } 367 0 stevel 368 356 muffin int 369 356 muffin prefix(tchar *sub, tchar *str) 370 0 stevel { 371 0 stevel 372 0 stevel for (;;) { 373 0 stevel if (*sub == 0) 374 0 stevel return (1); 375 0 stevel if (*str == 0) 376 0 stevel return (0); 377 0 stevel if (*sub++ != *str++) 378 0 stevel return (0); 379 0 stevel } 380 0 stevel } 381 0 stevel 382 0 stevel /* 383 0 stevel * blk*_ routines 384 0 stevel */ 385 0 stevel 386 0 stevel char ** 387 356 muffin blkend_(char **up) 388 0 stevel { 389 0 stevel 390 0 stevel while (*up) 391 0 stevel up++; 392 0 stevel return (up); 393 0 stevel } 394 0 stevel 395 356 muffin int 396 356 muffin blklen_(char **av) 397 0 stevel { 398 356 muffin int i = 0; 399 0 stevel 400 0 stevel while (*av++) 401 0 stevel i++; 402 0 stevel return (i); 403 0 stevel } 404 0 stevel 405 0 stevel char ** 406 356 muffin blkcpy_(char **oav, char **bv) 407 0 stevel { 408 356 muffin char **av = oav; 409 0 stevel 410 0 stevel while (*av++ = *bv++) 411 0 stevel continue; 412 0 stevel return (oav); 413 0 stevel } 414 0 stevel 415 0 stevel char ** 416 356 muffin blkcat_(char **up, char **vp) 417 0 stevel { 418 0 stevel 419 0 stevel (void) blkcpy_(blkend_(up), vp); 420 0 stevel return (up); 421 0 stevel } 422 0 stevel 423 0 stevel char ** 424 356 muffin blkspl_(char **up, char **vp) 425 0 stevel { 426 356 muffin char **wp = 427 559 nakanon (char **)xcalloc((unsigned)(blklen_(up) + blklen_(vp) + 1), 428 0 stevel sizeof (char **)); 429 0 stevel 430 0 stevel (void) blkcpy_(wp, up); 431 0 stevel return (blkcat_(wp, vp)); 432 0 stevel } 433 559 nakanon 434 559 nakanon /* 435 559 nakanon * If stack address was passed to free(), we have no good way to see if 436 559 nakanon * they are really in the stack. Therefore, we record the bottom of heap, 437 559 nakanon * and filter out the address not within heap's top(end) and bottom 438 559 nakanon * (xalloc_bottom). 439 559 nakanon */ 440 559 nakanon extern char end[]; 441 559 nakanon static char *xalloc_bottom; 442 559 nakanon 443 559 nakanon void * 444 559 nakanon xalloc(size_t size) 445 559 nakanon { 446 559 nakanon char *rptr, *bp; 447 559 nakanon 448 559 nakanon if ((rptr = malloc(size)) == NULL) 449 559 nakanon return (nomem(size)); 450 559 nakanon bp = rptr + size; 451 559 nakanon if (bp > xalloc_bottom) 452 559 nakanon xalloc_bottom = bp; 453 559 nakanon return (rptr); 454 559 nakanon } 455 559 nakanon 456 559 nakanon void * 457 559 nakanon xrealloc(void *ptr, size_t size) 458 559 nakanon { 459 559 nakanon char *rptr = ptr, *bp; 460 559 nakanon 461 559 nakanon if (ptr == NULL) 462 559 nakanon return (xalloc(size)); 463 559 nakanon if (rptr < end) { 464 559 nakanon /* data area, but not in heap area. don't touch it */ 465 559 nakanon oob: 466 559 nakanon if (size == 0) 467 559 nakanon return (NULL); 468 559 nakanon rptr = xalloc(size); 469 559 nakanon /* copy max size */ 470 559 nakanon (void) memcpy(rptr, ptr, size); 471 559 nakanon return (rptr); 472 559 nakanon } 473 559 nakanon if (rptr < xalloc_bottom) { 474 559 nakanon /* address in the heap */ 475 559 nakanon inb: 476 559 nakanon if (size == 0) { 477 559 nakanon free(ptr); 478 559 nakanon return (NULL); 479 559 nakanon } 480 559 nakanon if ((rptr = realloc(ptr, size)) == NULL) 481 559 nakanon return (nomem(size)); 482 559 nakanon bp = rptr + size; 483 559 nakanon if (bp > xalloc_bottom) 484 559 nakanon xalloc_bottom = bp; 485 559 nakanon return (rptr); 486 559 nakanon } 487 559 nakanon #if defined(__sparc) 488 559 nakanon if (rptr > (char *)&rptr) { 489 559 nakanon /* in the stack frame */ 490 559 nakanon goto oob; 491 559 nakanon } 492 559 nakanon #endif 493 559 nakanon /* 494 559 nakanon * can be a memory block returned indirectly from 495 559 nakanon * library functions. update bottom, and check it again. 496 559 nakanon */ 497 559 nakanon xalloc_bottom = sbrk(0); 498 559 nakanon if (rptr <= xalloc_bottom) 499 559 nakanon goto inb; 500 559 nakanon else 501 559 nakanon goto oob; 502 559 nakanon /*NOTREACHED*/ 503 559 nakanon } 504 559 nakanon 505 559 nakanon void 506 559 nakanon xfree(void *ptr) 507 559 nakanon { 508 559 nakanon char *rptr = ptr; 509 559 nakanon 510 559 nakanon if (rptr < end) { 511 559 nakanon return; 512 559 nakanon } 513 559 nakanon if (rptr < xalloc_bottom) { 514 559 nakanon free(ptr); 515 559 nakanon return; 516 559 nakanon } 517 559 nakanon #if defined(__sparc) 518 559 nakanon if (rptr > (char *)&rptr) { 519 559 nakanon /* in the stack frame */ 520 559 nakanon return; 521 559 nakanon } 522 559 nakanon #endif 523 559 nakanon xalloc_bottom = sbrk(0); 524 559 nakanon if (rptr <= xalloc_bottom) { 525 559 nakanon free(ptr); 526 559 nakanon } 527 559 nakanon } 528 559 nakanon 529 559 nakanon void * 530 559 nakanon xcalloc(size_t i, size_t j) 531 559 nakanon { 532 559 nakanon char *cp; 533 559 nakanon 534 559 nakanon i *= j; 535 559 nakanon cp = xalloc(i); 536 559 nakanon (void) memset(cp, '\0', i); 537 559 nakanon return (cp); 538 559 nakanon } 539