Home | History | Annotate | Download | only in csh
      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