diff options
author | raf <none@none> | 2008-01-23 12:00:31 -0800 |
---|---|---|
committer | raf <none@none> | 2008-01-23 12:00:31 -0800 |
commit | a574db851cdc636fc3939b68e80d79fe7fbd57f2 (patch) | |
tree | 7a28122042d1d24d9c4df92ba257e2d34d111e2e /usr/src/lib/libc/port/stdio | |
parent | 4a7ceb24cfcc0a97f96d86cfe5852ae445b50e57 (diff) | |
download | illumos-gate-a574db851cdc636fc3939b68e80d79fe7fbd57f2.tar.gz |
6598890 cancellation code abuses synonyms
--HG--
rename : usr/src/lib/libc/amd64/crt/cerror64.s => deleted_files/usr/src/lib/libc/amd64/crt/cerror64.s
rename : usr/src/lib/libc/port/gen/wait3.c => deleted_files/usr/src/lib/libc/port/gen/wait3.c
rename : usr/src/lib/libc/port/gen/wait4.c => deleted_files/usr/src/lib/libc/port/gen/wait4.c
rename : usr/src/lib/libc/port/sys/fsync.c => deleted_files/usr/src/lib/libc/port/sys/fsync.c
rename : usr/src/lib/libc/sparc/sys/syssun.s => deleted_files/usr/src/lib/libc/sparc/sys/syssun.s
rename : usr/src/lib/libc/common/sys/__fcntl.s => usr/src/lib/libc/common/sys/fcntl.s
rename : usr/src/lib/libc/common/sys/_rename.s => usr/src/lib/libc/common/sys/rename.s
rename : usr/src/lib/libc/port/gen/rename.c => usr/src/lib/libc/port/gen/remove.c
rename : usr/src/lib/libc/port/sys/fcntl.c => usr/src/lib/libc/port/sys/libc_fcntl.c
Diffstat (limited to 'usr/src/lib/libc/port/stdio')
-rw-r--r-- | usr/src/lib/libc/port/stdio/_filbuf.c | 18 | ||||
-rw-r--r-- | usr/src/lib/libc/port/stdio/_flsbuf.c | 16 | ||||
-rw-r--r-- | usr/src/lib/libc/port/stdio/flockf.c | 23 | ||||
-rw-r--r-- | usr/src/lib/libc/port/stdio/flush.c | 46 | ||||
-rw-r--r-- | usr/src/lib/libc/port/stdio/fputs.c | 15 | ||||
-rw-r--r-- | usr/src/lib/libc/port/stdio/fwrite.c | 14 | ||||
-rw-r--r-- | usr/src/lib/libc/port/stdio/popen.c | 33 | ||||
-rw-r--r-- | usr/src/lib/libc/port/stdio/system.c | 13 |
8 files changed, 94 insertions, 84 deletions
diff --git a/usr/src/lib/libc/port/stdio/_filbuf.c b/usr/src/lib/libc/port/stdio/_filbuf.c index a1c4591e46..4b271cef2d 100644 --- a/usr/src/lib/libc/port/stdio/_filbuf.c +++ b/usr/src/lib/libc/port/stdio/_filbuf.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -121,13 +121,11 @@ _filbuf(FILE *iop) iop->_cnt = res - 1; return (*iop->_ptr++); } - else - { - iop->_cnt = 0; - if (res == 0) - iop->_flag |= _IOEOF; - else - iop->_flag |= _IOERR; - return (EOF); - } + + iop->_cnt = 0; + if (res == 0) + iop->_flag |= _IOEOF; + else if (!cancel_active()) + iop->_flag |= _IOERR; + return (EOF); } diff --git a/usr/src/lib/libc/port/stdio/_flsbuf.c b/usr/src/lib/libc/port/stdio/_flsbuf.c index a3f6e9cf68..bcbc7f1a5a 100644 --- a/usr/src/lib/libc/port/stdio/_flsbuf.c +++ b/usr/src/lib/libc/port/stdio/_flsbuf.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -29,7 +29,6 @@ #pragma ident "%Z%%M% %I% %E% SMI" - #pragma weak _flsbuf = __flsbuf #include "synonyms.h" #include "file64.h" @@ -71,17 +70,20 @@ _flsbuf(int ch, FILE *iop) /* flush (write) buffer, save ch, */ case _IONBF | _IOWRT: /* okay to do no-buffered case */ iop->_cnt = 0; uch = (unsigned char)ch; - if (write(GET_FD(iop), (char *)&uch, 1) != 1) - iop->_flag |= _IOERR; + if (write(GET_FD(iop), (char *)&uch, 1) != 1) { + if (!cancel_active()) + iop->_flag |= _IOERR; + return (EOF); + } goto out; } if (_wrtchk(iop) != 0) /* check, correct permissions */ return (EOF); } while (iop->_flag & (_IOLBF | _IONBF)); -flush_putc:; +flush_putc: (void) _xflsbuf(iop); (void) PUTC(ch, iop); /* recursive call */ -out:; - /* necessary for putc() */ +out: + /* necessary for putc() */ return ((iop->_flag & _IOERR) ? EOF : (unsigned char)ch); } diff --git a/usr/src/lib/libc/port/stdio/flockf.c b/usr/src/lib/libc/port/stdio/flockf.c index 57ff8bf9b8..ce5ee78a5d 100644 --- a/usr/src/lib/libc/port/stdio/flockf.c +++ b/usr/src/lib/libc/port/stdio/flockf.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,8 +18,9 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -48,11 +48,8 @@ #include "stdiom.h" /* - * The rmutex_lock/unlock routines are only called (for stdio FILE - * locking in libc) by _flockget, _flockrel, flockfile, ftrylockfile, - * and funlockfile. _flockget and _flockrel are only called by the - * FLOCKFILE/FUNLOCKFILE macros in mtlib.h. rmutex_trylock(), as a - * special case, is called from GETIOP()/getiop() in _findiop(). + * _flockget and _flockrel are only called by the + * FLOCKFILE/FUNLOCKFILE macros in mtlib.h. */ /* @@ -65,7 +62,7 @@ _flockget(FILE *iop) rmutex_t *rl = IOB_LCK(iop); if (rl != NULL) - rmutex_lock(rl); + cancel_safe_mutex_lock(rl); return (rl); } @@ -75,7 +72,7 @@ ftrylockfile(FILE *iop) rmutex_t *rl = IOB_LCK(iop); if (rl != NULL) - return (rmutex_trylock(rl)); + return (_private_mutex_trylock(rl)); return (0); /* can't happen? */ } @@ -85,7 +82,7 @@ flockfile(FILE *iop) rmutex_t *rl = IOB_LCK(iop); if (rl != NULL) - rmutex_lock(rl); + _private_mutex_lock(rl); } void @@ -94,7 +91,7 @@ funlockfile(FILE *iop) rmutex_t *rl = IOB_LCK(iop); if (rl != NULL) - rmutex_unlock(rl); + _private_mutex_unlock(rl); } int diff --git a/usr/src/lib/libc/port/stdio/flush.c b/usr/src/lib/libc/port/stdio/flush.c index bd8328267c..a7d9fabdbb 100644 --- a/usr/src/lib/libc/port/stdio/flush.c +++ b/usr/src/lib/libc/port/stdio/flush.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -188,7 +188,7 @@ _flushlbf(void) /* fflush() all line-buffered streams */ int threaded = __libc_threaded; if (threaded) - (void) _private_mutex_lock(&_first_link_lock); + cancel_safe_mutex_lock(&_first_link_lock); lp = &__first_link; do { @@ -204,14 +204,14 @@ _flushlbf(void) /* fflush() all line-buffered streams */ (_IOLBF | _IOWRT)) { if (threaded) { rmutex_t *lk = FPLOCK(fp); - if (rmutex_trylock(lk) != 0) + if (cancel_safe_mutex_trylock(lk) != 0) continue; /* Recheck after locking */ if ((fp->_flag & (_IOLBF | _IOWRT)) == (_IOLBF | _IOWRT)) { (void) _fflush_u(fp); } - (void) rmutex_unlock(lk); + cancel_safe_mutex_unlock(lk); } else { (void) _fflush_u(fp); } @@ -220,7 +220,7 @@ _flushlbf(void) /* fflush() all line-buffered streams */ } while ((lp = lp->next) != NULL); if (threaded) - (void) _private_mutex_unlock(&_first_link_lock); + cancel_safe_mutex_unlock(&_first_link_lock); } /* allocate an unused stream; NULL if cannot */ @@ -255,7 +255,7 @@ _findiop(void) int threaded = __libc_threaded; if (threaded) - (void) _private_mutex_lock(&_first_link_lock); + cancel_safe_mutex_lock(&_first_link_lock); if (lastlink == NULL) { rescan: @@ -283,7 +283,7 @@ rescan: if (threaded) { ret = getiop(fp, FPLOCK(fp), FPSTATE(fp)); if (ret != NULL) { - (void) _private_mutex_unlock( + cancel_safe_mutex_unlock( &_first_link_lock); return (ret); } @@ -316,7 +316,7 @@ rescan: */ if ((pkgp = malloc(sizeof (Pkg))) == NULL) { if (threaded) - (void) _private_mutex_unlock(&_first_link_lock); + cancel_safe_mutex_unlock(&_first_link_lock); return (NULL); } @@ -346,9 +346,9 @@ rescan: * we need to use the reverse structure. */ if ((delta = 0x1000 - ((uintptr_t)pkgp & 0xfff)) <= - offsetof(Pkg, Pkgn.iob[FILE_ARY_SZ-1].xmagic) && + offsetof(Pkg, Pkgn.iob[FILE_ARY_SZ-1].xmagic) && delta % sizeof (struct xFILE) == - offsetof(Pkg, Pkgn.iob[0].xmagic)) { + offsetof(Pkg, Pkgn.iob[0].xmagic)) { /* Use reversed structure */ hdr = &pkgp->Pkgr.hdr; hdr->iobp = &pkgp->Pkgr.iob[0]; @@ -366,7 +366,7 @@ rescan: fp = hdr->iobp; for (i = 0; i < FILE_ARY_SZ; i++) _private_mutex_init(&fp[i]._lock, - USYNC_THREAD|LOCK_RECURSIVE, NULL); + USYNC_THREAD|LOCK_RECURSIVE, NULL); #else xfp = hdr->iobp; fp = &xfp->_iob; @@ -374,7 +374,7 @@ rescan: for (i = 0; i < FILE_ARY_SZ; i++) { xfp[i].xmagic = XMAGIC(&xfp[i]); _private_mutex_init(&xfp[i].xlock, - USYNC_THREAD|LOCK_RECURSIVE, NULL); + USYNC_THREAD|LOCK_RECURSIVE, NULL); } #endif /* _LP64 */ @@ -383,7 +383,7 @@ rescan: fp->_base = 0; fp->_flag = 0377; /* claim the fp by setting low 8 bits */ if (threaded) - (void) _private_mutex_unlock(&_first_link_lock); + cancel_safe_mutex_unlock(&_first_link_lock); return (fp); } @@ -551,10 +551,10 @@ _xflsbuf(FILE *iop) if (n > 0) { int fd = GET_FD(iop); - while ((num_wrote = - write(fd, base, (size_t)n)) != n) { + while ((num_wrote = write(fd, base, (size_t)n)) != n) { if (num_wrote <= 0) { - iop->_flag |= _IOERR; + if (!cancel_active()) + iop->_flag |= _IOERR; return (EOF); } n -= num_wrote; @@ -594,7 +594,7 @@ _fflush_l_iops(void) /* flush all buffers */ int threaded = __libc_threaded; if (threaded) - (void) _private_mutex_lock(&_first_link_lock); + cancel_safe_mutex_lock(&_first_link_lock); lp = &__first_link; @@ -627,7 +627,7 @@ _fflush_l_iops(void) /* flush all buffers */ if (threaded) { lk = FPLOCK(iop); - if (rmutex_trylock(lk) != 0) + if (cancel_safe_mutex_trylock(lk) != 0) continue; } @@ -651,11 +651,11 @@ _fflush_l_iops(void) /* flush all buffers */ } } if (threaded) - (void) rmutex_unlock(lk); + cancel_safe_mutex_unlock(lk); } } while ((lp = lp->next) != NULL); if (threaded) - (void) _private_mutex_unlock(&_first_link_lock); + cancel_safe_mutex_unlock(&_first_link_lock); return (res); } @@ -717,10 +717,10 @@ fclose(FILE *iop) FUNLOCKFILE(lk); if (__libc_threaded) - (void) _private_mutex_lock(&_first_link_lock); + cancel_safe_mutex_lock(&_first_link_lock); fcloses++; if (__libc_threaded) - (void) _private_mutex_unlock(&_first_link_lock); + cancel_safe_mutex_unlock(&_first_link_lock); return (res); } @@ -755,7 +755,7 @@ close_fd(FILE *iop) static FILE * getiop(FILE *fp, rmutex_t *lk, mbstate_t *mb) { - if (lk != NULL && rmutex_trylock(lk)) + if (lk != NULL && cancel_safe_mutex_trylock(lk) != 0) return (NULL); /* locked: fp in use */ if (fp->_flag == 0) { /* unused */ diff --git a/usr/src/lib/libc/port/stdio/fputs.c b/usr/src/lib/libc/port/stdio/fputs.c index 1ab3c57be5..e115d4012e 100644 --- a/usr/src/lib/libc/port/stdio/fputs.c +++ b/usr/src/lib/libc/port/stdio/fputs.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -121,13 +121,14 @@ fputs(const char *ptr, FILE *iop) int fd = GET_FD(iop); while ((num_wrote = write(fd, ptr, (size_t)count)) != count) { - if (num_wrote <= 0) { + if (num_wrote <= 0) { + if (!cancel_active()) iop->_flag |= _IOERR; - FUNLOCKFILE(lk); - return (EOF); - } - count -= num_wrote; - ptr += num_wrote; + FUNLOCKFILE(lk); + return (EOF); + } + count -= num_wrote; + ptr += num_wrote; } FUNLOCKFILE(lk); if (ptrlen <= INT_MAX) diff --git a/usr/src/lib/libc/port/stdio/fwrite.c b/usr/src/lib/libc/port/stdio/fwrite.c index 77b301228c..6ab340e26d 100644 --- a/usr/src/lib/libc/port/stdio/fwrite.c +++ b/usr/src/lib/libc/port/stdio/fwrite.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,8 +18,9 @@ * * CDDL HEADER END */ + /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -112,7 +112,8 @@ _fwrite_unlocked(const void *ptr, size_t size, size_t count, FILE *iop) while ((n = write(fileno(iop), data, (size_t)bytes)) != bytes) { if (n == -1) { - iop->_flag |= _IOERR; + if (!cancel_active()) + iop->_flag |= _IOERR; return (0); } else { data += n; @@ -128,7 +129,8 @@ _fwrite_unlocked(const void *ptr, size_t size, size_t count, FILE *iop) */ while ((n = write(fileno(iop), dptr, s)) != s) { if (n == -1) { - iop->_flag |= _IOERR; + if (!cancel_active()) + iop->_flag |= _IOERR; return (written / size); } else { dptr += n; diff --git a/usr/src/lib/libc/port/stdio/popen.c b/usr/src/lib/libc/port/stdio/popen.c index 11071de5bc..899e19d05b 100644 --- a/usr/src/lib/libc/port/stdio/popen.c +++ b/usr/src/lib/libc/port/stdio/popen.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -80,6 +80,11 @@ cleanup(void *arg) extern const sigset_t maskset; extern void *reapchild(void *); /* see port/stdio/system.c */ + /* + * We have been cancelled. There is no need to restore + * the original sigmask after blocking all signals because + * pthread_exit() will block all signals while we exit. + */ (void) thr_sigsetmask(SIG_SETMASK, &maskset, NULL); (void) thr_create(NULL, 0, reapchild, arg, THR_DAEMON, NULL); } @@ -156,8 +161,8 @@ popen(const char *cmd, const char *mode) /* * These conditions may apply if a previous iob returned * by popen() was closed with fclose() rather than pclose(), - * or if close(fileno(iob)) was called. - * Accommodate these programming error. + * or if close(fileno(iob)) was called. Don't let these + * programming errors cause us to malfunction here. */ if ((fd = curr->fd) != myside && fd != yourside && fcntl(fd, F_GETFD) >= 0) @@ -168,10 +173,10 @@ popen(const char *cmd, const char *mode) if (yourside != stdio) { if (error == 0) error = posix_spawn_file_actions_adddup2(&fact, - yourside, stdio); + yourside, stdio); if (error == 0) error = posix_spawn_file_actions_addclose(&fact, - yourside); + yourside); } if (error == 0) error = posix_spawnattr_setflags(&attr, @@ -191,7 +196,7 @@ popen(const char *cmd, const char *mode) argvec[2] = (char *)cmd; argvec[3] = NULL; error = posix_spawn(&pid, shpath, &fact, &attr, - (char *const *)argvec, (char *const *)environ); + (char *const *)argvec, (char *const *)environ); (void) posix_spawnattr_destroy(&attr); (void) posix_spawn_file_actions_destroy(&fact); (void) close(yourside); @@ -211,6 +216,9 @@ popen(const char *cmd, const char *mode) return (iop); } +/* + * pclose() is a cancellation point. + */ int pclose(FILE *ptr) { @@ -228,9 +236,8 @@ pclose(FILE *ptr) } /* - * pclose() is a cancellation point. - * Call waitpid_cancel() rather than _waitpid() to make - * sure that we actually perform the cancellation logic. + * waitpid() is a cancellation point. + * This causes pclose() to be a cancellation point. * * If we have already been cancelled (pclose() was called from * a cancellation cleanup handler), attempt to reap the process @@ -238,6 +245,7 @@ pclose(FILE *ptr) */ if (_thrp_cancelled()) { + /* waitpid(..., WNOHANG) is not a cancellation point */ if (waitpid(pid, &status, WNOHANG) == pid) return (status); cleanup((void *)(uintptr_t)pid); @@ -246,7 +254,7 @@ pclose(FILE *ptr) } pthread_cleanup_push(cleanup, (void *)(uintptr_t)pid); - while (waitpid_cancel(pid, &status, 0) < 0) { + while (waitpid(pid, &status, 0) < 0) { if (errno != EINTR) { status = -1; break; @@ -268,10 +276,11 @@ _insert_nolock(pid_t pid, int fd, node_t *new) /* * curr->fd can equal fd if a previous iob returned by * popen() was closed with fclose() rather than pclose(), - * or if close(fileno(iob)) was called. - * Accommodate this programming error. + * or if close(fileno(iob)) was called. Don't let these + * programming errors cause us to malfunction here. */ if (curr->fd == fd) { + /* make a lame attempt to reap the forgotten child */ (void) waitpid(curr->pid, NULL, WNOHANG); curr->pid = pid; lfree(new, sizeof (node_t)); diff --git a/usr/src/lib/libc/port/stdio/system.c b/usr/src/lib/libc/port/stdio/system.c index 707134751d..cef2648ced 100644 --- a/usr/src/lib/libc/port/stdio/system.c +++ b/usr/src/lib/libc/port/stdio/system.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -73,11 +73,14 @@ void * reapchild(void *arg) { pid_t pid = (pid_t)(uintptr_t)arg; + int cancel_state; + (void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel_state); while (waitpid(pid, NULL, 0) == -1) { if (errno != EINTR) break; } + (void) pthread_setcancelstate(cancel_state, NULL); return (NULL); } @@ -225,7 +228,7 @@ system(const char *cmd) argv[3] = NULL; if (error == 0) error = posix_spawn(&cu.pid, shpath, NULL, &attr, - (char *const *)argv, (char *const *)environ); + (char *const *)argv, (char *const *)environ); (void) posix_spawnattr_destroy(&attr); @@ -234,13 +237,11 @@ system(const char *cmd) status = -1; } else { /* - * system() is a cancellation point. - * Call waitpid_cancel() rather than _waitpid() to make - * sure that we actually perform the cancellation logic. + * system() is a cancellation point and so is waitpid(). */ pthread_cleanup_push(cleanup, &cu); do { - w = waitpid_cancel(cu.pid, &status, 0); + w = waitpid(cu.pid, &status, 0); } while (w == -1 && errno == EINTR); pthread_cleanup_pop(0); if (w == -1) |