Patchwork [v5,3/6] char: Let writers know how much data was written in case of errors

login
register
mail settings
Submitter Amit Shah
Date May 4, 2010, 10:52 a.m.
Message ID <1272970367-24647-4-git-send-email-amit.shah@redhat.com>
Download mbox | patch
Permalink /patch/51588/
State New
Headers show

Comments

Amit Shah - May 4, 2010, 10:52 a.m.
On writing errors, we just returned -1 even if some bytes were already
written out. Ensure we return the number of bytes written before we
return the error (on a subsequent call to qemu_chr_write()).

Signed-off-by: Amit Shah <amit.shah@redhat.com>
---
 qemu-char.c |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)
Gerd Hoffmann - May 4, 2010, 11:24 a.m.
> @@ -531,8 +534,12 @@ static int unix_write(int fd, const uint8_t *buf, int len1)
>       while (len>  0) {
>           ret = write(fd, buf, len);
>           if (ret<  0) {
> -            if (errno != EINTR&&  errno != EAGAIN)
> +            if (len1 - len) {
> +                return len1 - len;
> +            }
> +            if (errno != EINTR&&  errno != EAGAIN) {
>                   return -1;
> +            }

This makes unix_write pass -EINTR up to the caller which it didn't before.

cheers,
   Gerd
Amit Shah - May 4, 2010, 11:31 a.m.
On (Tue) May 04 2010 [13:24:58], Gerd Hoffmann wrote:
>> @@ -531,8 +534,12 @@ static int unix_write(int fd, const uint8_t *buf, int len1)
>>       while (len>  0) {
>>           ret = write(fd, buf, len);
>>           if (ret<  0) {
>> -            if (errno != EINTR&&  errno != EAGAIN)
>> +            if (len1 - len) {
>> +                return len1 - len;
>> +            }
>> +            if (errno != EINTR&&  errno != EAGAIN) {
>>                   return -1;
>> +            }
>
> This makes unix_write pass -EINTR up to the caller which it didn't before.

Only on partial writes. Should be OK, no?

		Amit
Gerd Hoffmann - May 4, 2010, 1:30 p.m.
On 05/04/10 13:31, Amit Shah wrote:
> On (Tue) May 04 2010 [13:24:58], Gerd Hoffmann wrote:
>>> @@ -531,8 +534,12 @@ static int unix_write(int fd, const uint8_t *buf, int len1)
>>>        while (len>   0) {
>>>            ret = write(fd, buf, len);
>>>            if (ret<   0) {
>>> -            if (errno != EINTR&&   errno != EAGAIN)
>>> +            if (len1 - len) {
>>> +                return len1 - len;
>>> +            }
>>> +            if (errno != EINTR&&   errno != EAGAIN) {
>>>                    return -1;
>>> +            }
>>
>> This makes unix_write pass -EINTR up to the caller which it didn't before.
>
> Only on partial writes. Should be OK, no?

No.  Callers which never saw partial writes due to write() syscall being 
interrupted by some signal start seeing them now.

cheers,
   Gerd

Patch

diff --git a/qemu-char.c b/qemu-char.c
index 65cb3f5..97f2ef6 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -507,6 +507,9 @@  int send_all(int fd, const void *buf, int len1)
     while (len > 0) {
         ret = send(fd, buf, len, 0);
         if (ret < 0) {
+            if (len1 - len) {
+                return len1 - len;
+            }
             errno = WSAGetLastError();
             if (errno != WSAEWOULDBLOCK) {
                 return -1;
@@ -531,8 +534,12 @@  static int unix_write(int fd, const uint8_t *buf, int len1)
     while (len > 0) {
         ret = write(fd, buf, len);
         if (ret < 0) {
-            if (errno != EINTR && errno != EAGAIN)
+            if (len1 - len) {
+                return len1 - len;
+            }
+            if (errno != EINTR && errno != EAGAIN) {
                 return -1;
+            }
         } else if (ret == 0) {
             break;
         } else {