Home | History | Annotate | Line # | Download | only in csh
misc.c revision 1.19.48.1
      1  1.19.48.1       tls /* $NetBSD: misc.c,v 1.19.48.1 2014/08/19 23:45:10 tls Exp $ */
      2        1.6       cgd 
      3        1.1       cgd /*-
      4        1.5   mycroft  * Copyright (c) 1980, 1991, 1993
      5        1.5   mycroft  *	The Regents of the University of California.  All rights reserved.
      6        1.1       cgd  *
      7        1.1       cgd  * Redistribution and use in source and binary forms, with or without
      8        1.1       cgd  * modification, are permitted provided that the following conditions
      9        1.1       cgd  * are met:
     10        1.1       cgd  * 1. Redistributions of source code must retain the above copyright
     11        1.1       cgd  *    notice, this list of conditions and the following disclaimer.
     12        1.1       cgd  * 2. Redistributions in binary form must reproduce the above copyright
     13        1.1       cgd  *    notice, this list of conditions and the following disclaimer in the
     14        1.1       cgd  *    documentation and/or other materials provided with the distribution.
     15       1.14       agc  * 3. Neither the name of the University nor the names of its contributors
     16        1.1       cgd  *    may be used to endorse or promote products derived from this software
     17        1.1       cgd  *    without specific prior written permission.
     18        1.1       cgd  *
     19        1.1       cgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     20        1.1       cgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21        1.1       cgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22        1.1       cgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     23        1.1       cgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24        1.1       cgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     25        1.1       cgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26        1.1       cgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27        1.1       cgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28        1.1       cgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29        1.1       cgd  * SUCH DAMAGE.
     30        1.1       cgd  */
     31        1.1       cgd 
     32        1.9  christos #include <sys/cdefs.h>
     33        1.1       cgd #ifndef lint
     34        1.6       cgd #if 0
     35        1.6       cgd static char sccsid[] = "@(#)misc.c	8.1 (Berkeley) 5/31/93";
     36        1.6       cgd #else
     37  1.19.48.1       tls __RCSID("$NetBSD: misc.c,v 1.19.48.1 2014/08/19 23:45:10 tls Exp $");
     38        1.6       cgd #endif
     39        1.1       cgd #endif /* not lint */
     40        1.1       cgd 
     41        1.1       cgd #include <sys/param.h>
     42       1.12       wiz 
     43       1.13       wiz #include <stdarg.h>
     44        1.1       cgd #include <stdlib.h>
     45       1.15  christos #include <string.h>
     46        1.1       cgd #include <unistd.h>
     47       1.15  christos #include <fcntl.h>
     48        1.1       cgd 
     49        1.1       cgd #include "csh.h"
     50        1.1       cgd #include "extern.h"
     51        1.1       cgd 
     52       1.12       wiz static int renum(int, int);
     53        1.1       cgd 
     54        1.1       cgd int
     55       1.17  christos any(const char *s, int c)
     56        1.1       cgd {
     57        1.1       cgd     if (!s)
     58        1.1       cgd 	return (0);		/* Check for nil pointer */
     59        1.1       cgd     while (*s)
     60        1.1       cgd 	if (*s++ == c)
     61        1.1       cgd 	    return (1);
     62        1.1       cgd     return (0);
     63        1.1       cgd }
     64        1.1       cgd 
     65       1.12       wiz char *
     66       1.17  christos strsave(const char *s)
     67        1.1       cgd {
     68       1.17  christos     const char *n;
     69       1.17  christos     char *p, *r;
     70        1.1       cgd 
     71        1.1       cgd     if (s == NULL)
     72        1.1       cgd 	s = "";
     73       1.17  christos     for (n = s; *n++;)
     74        1.5   mycroft 	continue;
     75  1.19.48.1       tls     r = p = xmalloc((size_t)(n - s) * sizeof(*p));
     76        1.5   mycroft     while ((*p++ = *s++) != '\0')
     77        1.5   mycroft 	continue;
     78       1.17  christos     return (r);
     79        1.1       cgd }
     80        1.1       cgd 
     81       1.12       wiz Char **
     82       1.12       wiz blkend(Char **up)
     83        1.1       cgd {
     84        1.1       cgd     while (*up)
     85        1.1       cgd 	up++;
     86        1.1       cgd     return (up);
     87        1.1       cgd }
     88        1.1       cgd 
     89        1.1       cgd 
     90        1.1       cgd void
     91       1.12       wiz blkpr(FILE *fp, Char **av)
     92        1.1       cgd {
     93        1.1       cgd     for (; *av; av++) {
     94       1.12       wiz 	(void)fprintf(fp, "%s", vis_str(*av));
     95        1.1       cgd 	if (av[1])
     96       1.12       wiz 	    (void)fprintf(fp, " ");
     97        1.1       cgd     }
     98        1.1       cgd }
     99        1.1       cgd 
    100        1.1       cgd int
    101       1.12       wiz blklen(Char **av)
    102        1.1       cgd {
    103       1.12       wiz     int i;
    104        1.1       cgd 
    105       1.12       wiz     i = 0;
    106        1.1       cgd     while (*av++)
    107        1.1       cgd 	i++;
    108        1.1       cgd     return (i);
    109        1.1       cgd }
    110        1.1       cgd 
    111       1.12       wiz Char **
    112       1.12       wiz blkcpy(Char **oav, Char **bv)
    113        1.1       cgd {
    114       1.12       wiz     Char **av;
    115        1.1       cgd 
    116       1.12       wiz     av = oav;
    117        1.5   mycroft     while ((*av++ = *bv++) != NULL)
    118        1.1       cgd 	continue;
    119        1.1       cgd     return (oav);
    120        1.1       cgd }
    121        1.1       cgd 
    122       1.12       wiz Char **
    123       1.12       wiz blkcat(Char **up, Char **vp)
    124        1.1       cgd {
    125       1.12       wiz     (void)blkcpy(blkend(up), vp);
    126        1.1       cgd     return (up);
    127        1.1       cgd }
    128        1.1       cgd 
    129        1.1       cgd void
    130       1.12       wiz blkfree(Char **av0)
    131        1.1       cgd {
    132       1.12       wiz     Char **av;
    133        1.1       cgd 
    134       1.12       wiz     av = av0;
    135        1.1       cgd     if (!av0)
    136        1.1       cgd 	return;
    137        1.1       cgd     for (; *av; av++)
    138        1.1       cgd 	xfree((ptr_t) * av);
    139        1.1       cgd     xfree((ptr_t) av0);
    140        1.1       cgd }
    141        1.1       cgd 
    142       1.12       wiz Char **
    143       1.12       wiz saveblk(Char **v)
    144       1.12       wiz {
    145       1.12       wiz     Char **newv, **onewv;
    146        1.1       cgd 
    147       1.19  christos     if (v == NULL)
    148       1.19  christos 	return NULL;
    149       1.19  christos 
    150  1.19.48.1       tls     newv = xcalloc((size_t)(blklen(v) + 1), sizeof(*newv));
    151       1.12       wiz     onewv = newv;
    152        1.1       cgd     while (*v)
    153        1.1       cgd 	*newv++ = Strsave(*v++);
    154        1.1       cgd     return (onewv);
    155        1.1       cgd }
    156        1.1       cgd 
    157        1.1       cgd #ifdef NOTUSED
    158       1.12       wiz char *
    159       1.12       wiz strstr(char *s, char *t)
    160        1.1       cgd {
    161        1.1       cgd     do {
    162       1.12       wiz 	char *ss;
    163       1.12       wiz 	char *tt;
    164       1.12       wiz 
    165       1.12       wiz 	ss = s;
    166       1.12       wiz 	tt = t;
    167        1.1       cgd 
    168        1.1       cgd 	do
    169        1.1       cgd 	    if (*tt == '\0')
    170        1.1       cgd 		return (s);
    171        1.1       cgd 	while (*ss++ == *tt++);
    172        1.1       cgd     } while (*s++ != '\0');
    173        1.1       cgd     return (NULL);
    174        1.1       cgd }
    175        1.1       cgd 
    176        1.1       cgd #endif /* NOTUSED */
    177        1.1       cgd 
    178        1.1       cgd #ifndef SHORT_STRINGS
    179       1.12       wiz char *
    180       1.12       wiz strspl(char *cp, char *dp)
    181        1.1       cgd {
    182       1.12       wiz     char *ep, *p, *q;
    183        1.1       cgd 
    184        1.1       cgd     if (!cp)
    185        1.1       cgd 	cp = "";
    186        1.1       cgd     if (!dp)
    187        1.1       cgd 	dp = "";
    188        1.5   mycroft     for (p = cp; *p++;)
    189        1.5   mycroft 	continue;
    190        1.5   mycroft     for (q = dp; *q++;)
    191        1.5   mycroft 	continue;
    192  1.19.48.1       tls     ep = xmalloc((size_t)(((p - cp) + (q - dp) - 1) * sizeof(*ep)));
    193        1.5   mycroft     for (p = ep, q = cp; *p++ = *q++;)
    194        1.5   mycroft 	continue;
    195        1.5   mycroft     for (p--, q = dp; *p++ = *q++;)
    196        1.5   mycroft 	continue;
    197        1.1       cgd     return (ep);
    198        1.1       cgd }
    199        1.1       cgd 
    200        1.1       cgd #endif
    201        1.1       cgd 
    202       1.12       wiz Char **
    203       1.12       wiz blkspl(Char **up, Char **vp)
    204       1.12       wiz {
    205       1.12       wiz     Char **wp;
    206        1.1       cgd 
    207  1.19.48.1       tls     wp = xcalloc((size_t)(blklen(up) + blklen(vp) + 1), sizeof(*wp));
    208       1.12       wiz     (void)blkcpy(wp, up);
    209        1.1       cgd     return (blkcat(wp, vp));
    210        1.1       cgd }
    211        1.1       cgd 
    212        1.1       cgd Char
    213       1.12       wiz lastchr(Char *cp)
    214        1.1       cgd {
    215        1.1       cgd     if (!cp)
    216        1.1       cgd 	return (0);
    217        1.1       cgd     if (!*cp)
    218        1.1       cgd 	return (0);
    219        1.1       cgd     while (cp[1])
    220        1.1       cgd 	cp++;
    221        1.1       cgd     return (*cp);
    222        1.1       cgd }
    223        1.1       cgd 
    224        1.1       cgd /*
    225        1.1       cgd  * This routine is called after an error to close up
    226        1.1       cgd  * any units which may have been left open accidentally.
    227        1.1       cgd  */
    228        1.1       cgd void
    229       1.12       wiz closem(void)
    230        1.1       cgd {
    231        1.8       tls     int f;
    232       1.15  christos     int nofile;
    233        1.1       cgd 
    234       1.15  christos #ifdef F_CLOSEM
    235       1.15  christos     nofile = FOLDSTD + 1;
    236       1.15  christos     if (fcntl(nofile, F_CLOSEM, 0) == -1)
    237       1.15  christos #endif
    238       1.16  christos 	nofile = NOFILE;
    239       1.15  christos 
    240       1.15  christos     for (f = 0; f < nofile; f++)
    241        1.5   mycroft 	if (f != SHIN && f != SHOUT && f != SHERR && f != OLDSTD &&
    242        1.1       cgd 	    f != FSHTTY)
    243        1.1       cgd 	    (void) close(f);
    244        1.1       cgd }
    245        1.1       cgd 
    246        1.1       cgd void
    247       1.12       wiz donefds(void)
    248        1.1       cgd {
    249       1.12       wiz     (void)close(0);
    250       1.12       wiz     (void)close(1);
    251       1.12       wiz     (void)close(2);
    252        1.5   mycroft 
    253        1.1       cgd     didfds = 0;
    254        1.1       cgd }
    255        1.1       cgd 
    256        1.1       cgd /*
    257        1.1       cgd  * Move descriptor i to j.
    258        1.1       cgd  * If j is -1 then we just want to get i to a safe place,
    259        1.1       cgd  * i.e. to a unit > 2.  This also happens in dcopy.
    260        1.1       cgd  */
    261        1.1       cgd int
    262       1.12       wiz dmove(int i, int j)
    263        1.1       cgd {
    264        1.1       cgd     if (i == j || i < 0)
    265        1.1       cgd 	return (i);
    266        1.1       cgd     if (j >= 0) {
    267       1.12       wiz 	(void)dup2(i, j);
    268        1.1       cgd 	if (j != i)
    269       1.12       wiz 	    (void)close(i);
    270        1.1       cgd 	return (j);
    271        1.1       cgd     }
    272        1.1       cgd     j = dcopy(i, j);
    273        1.1       cgd     if (j != i)
    274       1.12       wiz 	(void)close(i);
    275        1.1       cgd     return (j);
    276        1.1       cgd }
    277        1.1       cgd 
    278        1.1       cgd int
    279       1.12       wiz dcopy(int i, int j)
    280        1.1       cgd {
    281        1.5   mycroft     if (i == j || i < 0 || (j < 0 && i > 2))
    282        1.1       cgd 	return (i);
    283        1.1       cgd     if (j >= 0) {
    284       1.12       wiz 	(void)dup2(i, j);
    285        1.1       cgd 	return (j);
    286        1.1       cgd     }
    287        1.1       cgd     return (renum(i, j));
    288        1.1       cgd }
    289        1.1       cgd 
    290        1.1       cgd static int
    291       1.12       wiz renum(int i, int j)
    292        1.1       cgd {
    293       1.12       wiz     int k;
    294        1.1       cgd 
    295       1.12       wiz     k = dup(i);
    296        1.1       cgd     if (k < 0)
    297        1.1       cgd 	return (-1);
    298        1.1       cgd     if (j == -1 && k > 2)
    299        1.1       cgd 	return (k);
    300        1.1       cgd     if (k != j) {
    301        1.1       cgd 	j = renum(k, j);
    302       1.12       wiz 	(void)close(k);
    303        1.1       cgd 	return (j);
    304        1.1       cgd     }
    305        1.1       cgd     return (k);
    306        1.1       cgd }
    307        1.1       cgd 
    308        1.1       cgd /*
    309        1.1       cgd  * Left shift a command argument list, discarding
    310        1.1       cgd  * the first c arguments.  Used in "shift" commands
    311        1.1       cgd  * as well as by commands like "repeat".
    312        1.1       cgd  */
    313        1.1       cgd void
    314  1.19.48.1       tls lshift(Char **v, size_t c)
    315        1.1       cgd {
    316        1.8       tls     Char **u;
    317        1.1       cgd 
    318  1.19.48.1       tls     for (u = v; *u && c-- > 0; u++)
    319        1.5   mycroft 	xfree((ptr_t) *u);
    320       1.12       wiz     (void)blkcpy(v, u);
    321        1.1       cgd }
    322        1.1       cgd 
    323        1.1       cgd int
    324       1.12       wiz number(Char *cp)
    325        1.1       cgd {
    326        1.1       cgd     if (!cp)
    327        1.1       cgd 	return(0);
    328        1.1       cgd     if (*cp == '-') {
    329        1.1       cgd 	cp++;
    330        1.1       cgd 	if (!Isdigit(*cp))
    331        1.1       cgd 	    return (0);
    332        1.1       cgd 	cp++;
    333        1.1       cgd     }
    334        1.1       cgd     while (*cp && Isdigit(*cp))
    335        1.1       cgd 	cp++;
    336        1.1       cgd     return (*cp == 0);
    337        1.1       cgd }
    338        1.1       cgd 
    339       1.12       wiz Char **
    340       1.12       wiz copyblk(Char **v)
    341        1.1       cgd {
    342       1.12       wiz     Char **nv;
    343       1.12       wiz 
    344  1.19.48.1       tls     nv = xcalloc((size_t)(blklen(v) + 1), sizeof(*nv));
    345        1.1       cgd 
    346        1.1       cgd     return (blkcpy(nv, v));
    347        1.1       cgd }
    348        1.1       cgd 
    349        1.1       cgd #ifndef SHORT_STRINGS
    350       1.12       wiz char *
    351       1.12       wiz strend(char *cp)
    352        1.1       cgd {
    353        1.1       cgd     if (!cp)
    354        1.1       cgd 	return (cp);
    355        1.1       cgd     while (*cp)
    356        1.1       cgd 	cp++;
    357        1.1       cgd     return (cp);
    358        1.1       cgd }
    359        1.1       cgd 
    360        1.5   mycroft #endif /* SHORT_STRINGS */
    361        1.1       cgd 
    362       1.12       wiz Char *
    363       1.12       wiz strip(Char *cp)
    364        1.1       cgd {
    365       1.12       wiz     Char *dp;
    366        1.1       cgd 
    367       1.12       wiz     dp = cp;
    368        1.1       cgd     if (!cp)
    369        1.1       cgd 	return (cp);
    370        1.5   mycroft     while ((*dp++ &= TRIM) != '\0')
    371        1.1       cgd 	continue;
    372        1.7  christos     return (cp);
    373        1.7  christos }
    374        1.7  christos 
    375       1.12       wiz Char *
    376       1.12       wiz quote(Char *cp)
    377        1.7  christos {
    378       1.12       wiz     Char *dp;
    379        1.7  christos 
    380       1.12       wiz     dp = cp;
    381        1.7  christos     if (!cp)
    382        1.7  christos 	return (cp);
    383        1.7  christos     while (*dp != '\0')
    384        1.7  christos 	*dp++ |= QUOTE;
    385        1.1       cgd     return (cp);
    386        1.1       cgd }
    387        1.1       cgd 
    388        1.1       cgd void
    389       1.12       wiz udvar(Char *name)
    390        1.1       cgd {
    391        1.5   mycroft     setname(vis_str(name));
    392        1.1       cgd     stderror(ERR_NAME | ERR_UNDVAR);
    393       1.10   mycroft     /* NOTREACHED */
    394        1.1       cgd }
    395        1.1       cgd 
    396        1.1       cgd int
    397       1.12       wiz prefix(Char *sub, Char *str)
    398        1.1       cgd {
    399        1.1       cgd     for (;;) {
    400        1.1       cgd 	if (*sub == 0)
    401        1.1       cgd 	    return (1);
    402        1.1       cgd 	if (*str == 0)
    403        1.1       cgd 	    return (0);
    404        1.1       cgd 	if (*sub++ != *str++)
    405        1.1       cgd 	    return (0);
    406        1.1       cgd     }
    407        1.1       cgd }
    408