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