1*9ccc37e3SMark Peek /* $Header: /p/tcsh/cvsroot/tcsh/sh.misc.c,v 3.46 2010/05/08 00:41:58 christos Exp $ */ 2c80476e4SDavid E. O'Brien /* 3c80476e4SDavid E. O'Brien * sh.misc.c: Miscelaneous functions 4c80476e4SDavid E. O'Brien */ 5c80476e4SDavid E. O'Brien /*- 6c80476e4SDavid E. O'Brien * Copyright (c) 1980, 1991 The Regents of the University of California. 7c80476e4SDavid E. O'Brien * All rights reserved. 8c80476e4SDavid E. O'Brien * 9c80476e4SDavid E. O'Brien * Redistribution and use in source and binary forms, with or without 10c80476e4SDavid E. O'Brien * modification, are permitted provided that the following conditions 11c80476e4SDavid E. O'Brien * are met: 12c80476e4SDavid E. O'Brien * 1. Redistributions of source code must retain the above copyright 13c80476e4SDavid E. O'Brien * notice, this list of conditions and the following disclaimer. 14c80476e4SDavid E. O'Brien * 2. Redistributions in binary form must reproduce the above copyright 15c80476e4SDavid E. O'Brien * notice, this list of conditions and the following disclaimer in the 16c80476e4SDavid E. O'Brien * documentation and/or other materials provided with the distribution. 1729301572SMark Peek * 3. Neither the name of the University nor the names of its contributors 18c80476e4SDavid E. O'Brien * may be used to endorse or promote products derived from this software 19c80476e4SDavid E. O'Brien * without specific prior written permission. 20c80476e4SDavid E. O'Brien * 21c80476e4SDavid E. O'Brien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22c80476e4SDavid E. O'Brien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23c80476e4SDavid E. O'Brien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24c80476e4SDavid E. O'Brien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25c80476e4SDavid E. O'Brien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26c80476e4SDavid E. O'Brien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27c80476e4SDavid E. O'Brien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28c80476e4SDavid E. O'Brien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29c80476e4SDavid E. O'Brien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30c80476e4SDavid E. O'Brien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31c80476e4SDavid E. O'Brien * SUCH DAMAGE. 32c80476e4SDavid E. O'Brien */ 33c80476e4SDavid E. O'Brien #include "sh.h" 34c80476e4SDavid E. O'Brien 35*9ccc37e3SMark Peek RCSID("$tcsh: sh.misc.c,v 3.46 2010/05/08 00:41:58 christos Exp $") 36c80476e4SDavid E. O'Brien 3745e5710bSMark Peek static int renum (int, int); 3845e5710bSMark Peek static Char **blkend (Char **); 3945e5710bSMark Peek static Char **blkcat (Char **, Char **); 4045e5710bSMark Peek static int xdup2 (int, int); 41c80476e4SDavid E. O'Brien 42c80476e4SDavid E. O'Brien /* 43c80476e4SDavid E. O'Brien * C Shell 44c80476e4SDavid E. O'Brien */ 45c80476e4SDavid E. O'Brien 46c80476e4SDavid E. O'Brien int 4745e5710bSMark Peek any(const char *s, Char c) 48c80476e4SDavid E. O'Brien { 49c80476e4SDavid E. O'Brien if (!s) 50c80476e4SDavid E. O'Brien return (0); /* Check for nil pointer */ 51c80476e4SDavid E. O'Brien while (*s) 5223338178SMark Peek if ((Char)*s++ == c) 53c80476e4SDavid E. O'Brien return (1); 54c80476e4SDavid E. O'Brien return (0); 55c80476e4SDavid E. O'Brien } 56c80476e4SDavid E. O'Brien 57c80476e4SDavid E. O'Brien void 5845e5710bSMark Peek setzero(void *p, size_t size) 59c80476e4SDavid E. O'Brien { 6045e5710bSMark Peek memset(p, 0, size); 61c80476e4SDavid E. O'Brien } 62c80476e4SDavid E. O'Brien 63*9ccc37e3SMark Peek #ifndef SHORT_STRINGS 64c80476e4SDavid E. O'Brien char * 6545e5710bSMark Peek strnsave(const char *s, size_t len) 66c80476e4SDavid E. O'Brien { 6745e5710bSMark Peek char *r; 6845e5710bSMark Peek 6945e5710bSMark Peek r = xmalloc(len + 1); 7045e5710bSMark Peek memcpy(r, s, len); 7145e5710bSMark Peek r[len] = '\0'; 7245e5710bSMark Peek return r; 7345e5710bSMark Peek } 74*9ccc37e3SMark Peek #endif 7545e5710bSMark Peek 7645e5710bSMark Peek char * 7745e5710bSMark Peek strsave(const char *s) 7845e5710bSMark Peek { 7945e5710bSMark Peek char *r; 8045e5710bSMark Peek size_t size; 81c80476e4SDavid E. O'Brien 82c80476e4SDavid E. O'Brien if (s == NULL) 8323338178SMark Peek s = ""; 8445e5710bSMark Peek size = strlen(s) + 1; 8545e5710bSMark Peek r = xmalloc(size); 8645e5710bSMark Peek memcpy(r, s, size); 8723338178SMark Peek return (r); 88c80476e4SDavid E. O'Brien } 89c80476e4SDavid E. O'Brien 90c80476e4SDavid E. O'Brien static Char ** 9145e5710bSMark Peek blkend(Char **up) 92c80476e4SDavid E. O'Brien { 93c80476e4SDavid E. O'Brien 94c80476e4SDavid E. O'Brien while (*up) 95c80476e4SDavid E. O'Brien up++; 96c80476e4SDavid E. O'Brien return (up); 97c80476e4SDavid E. O'Brien } 98c80476e4SDavid E. O'Brien 99c80476e4SDavid E. O'Brien 100c80476e4SDavid E. O'Brien void 10145e5710bSMark Peek blkpr(Char *const *av) 102c80476e4SDavid E. O'Brien { 103c80476e4SDavid E. O'Brien 104c80476e4SDavid E. O'Brien for (; *av; av++) { 105c80476e4SDavid E. O'Brien xprintf("%S", *av); 106c80476e4SDavid E. O'Brien if (av[1]) 107c80476e4SDavid E. O'Brien xprintf(" "); 108c80476e4SDavid E. O'Brien } 109c80476e4SDavid E. O'Brien } 110c80476e4SDavid E. O'Brien 11145e5710bSMark Peek Char * 11245e5710bSMark Peek blkexpand(Char *const *av) 113c80476e4SDavid E. O'Brien { 11445e5710bSMark Peek struct Strbuf buf = Strbuf_INIT; 11545e5710bSMark Peek 116c80476e4SDavid E. O'Brien for (; *av; av++) { 11745e5710bSMark Peek Strbuf_append(&buf, *av); 118c80476e4SDavid E. O'Brien if (av[1]) 11945e5710bSMark Peek Strbuf_append1(&buf, ' '); 120c80476e4SDavid E. O'Brien } 12145e5710bSMark Peek return Strbuf_finish(&buf); 122c80476e4SDavid E. O'Brien } 123c80476e4SDavid E. O'Brien 124c80476e4SDavid E. O'Brien int 12545e5710bSMark Peek blklen(Char **av) 126c80476e4SDavid E. O'Brien { 12723338178SMark Peek int i = 0; 128c80476e4SDavid E. O'Brien 129c80476e4SDavid E. O'Brien while (*av++) 130c80476e4SDavid E. O'Brien i++; 131c80476e4SDavid E. O'Brien return (i); 132c80476e4SDavid E. O'Brien } 133c80476e4SDavid E. O'Brien 134c80476e4SDavid E. O'Brien Char ** 13545e5710bSMark Peek blkcpy(Char **oav, Char **bv) 136c80476e4SDavid E. O'Brien { 13723338178SMark Peek Char **av = oav; 138c80476e4SDavid E. O'Brien 139c80476e4SDavid E. O'Brien while ((*av++ = *bv++) != NULL) 140c80476e4SDavid E. O'Brien continue; 141c80476e4SDavid E. O'Brien return (oav); 142c80476e4SDavid E. O'Brien } 143c80476e4SDavid E. O'Brien 144c80476e4SDavid E. O'Brien static Char ** 14545e5710bSMark Peek blkcat(Char **up, Char **vp) 146c80476e4SDavid E. O'Brien { 147c80476e4SDavid E. O'Brien 148c80476e4SDavid E. O'Brien (void) blkcpy(blkend(up), vp); 149c80476e4SDavid E. O'Brien return (up); 150c80476e4SDavid E. O'Brien } 151c80476e4SDavid E. O'Brien 152c80476e4SDavid E. O'Brien void 15345e5710bSMark Peek blkfree(Char **av0) 154c80476e4SDavid E. O'Brien { 15523338178SMark Peek Char **av = av0; 156c80476e4SDavid E. O'Brien 157c80476e4SDavid E. O'Brien if (!av0) 158c80476e4SDavid E. O'Brien return; 159c80476e4SDavid E. O'Brien for (; *av; av++) 16045e5710bSMark Peek xfree(*av); 16145e5710bSMark Peek xfree(av0); 16245e5710bSMark Peek } 16345e5710bSMark Peek 16445e5710bSMark Peek void 16545e5710bSMark Peek blk_cleanup(void *ptr) 16645e5710bSMark Peek { 16745e5710bSMark Peek blkfree(ptr); 16845e5710bSMark Peek } 16945e5710bSMark Peek 17045e5710bSMark Peek void 17145e5710bSMark Peek blk_indirect_cleanup(void *xptr) 17245e5710bSMark Peek { 17345e5710bSMark Peek Char ***ptr; 17445e5710bSMark Peek 17545e5710bSMark Peek ptr = xptr; 17645e5710bSMark Peek blkfree(*ptr); 17745e5710bSMark Peek xfree(ptr); 178c80476e4SDavid E. O'Brien } 179c80476e4SDavid E. O'Brien 180c80476e4SDavid E. O'Brien Char ** 18145e5710bSMark Peek saveblk(Char **v) 182c80476e4SDavid E. O'Brien { 18345e5710bSMark Peek Char **newv, **onewv; 18445e5710bSMark Peek 18545e5710bSMark Peek if (v == NULL) 18645e5710bSMark Peek return NULL; 18745e5710bSMark Peek 18845e5710bSMark Peek onewv = newv = xcalloc(blklen(v) + 1, sizeof(Char **)); 189c80476e4SDavid E. O'Brien 190c80476e4SDavid E. O'Brien while (*v) 191c80476e4SDavid E. O'Brien *newv++ = Strsave(*v++); 192c80476e4SDavid E. O'Brien return (onewv); 193c80476e4SDavid E. O'Brien } 194c80476e4SDavid E. O'Brien 19523338178SMark Peek #ifndef HAVE_STRSTR 196c80476e4SDavid E. O'Brien char * 19745e5710bSMark Peek strstr(const char *s, const char *t) 198c80476e4SDavid E. O'Brien { 199c80476e4SDavid E. O'Brien do { 20023338178SMark Peek const char *ss = s; 20123338178SMark Peek const char *tt = t; 202c80476e4SDavid E. O'Brien 203c80476e4SDavid E. O'Brien do 204c80476e4SDavid E. O'Brien if (*tt == '\0') 20545e5710bSMark Peek return (s); 206c80476e4SDavid E. O'Brien while (*ss++ == *tt++); 207c80476e4SDavid E. O'Brien } while (*s++ != '\0'); 208c80476e4SDavid E. O'Brien return (NULL); 209c80476e4SDavid E. O'Brien } 21023338178SMark Peek #endif /* !HAVE_STRSTR */ 211c80476e4SDavid E. O'Brien 212c80476e4SDavid E. O'Brien char * 21345e5710bSMark Peek strspl(const char *cp, const char *dp) 214c80476e4SDavid E. O'Brien { 215c80476e4SDavid E. O'Brien char *ep; 21623338178SMark Peek size_t cl, dl; 217c80476e4SDavid E. O'Brien 218c80476e4SDavid E. O'Brien if (!cp) 219c80476e4SDavid E. O'Brien cp = ""; 220c80476e4SDavid E. O'Brien if (!dp) 221c80476e4SDavid E. O'Brien dp = ""; 22223338178SMark Peek cl = strlen(cp); 22323338178SMark Peek dl = strlen(dp); 22445e5710bSMark Peek ep = xmalloc((cl + dl + 1) * sizeof(char)); 22523338178SMark Peek memcpy(ep, cp, cl); 22623338178SMark Peek memcpy(ep + cl, dp, dl + 1); 227c80476e4SDavid E. O'Brien return (ep); 228c80476e4SDavid E. O'Brien } 229c80476e4SDavid E. O'Brien 230c80476e4SDavid E. O'Brien Char ** 23145e5710bSMark Peek blkspl(Char **up, Char **vp) 232c80476e4SDavid E. O'Brien { 23345e5710bSMark Peek Char **wp = xcalloc(blklen(up) + blklen(vp) + 1, sizeof(Char **)); 234c80476e4SDavid E. O'Brien 235c80476e4SDavid E. O'Brien (void) blkcpy(wp, up); 236c80476e4SDavid E. O'Brien return (blkcat(wp, vp)); 237c80476e4SDavid E. O'Brien } 238c80476e4SDavid E. O'Brien 239c80476e4SDavid E. O'Brien Char 24045e5710bSMark Peek lastchr(Char *cp) 241c80476e4SDavid E. O'Brien { 242c80476e4SDavid E. O'Brien 243c80476e4SDavid E. O'Brien if (!cp) 244c80476e4SDavid E. O'Brien return (0); 245c80476e4SDavid E. O'Brien if (!*cp) 246c80476e4SDavid E. O'Brien return (0); 247c80476e4SDavid E. O'Brien while (cp[1]) 248c80476e4SDavid E. O'Brien cp++; 249c80476e4SDavid E. O'Brien return (*cp); 250c80476e4SDavid E. O'Brien } 251c80476e4SDavid E. O'Brien 252c80476e4SDavid E. O'Brien /* 253c80476e4SDavid E. O'Brien * This routine is called after an error to close up 254c80476e4SDavid E. O'Brien * any units which may have been left open accidentally. 255c80476e4SDavid E. O'Brien */ 256c80476e4SDavid E. O'Brien void 25745e5710bSMark Peek closem(void) 258c80476e4SDavid E. O'Brien { 25945e5710bSMark Peek int f, num_files; 260c80476e4SDavid E. O'Brien 261b2d5d167SMark Peek #ifdef NLS_BUGS 262b2d5d167SMark Peek #ifdef NLS_CATALOGS 26323338178SMark Peek nlsclose(); 264b2d5d167SMark Peek #endif /* NLS_CATALOGS */ 265b2d5d167SMark Peek #endif /* NLS_BUGS */ 266c80476e4SDavid E. O'Brien #ifdef YPBUGS 267c80476e4SDavid E. O'Brien /* suggested by Justin Bur; thanks to Karl Kleinpaste */ 268c80476e4SDavid E. O'Brien fix_yp_bugs(); 269c80476e4SDavid E. O'Brien #endif /* YPBUGS */ 27045e5710bSMark Peek num_files = NOFILE; 27145e5710bSMark Peek for (f = 0; f < num_files; f++) 272c80476e4SDavid E. O'Brien if (f != SHIN && f != SHOUT && f != SHDIAG && f != OLDSTD && 273c80476e4SDavid E. O'Brien f != FSHTTY 274c80476e4SDavid E. O'Brien #ifdef MALLOC_TRACE 275c80476e4SDavid E. O'Brien && f != 25 276c80476e4SDavid E. O'Brien #endif /* MALLOC_TRACE */ 277c80476e4SDavid E. O'Brien ) 278c80476e4SDavid E. O'Brien { 27945e5710bSMark Peek xclose(f); 280c80476e4SDavid E. O'Brien #ifdef NISPLUS 281c80476e4SDavid E. O'Brien if(f < 3) 28245e5710bSMark Peek (void) xopen(_PATH_DEVNULL, O_RDONLY|O_LARGEFILE); 283c80476e4SDavid E. O'Brien #endif /* NISPLUS */ 284c80476e4SDavid E. O'Brien } 285b2d5d167SMark Peek #ifdef NLS_BUGS 286b2d5d167SMark Peek #ifdef NLS_CATALOGS 287b2d5d167SMark Peek nlsinit(); 288b2d5d167SMark Peek #endif /* NLS_CATALOGS */ 289b2d5d167SMark Peek #endif /* NLS_BUGS */ 290c80476e4SDavid E. O'Brien } 291c80476e4SDavid E. O'Brien 292c80476e4SDavid E. O'Brien #ifndef CLOSE_ON_EXEC 293c80476e4SDavid E. O'Brien /* 294c80476e4SDavid E. O'Brien * Close files before executing a file. 295c80476e4SDavid E. O'Brien * We could be MUCH more intelligent, since (on a version 7 system) 296c80476e4SDavid E. O'Brien * we need only close files here during a source, the other 297c80476e4SDavid E. O'Brien * shell fd's being in units 16-19 which are closed automatically! 298c80476e4SDavid E. O'Brien */ 299c80476e4SDavid E. O'Brien void 30045e5710bSMark Peek closech(void) 301c80476e4SDavid E. O'Brien { 30245e5710bSMark Peek int f, num_files; 303c80476e4SDavid E. O'Brien 304c80476e4SDavid E. O'Brien if (didcch) 305c80476e4SDavid E. O'Brien return; 306c80476e4SDavid E. O'Brien didcch = 1; 307c80476e4SDavid E. O'Brien SHIN = 0; 308c80476e4SDavid E. O'Brien SHOUT = 1; 309c80476e4SDavid E. O'Brien SHDIAG = 2; 310c80476e4SDavid E. O'Brien OLDSTD = 0; 311c80476e4SDavid E. O'Brien isoutatty = isatty(SHOUT); 312c80476e4SDavid E. O'Brien isdiagatty = isatty(SHDIAG); 31345e5710bSMark Peek num_files = NOFILE; 31445e5710bSMark Peek for (f = 3; f < num_files; f++) 31545e5710bSMark Peek xclose(f); 316c80476e4SDavid E. O'Brien } 317c80476e4SDavid E. O'Brien 318c80476e4SDavid E. O'Brien #endif /* CLOSE_ON_EXEC */ 319c80476e4SDavid E. O'Brien 320c80476e4SDavid E. O'Brien void 32145e5710bSMark Peek donefds(void) 322c80476e4SDavid E. O'Brien { 323c80476e4SDavid E. O'Brien 32445e5710bSMark Peek xclose(0); 32545e5710bSMark Peek xclose(1); 32645e5710bSMark Peek xclose(2); 327c80476e4SDavid E. O'Brien didfds = 0; 328c80476e4SDavid E. O'Brien #ifdef NISPLUS 329c80476e4SDavid E. O'Brien { 33045e5710bSMark Peek int fd = xopen(_PATH_DEVNULL, O_RDONLY|O_LARGEFILE); 33123338178SMark Peek (void)dcopy(fd, 1); 33223338178SMark Peek (void)dcopy(fd, 2); 33323338178SMark Peek (void)dmove(fd, 0); 334c80476e4SDavid E. O'Brien } 335c80476e4SDavid E. O'Brien #endif /*NISPLUS*/ 336c80476e4SDavid E. O'Brien } 337c80476e4SDavid E. O'Brien 338c80476e4SDavid E. O'Brien /* 339c80476e4SDavid E. O'Brien * Move descriptor i to j. 340c80476e4SDavid E. O'Brien * If j is -1 then we just want to get i to a safe place, 34123338178SMark Peek * i.e. to a unit > FSAFE. This also happens in dcopy. 342c80476e4SDavid E. O'Brien */ 343c80476e4SDavid E. O'Brien int 34445e5710bSMark Peek dmove(int i, int j) 345c80476e4SDavid E. O'Brien { 346c80476e4SDavid E. O'Brien 347c80476e4SDavid E. O'Brien if (i == j || i < 0) 348c80476e4SDavid E. O'Brien return (i); 34923338178SMark Peek #ifdef HAVE_DUP2 350c80476e4SDavid E. O'Brien if (j >= 0) { 35145e5710bSMark Peek (void) xdup2(i, j); 352c80476e4SDavid E. O'Brien if (j != i) 35345e5710bSMark Peek xclose(i); 354c80476e4SDavid E. O'Brien return (j); 355c80476e4SDavid E. O'Brien } 356c80476e4SDavid E. O'Brien #endif 357c80476e4SDavid E. O'Brien j = dcopy(i, j); 358c80476e4SDavid E. O'Brien if (j != i) 35945e5710bSMark Peek xclose(i); 360c80476e4SDavid E. O'Brien return (j); 361c80476e4SDavid E. O'Brien } 362c80476e4SDavid E. O'Brien 363c80476e4SDavid E. O'Brien int 36445e5710bSMark Peek dcopy(int i, int j) 365c80476e4SDavid E. O'Brien { 366c80476e4SDavid E. O'Brien 36723338178SMark Peek if (i == j || i < 0 || (j < 0 && i > FSAFE)) 368c80476e4SDavid E. O'Brien return (i); 369c80476e4SDavid E. O'Brien if (j >= 0) { 37023338178SMark Peek #ifdef HAVE_DUP2 37145e5710bSMark Peek (void) xdup2(i, j); 372c80476e4SDavid E. O'Brien return (j); 373c80476e4SDavid E. O'Brien #else 37445e5710bSMark Peek xclose(j); 375c80476e4SDavid E. O'Brien #endif 376c80476e4SDavid E. O'Brien } 377c80476e4SDavid E. O'Brien return (renum(i, j)); 378c80476e4SDavid E. O'Brien } 379c80476e4SDavid E. O'Brien 380c80476e4SDavid E. O'Brien static int 38145e5710bSMark Peek renum(int i, int j) 382c80476e4SDavid E. O'Brien { 38323338178SMark Peek int k = dup(i); 384c80476e4SDavid E. O'Brien 385c80476e4SDavid E. O'Brien if (k < 0) 386c80476e4SDavid E. O'Brien return (-1); 38723338178SMark Peek if (j == -1 && k > FSAFE) 388c80476e4SDavid E. O'Brien return (k); 389c80476e4SDavid E. O'Brien if (k != j) { 390c80476e4SDavid E. O'Brien j = renum(k, j); 39145e5710bSMark Peek xclose(k); 392c80476e4SDavid E. O'Brien return (j); 393c80476e4SDavid E. O'Brien } 394c80476e4SDavid E. O'Brien return (k); 395c80476e4SDavid E. O'Brien } 396c80476e4SDavid E. O'Brien 397c80476e4SDavid E. O'Brien /* 398c80476e4SDavid E. O'Brien * Left shift a command argument list, discarding 399c80476e4SDavid E. O'Brien * the first c arguments. Used in "shift" commands 400c80476e4SDavid E. O'Brien * as well as by commands like "repeat". 401c80476e4SDavid E. O'Brien */ 402c80476e4SDavid E. O'Brien void 40345e5710bSMark Peek lshift(Char **v, int c) 404c80476e4SDavid E. O'Brien { 40523338178SMark Peek Char **u; 406c80476e4SDavid E. O'Brien 407c80476e4SDavid E. O'Brien for (u = v; *u && --c >= 0; u++) 40845e5710bSMark Peek xfree(*u); 409c80476e4SDavid E. O'Brien (void) blkcpy(v, u); 410c80476e4SDavid E. O'Brien } 411c80476e4SDavid E. O'Brien 412c80476e4SDavid E. O'Brien int 41345e5710bSMark Peek number(Char *cp) 414c80476e4SDavid E. O'Brien { 415c80476e4SDavid E. O'Brien if (!cp) 416c80476e4SDavid E. O'Brien return (0); 417c80476e4SDavid E. O'Brien if (*cp == '-') { 418c80476e4SDavid E. O'Brien cp++; 419c80476e4SDavid E. O'Brien if (!Isdigit(*cp)) 420c80476e4SDavid E. O'Brien return (0); 421c80476e4SDavid E. O'Brien cp++; 422c80476e4SDavid E. O'Brien } 423c80476e4SDavid E. O'Brien while (*cp && Isdigit(*cp)) 424c80476e4SDavid E. O'Brien cp++; 425c80476e4SDavid E. O'Brien return (*cp == 0); 426c80476e4SDavid E. O'Brien } 427c80476e4SDavid E. O'Brien 428c80476e4SDavid E. O'Brien Char ** 42945e5710bSMark Peek copyblk(Char **v) 430c80476e4SDavid E. O'Brien { 43145e5710bSMark Peek Char **nv = xcalloc(blklen(v) + 1, sizeof(Char **)); 432c80476e4SDavid E. O'Brien 433c80476e4SDavid E. O'Brien return (blkcpy(nv, v)); 434c80476e4SDavid E. O'Brien } 435c80476e4SDavid E. O'Brien 436c80476e4SDavid E. O'Brien char * 43745e5710bSMark Peek strend(const char *cp) 438c80476e4SDavid E. O'Brien { 439c80476e4SDavid E. O'Brien if (!cp) 44045e5710bSMark Peek return ((char *)(intptr_t)cp); 441c80476e4SDavid E. O'Brien while (*cp) 442c80476e4SDavid E. O'Brien cp++; 44345e5710bSMark Peek return ((char *)(intptr_t)cp); 444c80476e4SDavid E. O'Brien } 445c80476e4SDavid E. O'Brien 446c80476e4SDavid E. O'Brien Char * 44745e5710bSMark Peek strip(Char *cp) 448c80476e4SDavid E. O'Brien { 44923338178SMark Peek Char *dp = cp; 450c80476e4SDavid E. O'Brien 451c80476e4SDavid E. O'Brien if (!cp) 452c80476e4SDavid E. O'Brien return (cp); 453c80476e4SDavid E. O'Brien while ((*dp++ &= TRIM) != '\0') 454c80476e4SDavid E. O'Brien continue; 455c80476e4SDavid E. O'Brien return (cp); 456c80476e4SDavid E. O'Brien } 457c80476e4SDavid E. O'Brien 458c80476e4SDavid E. O'Brien Char * 45945e5710bSMark Peek quote(Char *cp) 460c80476e4SDavid E. O'Brien { 46123338178SMark Peek Char *dp = cp; 462c80476e4SDavid E. O'Brien 463c80476e4SDavid E. O'Brien if (!cp) 464c80476e4SDavid E. O'Brien return (cp); 465c80476e4SDavid E. O'Brien while (*dp != '\0') 466c80476e4SDavid E. O'Brien *dp++ |= QUOTE; 467c80476e4SDavid E. O'Brien return (cp); 468c80476e4SDavid E. O'Brien } 469c80476e4SDavid E. O'Brien 47045e5710bSMark Peek const Char * 47145e5710bSMark Peek quote_meta(struct Strbuf *buf, const Char *s) 472c80476e4SDavid E. O'Brien { 47345e5710bSMark Peek buf->len = 0; 474c80476e4SDavid E. O'Brien while (*s != '\0') { 475c80476e4SDavid E. O'Brien if (cmap(*s, _META | _DOL | _QF | _QB | _ESC | _GLOB)) 47645e5710bSMark Peek Strbuf_append1(buf, '\\'); 47745e5710bSMark Peek Strbuf_append1(buf, *s++); 478c80476e4SDavid E. O'Brien } 47945e5710bSMark Peek Strbuf_terminate(buf); 48045e5710bSMark Peek return buf->s; 481c80476e4SDavid E. O'Brien } 482c80476e4SDavid E. O'Brien 483c80476e4SDavid E. O'Brien void 48445e5710bSMark Peek udvar(Char *name) 485c80476e4SDavid E. O'Brien { 486c80476e4SDavid E. O'Brien setname(short2str(name)); 487c80476e4SDavid E. O'Brien stderror(ERR_NAME | ERR_UNDVAR); 488c80476e4SDavid E. O'Brien } 489c80476e4SDavid E. O'Brien 490c80476e4SDavid E. O'Brien int 49145e5710bSMark Peek prefix(const Char *sub, const Char *str) 492c80476e4SDavid E. O'Brien { 493c80476e4SDavid E. O'Brien 494c80476e4SDavid E. O'Brien for (;;) { 495c80476e4SDavid E. O'Brien if (*sub == 0) 496c80476e4SDavid E. O'Brien return (1); 497c80476e4SDavid E. O'Brien if (*str == 0) 498c80476e4SDavid E. O'Brien return (0); 499c80476e4SDavid E. O'Brien if ((*sub++ & TRIM) != (*str++ & TRIM)) 500c80476e4SDavid E. O'Brien return (0); 501c80476e4SDavid E. O'Brien } 502c80476e4SDavid E. O'Brien } 50345e5710bSMark Peek #ifndef WINNT_NATIVE 50445e5710bSMark Peek char * 50545e5710bSMark Peek areadlink(const char *path) 50645e5710bSMark Peek { 50745e5710bSMark Peek char *buf; 50845e5710bSMark Peek size_t size; 50945e5710bSMark Peek ssize_t res; 51045e5710bSMark Peek 51145e5710bSMark Peek size = MAXPATHLEN + 1; 51245e5710bSMark Peek buf = xmalloc(size); 51345e5710bSMark Peek while ((size_t)(res = readlink(path, buf, size)) == size) { 51445e5710bSMark Peek size *= 2; 51545e5710bSMark Peek buf = xrealloc(buf, size); 51645e5710bSMark Peek } 51745e5710bSMark Peek if (res == -1) { 51845e5710bSMark Peek int err; 51945e5710bSMark Peek 52045e5710bSMark Peek err = errno; 52145e5710bSMark Peek xfree(buf); 52245e5710bSMark Peek errno = err; 52345e5710bSMark Peek return NULL; 52445e5710bSMark Peek } 52545e5710bSMark Peek buf[res] = '\0'; 52645e5710bSMark Peek return xrealloc(buf, res + 1); 52745e5710bSMark Peek } 52845e5710bSMark Peek #endif /*!WINNT_NATIVE*/ 52945e5710bSMark Peek 53045e5710bSMark Peek void 53145e5710bSMark Peek xclose(int fildes) 53245e5710bSMark Peek { 53345e5710bSMark Peek if (fildes < 0) 53445e5710bSMark Peek return; 53545e5710bSMark Peek while (close(fildes) == -1 && errno == EINTR) 53645e5710bSMark Peek handle_pending_signals(); 53745e5710bSMark Peek } 53845e5710bSMark Peek 53945e5710bSMark Peek void 54045e5710bSMark Peek xclosedir(DIR *dirp) 54145e5710bSMark Peek { 54245e5710bSMark Peek while (closedir(dirp) == -1 && errno == EINTR) 54345e5710bSMark Peek handle_pending_signals(); 54445e5710bSMark Peek } 54545e5710bSMark Peek 54645e5710bSMark Peek int 54745e5710bSMark Peek xcreat(const char *path, mode_t mode) 54845e5710bSMark Peek { 54945e5710bSMark Peek int res; 55045e5710bSMark Peek 55145e5710bSMark Peek while ((res = creat(path, mode)) == -1 && errno == EINTR) 55245e5710bSMark Peek handle_pending_signals(); 55345e5710bSMark Peek return res; 55445e5710bSMark Peek } 55545e5710bSMark Peek 55645e5710bSMark Peek #ifdef HAVE_DUP2 55745e5710bSMark Peek static int 55845e5710bSMark Peek xdup2(int fildes, int fildes2) 55945e5710bSMark Peek { 56045e5710bSMark Peek int res; 56145e5710bSMark Peek 56245e5710bSMark Peek while ((res = dup2(fildes, fildes2)) == -1 && errno == EINTR) 56345e5710bSMark Peek handle_pending_signals(); 56445e5710bSMark Peek return res; 56545e5710bSMark Peek } 56645e5710bSMark Peek #endif 56745e5710bSMark Peek 56845e5710bSMark Peek struct group * 56945e5710bSMark Peek xgetgrgid(gid_t xgid) 57045e5710bSMark Peek { 57145e5710bSMark Peek struct group *res; 57245e5710bSMark Peek 57345e5710bSMark Peek errno = 0; 57445e5710bSMark Peek while ((res = getgrgid(xgid)) == NULL && errno == EINTR) { 57545e5710bSMark Peek handle_pending_signals(); 57645e5710bSMark Peek errno = 0; 57745e5710bSMark Peek } 57845e5710bSMark Peek return res; 57945e5710bSMark Peek } 58045e5710bSMark Peek 58145e5710bSMark Peek struct passwd * 58245e5710bSMark Peek xgetpwnam(const char *name) 58345e5710bSMark Peek { 58445e5710bSMark Peek struct passwd *res; 58545e5710bSMark Peek 58645e5710bSMark Peek errno = 0; 58745e5710bSMark Peek while ((res = getpwnam(name)) == NULL && errno == EINTR) { 58845e5710bSMark Peek handle_pending_signals(); 58945e5710bSMark Peek errno = 0; 59045e5710bSMark Peek } 59145e5710bSMark Peek return res; 59245e5710bSMark Peek } 59345e5710bSMark Peek 59445e5710bSMark Peek struct passwd * 59545e5710bSMark Peek xgetpwuid(uid_t xuid) 59645e5710bSMark Peek { 59745e5710bSMark Peek struct passwd *res; 59845e5710bSMark Peek 59945e5710bSMark Peek errno = 0; 60045e5710bSMark Peek while ((res = getpwuid(xuid)) == NULL && errno == EINTR) { 60145e5710bSMark Peek handle_pending_signals(); 60245e5710bSMark Peek errno = 0; 60345e5710bSMark Peek } 60445e5710bSMark Peek return res; 60545e5710bSMark Peek } 60645e5710bSMark Peek 60745e5710bSMark Peek int 60845e5710bSMark Peek xopen(const char *path, int oflag, ...) 60945e5710bSMark Peek { 61045e5710bSMark Peek int res; 61145e5710bSMark Peek 61245e5710bSMark Peek if ((oflag & O_CREAT) == 0) { 61345e5710bSMark Peek while ((res = open(path, oflag)) == -1 && errno == EINTR) 61445e5710bSMark Peek handle_pending_signals(); 61545e5710bSMark Peek } else { 61645e5710bSMark Peek va_list ap; 61745e5710bSMark Peek mode_t mode; 61845e5710bSMark Peek 61945e5710bSMark Peek va_start(ap, oflag); 62045e5710bSMark Peek /* "int" should actually be "mode_t after default argument 62145e5710bSMark Peek promotions". "int" is the best guess we have, "mode_t" used to be 62245e5710bSMark Peek "unsigned short", which we obviously can't use. */ 62345e5710bSMark Peek mode = va_arg(ap, int); 62445e5710bSMark Peek va_end(ap); 62545e5710bSMark Peek while ((res = open(path, oflag, mode)) == -1 && errno == EINTR) 62645e5710bSMark Peek handle_pending_signals(); 62745e5710bSMark Peek } 62845e5710bSMark Peek return res; 62945e5710bSMark Peek } 63045e5710bSMark Peek 63145e5710bSMark Peek ssize_t 63245e5710bSMark Peek xread(int fildes, void *buf, size_t nbyte) 63345e5710bSMark Peek { 63445e5710bSMark Peek ssize_t res; 63545e5710bSMark Peek 63645e5710bSMark Peek /* This is where we will be blocked most of the time, so handle signals 63745e5710bSMark Peek that didn't interrupt any system call. */ 63845e5710bSMark Peek do 63945e5710bSMark Peek handle_pending_signals(); 64045e5710bSMark Peek while ((res = read(fildes, buf, nbyte)) == -1 && errno == EINTR); 64145e5710bSMark Peek return res; 64245e5710bSMark Peek } 64345e5710bSMark Peek 64445e5710bSMark Peek #ifdef POSIX 64545e5710bSMark Peek int 64645e5710bSMark Peek xtcsetattr(int fildes, int optional_actions, const struct termios *termios_p) 64745e5710bSMark Peek { 64845e5710bSMark Peek int res; 64945e5710bSMark Peek 65045e5710bSMark Peek while ((res = tcsetattr(fildes, optional_actions, termios_p)) == -1 && 65145e5710bSMark Peek errno == EINTR) 65245e5710bSMark Peek handle_pending_signals(); 65345e5710bSMark Peek return res; 65445e5710bSMark Peek } 65545e5710bSMark Peek #endif 65645e5710bSMark Peek 65745e5710bSMark Peek ssize_t 65845e5710bSMark Peek xwrite(int fildes, const void *buf, size_t nbyte) 65945e5710bSMark Peek { 66045e5710bSMark Peek ssize_t res; 66145e5710bSMark Peek 66245e5710bSMark Peek /* This is where we will be blocked most of the time, so handle signals 66345e5710bSMark Peek that didn't interrupt any system call. */ 66445e5710bSMark Peek do 66545e5710bSMark Peek handle_pending_signals(); 66645e5710bSMark Peek while ((res = write(fildes, buf, nbyte)) == -1 && errno == EINTR); 66745e5710bSMark Peek return res; 66845e5710bSMark Peek } 669