diff options
author | Brad Smith <brad@cvs.openbsd.org> | 2003-12-22 00:33:43 +0000 |
---|---|---|
committer | Brad Smith <brad@cvs.openbsd.org> | 2003-12-22 00:33:43 +0000 |
commit | e54709f1989d77746c21ddaa457984d6eecfc494 (patch) | |
tree | faf002c19b0e7582b7b2c78e19a039b229b300f7 /lib/libpthread | |
parent | 726b209e53304d863de5f8e18010721eab9a30c7 (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@
Diffstat (limited to 'lib/libpthread')
-rw-r--r-- | lib/libpthread/uthread/uthread_write.c | 33 |
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: */ |