]>
Commit | Line | Data |
---|---|---|
798bfe00 FZ |
1 | /* |
2 | * Copyright (C) 2005 Anthony Liguori <[email protected]> | |
3 | * | |
4 | * Network Block Device Common Code | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License as published by | |
8 | * the Free Software Foundation; under version 2 of the License. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | * GNU General Public License for more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License | |
16 | * along with this program; if not, see <http://www.gnu.org/licenses/>. | |
17 | */ | |
18 | ||
d38ea87a | 19 | #include "qemu/osdep.h" |
798bfe00 FZ |
20 | #include "nbd-internal.h" |
21 | ||
22 | ssize_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read) | |
23 | { | |
24 | size_t offset = 0; | |
25 | int err; | |
26 | ||
27 | if (qemu_in_coroutine()) { | |
28 | if (do_read) { | |
29 | return qemu_co_recv(fd, buffer, size); | |
30 | } else { | |
31 | return qemu_co_send(fd, buffer, size); | |
32 | } | |
33 | } | |
34 | ||
35 | while (offset < size) { | |
36 | ssize_t len; | |
37 | ||
38 | if (do_read) { | |
39 | len = qemu_recv(fd, buffer + offset, size - offset, 0); | |
40 | } else { | |
41 | len = send(fd, buffer + offset, size - offset, 0); | |
42 | } | |
43 | ||
44 | if (len < 0) { | |
45 | err = socket_error(); | |
46 | ||
47 | /* recoverable error */ | |
48 | if (err == EINTR || (offset > 0 && (err == EAGAIN || err == EWOULDBLOCK))) { | |
49 | continue; | |
50 | } | |
51 | ||
52 | /* unrecoverable error */ | |
53 | return -err; | |
54 | } | |
55 | ||
56 | /* eof */ | |
57 | if (len == 0) { | |
58 | break; | |
59 | } | |
60 | ||
61 | offset += len; | |
62 | } | |
63 | ||
64 | return offset; | |
65 | } |