* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "nbd.h"
#include <errno.h>
#include <string.h>
+#ifndef _WIN32
#include <sys/ioctl.h>
+#endif
#ifdef __sun__
#include <sys/ioccom.h>
#endif
#include <ctype.h>
#include <inttypes.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-
-#if defined(QEMU_NBD)
-extern int verbose;
-#else
-static int verbose = 0;
-#endif
+#include "qemu_socket.h"
+
+//#define DEBUG_NBD
+
+#ifdef DEBUG_NBD
#define TRACE(msg, ...) do { \
- if (verbose) LOG(msg, ## __VA_ARGS__); \
+ LOG(msg, ## __VA_ARGS__); \
} while(0)
+#else
+#define TRACE(msg, ...) \
+ do { } while (0)
+#endif
#define LOG(msg, ...) do { \
fprintf(stderr, "%s:%s():L%d: " msg "\n", \
ssize_t len;
if (do_read) {
- len = read(fd, buffer + offset, size - offset);
+ len = recv(fd, buffer + offset, size - offset, 0);
} else {
- len = write(fd, buffer + offset, size - offset);
+ len = send(fd, buffer + offset, size - offset, 0);
}
+ if (len == -1)
+ errno = socket_error();
+
/* recoverable error */
if (len == -1 && (errno == EAGAIN || errno == EINTR)) {
continue;
int s;
struct in_addr in;
struct sockaddr_in addr;
- int serrno;
s = socket(PF_INET, SOCK_STREAM, 0);
if (s == -1) {
return s;
error:
- serrno = errno;
- close(s);
- errno = serrno;
+ closesocket(s);
return -1;
}
int s;
struct in_addr in;
struct sockaddr_in addr;
- int serrno;
int opt;
s = socket(PF_INET, SOCK_STREAM, 0);
memcpy(&addr.sin_addr.s_addr, &in, sizeof(in));
opt = 1;
- if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1) {
+ if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
+ (const void *) &opt, sizeof(opt)) == -1) {
goto error;
}
return s;
error:
- serrno = errno;
- close(s);
- errno = serrno;
+ closesocket(s);
return -1;
}
+#ifndef _WIN32
int unix_socket_incoming(const char *path)
{
int s;
struct sockaddr_un addr;
- int serrno;
s = socket(PF_UNIX, SOCK_STREAM, 0);
if (s == -1) {
return s;
error:
- serrno = errno;
- close(s);
- errno = serrno;
+ closesocket(s);
return -1;
}
{
int s;
struct sockaddr_un addr;
- int serrno;
s = socket(PF_UNIX, SOCK_STREAM, 0);
if (s == -1) {
return s;
error:
- serrno = errno;
- close(s);
- errno = serrno;
+ closesocket(s);
+ return -1;
+}
+#else
+int unix_socket_incoming(const char *path)
+{
+ errno = ENOTSUP;
return -1;
}
+int unix_socket_outgoing(const char *path)
+{
+ errno = ENOTSUP;
+ return -1;
+}
+#endif
+
/* Basic flow
*blocksize = 1024;
TRACE("Magic is %c%c%c%c%c%c%c%c",
- isprint(buf[0]) ? buf[0] : '.',
- isprint(buf[1]) ? buf[1] : '.',
- isprint(buf[2]) ? buf[2] : '.',
- isprint(buf[3]) ? buf[3] : '.',
- isprint(buf[4]) ? buf[4] : '.',
- isprint(buf[5]) ? buf[5] : '.',
- isprint(buf[6]) ? buf[6] : '.',
- isprint(buf[7]) ? buf[7] : '.');
+ qemu_isprint(buf[0]) ? buf[0] : '.',
+ qemu_isprint(buf[1]) ? buf[1] : '.',
+ qemu_isprint(buf[2]) ? buf[2] : '.',
+ qemu_isprint(buf[3]) ? buf[3] : '.',
+ qemu_isprint(buf[4]) ? buf[4] : '.',
+ qemu_isprint(buf[5]) ? buf[5] : '.',
+ qemu_isprint(buf[6]) ? buf[6] : '.',
+ qemu_isprint(buf[7]) ? buf[7] : '.');
TRACE("Magic is 0x%" PRIx64, magic);
TRACE("Size is %" PRIu64, *size);
return 0;
}
+#ifndef _WIN32
int nbd_init(int fd, int csock, off_t size, size_t blocksize)
{
TRACE("Setting block size to %lu", (unsigned long)blocksize);
errno = serrno;
return ret;
}
+#else
+int nbd_init(int fd, int csock, off_t size, size_t blocksize)
+{
+ errno = ENOTSUP;
+ return -1;
+}
+
+int nbd_disconnect(int fd)
+{
+ errno = ENOTSUP;
+ return -1;
+}
+
+int nbd_client(int fd, int csock)
+{
+ errno = ENOTSUP;
+ return -1;
+}
+#endif
int nbd_send_request(int csock, struct nbd_request *request)
{
if ((request.from + request.len) > size) {
LOG("From: %" PRIu64 ", Len: %u, Size: %" PRIu64
", Offset: %" PRIu64 "\n",
- request.from, request.len, size, dev_offset);
+ request.from, request.len, (uint64_t)size, dev_offset);
LOG("requested operation past EOF--bad client?");
errno = EINVAL;
return -1;