sh.misc.c revision 256281
167754Smsmith/* $Header: /p/tcsh/cvsroot/tcsh/sh.misc.c,v 3.46 2010/05/08 00:41:58 christos Exp $ */ 267754Smsmith/* 367754Smsmith * sh.misc.c: Miscelaneous functions 467754Smsmith */ 567754Smsmith/*- 667754Smsmith * Copyright (c) 1980, 1991 The Regents of the University of California. 767754Smsmith * All rights reserved. 867754Smsmith * 967754Smsmith * Redistribution and use in source and binary forms, with or without 1067754Smsmith * modification, are permitted provided that the following conditions 1167754Smsmith * are met: 12193267Sjkim * 1. Redistributions of source code must retain the above copyright 1370243Smsmith * notice, this list of conditions and the following disclaimer. 1467754Smsmith * 2. Redistributions in binary form must reproduce the above copyright 1567754Smsmith * notice, this list of conditions and the following disclaimer in the 1667754Smsmith * documentation and/or other materials provided with the distribution. 1767754Smsmith * 3. Neither the name of the University nor the names of its contributors 1867754Smsmith * may be used to endorse or promote products derived from this software 1967754Smsmith * without specific prior written permission. 2067754Smsmith * 2167754Smsmith * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2267754Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2367754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2467754Smsmith * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2567754Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2667754Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2767754Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2867754Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2967754Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3067754Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3167754Smsmith * SUCH DAMAGE. 3267754Smsmith */ 3367754Smsmith#include "sh.h" 3467754Smsmith 3567754SmsmithRCSID("$tcsh: sh.misc.c,v 3.46 2010/05/08 00:41:58 christos Exp $") 3667754Smsmith 3767754Smsmithstatic int renum (int, int); 3867754Smsmithstatic Char **blkend (Char **); 3967754Smsmithstatic Char **blkcat (Char **, Char **); 4067754Smsmithstatic int xdup2 (int, int); 4167754Smsmith 4267754Smsmith/* 4367754Smsmith * C Shell 4467754Smsmith */ 4567754Smsmith 4667754Smsmithint 4767754Smsmithany(const char *s, Char c) 4867754Smsmith{ 4967754Smsmith if (!s) 5067754Smsmith return (0); /* Check for nil pointer */ 5167754Smsmith while (*s) 5267754Smsmith if ((Char)*s++ == c) 5367754Smsmith return (1); 5467754Smsmith return (0); 5567754Smsmith} 5667754Smsmith 5767754Smsmithvoid 5867754Smsmithsetzero(void *p, size_t size) 5967754Smsmith{ 6067754Smsmith memset(p, 0, size); 6167754Smsmith} 6267754Smsmith 6367754Smsmith#ifndef SHORT_STRINGS 6467754Smsmithchar * 6567754Smsmithstrnsave(const char *s, size_t len) 6667754Smsmith{ 6767754Smsmith char *r; 6867754Smsmith 6967754Smsmith r = xmalloc(len + 1); 7067754Smsmith memcpy(r, s, len); 7167754Smsmith r[len] = '\0'; 7267754Smsmith return r; 7367754Smsmith} 7467754Smsmith#endif 7567754Smsmith 7667754Smsmithchar * 7767754Smsmithstrsave(const char *s) 7867754Smsmith{ 7967754Smsmith char *r; 8067754Smsmith size_t size; 8167754Smsmith 8267754Smsmith if (s == NULL) 8367754Smsmith s = ""; 8467754Smsmith size = strlen(s) + 1; 8567754Smsmith r = xmalloc(size); 8667754Smsmith memcpy(r, s, size); 8767754Smsmith return (r); 8867754Smsmith} 8967754Smsmith 9067754Smsmithstatic Char ** 9167754Smsmithblkend(Char **up) 9267754Smsmith{ 9367754Smsmith 9467754Smsmith while (*up) 9567754Smsmith up++; 9667754Smsmith return (up); 9767754Smsmith} 9867754Smsmith 9967754Smsmith 10067754Smsmithvoid 10167754Smsmithblkpr(Char *const *av) 10267754Smsmith{ 10367754Smsmith 10467754Smsmith for (; *av; av++) { 10567754Smsmith xprintf("%S", *av); 10667754Smsmith if (av[1]) 10767754Smsmith xprintf(" "); 10867754Smsmith } 10967754Smsmith} 11067754Smsmith 11167754SmsmithChar * 11267754Smsmithblkexpand(Char *const *av) 11367754Smsmith{ 11467754Smsmith struct Strbuf buf = Strbuf_INIT; 11567754Smsmith 11667754Smsmith for (; *av; av++) { 11767754Smsmith Strbuf_append(&buf, *av); 11867754Smsmith if (av[1]) 119193251Sjkim Strbuf_append1(&buf, ' '); 120193267Sjkim } 121193251Sjkim return Strbuf_finish(&buf); 122193267Sjkim} 123193267Sjkim 12467754Smsmithint 12567754Smsmithblklen(Char **av) 12677424Smsmith{ 12791116Smsmith int i = 0; 12867754Smsmith 12967754Smsmith while (*av++) 130117521Snjl i++; 13167754Smsmith return (i); 13267754Smsmith} 13367754Smsmith 13467754SmsmithChar ** 135151937Sjkimblkcpy(Char **oav, Char **bv) 136151937Sjkim{ 137151937Sjkim Char **av = oav; 13867754Smsmith 13967754Smsmith while ((*av++ = *bv++) != NULL) 14067754Smsmith continue; 14167754Smsmith return (oav); 14267754Smsmith} 14367754Smsmith 14467754Smsmithstatic Char ** 14567754Smsmithblkcat(Char **up, Char **vp) 14667754Smsmith{ 14767754Smsmith 14867754Smsmith (void) blkcpy(blkend(up), vp); 14967754Smsmith return (up); 15067754Smsmith} 15167754Smsmith 15267754Smsmithvoid 15367754Smsmithblkfree(Char **av0) 15467754Smsmith{ 15569450Smsmith Char **av = av0; 15667754Smsmith 15767754Smsmith if (!av0) 15867754Smsmith return; 15991116Smsmith for (; *av; av++) 16083174Smsmith xfree(*av); 16183174Smsmith xfree(av0); 16277424Smsmith} 16377424Smsmith 16467754Smsmithvoid 16567754Smsmithblk_cleanup(void *ptr) 16667754Smsmith{ 16767754Smsmith blkfree(ptr); 16867754Smsmith} 16969746Smsmith 17069746Smsmithvoid 17167754Smsmithblk_indirect_cleanup(void *xptr) 17267754Smsmith{ 17385756Smsmith Char ***ptr; 17469450Smsmith 17567754Smsmith ptr = xptr; 17667754Smsmith blkfree(*ptr); 17767754Smsmith xfree(ptr); 178167802Sjkim} 17967754Smsmith 180167802SjkimChar ** 181167802Sjkimsaveblk(Char **v) 182167802Sjkim{ 183167802Sjkim Char **newv, **onewv; 184167802Sjkim 185167802Sjkim if (v == NULL) 186167802Sjkim return NULL; 187167802Sjkim 188167802Sjkim onewv = newv = xcalloc(blklen(v) + 1, sizeof(Char **)); 189167802Sjkim 190167802Sjkim while (*v) 191167802Sjkim *newv++ = Strsave(*v++); 192167802Sjkim return (onewv); 193167802Sjkim} 19491116Smsmith 195167802Sjkim#ifndef HAVE_STRSTR 196167802Sjkimchar * 19791116Smsmithstrstr(const char *s, const char *t) 19867754Smsmith{ 199167802Sjkim do { 200167802Sjkim const char *ss = s; 201167802Sjkim const char *tt = t; 20267754Smsmith 203167802Sjkim do 20467754Smsmith if (*tt == '\0') 20567754Smsmith return (s); 206167802Sjkim while (*ss++ == *tt++); 20767754Smsmith } while (*s++ != '\0'); 208167802Sjkim return (NULL); 20969746Smsmith} 21067754Smsmith#endif /* !HAVE_STRSTR */ 21167754Smsmith 21267754Smsmithchar * 21367754Smsmithstrspl(const char *cp, const char *dp) 21467754Smsmith{ 21567754Smsmith char *ep; 21667754Smsmith size_t cl, dl; 217167802Sjkim 21867754Smsmith if (!cp) 219167802Sjkim cp = ""; 220117521Snjl if (!dp) 22167754Smsmith dp = ""; 22283174Smsmith cl = strlen(cp); 22367754Smsmith dl = strlen(dp); 22467754Smsmith ep = xmalloc((cl + dl + 1) * sizeof(char)); 22567754Smsmith memcpy(ep, cp, cl); 22691116Smsmith memcpy(ep + cl, dp, dl + 1); 22767754Smsmith return (ep); 22867754Smsmith} 22967754Smsmith 23067754SmsmithChar ** 23167754Smsmithblkspl(Char **up, Char **vp) 23267754Smsmith{ 23367754Smsmith Char **wp = xcalloc(blklen(up) + blklen(vp) + 1, sizeof(Char **)); 23467754Smsmith 23567754Smsmith (void) blkcpy(wp, up); 23667754Smsmith return (blkcat(wp, vp)); 23767754Smsmith} 23867754Smsmith 23967754SmsmithChar 24091116Smsmithlastchr(Char *cp) 24167754Smsmith{ 24267754Smsmith 24367754Smsmith if (!cp) 24467754Smsmith return (0); 24567754Smsmith if (!*cp) 24691116Smsmith return (0); 24767754Smsmith while (cp[1]) 24891116Smsmith cp++; 24967754Smsmith return (*cp); 25067754Smsmith} 25167754Smsmith 25267754Smsmith/* 25391116Smsmith * This routine is called after an error to close up 25491116Smsmith * any units which may have been left open accidentally. 25567754Smsmith */ 25691116Smsmithvoid 25767754Smsmithclosem(void) 25867754Smsmith{ 25967754Smsmith int f, num_files; 26067754Smsmith 26167754Smsmith#ifdef NLS_BUGS 26267754Smsmith#ifdef NLS_CATALOGS 26391116Smsmith nlsclose(); 26467754Smsmith#endif /* NLS_CATALOGS */ 26567754Smsmith#endif /* NLS_BUGS */ 26667754Smsmith#ifdef YPBUGS 26767754Smsmith /* suggested by Justin Bur; thanks to Karl Kleinpaste */ 26867754Smsmith fix_yp_bugs(); 26991116Smsmith#endif /* YPBUGS */ 27067754Smsmith num_files = NOFILE; 27191116Smsmith for (f = 0; f < num_files; f++) 27291116Smsmith if (f != SHIN && f != SHOUT && f != SHDIAG && f != OLDSTD && 27391116Smsmith f != FSHTTY 27491116Smsmith#ifdef MALLOC_TRACE 27591116Smsmith && f != 25 27691116Smsmith#endif /* MALLOC_TRACE */ 27785756Smsmith ) 27867754Smsmith { 27967754Smsmith xclose(f); 28067754Smsmith#ifdef NISPLUS 28167754Smsmith if(f < 3) 28267754Smsmith (void) xopen(_PATH_DEVNULL, O_RDONLY|O_LARGEFILE); 28367754Smsmith#endif /* NISPLUS */ 28491116Smsmith } 28567754Smsmith#ifdef NLS_BUGS 286114237Snjl#ifdef NLS_CATALOGS 28791116Smsmith nlsinit(); 28867754Smsmith#endif /* NLS_CATALOGS */ 28967754Smsmith#endif /* NLS_BUGS */ 29067754Smsmith} 29167754Smsmith 29267754Smsmith#ifndef CLOSE_ON_EXEC 29367754Smsmith/* 294123315Snjl * Close files before executing a file. 29567754Smsmith * We could be MUCH more intelligent, since (on a version 7 system) 296114237Snjl * we need only close files here during a source, the other 29767754Smsmith * shell fd's being in units 16-19 which are closed automatically! 29867754Smsmith */ 29967754Smsmithvoid 30067754Smsmithclosech(void) 30167754Smsmith{ 30291116Smsmith int f, num_files; 30367754Smsmith 30467754Smsmith if (didcch) 30567754Smsmith return; 306167802Sjkim didcch = 1; 30767754Smsmith SHIN = 0; 308167802Sjkim SHOUT = 1; 309117521Snjl SHDIAG = 2; 31067754Smsmith OLDSTD = 0; 31167754Smsmith isoutatty = isatty(SHOUT); 31267754Smsmith isdiagatty = isatty(SHDIAG); 31367754Smsmith num_files = NOFILE; 314151937Sjkim for (f = 3; f < num_files; f++) 31567754Smsmith xclose(f); 31667754Smsmith} 31767754Smsmith 31867754Smsmith#endif /* CLOSE_ON_EXEC */ 31967754Smsmith 32067754Smsmithvoid 32167754Smsmithdonefds(void) 32267754Smsmith{ 32367754Smsmith 32467754Smsmith xclose(0); 32567754Smsmith xclose(1); 32667754Smsmith xclose(2); 327117521Snjl didfds = 0; 32867754Smsmith#ifdef NISPLUS 32967754Smsmith { 33067754Smsmith int fd = xopen(_PATH_DEVNULL, O_RDONLY|O_LARGEFILE); 331151937Sjkim (void)dcopy(fd, 1); 332117521Snjl (void)dcopy(fd, 2); 333117521Snjl (void)dmove(fd, 0); 334117521Snjl } 33567754Smsmith#endif /*NISPLUS*/ 33667754Smsmith} 33767754Smsmith 33867754Smsmith/* 339117521Snjl * Move descriptor i to j. 34067754Smsmith * If j is -1 then we just want to get i to a safe place, 34167754Smsmith * i.e. to a unit > FSAFE. This also happens in dcopy. 34267754Smsmith */ 34367754Smsmithint 344117521Snjldmove(int i, int j) 345117521Snjl{ 346117521Snjl 347117521Snjl if (i == j || i < 0) 348117521Snjl return (i); 349117521Snjl#ifdef HAVE_DUP2 350167802Sjkim if (j >= 0) { 351151937Sjkim (void) xdup2(i, j); 352151937Sjkim if (j != i) 353151937Sjkim xclose(i); 354151937Sjkim return (j); 355151937Sjkim } 35691116Smsmith#endif 35791116Smsmith j = dcopy(i, j); 35891116Smsmith if (j != i) 359151937Sjkim xclose(i); 36091116Smsmith return (j); 36167754Smsmith} 36285756Smsmith 36367754Smsmithint 36467754Smsmithdcopy(int i, int j) 36591116Smsmith{ 366193267Sjkim 367151937Sjkim if (i == j || i < 0 || (j < 0 && i > FSAFE)) 36867754Smsmith return (i); 36967754Smsmith if (j >= 0) { 370117521Snjl#ifdef HAVE_DUP2 37167754Smsmith (void) xdup2(i, j); 372117521Snjl return (j); 373117521Snjl#else 374151937Sjkim xclose(j); 375151937Sjkim#endif 376151937Sjkim } 377117521Snjl return (renum(i, j)); 378193267Sjkim} 379193267Sjkim 380193267Sjkimstatic int 381193267Sjkimrenum(int i, int j) 382193267Sjkim{ 38391116Smsmith int k = dup(i); 38491116Smsmith 38591116Smsmith if (k < 0) 386151937Sjkim return (-1); 38791116Smsmith if (j == -1 && k > FSAFE) 38867754Smsmith return (k); 389117521Snjl if (k != j) { 390117521Snjl j = renum(k, j); 391151937Sjkim xclose(k); 39267754Smsmith return (j); 393117521Snjl } 394117521Snjl return (k); 395129684Snjl} 396123315Snjl 397117521Snjl/* 398151937Sjkim * Left shift a command argument list, discarding 399117521Snjl * the first c arguments. Used in "shift" commands 400117521Snjl * as well as by commands like "repeat". 40167754Smsmith */ 402117521Snjlvoid 40367754Smsmithlshift(Char **v, int c) 404151937Sjkim{ 405117521Snjl Char **u; 406117521Snjl 407151937Sjkim for (u = v; *u && --c >= 0; u++) 408117521Snjl xfree(*u); 40967754Smsmith (void) blkcpy(v, u); 410117521Snjl} 41167754Smsmith 412151937Sjkimint 413117521Snjlnumber(Char *cp) 414117521Snjl{ 415151937Sjkim if (!cp) 416117521Snjl return (0); 417117521Snjl if (*cp == '-') { 418117521Snjl cp++; 419117521Snjl if (!Isdigit(*cp)) 420117521Snjl return (0); 421117521Snjl cp++; 422117521Snjl } 423167802Sjkim while (*cp && Isdigit(*cp)) 424151937Sjkim cp++; 425117521Snjl return (*cp == 0); 426117521Snjl} 427117521Snjl 428117521SnjlChar ** 429151937Sjkimcopyblk(Char **v) 430117521Snjl{ 431117521Snjl Char **nv = xcalloc(blklen(v) + 1, sizeof(Char **)); 432151937Sjkim 433117521Snjl return (blkcpy(nv, v)); 434117521Snjl} 435117521Snjl 436117521Snjlchar * 437123315Snjlstrend(const char *cp) 438151937Sjkim{ 439117521Snjl if (!cp) 440117521Snjl return ((char *)(intptr_t)cp); 441151937Sjkim while (*cp) 442117521Snjl cp++; 443117521Snjl return ((char *)(intptr_t)cp); 444126372Snjl} 445126372Snjl 446151937SjkimChar * 447126372Snjlstrip(Char *cp) 448126372Snjl{ 449151937Sjkim Char *dp = cp; 450126372Snjl 45167754Smsmith if (!cp) 45267754Smsmith return (cp); 453117521Snjl while ((*dp++ &= TRIM) != '\0') 45467754Smsmith continue; 455117521Snjl return (cp); 456117521Snjl} 45767754Smsmith 458117521SnjlChar * 45967754Smsmithquote(Char *cp) 46067754Smsmith{ 461117521Snjl Char *dp = cp; 462117521Snjl 463117521Snjl if (!cp) 464151937Sjkim return (cp); 465117521Snjl while (*dp != '\0') 466117521Snjl *dp++ |= QUOTE; 46767754Smsmith return (cp); 468117521Snjl} 46967754Smsmith 47067754Smsmithconst Char * 47167754Smsmithquote_meta(struct Strbuf *buf, const Char *s) 472117521Snjl{ 473167802Sjkim buf->len = 0; 474117521Snjl while (*s != '\0') { 47567754Smsmith if (cmap(*s, _META | _DOL | _QF | _QB | _ESC | _GLOB)) 476167802Sjkim Strbuf_append1(buf, '\\'); 47767754Smsmith Strbuf_append1(buf, *s++); 478117521Snjl } 47967754Smsmith Strbuf_terminate(buf); 48067754Smsmith return buf->s; 481167802Sjkim} 482167802Sjkim 483193267Sjkimvoid 484193267Sjkimudvar(Char *name) 485193267Sjkim{ 486193267Sjkim setname(short2str(name)); 487193267Sjkim stderror(ERR_NAME | ERR_UNDVAR); 488193267Sjkim} 489193267Sjkim 490193267Sjkimint 491193267Sjkimprefix(const Char *sub, const Char *str) 492193267Sjkim{ 493193267Sjkim 494193267Sjkim for (;;) { 495193267Sjkim if (*sub == 0) 496193267Sjkim return (1); 497193267Sjkim if (*str == 0) 498193267Sjkim return (0); 499193267Sjkim if ((*sub++ & TRIM) != (*str++ & TRIM)) 500193267Sjkim return (0); 501193267Sjkim } 502193267Sjkim} 503193267Sjkim#ifndef WINNT_NATIVE 504193267Sjkimchar * 505193267Sjkimareadlink(const char *path) 506193267Sjkim{ 507193267Sjkim char *buf; 508193267Sjkim size_t size; 509193267Sjkim ssize_t res; 510193267Sjkim 511193267Sjkim size = MAXPATHLEN + 1; 512193267Sjkim buf = xmalloc(size); 513193267Sjkim while ((size_t)(res = readlink(path, buf, size)) == size) { 514193267Sjkim size *= 2; 515193267Sjkim buf = xrealloc(buf, size); 516193267Sjkim } 517193267Sjkim if (res == -1) { 518193267Sjkim int err; 519193267Sjkim 520193267Sjkim err = errno; 521193267Sjkim xfree(buf); 522193267Sjkim errno = err; 523193267Sjkim return NULL; 524193267Sjkim } 525193267Sjkim buf[res] = '\0'; 526193267Sjkim return xrealloc(buf, res + 1); 527193267Sjkim} 528193267Sjkim#endif /*!WINNT_NATIVE*/ 529193267Sjkim 530193267Sjkimvoid 531193267Sjkimxclose(int fildes) 532193267Sjkim{ 533193267Sjkim if (fildes < 0) 534193267Sjkim return; 535193267Sjkim while (close(fildes) == -1 && errno == EINTR) 536193267Sjkim handle_pending_signals(); 537193267Sjkim} 538193267Sjkim 539193267Sjkimvoid 540193267Sjkimxclosedir(DIR *dirp) 541193267Sjkim{ 542193267Sjkim while (closedir(dirp) == -1 && errno == EINTR) 543193267Sjkim handle_pending_signals(); 544193267Sjkim} 545193267Sjkim 546193267Sjkimint 547193267Sjkimxcreat(const char *path, mode_t mode) 548193267Sjkim{ 549193267Sjkim int res; 550193267Sjkim 551193267Sjkim while ((res = creat(path, mode)) == -1 && errno == EINTR) 552193267Sjkim handle_pending_signals(); 553193267Sjkim return res; 554193267Sjkim} 555193267Sjkim 556193267Sjkim#ifdef HAVE_DUP2 557193267Sjkimstatic int 558193267Sjkimxdup2(int fildes, int fildes2) 559193267Sjkim{ 560193267Sjkim int res; 561193267Sjkim 562193267Sjkim while ((res = dup2(fildes, fildes2)) == -1 && errno == EINTR) 563193267Sjkim handle_pending_signals(); 564193267Sjkim return res; 565193267Sjkim} 566193267Sjkim#endif 567193267Sjkim 568193267Sjkimstruct group * 569193267Sjkimxgetgrgid(gid_t xgid) 570193267Sjkim{ 571193267Sjkim struct group *res; 572193267Sjkim 573193267Sjkim errno = 0; 574193267Sjkim while ((res = getgrgid(xgid)) == NULL && errno == EINTR) { 575193267Sjkim handle_pending_signals(); 576193267Sjkim errno = 0; 577193267Sjkim } 578193267Sjkim return res; 579193267Sjkim} 580193267Sjkim 581193267Sjkimstruct passwd * 582193267Sjkimxgetpwnam(const char *name) 583193267Sjkim{ 584193267Sjkim struct passwd *res; 585193267Sjkim 586193267Sjkim errno = 0; 587193267Sjkim while ((res = getpwnam(name)) == NULL && errno == EINTR) { 588193267Sjkim handle_pending_signals(); 589193267Sjkim errno = 0; 590193267Sjkim } 591193267Sjkim return res; 592193267Sjkim} 593193267Sjkim 594193267Sjkimstruct passwd * 595193267Sjkimxgetpwuid(uid_t xuid) 596193267Sjkim{ 597193267Sjkim struct passwd *res; 598193267Sjkim 599193267Sjkim errno = 0; 600193267Sjkim while ((res = getpwuid(xuid)) == NULL && errno == EINTR) { 601193267Sjkim handle_pending_signals(); 602193267Sjkim errno = 0; 603193267Sjkim } 604193267Sjkim return res; 605193267Sjkim} 606193267Sjkim 607193267Sjkimint 608193267Sjkimxopen(const char *path, int oflag, ...) 609193267Sjkim{ 610193267Sjkim int res; 611193267Sjkim 612193267Sjkim if ((oflag & O_CREAT) == 0) { 613193267Sjkim while ((res = open(path, oflag)) == -1 && errno == EINTR) 614193267Sjkim handle_pending_signals(); 615193267Sjkim } else { 616193267Sjkim va_list ap; 617193267Sjkim mode_t mode; 618193267Sjkim 619193267Sjkim va_start(ap, oflag); 620193267Sjkim /* "int" should actually be "mode_t after default argument 621193267Sjkim promotions". "int" is the best guess we have, "mode_t" used to be 622193267Sjkim "unsigned short", which we obviously can't use. */ 623193267Sjkim mode = va_arg(ap, int); 624193267Sjkim va_end(ap); 625193267Sjkim while ((res = open(path, oflag, mode)) == -1 && errno == EINTR) 626193267Sjkim handle_pending_signals(); 627193267Sjkim } 628193267Sjkim return res; 629193267Sjkim} 630193267Sjkim 631193267Sjkimssize_t 632193267Sjkimxread(int fildes, void *buf, size_t nbyte) 633193267Sjkim{ 634193267Sjkim ssize_t res; 635193267Sjkim 636193267Sjkim /* This is where we will be blocked most of the time, so handle signals 637193267Sjkim that didn't interrupt any system call. */ 638193267Sjkim do 639193267Sjkim handle_pending_signals(); 640193267Sjkim while ((res = read(fildes, buf, nbyte)) == -1 && errno == EINTR); 641193267Sjkim return res; 642193267Sjkim} 643193267Sjkim 644193267Sjkim#ifdef POSIX 645int 646xtcsetattr(int fildes, int optional_actions, const struct termios *termios_p) 647{ 648 int res; 649 650 while ((res = tcsetattr(fildes, optional_actions, termios_p)) == -1 && 651 errno == EINTR) 652 handle_pending_signals(); 653 return res; 654} 655#endif 656 657ssize_t 658xwrite(int fildes, const void *buf, size_t nbyte) 659{ 660 ssize_t res; 661 662 /* This is where we will be blocked most of the time, so handle signals 663 that didn't interrupt any system call. */ 664 do 665 handle_pending_signals(); 666 while ((res = write(fildes, buf, nbyte)) == -1 && errno == EINTR); 667 return res; 668} 669