xref: /dragonfly/contrib/tcsh-6/sh.misc.c (revision d6ab524c)
17d8fb588SMatthias Schmidt /*
27d8fb588SMatthias Schmidt  * sh.misc.c: Miscelaneous functions
37d8fb588SMatthias Schmidt  */
47d8fb588SMatthias Schmidt /*-
57d8fb588SMatthias Schmidt  * Copyright (c) 1980, 1991 The Regents of the University of California.
67d8fb588SMatthias Schmidt  * All rights reserved.
77d8fb588SMatthias Schmidt  *
87d8fb588SMatthias Schmidt  * Redistribution and use in source and binary forms, with or without
97d8fb588SMatthias Schmidt  * modification, are permitted provided that the following conditions
107d8fb588SMatthias Schmidt  * are met:
117d8fb588SMatthias Schmidt  * 1. Redistributions of source code must retain the above copyright
127d8fb588SMatthias Schmidt  *    notice, this list of conditions and the following disclaimer.
137d8fb588SMatthias Schmidt  * 2. Redistributions in binary form must reproduce the above copyright
147d8fb588SMatthias Schmidt  *    notice, this list of conditions and the following disclaimer in the
157d8fb588SMatthias Schmidt  *    documentation and/or other materials provided with the distribution.
167d8fb588SMatthias Schmidt  * 3. Neither the name of the University nor the names of its contributors
177d8fb588SMatthias Schmidt  *    may be used to endorse or promote products derived from this software
187d8fb588SMatthias Schmidt  *    without specific prior written permission.
197d8fb588SMatthias Schmidt  *
207d8fb588SMatthias Schmidt  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
217d8fb588SMatthias Schmidt  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
227d8fb588SMatthias Schmidt  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
237d8fb588SMatthias Schmidt  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
247d8fb588SMatthias Schmidt  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
257d8fb588SMatthias Schmidt  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
267d8fb588SMatthias Schmidt  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
277d8fb588SMatthias Schmidt  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
287d8fb588SMatthias Schmidt  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
297d8fb588SMatthias Schmidt  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
307d8fb588SMatthias Schmidt  * SUCH DAMAGE.
317d8fb588SMatthias Schmidt  */
327d8fb588SMatthias Schmidt #include "sh.h"
337d8fb588SMatthias Schmidt 
347d8fb588SMatthias Schmidt static	int	renum	(int, int);
357d8fb588SMatthias Schmidt static  Char  **blkend	(Char **);
367d8fb588SMatthias Schmidt static  Char  **blkcat	(Char **, Char **);
377d8fb588SMatthias Schmidt static	int	xdup2	(int, int);
387d8fb588SMatthias Schmidt 
397d8fb588SMatthias Schmidt /*
407d8fb588SMatthias Schmidt  * C Shell
417d8fb588SMatthias Schmidt  */
427d8fb588SMatthias Schmidt 
437d8fb588SMatthias Schmidt int
any(const char * s,Char c)447d8fb588SMatthias Schmidt any(const char *s, Char c)
457d8fb588SMatthias Schmidt {
467d8fb588SMatthias Schmidt     if (!s)
477d8fb588SMatthias Schmidt 	return (0);		/* Check for nil pointer */
487d8fb588SMatthias Schmidt     while (*s)
497d8fb588SMatthias Schmidt 	if ((Char)*s++ == c)
507d8fb588SMatthias Schmidt 	    return (1);
517d8fb588SMatthias Schmidt     return (0);
527d8fb588SMatthias Schmidt }
537d8fb588SMatthias Schmidt 
547d8fb588SMatthias Schmidt void
setzero(void * p,size_t size)557d8fb588SMatthias Schmidt setzero(void *p, size_t size)
567d8fb588SMatthias Schmidt {
577d8fb588SMatthias Schmidt     memset(p, 0, size);
587d8fb588SMatthias Schmidt }
597d8fb588SMatthias Schmidt 
6094afa86dSJohn Marino #ifndef SHORT_STRINGS
617d8fb588SMatthias Schmidt char *
strnsave(const char * s,size_t len)627d8fb588SMatthias Schmidt strnsave(const char *s, size_t len)
637d8fb588SMatthias Schmidt {
647d8fb588SMatthias Schmidt     char *r;
657d8fb588SMatthias Schmidt 
667d8fb588SMatthias Schmidt     r = xmalloc(len + 1);
677d8fb588SMatthias Schmidt     memcpy(r, s, len);
687d8fb588SMatthias Schmidt     r[len] = '\0';
697d8fb588SMatthias Schmidt     return r;
707d8fb588SMatthias Schmidt }
7194afa86dSJohn Marino #endif
727d8fb588SMatthias Schmidt 
737d8fb588SMatthias Schmidt char   *
strsave(const char * s)747d8fb588SMatthias Schmidt strsave(const char *s)
757d8fb588SMatthias Schmidt {
767d8fb588SMatthias Schmidt     char   *r;
777d8fb588SMatthias Schmidt     size_t size;
787d8fb588SMatthias Schmidt 
797d8fb588SMatthias Schmidt     if (s == NULL)
807d8fb588SMatthias Schmidt 	s = "";
817d8fb588SMatthias Schmidt     size = strlen(s) + 1;
827d8fb588SMatthias Schmidt     r = xmalloc(size);
837d8fb588SMatthias Schmidt     memcpy(r, s, size);
847d8fb588SMatthias Schmidt     return (r);
857d8fb588SMatthias Schmidt }
867d8fb588SMatthias Schmidt 
877d8fb588SMatthias Schmidt static Char  **
blkend(Char ** up)887d8fb588SMatthias Schmidt blkend(Char **up)
897d8fb588SMatthias Schmidt {
907d8fb588SMatthias Schmidt 
917d8fb588SMatthias Schmidt     while (*up)
927d8fb588SMatthias Schmidt 	up++;
937d8fb588SMatthias Schmidt     return (up);
947d8fb588SMatthias Schmidt }
957d8fb588SMatthias Schmidt 
967d8fb588SMatthias Schmidt 
977d8fb588SMatthias Schmidt void
blkpr(Char * const * av)987d8fb588SMatthias Schmidt blkpr(Char *const *av)
997d8fb588SMatthias Schmidt {
1007d8fb588SMatthias Schmidt 
1017d8fb588SMatthias Schmidt     for (; *av; av++) {
102*d6ab524cSAntonio Huete Jimenez 	xprintf("%" TCSH_S, *av);
1037d8fb588SMatthias Schmidt 	if (av[1])
1047d8fb588SMatthias Schmidt 	    xprintf(" ");
1057d8fb588SMatthias Schmidt     }
1067d8fb588SMatthias Schmidt }
1077d8fb588SMatthias Schmidt 
1087d8fb588SMatthias Schmidt Char *
blkexpand(Char * const * av)1097d8fb588SMatthias Schmidt blkexpand(Char *const *av)
1107d8fb588SMatthias Schmidt {
1117d8fb588SMatthias Schmidt     struct Strbuf buf = Strbuf_INIT;
1127d8fb588SMatthias Schmidt 
1137d8fb588SMatthias Schmidt     for (; *av; av++) {
1147d8fb588SMatthias Schmidt 	Strbuf_append(&buf, *av);
1157d8fb588SMatthias Schmidt 	if (av[1])
1167d8fb588SMatthias Schmidt 	    Strbuf_append1(&buf, ' ');
1177d8fb588SMatthias Schmidt     }
1187d8fb588SMatthias Schmidt     return Strbuf_finish(&buf);
1197d8fb588SMatthias Schmidt }
1207d8fb588SMatthias Schmidt 
1217d8fb588SMatthias Schmidt int
blklen(Char ** av)1227d8fb588SMatthias Schmidt blklen(Char **av)
1237d8fb588SMatthias Schmidt {
1247d8fb588SMatthias Schmidt     int i = 0;
1257d8fb588SMatthias Schmidt 
1267d8fb588SMatthias Schmidt     while (*av++)
1277d8fb588SMatthias Schmidt 	i++;
1287d8fb588SMatthias Schmidt     return (i);
1297d8fb588SMatthias Schmidt }
1307d8fb588SMatthias Schmidt 
1317d8fb588SMatthias Schmidt Char  **
blkcpy(Char ** oav,Char ** bv)1327d8fb588SMatthias Schmidt blkcpy(Char **oav, Char **bv)
1337d8fb588SMatthias Schmidt {
1347d8fb588SMatthias Schmidt     Char **av = oav;
1357d8fb588SMatthias Schmidt 
1367d8fb588SMatthias Schmidt     while ((*av++ = *bv++) != NULL)
1377d8fb588SMatthias Schmidt 	continue;
1387d8fb588SMatthias Schmidt     return (oav);
1397d8fb588SMatthias Schmidt }
1407d8fb588SMatthias Schmidt 
1417d8fb588SMatthias Schmidt static Char  **
blkcat(Char ** up,Char ** vp)1427d8fb588SMatthias Schmidt blkcat(Char **up, Char **vp)
1437d8fb588SMatthias Schmidt {
1447d8fb588SMatthias Schmidt 
1457d8fb588SMatthias Schmidt     (void) blkcpy(blkend(up), vp);
1467d8fb588SMatthias Schmidt     return (up);
1477d8fb588SMatthias Schmidt }
1487d8fb588SMatthias Schmidt 
1497d8fb588SMatthias Schmidt void
blkfree(Char ** av0)1507d8fb588SMatthias Schmidt blkfree(Char **av0)
1517d8fb588SMatthias Schmidt {
1527d8fb588SMatthias Schmidt     Char **av = av0;
1537d8fb588SMatthias Schmidt 
1547d8fb588SMatthias Schmidt     if (!av0)
1557d8fb588SMatthias Schmidt 	return;
1567d8fb588SMatthias Schmidt     for (; *av; av++)
1577d8fb588SMatthias Schmidt 	xfree(*av);
1587d8fb588SMatthias Schmidt     xfree(av0);
1597d8fb588SMatthias Schmidt }
1607d8fb588SMatthias Schmidt 
1617d8fb588SMatthias Schmidt void
blk_cleanup(void * ptr)1627d8fb588SMatthias Schmidt blk_cleanup(void *ptr)
1637d8fb588SMatthias Schmidt {
1647d8fb588SMatthias Schmidt     blkfree(ptr);
1657d8fb588SMatthias Schmidt }
1667d8fb588SMatthias Schmidt 
1677d8fb588SMatthias Schmidt void
blk_indirect_cleanup(void * xptr)1687d8fb588SMatthias Schmidt blk_indirect_cleanup(void *xptr)
1697d8fb588SMatthias Schmidt {
1707d8fb588SMatthias Schmidt     Char ***ptr;
1717d8fb588SMatthias Schmidt 
1727d8fb588SMatthias Schmidt     ptr = xptr;
1737d8fb588SMatthias Schmidt     blkfree(*ptr);
1747d8fb588SMatthias Schmidt     xfree(ptr);
1757d8fb588SMatthias Schmidt }
1767d8fb588SMatthias Schmidt 
1777d8fb588SMatthias Schmidt Char  **
saveblk(Char ** v)1787d8fb588SMatthias Schmidt saveblk(Char **v)
1797d8fb588SMatthias Schmidt {
1807d8fb588SMatthias Schmidt     Char **newv, **onewv;
1817d8fb588SMatthias Schmidt 
1827d8fb588SMatthias Schmidt     if (v == NULL)
1837d8fb588SMatthias Schmidt 	return NULL;
1847d8fb588SMatthias Schmidt 
1857d8fb588SMatthias Schmidt     onewv = newv = xcalloc(blklen(v) + 1, sizeof(Char **));
1867d8fb588SMatthias Schmidt 
1877d8fb588SMatthias Schmidt     while (*v)
1887d8fb588SMatthias Schmidt 	*newv++ = Strsave(*v++);
1897d8fb588SMatthias Schmidt     return (onewv);
1907d8fb588SMatthias Schmidt }
1917d8fb588SMatthias Schmidt 
1927d8fb588SMatthias Schmidt #ifndef HAVE_STRSTR
1937d8fb588SMatthias Schmidt char   *
strstr(const char * s,const char * t)1947d8fb588SMatthias Schmidt strstr(const char *s, const char *t)
1957d8fb588SMatthias Schmidt {
1967d8fb588SMatthias Schmidt     do {
1977d8fb588SMatthias Schmidt 	const char *ss = s;
1987d8fb588SMatthias Schmidt 	const char *tt = t;
1997d8fb588SMatthias Schmidt 
2007d8fb588SMatthias Schmidt 	do
2017d8fb588SMatthias Schmidt 	    if (*tt == '\0')
2027d8fb588SMatthias Schmidt 		return (s);
2037d8fb588SMatthias Schmidt 	while (*ss++ == *tt++);
2047d8fb588SMatthias Schmidt     } while (*s++ != '\0');
2057d8fb588SMatthias Schmidt     return (NULL);
2067d8fb588SMatthias Schmidt }
2077d8fb588SMatthias Schmidt #endif /* !HAVE_STRSTR */
2087d8fb588SMatthias Schmidt 
2097d8fb588SMatthias Schmidt char   *
strspl(const char * cp,const char * dp)2107d8fb588SMatthias Schmidt strspl(const char *cp, const char *dp)
2117d8fb588SMatthias Schmidt {
2127d8fb588SMatthias Schmidt     char   *ep;
2137d8fb588SMatthias Schmidt     size_t cl, dl;
2147d8fb588SMatthias Schmidt 
2157d8fb588SMatthias Schmidt     if (!cp)
2167d8fb588SMatthias Schmidt 	cp = "";
2177d8fb588SMatthias Schmidt     if (!dp)
2187d8fb588SMatthias Schmidt 	dp = "";
2197d8fb588SMatthias Schmidt     cl = strlen(cp);
2207d8fb588SMatthias Schmidt     dl = strlen(dp);
2217d8fb588SMatthias Schmidt     ep = xmalloc((cl + dl + 1) * sizeof(char));
2227d8fb588SMatthias Schmidt     memcpy(ep, cp, cl);
2237d8fb588SMatthias Schmidt     memcpy(ep + cl, dp, dl + 1);
2247d8fb588SMatthias Schmidt     return (ep);
2257d8fb588SMatthias Schmidt }
2267d8fb588SMatthias Schmidt 
2277d8fb588SMatthias Schmidt Char  **
blkspl(Char ** up,Char ** vp)2287d8fb588SMatthias Schmidt blkspl(Char **up, Char **vp)
2297d8fb588SMatthias Schmidt {
2307d8fb588SMatthias Schmidt     Char **wp = xcalloc(blklen(up) + blklen(vp) + 1, sizeof(Char **));
2317d8fb588SMatthias Schmidt 
2327d8fb588SMatthias Schmidt     (void) blkcpy(wp, up);
2337d8fb588SMatthias Schmidt     return (blkcat(wp, vp));
2347d8fb588SMatthias Schmidt }
2357d8fb588SMatthias Schmidt 
2367d8fb588SMatthias Schmidt Char
lastchr(Char * cp)2377d8fb588SMatthias Schmidt lastchr(Char *cp)
2387d8fb588SMatthias Schmidt {
2397d8fb588SMatthias Schmidt 
2407d8fb588SMatthias Schmidt     if (!cp)
2417d8fb588SMatthias Schmidt 	return (0);
2427d8fb588SMatthias Schmidt     if (!*cp)
2437d8fb588SMatthias Schmidt 	return (0);
2447d8fb588SMatthias Schmidt     while (cp[1])
2457d8fb588SMatthias Schmidt 	cp++;
2467d8fb588SMatthias Schmidt     return (*cp);
2477d8fb588SMatthias Schmidt }
2487d8fb588SMatthias Schmidt 
2497d8fb588SMatthias Schmidt /*
2507d8fb588SMatthias Schmidt  * This routine is called after an error to close up
2517d8fb588SMatthias Schmidt  * any units which may have been left open accidentally.
2527d8fb588SMatthias Schmidt  */
2537d8fb588SMatthias Schmidt void
closem(void)2547d8fb588SMatthias Schmidt closem(void)
2557d8fb588SMatthias Schmidt {
2567d8fb588SMatthias Schmidt     int f, num_files;
257653fab9eSSascha Wildner #ifdef S_ISSOCK
258653fab9eSSascha Wildner     struct stat st;
259653fab9eSSascha Wildner #endif /*S_ISSOCK*/
2607d8fb588SMatthias Schmidt 
2617d8fb588SMatthias Schmidt #ifdef NLS_BUGS
2627d8fb588SMatthias Schmidt #ifdef NLS_CATALOGS
2637d8fb588SMatthias Schmidt     nlsclose();
2647d8fb588SMatthias Schmidt #endif /* NLS_CATALOGS */
2657d8fb588SMatthias Schmidt #endif /* NLS_BUGS */
2667d8fb588SMatthias Schmidt #ifdef YPBUGS
2677d8fb588SMatthias Schmidt     /* suggested by Justin Bur; thanks to Karl Kleinpaste */
2687d8fb588SMatthias Schmidt     fix_yp_bugs();
2697d8fb588SMatthias Schmidt #endif /* YPBUGS */
2707d8fb588SMatthias Schmidt     num_files = NOFILE;
2717d8fb588SMatthias Schmidt     for (f = 0; f < num_files; f++)
2727d8fb588SMatthias Schmidt 	if (f != SHIN && f != SHOUT && f != SHDIAG && f != OLDSTD &&
2737d8fb588SMatthias Schmidt 	    f != FSHTTY
2747d8fb588SMatthias Schmidt #ifdef MALLOC_TRACE
2757d8fb588SMatthias Schmidt 	    && f != 25
2767d8fb588SMatthias Schmidt #endif /* MALLOC_TRACE */
277653fab9eSSascha Wildner #ifdef S_ISSOCK
278653fab9eSSascha Wildner 	    /* NSS modules (e.g. Linux nss_ldap) might keep sockets open.
279653fab9eSSascha Wildner 	     * If we close such a socket, both the NSS module and tcsh think
280653fab9eSSascha Wildner 	     * they "own" the descriptor.
281653fab9eSSascha Wildner 	     *
282653fab9eSSascha Wildner 	     * Not closing sockets does not make the cleanup use of closem()
283653fab9eSSascha Wildner 	     * less reliable because tcsh never creates sockets.
284653fab9eSSascha Wildner 	     */
285653fab9eSSascha Wildner 	    && fstat(f, &st) == 0 && !S_ISSOCK(st.st_mode)
286653fab9eSSascha Wildner #endif
2877d8fb588SMatthias Schmidt 	    )
2887d8fb588SMatthias Schmidt 	  {
2897d8fb588SMatthias Schmidt 	    xclose(f);
2907d8fb588SMatthias Schmidt #ifdef NISPLUS
2917d8fb588SMatthias Schmidt 	    if (f < 3)
2927d8fb588SMatthias Schmidt 		(void) xopen(_PATH_DEVNULL, O_RDONLY|O_LARGEFILE);
2937d8fb588SMatthias Schmidt #endif /* NISPLUS */
2947d8fb588SMatthias Schmidt 	  }
2957d8fb588SMatthias Schmidt #ifdef NLS_BUGS
2967d8fb588SMatthias Schmidt #ifdef NLS_CATALOGS
2977d8fb588SMatthias Schmidt     nlsinit();
2987d8fb588SMatthias Schmidt #endif /* NLS_CATALOGS */
2997d8fb588SMatthias Schmidt #endif /* NLS_BUGS */
3007d8fb588SMatthias Schmidt }
3017d8fb588SMatthias Schmidt 
3027d8fb588SMatthias Schmidt #ifndef CLOSE_ON_EXEC
3037d8fb588SMatthias Schmidt /*
3047d8fb588SMatthias Schmidt  * Close files before executing a file.
3057d8fb588SMatthias Schmidt  * We could be MUCH more intelligent, since (on a version 7 system)
3067d8fb588SMatthias Schmidt  * we need only close files here during a source, the other
3077d8fb588SMatthias Schmidt  * shell fd's being in units 16-19 which are closed automatically!
3087d8fb588SMatthias Schmidt  */
3097d8fb588SMatthias Schmidt void
closech(void)3107d8fb588SMatthias Schmidt closech(void)
3117d8fb588SMatthias Schmidt {
3127d8fb588SMatthias Schmidt     int f, num_files;
3137d8fb588SMatthias Schmidt 
3147d8fb588SMatthias Schmidt     if (didcch)
3157d8fb588SMatthias Schmidt 	return;
3167d8fb588SMatthias Schmidt     didcch = 1;
3177d8fb588SMatthias Schmidt     SHIN = 0;
3187d8fb588SMatthias Schmidt     SHOUT = 1;
3197d8fb588SMatthias Schmidt     SHDIAG = 2;
3207d8fb588SMatthias Schmidt     OLDSTD = 0;
3217d8fb588SMatthias Schmidt     isoutatty = isatty(SHOUT);
3227d8fb588SMatthias Schmidt     isdiagatty = isatty(SHDIAG);
3237d8fb588SMatthias Schmidt     num_files = NOFILE;
3247d8fb588SMatthias Schmidt     for (f = 3; f < num_files; f++)
3257d8fb588SMatthias Schmidt 	xclose(f);
3267d8fb588SMatthias Schmidt }
3277d8fb588SMatthias Schmidt 
3287d8fb588SMatthias Schmidt #endif /* CLOSE_ON_EXEC */
3297d8fb588SMatthias Schmidt 
3307d8fb588SMatthias Schmidt void
donefds(void)3317d8fb588SMatthias Schmidt donefds(void)
3327d8fb588SMatthias Schmidt {
3337d8fb588SMatthias Schmidt 
3347d8fb588SMatthias Schmidt     xclose(0);
3357d8fb588SMatthias Schmidt     xclose(1);
3367d8fb588SMatthias Schmidt     xclose(2);
3377d8fb588SMatthias Schmidt     didfds = 0;
3387d8fb588SMatthias Schmidt #ifdef NISPLUS
3397d8fb588SMatthias Schmidt     {
3407d8fb588SMatthias Schmidt 	int fd = xopen(_PATH_DEVNULL, O_RDONLY|O_LARGEFILE);
3417d8fb588SMatthias Schmidt 	(void)dcopy(fd, 1);
3427d8fb588SMatthias Schmidt 	(void)dcopy(fd, 2);
3437d8fb588SMatthias Schmidt 	(void)dmove(fd, 0);
3447d8fb588SMatthias Schmidt     }
3457d8fb588SMatthias Schmidt #endif /*NISPLUS*/
3467d8fb588SMatthias Schmidt }
3477d8fb588SMatthias Schmidt 
3487d8fb588SMatthias Schmidt /*
3497d8fb588SMatthias Schmidt  * Move descriptor i to j.
3507d8fb588SMatthias Schmidt  * If j is -1 then we just want to get i to a safe place,
3517d8fb588SMatthias Schmidt  * i.e. to a unit > FSAFE.  This also happens in dcopy.
3527d8fb588SMatthias Schmidt  */
3537d8fb588SMatthias Schmidt int
dmove(int i,int j)3547d8fb588SMatthias Schmidt dmove(int i, int j)
3557d8fb588SMatthias Schmidt {
3567d8fb588SMatthias Schmidt 
3577d8fb588SMatthias Schmidt     if (i == j || i < 0)
3587d8fb588SMatthias Schmidt 	return (i);
3597d8fb588SMatthias Schmidt #ifdef HAVE_DUP2
3607d8fb588SMatthias Schmidt     if (j >= 0) {
3617d8fb588SMatthias Schmidt 	(void) xdup2(i, j);
3627d8fb588SMatthias Schmidt 	if (j != i)
3637d8fb588SMatthias Schmidt 	    xclose(i);
3647d8fb588SMatthias Schmidt 	return (j);
3657d8fb588SMatthias Schmidt     }
3667d8fb588SMatthias Schmidt #endif
3677d8fb588SMatthias Schmidt     j = dcopy(i, j);
3687d8fb588SMatthias Schmidt     if (j != i)
3697d8fb588SMatthias Schmidt 	xclose(i);
3707d8fb588SMatthias Schmidt     return (j);
3717d8fb588SMatthias Schmidt }
3727d8fb588SMatthias Schmidt 
3737d8fb588SMatthias Schmidt int
dcopy(int i,int j)3747d8fb588SMatthias Schmidt dcopy(int i, int j)
3757d8fb588SMatthias Schmidt {
3767d8fb588SMatthias Schmidt 
3777d8fb588SMatthias Schmidt     if (i == j || i < 0 || (j < 0 && i > FSAFE))
3787d8fb588SMatthias Schmidt 	return (i);
3797d8fb588SMatthias Schmidt     if (j >= 0) {
3807d8fb588SMatthias Schmidt #ifdef HAVE_DUP2
3817d8fb588SMatthias Schmidt 	(void) xdup2(i, j);
3827d8fb588SMatthias Schmidt 	return (j);
3837d8fb588SMatthias Schmidt #else
3847d8fb588SMatthias Schmidt 	xclose(j);
3857d8fb588SMatthias Schmidt #endif
3867d8fb588SMatthias Schmidt     }
3877d8fb588SMatthias Schmidt     return (renum(i, j));
3887d8fb588SMatthias Schmidt }
3897d8fb588SMatthias Schmidt 
3907d8fb588SMatthias Schmidt static int
renum(int i,int j)3917d8fb588SMatthias Schmidt renum(int i, int j)
3927d8fb588SMatthias Schmidt {
3937d8fb588SMatthias Schmidt     int k = dup(i);
3947d8fb588SMatthias Schmidt 
3957d8fb588SMatthias Schmidt     if (k < 0)
3967d8fb588SMatthias Schmidt 	return (-1);
3977d8fb588SMatthias Schmidt     if (j == -1 && k > FSAFE)
3987d8fb588SMatthias Schmidt 	return (k);
3997d8fb588SMatthias Schmidt     if (k != j) {
4007d8fb588SMatthias Schmidt 	j = renum(k, j);
4017d8fb588SMatthias Schmidt 	xclose(k);
4027d8fb588SMatthias Schmidt 	return (j);
4037d8fb588SMatthias Schmidt     }
4047d8fb588SMatthias Schmidt     return (k);
4057d8fb588SMatthias Schmidt }
4067d8fb588SMatthias Schmidt 
4077d8fb588SMatthias Schmidt /*
4087d8fb588SMatthias Schmidt  * Left shift a command argument list, discarding
4097d8fb588SMatthias Schmidt  * the first c arguments.  Used in "shift" commands
4107d8fb588SMatthias Schmidt  * as well as by commands like "repeat".
4117d8fb588SMatthias Schmidt  */
4127d8fb588SMatthias Schmidt void
lshift(Char ** v,int c)4137d8fb588SMatthias Schmidt lshift(Char **v, int c)
4147d8fb588SMatthias Schmidt {
4157d8fb588SMatthias Schmidt     Char **u;
4167d8fb588SMatthias Schmidt 
4177d8fb588SMatthias Schmidt     for (u = v; *u && --c >= 0; u++)
4187d8fb588SMatthias Schmidt 	xfree(*u);
4197d8fb588SMatthias Schmidt     (void) blkcpy(v, u);
4207d8fb588SMatthias Schmidt }
4217d8fb588SMatthias Schmidt 
4227d8fb588SMatthias Schmidt int
number(Char * cp)4237d8fb588SMatthias Schmidt number(Char *cp)
4247d8fb588SMatthias Schmidt {
4257d8fb588SMatthias Schmidt     if (!cp)
4267d8fb588SMatthias Schmidt 	return (0);
4277d8fb588SMatthias Schmidt     if (*cp == '-') {
4287d8fb588SMatthias Schmidt 	cp++;
4297d8fb588SMatthias Schmidt 	if (!Isdigit(*cp))
4307d8fb588SMatthias Schmidt 	    return (0);
4317d8fb588SMatthias Schmidt 	cp++;
4327d8fb588SMatthias Schmidt     }
4337d8fb588SMatthias Schmidt     while (*cp && Isdigit(*cp))
4347d8fb588SMatthias Schmidt 	cp++;
4357d8fb588SMatthias Schmidt     return (*cp == 0);
4367d8fb588SMatthias Schmidt }
4377d8fb588SMatthias Schmidt 
4387d8fb588SMatthias Schmidt Char  **
copyblk(Char ** v)4397d8fb588SMatthias Schmidt copyblk(Char **v)
4407d8fb588SMatthias Schmidt {
4417d8fb588SMatthias Schmidt     Char **nv = xcalloc(blklen(v) + 1, sizeof(Char **));
4427d8fb588SMatthias Schmidt 
4437d8fb588SMatthias Schmidt     return (blkcpy(nv, v));
4447d8fb588SMatthias Schmidt }
4457d8fb588SMatthias Schmidt 
4467d8fb588SMatthias Schmidt char   *
strend(const char * cp)4477d8fb588SMatthias Schmidt strend(const char *cp)
4487d8fb588SMatthias Schmidt {
4497d8fb588SMatthias Schmidt     if (!cp)
4507d8fb588SMatthias Schmidt 	return ((char *)(intptr_t)cp);
4517d8fb588SMatthias Schmidt     while (*cp)
4527d8fb588SMatthias Schmidt 	cp++;
4537d8fb588SMatthias Schmidt     return ((char *)(intptr_t)cp);
4547d8fb588SMatthias Schmidt }
4557d8fb588SMatthias Schmidt 
4567d8fb588SMatthias Schmidt Char   *
strip(Char * cp)4577d8fb588SMatthias Schmidt strip(Char *cp)
4587d8fb588SMatthias Schmidt {
4597d8fb588SMatthias Schmidt     Char *dp = cp;
4607d8fb588SMatthias Schmidt 
4617d8fb588SMatthias Schmidt     if (!cp)
4627d8fb588SMatthias Schmidt 	return (cp);
463653fab9eSSascha Wildner     while (*dp != '\0') {
464653fab9eSSascha Wildner #if INVALID_BYTE != 0
465653fab9eSSascha Wildner 	if ((*dp & INVALID_BYTE) != INVALID_BYTE)    /* *dp < INVALID_BYTE */
466653fab9eSSascha Wildner #endif
467653fab9eSSascha Wildner 		*dp &= TRIM;
468653fab9eSSascha Wildner 	dp++;
469653fab9eSSascha Wildner     }
4707d8fb588SMatthias Schmidt     return (cp);
4717d8fb588SMatthias Schmidt }
4727d8fb588SMatthias Schmidt 
4737d8fb588SMatthias Schmidt Char   *
quote(Char * cp)4747d8fb588SMatthias Schmidt quote(Char *cp)
4757d8fb588SMatthias Schmidt {
4767d8fb588SMatthias Schmidt     Char *dp = cp;
4777d8fb588SMatthias Schmidt 
4787d8fb588SMatthias Schmidt     if (!cp)
4797d8fb588SMatthias Schmidt 	return (cp);
480653fab9eSSascha Wildner     while (*dp != '\0') {
481653fab9eSSascha Wildner #ifdef WIDE_STRINGS
482653fab9eSSascha Wildner 	if ((*dp & 0xffffff80) == 0)	/* *dp < 0x80 */
483653fab9eSSascha Wildner #elif defined SHORT_STRINGS
484653fab9eSSascha Wildner 	if ((*dp & 0xff80) == 0)	/* *dp < 0x80 */
485653fab9eSSascha Wildner #else
486653fab9eSSascha Wildner 	if ((*dp & 0x80) == 0)		/* *dp < 0x80 */
487653fab9eSSascha Wildner #endif
488653fab9eSSascha Wildner 	    *dp |= QUOTE;
489653fab9eSSascha Wildner 	dp++;
490653fab9eSSascha Wildner     }
4917d8fb588SMatthias Schmidt     return (cp);
4927d8fb588SMatthias Schmidt }
4937d8fb588SMatthias Schmidt 
4947d8fb588SMatthias Schmidt const Char *
quote_meta(struct Strbuf * buf,const Char * s)4957d8fb588SMatthias Schmidt quote_meta(struct Strbuf *buf, const Char *s)
4967d8fb588SMatthias Schmidt {
4977d8fb588SMatthias Schmidt     buf->len = 0;
4987d8fb588SMatthias Schmidt     while (*s != '\0') {
4997d8fb588SMatthias Schmidt 	if (cmap(*s, _META | _DOL | _QF | _QB | _ESC | _GLOB))
5007d8fb588SMatthias Schmidt 	    Strbuf_append1(buf, '\\');
5017d8fb588SMatthias Schmidt 	Strbuf_append1(buf, *s++);
5027d8fb588SMatthias Schmidt     }
5037d8fb588SMatthias Schmidt     Strbuf_terminate(buf);
5047d8fb588SMatthias Schmidt     return buf->s;
5057d8fb588SMatthias Schmidt }
5067d8fb588SMatthias Schmidt 
5077d8fb588SMatthias Schmidt void
udvar(Char * name)5087d8fb588SMatthias Schmidt udvar(Char *name)
5097d8fb588SMatthias Schmidt {
5107d8fb588SMatthias Schmidt     setname(short2str(name));
5117d8fb588SMatthias Schmidt     stderror(ERR_NAME | ERR_UNDVAR);
5127d8fb588SMatthias Schmidt }
5137d8fb588SMatthias Schmidt 
5147d8fb588SMatthias Schmidt int
prefix(const Char * sub,const Char * str)5157d8fb588SMatthias Schmidt prefix(const Char *sub, const Char *str)
5167d8fb588SMatthias Schmidt {
5177d8fb588SMatthias Schmidt 
5187d8fb588SMatthias Schmidt     for (;;) {
5197d8fb588SMatthias Schmidt 	if (*sub == 0)
5207d8fb588SMatthias Schmidt 	    return (1);
5217d8fb588SMatthias Schmidt 	if (*str == 0)
5227d8fb588SMatthias Schmidt 	    return (0);
5237d8fb588SMatthias Schmidt 	if ((*sub++ & TRIM) != (*str++ & TRIM))
5247d8fb588SMatthias Schmidt 	    return (0);
5257d8fb588SMatthias Schmidt     }
5267d8fb588SMatthias Schmidt }
5277d8fb588SMatthias Schmidt #ifndef WINNT_NATIVE
5287d8fb588SMatthias Schmidt char *
areadlink(const char * path)5297d8fb588SMatthias Schmidt areadlink(const char *path)
5307d8fb588SMatthias Schmidt {
5317d8fb588SMatthias Schmidt     char *buf;
5327d8fb588SMatthias Schmidt     size_t size;
5337d8fb588SMatthias Schmidt     ssize_t res;
534*d6ab524cSAntonio Huete Jimenez #ifdef __IBMC__
535*d6ab524cSAntonio Huete Jimenez     /*
536*d6ab524cSAntonio Huete Jimenez      * Prevent infinite recursion. Someone should tell me how to expand
537*d6ab524cSAntonio Huete Jimenez      * these...
538*d6ab524cSAntonio Huete Jimenez      */
539*d6ab524cSAntonio Huete Jimenez     size_t i;
540*d6ab524cSAntonio Huete Jimenez     static const char *vars[] = {
541*d6ab524cSAntonio Huete Jimenez 	"/$VERSION",
542*d6ab524cSAntonio Huete Jimenez 	"/$SYSNAME",
543*d6ab524cSAntonio Huete Jimenez 	"/$SYSSYMR",
544*d6ab524cSAntonio Huete Jimenez 	"/$SYSSYMA",
545*d6ab524cSAntonio Huete Jimenez     };
546*d6ab524cSAntonio Huete Jimenez     for (i = 0; i < sizeof(vars) / sizeof(vars[0]); i++) {
547*d6ab524cSAntonio Huete Jimenez 	if (strcmp(vars[i], path) == 0) {
548*d6ab524cSAntonio Huete Jimenez 	    return NULL;
549*d6ab524cSAntonio Huete Jimenez 	}
550*d6ab524cSAntonio Huete Jimenez     }
551*d6ab524cSAntonio Huete Jimenez #endif
552*d6ab524cSAntonio Huete Jimenez 
5537d8fb588SMatthias Schmidt 
5547d8fb588SMatthias Schmidt     size = MAXPATHLEN + 1;
5557d8fb588SMatthias Schmidt     buf = xmalloc(size);
5567d8fb588SMatthias Schmidt     while ((size_t)(res = readlink(path, buf, size)) == size) {
5577d8fb588SMatthias Schmidt 	size *= 2;
5587d8fb588SMatthias Schmidt 	buf = xrealloc(buf, size);
5597d8fb588SMatthias Schmidt     }
5607d8fb588SMatthias Schmidt     if (res == -1) {
5617d8fb588SMatthias Schmidt 	int err;
5627d8fb588SMatthias Schmidt 
5637d8fb588SMatthias Schmidt 	err = errno;
5647d8fb588SMatthias Schmidt 	xfree(buf);
5657d8fb588SMatthias Schmidt 	errno = err;
5667d8fb588SMatthias Schmidt 	return NULL;
5677d8fb588SMatthias Schmidt     }
5687d8fb588SMatthias Schmidt     buf[res] = '\0';
5697d8fb588SMatthias Schmidt     return xrealloc(buf, res + 1);
5707d8fb588SMatthias Schmidt }
5717d8fb588SMatthias Schmidt #endif /*!WINNT_NATIVE*/
5727d8fb588SMatthias Schmidt 
5737d8fb588SMatthias Schmidt void
xclose(int fildes)5747d8fb588SMatthias Schmidt xclose(int fildes)
5757d8fb588SMatthias Schmidt {
5767d8fb588SMatthias Schmidt     if (fildes < 0)
5777d8fb588SMatthias Schmidt 	return;
5787d8fb588SMatthias Schmidt     while (close(fildes) == -1 && errno == EINTR)
57960962bbcSJohn Marino 	if (handle_pending_signals())
58060962bbcSJohn Marino 	    break;
5817d8fb588SMatthias Schmidt }
5827d8fb588SMatthias Schmidt 
5837d8fb588SMatthias Schmidt void
xclosedir(DIR * dirp)5847d8fb588SMatthias Schmidt xclosedir(DIR *dirp)
5857d8fb588SMatthias Schmidt {
5867d8fb588SMatthias Schmidt     while (closedir(dirp) == -1 && errno == EINTR)
58760962bbcSJohn Marino 	if (handle_pending_signals())
58860962bbcSJohn Marino 	    break;
5897d8fb588SMatthias Schmidt }
5907d8fb588SMatthias Schmidt 
5917d8fb588SMatthias Schmidt int
xcreat(const char * path,mode_t mode)5927d8fb588SMatthias Schmidt xcreat(const char *path, mode_t mode)
5937d8fb588SMatthias Schmidt {
5947d8fb588SMatthias Schmidt     int res;
5957d8fb588SMatthias Schmidt 
5967d8fb588SMatthias Schmidt     while ((res = creat(path, mode)) == -1 && errno == EINTR)
59760962bbcSJohn Marino 	if (handle_pending_signals())
59860962bbcSJohn Marino 	    break;
5997d8fb588SMatthias Schmidt     return res;
6007d8fb588SMatthias Schmidt }
6017d8fb588SMatthias Schmidt 
6027d8fb588SMatthias Schmidt #ifdef HAVE_DUP2
6037d8fb588SMatthias Schmidt static int
xdup2(int fildes,int fildes2)6047d8fb588SMatthias Schmidt xdup2(int fildes, int fildes2)
6057d8fb588SMatthias Schmidt {
6067d8fb588SMatthias Schmidt     int res;
6077d8fb588SMatthias Schmidt 
6087d8fb588SMatthias Schmidt     while ((res = dup2(fildes, fildes2)) == -1 && errno == EINTR)
60960962bbcSJohn Marino 	if (handle_pending_signals())
61060962bbcSJohn Marino 	    break;
6117d8fb588SMatthias Schmidt     return res;
6127d8fb588SMatthias Schmidt }
6137d8fb588SMatthias Schmidt #endif
6147d8fb588SMatthias Schmidt 
6157d8fb588SMatthias Schmidt struct group *
xgetgrgid(gid_t xgid)6167d8fb588SMatthias Schmidt xgetgrgid(gid_t xgid)
6177d8fb588SMatthias Schmidt {
6187d8fb588SMatthias Schmidt     struct group *res;
6197d8fb588SMatthias Schmidt 
6207d8fb588SMatthias Schmidt     errno = 0;
6217d8fb588SMatthias Schmidt     while ((res = getgrgid(xgid)) == NULL && errno == EINTR) {
62260962bbcSJohn Marino 	if (handle_pending_signals())
62360962bbcSJohn Marino 	    break;
6247d8fb588SMatthias Schmidt 	errno = 0;
6257d8fb588SMatthias Schmidt     }
6267d8fb588SMatthias Schmidt     return res;
6277d8fb588SMatthias Schmidt }
6287d8fb588SMatthias Schmidt 
6297d8fb588SMatthias Schmidt struct passwd *
xgetpwnam(const char * name)6307d8fb588SMatthias Schmidt xgetpwnam(const char *name)
6317d8fb588SMatthias Schmidt {
6327d8fb588SMatthias Schmidt     struct passwd *res;
6337d8fb588SMatthias Schmidt 
6347d8fb588SMatthias Schmidt     errno = 0;
6357d8fb588SMatthias Schmidt     while ((res = getpwnam(name)) == NULL && errno == EINTR) {
63660962bbcSJohn Marino 	if (handle_pending_signals())
63760962bbcSJohn Marino 	    break;
6387d8fb588SMatthias Schmidt 	errno = 0;
6397d8fb588SMatthias Schmidt     }
6407d8fb588SMatthias Schmidt     return res;
6417d8fb588SMatthias Schmidt }
6427d8fb588SMatthias Schmidt 
6437d8fb588SMatthias Schmidt struct passwd *
xgetpwuid(uid_t xuid)6447d8fb588SMatthias Schmidt xgetpwuid(uid_t xuid)
6457d8fb588SMatthias Schmidt {
6467d8fb588SMatthias Schmidt     struct passwd *res;
6477d8fb588SMatthias Schmidt 
6487d8fb588SMatthias Schmidt     errno = 0;
6497d8fb588SMatthias Schmidt     while ((res = getpwuid(xuid)) == NULL && errno == EINTR) {
65060962bbcSJohn Marino 	if (handle_pending_signals())
65160962bbcSJohn Marino 	    break;
6527d8fb588SMatthias Schmidt 	errno = 0;
6537d8fb588SMatthias Schmidt     }
6547d8fb588SMatthias Schmidt     return res;
6557d8fb588SMatthias Schmidt }
6567d8fb588SMatthias Schmidt 
6577d8fb588SMatthias Schmidt int
xopen(const char * path,int oflag,...)6587d8fb588SMatthias Schmidt xopen(const char *path, int oflag, ...)
6597d8fb588SMatthias Schmidt {
6607d8fb588SMatthias Schmidt     int res;
6617d8fb588SMatthias Schmidt 
6627d8fb588SMatthias Schmidt     if ((oflag & O_CREAT) == 0) {
6637d8fb588SMatthias Schmidt 	while ((res = open(path, oflag)) == -1 && errno == EINTR)
66460962bbcSJohn Marino 	    if (handle_pending_signals())
66560962bbcSJohn Marino 		break;
6667d8fb588SMatthias Schmidt     } else {
6677d8fb588SMatthias Schmidt 	va_list ap;
6687d8fb588SMatthias Schmidt 	mode_t mode;
6697d8fb588SMatthias Schmidt 
6707d8fb588SMatthias Schmidt 	va_start(ap, oflag);
6717d8fb588SMatthias Schmidt 	/* "int" should actually be "mode_t after default argument
6727d8fb588SMatthias Schmidt 	   promotions". "int" is the best guess we have, "mode_t" used to be
6737d8fb588SMatthias Schmidt 	   "unsigned short", which we obviously can't use. */
6747d8fb588SMatthias Schmidt 	mode = va_arg(ap, int);
6757d8fb588SMatthias Schmidt 	va_end(ap);
6767d8fb588SMatthias Schmidt 	while ((res = open(path, oflag, mode)) == -1 && errno == EINTR)
67760962bbcSJohn Marino 	    if (handle_pending_signals())
67860962bbcSJohn Marino 		break;
6797d8fb588SMatthias Schmidt     }
6807d8fb588SMatthias Schmidt     return res;
6817d8fb588SMatthias Schmidt }
6827d8fb588SMatthias Schmidt 
6837d8fb588SMatthias Schmidt ssize_t
xread(int fildes,void * buf,size_t nbyte)6847d8fb588SMatthias Schmidt xread(int fildes, void *buf, size_t nbyte)
6857d8fb588SMatthias Schmidt {
686653fab9eSSascha Wildner     ssize_t res = -1;
6877d8fb588SMatthias Schmidt 
6887d8fb588SMatthias Schmidt     /* This is where we will be blocked most of the time, so handle signals
6897d8fb588SMatthias Schmidt        that didn't interrupt any system call. */
6907d8fb588SMatthias Schmidt     do
69160962bbcSJohn Marino       if (handle_pending_signals())
69260962bbcSJohn Marino 	  break;
6937d8fb588SMatthias Schmidt     while ((res = read(fildes, buf, nbyte)) == -1 && errno == EINTR);
6947d8fb588SMatthias Schmidt     return res;
6957d8fb588SMatthias Schmidt }
6967d8fb588SMatthias Schmidt 
6977d8fb588SMatthias Schmidt #ifdef POSIX
6987d8fb588SMatthias Schmidt int
xtcsetattr(int fildes,int optional_actions,const struct termios * termios_p)6997d8fb588SMatthias Schmidt xtcsetattr(int fildes, int optional_actions, const struct termios *termios_p)
7007d8fb588SMatthias Schmidt {
7017d8fb588SMatthias Schmidt     int res;
7027d8fb588SMatthias Schmidt 
7037d8fb588SMatthias Schmidt     while ((res = tcsetattr(fildes, optional_actions, termios_p)) == -1 &&
7047d8fb588SMatthias Schmidt 	   errno == EINTR)
70560962bbcSJohn Marino 	if (handle_pending_signals())
70660962bbcSJohn Marino 	    break;
7077d8fb588SMatthias Schmidt     return res;
7087d8fb588SMatthias Schmidt }
7097d8fb588SMatthias Schmidt #endif
7107d8fb588SMatthias Schmidt 
7117d8fb588SMatthias Schmidt ssize_t
xwrite(int fildes,const void * buf,size_t nbyte)7127d8fb588SMatthias Schmidt xwrite(int fildes, const void *buf, size_t nbyte)
7137d8fb588SMatthias Schmidt {
714653fab9eSSascha Wildner     ssize_t res = -1;
7157d8fb588SMatthias Schmidt 
7167d8fb588SMatthias Schmidt     /* This is where we will be blocked most of the time, so handle signals
7177d8fb588SMatthias Schmidt        that didn't interrupt any system call. */
7187d8fb588SMatthias Schmidt     do
71960962bbcSJohn Marino       if (handle_pending_signals())
72060962bbcSJohn Marino 	  break;
7217d8fb588SMatthias Schmidt     while ((res = write(fildes, buf, nbyte)) == -1 && errno == EINTR);
7227d8fb588SMatthias Schmidt     return res;
7237d8fb588SMatthias Schmidt }
724