]>
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 | ||
19 | #include "nbd-internal.h" | |
20 | ||
21 | ssize_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read) | |
22 | { | |
23 | size_t offset = 0; | |
24 | int err; | |
25 | ||
26 | if (qemu_in_coroutine()) { | |
27 | if (do_read) { | |
28 | return qemu_co_recv(fd, buffer, size); | |
29 | } else { | |
30 | return qemu_co_send(fd, buffer, size); | |
31 | } | |
32 | } | |
33 | ||
34 | while (offset < size) { | |
35 | ssize_t len; | |
36 | ||
37 | if (do_read) { | |
38 | len = qemu_recv(fd, buffer + offset, size - offset, 0); | |
39 | } else { | |
40 | len = send(fd, buffer + offset, size - offset, 0); | |
41 | } | |
42 | ||
43 | if (len < 0) { | |
44 | err = socket_error(); | |
45 | ||
46 | /* recoverable error */ | |
47 | if (err == EINTR || (offset > 0 && (err == EAGAIN || err == EWOULDBLOCK))) { | |
48 | continue; | |
49 | } | |
50 | ||
51 | /* unrecoverable error */ | |
52 | return -err; | |
53 | } | |
54 | ||
55 | /* eof */ | |
56 | if (len == 0) { | |
57 | break; | |
58 | } | |
59 | ||
60 | offset += len; | |
61 | } | |
62 | ||
63 | return offset; | |
64 | } |