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