diff options
author | archie <archie@FreeBSD.org> | 2002-11-05 00:59:18 +0000 |
---|---|---|
committer | archie <archie@FreeBSD.org> | 2002-11-05 00:59:18 +0000 |
commit | 8f843aa0d7426f23ed1bfdd29145be80286b1148 (patch) | |
tree | 19511f89455b9f59253bcddee93308fc759b3db5 /lib | |
parent | 8a4e33ad885bc2f06155b2a65fd3a33bcc2cd488 (diff) | |
download | FreeBSD-src-8f843aa0d7426f23ed1bfdd29145be80286b1148.zip FreeBSD-src-8f843aa0d7426f23ed1bfdd29145be80286b1148.tar.gz |
Fix bogus return values from libc_r's write() routine in situations where
a partial-write is followed by an error.
PR: 43335
MFC after: 1 week
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libc_r/uthread/uthread_write.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/lib/libc_r/uthread/uthread_write.c b/lib/libc_r/uthread/uthread_write.c index 072b989..85ef9eb 100644 --- a/lib/libc_r/uthread/uthread_write.c +++ b/lib/libc_r/uthread/uthread_write.c @@ -110,20 +110,35 @@ _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; + /* Check if the write has completed: */ } else if (num >= nbytes) /* Return the number of bytes written: */ |