summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Smith <brad@cvs.openbsd.org>2003-12-22 00:33:43 +0000
committerBrad Smith <brad@cvs.openbsd.org>2003-12-22 00:33:43 +0000
commite54709f1989d77746c21ddaa457984d6eecfc494 (patch)
treefaf002c19b0e7582b7b2c78e19a039b229b300f7
parent726b209e53304d863de5f8e18010721eab9a30c7 (diff)
Fixes from FreeBSD' libc_r
rev 1.21 Fix bogus return values from libc_r's write() routine in situations where partial-write is followed by an error. rev 1.22 If __sys_write() returns 0, allow that to exit the loop in libc_r's wrapped version of write(). rev 1.23 Return to the caller if write() returns 0. ok marc@
-rw-r--r--lib/libpthread/uthread/uthread_write.c33
1 files changed, 25 insertions, 8 deletions
diff --git a/lib/libpthread/uthread/uthread_write.c b/lib/libpthread/uthread/uthread_write.c
index dc45cc483d7..393b9da65c7 100644
--- a/lib/libpthread/uthread/uthread_write.c
+++ b/lib/libpthread/uthread/uthread_write.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_write.c,v 1.9 2003/01/31 04:46:17 marc Exp $ */
+/* $OpenBSD: uthread_write.c,v 1.10 2003/12/22 00:33:42 brad Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -99,7 +99,7 @@ write(int fd, const void *buf, size_t nbytes)
* write:
*/
if (blocking && ((n < 0 && (errno == EWOULDBLOCK ||
- errno == EAGAIN)) || (n >= 0 && num < nbytes))) {
+ errno == EAGAIN)) || (n > 0 && num < nbytes))) {
curthread->data.fd.fd = fd;
_thread_kern_set_timeout(NULL);
@@ -114,20 +114,37 @@ write(int fd, const void *buf, size_t nbytes)
* interrupted by a signal
*/
if (curthread->interrupted) {
- /* Return an error: */
- ret = -1;
+ if (num > 0) {
+ /* Return partial success: */
+ ret = num;
+ } else {
+ /* Return an error: */
+ errno = EINTR;
+ ret = -1;
+ }
}
/*
- * If performing a non-blocking write or if an
- * error occurred, just return whatever the write
- * syscall did:
+ * If performing a non-blocking write,
+ * just return whatever the write syscall did:
*/
- } else if (!blocking || n < 0) {
+ } else if (!blocking) {
/* A non-blocking call might return zero: */
ret = n;
break;
+ /*
+ * If there was an error, return partial success
+ * (if any bytes were written) or else the error:
+ */
+ } else if (n <= 0) {
+ if (num > 0)
+ ret = num;
+ else
+ ret = n;
+ if (n == 0)
+ break;
+
/* Check if the write has completed: */
} else if (num >= nbytes)
/* Return the number of bytes written: */