summaryrefslogtreecommitdiff
path: root/usr/src/lib/libc/port/stdio
diff options
context:
space:
mode:
authorraf <none@none>2008-01-23 12:00:31 -0800
committerraf <none@none>2008-01-23 12:00:31 -0800
commita574db851cdc636fc3939b68e80d79fe7fbd57f2 (patch)
tree7a28122042d1d24d9c4df92ba257e2d34d111e2e /usr/src/lib/libc/port/stdio
parent4a7ceb24cfcc0a97f96d86cfe5852ae445b50e57 (diff)
downloadillumos-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.c18
-rw-r--r--usr/src/lib/libc/port/stdio/_flsbuf.c16
-rw-r--r--usr/src/lib/libc/port/stdio/flockf.c23
-rw-r--r--usr/src/lib/libc/port/stdio/flush.c46
-rw-r--r--usr/src/lib/libc/port/stdio/fputs.c15
-rw-r--r--usr/src/lib/libc/port/stdio/fwrite.c14
-rw-r--r--usr/src/lib/libc/port/stdio/popen.c33
-rw-r--r--usr/src/lib/libc/port/stdio/system.c13
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)