]>
Commit | Line | Data |
---|---|---|
34dc7c2f BB |
1 | /* |
2 | * CDDL HEADER START | |
3 | * | |
4 | * The contents of this file are subject to the terms of the | |
5 | * Common Development and Distribution License, Version 1.0 only | |
6 | * (the "License"). You may not use this file except in compliance | |
7 | * with the License. | |
8 | * | |
9 | * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE | |
10 | * or http://www.opensolaris.org/os/licensing. | |
11 | * See the License for the specific language governing permissions | |
12 | * and limitations under the License. | |
13 | * | |
14 | * When distributing Covered Code, include this CDDL HEADER in each | |
15 | * file and include the License file at usr/src/OPENSOLARIS.LICENSE. | |
16 | * If applicable, add the following below this CDDL HEADER, with the | |
17 | * fields enclosed by brackets "[]" replaced with your own identifying | |
18 | * information: Portions Copyright [yyyy] [name of copyright owner] | |
19 | * | |
20 | * CDDL HEADER END | |
21 | */ | |
22 | /* | |
23 | * Copyright 2008 Sun Microsystems, Inc. All rights reserved. | |
24 | * Use is subject to license terms. | |
25 | */ | |
26 | ||
27 | #include <stdio.h> | |
28 | #include <errno.h> | |
29 | #include <sys/types.h> | |
30 | #include <sys/socket.h> | |
31 | ||
32 | #include <sys/dmu_ctl.h> | |
33 | #include <sys/dmu_ctl_impl.h> | |
34 | ||
35 | int dctl_read_msg(int fd, dctl_cmd_t *cmd) | |
36 | { | |
37 | int error; | |
38 | ||
39 | /* | |
40 | * First, read only the magic number and the protocol version. | |
41 | * | |
42 | * This prevents blocking forever in case the size of dctl_cmd_t | |
43 | * shrinks in future protocol versions. | |
44 | */ | |
45 | error = dctl_read_data(fd, cmd, DCTL_CMD_HEADER_SIZE); | |
46 | ||
47 | if (!error &&cmd->dcmd_magic != DCTL_MAGIC) { | |
48 | fprintf(stderr, "%s(): invalid magic number\n", __func__); | |
49 | error = EIO; | |
50 | } | |
51 | ||
52 | if (!error && cmd->dcmd_version != DCTL_PROTOCOL_VER) { | |
53 | fprintf(stderr, "%s(): invalid protocol version\n", __func__); | |
54 | error = ENOTSUP; | |
55 | } | |
56 | ||
57 | if (error) | |
58 | return error; | |
59 | ||
60 | /* Get the rest of the command */ | |
61 | return dctl_read_data(fd, (caddr_t) cmd + DCTL_CMD_HEADER_SIZE, | |
62 | sizeof(dctl_cmd_t) - DCTL_CMD_HEADER_SIZE); | |
63 | } | |
64 | ||
65 | int dctl_send_msg(int fd, dctl_cmd_t *cmd) | |
66 | { | |
67 | cmd->dcmd_magic = DCTL_MAGIC; | |
68 | cmd->dcmd_version = DCTL_PROTOCOL_VER; | |
69 | ||
70 | return dctl_send_data(fd, cmd, sizeof(dctl_cmd_t)); | |
71 | } | |
72 | ||
73 | int dctl_read_data(int fd, void *ptr, size_t size) | |
74 | { | |
75 | size_t read = 0; | |
76 | size_t left = size; | |
77 | ssize_t rc; | |
78 | ||
79 | while (left > 0) { | |
80 | rc = recv(fd, (caddr_t) ptr + read, left, 0); | |
81 | ||
82 | /* File descriptor closed */ | |
83 | if (rc == 0) | |
84 | return ECONNRESET; | |
85 | ||
86 | if (rc == -1) { | |
87 | if (errno == EINTR) | |
88 | continue; | |
89 | return errno; | |
90 | } | |
91 | ||
92 | read += rc; | |
93 | left -= rc; | |
94 | } | |
95 | ||
96 | return 0; | |
97 | } | |
98 | ||
99 | int dctl_send_data(int fd, const void *ptr, size_t size) | |
100 | { | |
101 | ssize_t rc; | |
102 | ||
103 | do { | |
104 | rc = send(fd, ptr, size, MSG_NOSIGNAL); | |
105 | } while(rc == -1 && errno == EINTR); | |
106 | ||
107 | return rc == size ? 0 : EIO; | |
108 | } | |
109 |