1 /* $Header: /src/pub/tcsh/sh.misc.c,v 3.24 2002/03/08 17:36:46 christos Exp $ */
3 * sh.misc.c: Miscelaneous functions
6 * Copyright (c) 1980, 1991 The Regents of the University of California.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 RCSID("$Id: sh.misc.c,v 3.24 2002/03/08 17:36:46 christos Exp $")
37 static int renum __P((int, int));
38 static Char **blkend __P((Char **));
39 static Char **blkcat __P((Char **, Char **));
51 return (0); /* Check for nil pointer */
71 register const char *s;
77 s = (const char *) "";
78 for (p = (char *) s; *p++ != '\0';)
80 n = p = (char *) xmalloc((size_t)
81 ((((const char *) p) - s) * sizeof(char)));
82 while ((*p++ = *s++) != '\0')
117 (void) Strcat(str, *av);
119 (void) Strcat(str, STRspace);
139 register Char **av = oav;
141 while ((*av++ = *bv++) != NULL)
151 (void) blkcpy(blkend(up), vp);
159 register Char **av = av0;
172 register Char **newv =
173 (Char **) xcalloc((size_t) (blklen(v) + 1), sizeof(Char **));
177 *newv++ = Strsave(*v++);
181 #if !defined(SHORT_STRINGS) && !defined(POSIX)
184 register const char *s, *t;
187 register const char *ss = s;
188 register const char *tt = t;
193 while (*ss++ == *tt++);
194 } while (*s++ != '\0');
198 #endif /* !SHORT_STRINGS && !POSIX */
200 #ifndef SHORT_STRINGS
206 register char *p, *q;
212 for (p = cp; *p++ != '\0';)
214 for (q = dp; *q++ != '\0';)
216 ep = (char *) xmalloc((size_t) (((p - cp) + (q - dp) - 1) * sizeof(char)));
217 for (p = ep, q = cp; (*p++ = *q++) != '\0';)
219 for (p--, q = dp; (*p++ = *q++) != '\0';)
224 #endif /* !SHORT_STRINGS */
228 register Char **up, **vp;
231 (Char **) xcalloc((size_t) (blklen(up) + blklen(vp) + 1),
234 (void) blkcpy(wp, up);
235 return (blkcat(wp, vp));
253 * This routine is called after an error to close up
254 * any units which may have been left open accidentally.
262 /* suggested by Justin Bur; thanks to Karl Kleinpaste */
265 for (f = 0; f < NOFILE; f++)
266 if (f != SHIN && f != SHOUT && f != SHDIAG && f != OLDSTD &&
270 #endif /* MALLOC_TRACE */
276 (void) open(_PATH_DEVNULL, O_RDONLY);
281 #ifndef CLOSE_ON_EXEC
283 * Close files before executing a file.
284 * We could be MUCH more intelligent, since (on a version 7 system)
285 * we need only close files here during a source, the other
286 * shell fd's being in units 16-19 which are closed automatically!
300 isoutatty = isatty(SHOUT);
301 isdiagatty = isatty(SHDIAG);
302 for (f = 3; f < NOFILE; f++)
306 #endif /* CLOSE_ON_EXEC */
318 int fd = open(_PATH_DEVNULL, O_RDONLY);
330 * Move descriptor i to j.
331 * If j is -1 then we just want to get i to a safe place,
332 * i.e. to a unit > 2. This also happens in dcopy.
360 if (i == j || i < 0 || (j < 0 && i > 2))
370 return (renum(i, j));
377 register int k = dup(i);
381 if (j == -1 && k > 2)
392 * Left shift a command argument list, discarding
393 * the first c arguments. Used in "shift" commands
394 * as well as by commands like "repeat".
403 for (u = v; *u && --c >= 0; u++)
420 while (*cp && Isdigit(*cp))
430 (Char **) xcalloc((size_t) (blklen(v) + 1), sizeof(Char **));
432 return (blkcpy(nv, v));
435 #ifndef SHORT_STRINGS
447 #endif /* SHORT_STRINGS */
453 register Char *dp = cp;
457 while ((*dp++ &= TRIM) != '\0')
466 register Char *dp = cp;
482 if (cmap(*s, _META | _DOL | _QF | _QB | _ESC | _GLOB))
495 setname(short2str(name));
496 stderror(ERR_NAME | ERR_UNDVAR);
501 register Char *sub, *str;
509 if ((*sub++ & TRIM) != (*str++ & TRIM))