1 #include <glib.h> 2 #include <termios.h> 3 #include <errno.h> 4 #include <unistd.h> 5 #include <fcntl.h> 6 #include <stdlib.h> 7 #include "osdep.h" 8 #include "qemu_socket.h" 9 #include "qga/channel.h" 10 11 #ifdef CONFIG_SOLARIS 12 #include <stropts.h> 13 #endif 14 15 #define GA_CHANNEL_BAUDRATE_DEFAULT B38400 /* for isa-serial channels */ 16 17 struct GAChannel { 18 GIOChannel *listen_channel; 19 GIOChannel *client_channel; 20 GAChannelMethod method; 21 GAChannelCallback event_cb; 22 gpointer user_data; 23 }; 24 25 static int ga_channel_client_add(GAChannel *c, int fd); 26 27 static gboolean ga_channel_listen_accept(GIOChannel *channel, 28 GIOCondition condition, gpointer data) 29 { 30 GAChannel *c = data; 31 int ret, client_fd; 32 bool accepted = false; 33 struct sockaddr_un addr; 34 socklen_t addrlen = sizeof(addr); 35 36 g_assert(channel != NULL); 37 38 client_fd = qemu_accept(g_io_channel_unix_get_fd(channel), 39 (struct sockaddr *)&addr, &addrlen); 40 if (client_fd == -1) { 41 g_warning("error converting fd to gsocket: %s", strerror(errno)); 42 goto out; 43 } 44 fcntl(client_fd, F_SETFL, O_NONBLOCK); 45 ret = ga_channel_client_add(c, client_fd); 46 if (ret) { 47 g_warning("error setting up connection"); 48 goto out; 49 } 50 accepted = true; 51 52 out: 53 /* only accept 1 connection at a time */ 54 return !accepted; 55 } 56 57 /* start polling for readable events on listen fd, new==true 58 * indicates we should use the existing s->listen_channel 59 */ 60 static void ga_channel_listen_add(GAChannel *c, int listen_fd, bool create) 61 { 62 if (create) { 63 c->listen_channel = g_io_channel_unix_new(listen_fd); 64 } 65 g_io_add_watch(c->listen_channel, G_IO_IN, ga_channel_listen_accept, c); 66 } 67 68 static void ga_channel_listen_close(GAChannel *c) 69 { 70 g_assert(c->method == GA_CHANNEL_UNIX_LISTEN); 71 g_assert(c->listen_channel); 72 g_io_channel_shutdown(c->listen_channel, true, NULL); 73 g_io_channel_unref(c->listen_channel); 74 c->listen_channel = NULL; 75 } 76 77 /* cleanup state for closed connection/session, start accepting new 78 * connections if we're in listening mode 79 */ 80 static void ga_channel_client_close(GAChannel *c) 81 { 82 g_assert(c->client_channel); 83 g_io_channel_shutdown(c->client_channel, true, NULL); 84 g_io_channel_unref(c->client_channel); 85 c->client_channel = NULL; 86 if (c->method == GA_CHANNEL_UNIX_LISTEN && c->listen_channel) { 87 ga_channel_listen_add(c, 0, false); 88 } 89 } 90 91 static gboolean ga_channel_client_event(GIOChannel *channel, 92 GIOCondition condition, gpointer data) 93 { 94 GAChannel *c = data; 95 gboolean client_cont; 96 97 g_assert(c); 98 if (c->event_cb) { 99 client_cont = c->event_cb(condition, c->user_data); 100 if (!client_cont) { 101 ga_channel_client_close(c); 102 return false; 103 } 104 } 105 return true; 106 } 107 108 static int ga_channel_client_add(GAChannel *c, int fd) 109 { 110 GIOChannel *client_channel; 111 GError *err = NULL; 112 113 g_assert(c && !c->client_channel); 114 client_channel = g_io_channel_unix_new(fd); 115 g_assert(client_channel); 116 g_io_channel_set_encoding(client_channel, NULL, &err); 117 if (err != NULL) { 118 g_warning("error setting channel encoding to binary"); 119 g_error_free(err); 120 return -1; 121 } 122 g_io_add_watch(client_channel, G_IO_IN | G_IO_HUP, 123 ga_channel_client_event, c); 124 c->client_channel = client_channel; 125 return 0; 126 } 127 128 static gboolean ga_channel_open(GAChannel *c, const gchar *path, GAChannelMethod method) 129 { 130 int ret; 131 c->method = method; 132 133 switch (c->method) { 134 case GA_CHANNEL_VIRTIO_SERIAL: { 135 int fd = qemu_open(path, O_RDWR | O_NONBLOCK 136 #ifndef CONFIG_SOLARIS 137 | O_ASYNC 138 #endif 139 ); 140 if (fd == -1) { 141 g_critical("error opening channel: %s", strerror(errno)); 142 exit(EXIT_FAILURE); 143 } 144 #ifdef CONFIG_SOLARIS 145 ret = ioctl(fd, I_SETSIG, S_OUTPUT | S_INPUT | S_HIPRI); 146 if (ret == -1) { 147 g_critical("error setting event mask for channel: %s", 148 strerror(errno)); 149 exit(EXIT_FAILURE); 150 } 151 #endif 152 ret = ga_channel_client_add(c, fd); 153 if (ret) { 154 g_critical("error adding channel to main loop"); 155 return false; 156 } 157 break; 158 } 159 case GA_CHANNEL_ISA_SERIAL: { 160 struct termios tio; 161 int fd = qemu_open(path, O_RDWR | O_NOCTTY | O_NONBLOCK); 162 if (fd == -1) { 163 g_critical("error opening channel: %s", strerror(errno)); 164 exit(EXIT_FAILURE); 165 } 166 tcgetattr(fd, &tio); 167 /* set up serial port for non-canonical, dumb byte streaming */ 168 tio.c_iflag &= ~(IGNBRK | BRKINT | IGNPAR | PARMRK | INPCK | ISTRIP | 169 INLCR | IGNCR | ICRNL | IXON | IXOFF | IXANY | 170 IMAXBEL); 171 tio.c_oflag = 0; 172 tio.c_lflag = 0; 173 tio.c_cflag |= GA_CHANNEL_BAUDRATE_DEFAULT; 174 /* 1 available byte min or reads will block (we'll set non-blocking 175 * elsewhere, else we have to deal with read()=0 instead) 176 */ 177 tio.c_cc[VMIN] = 1; 178 tio.c_cc[VTIME] = 0; 179 /* flush everything waiting for read/xmit, it's garbage at this point */ 180 tcflush(fd, TCIFLUSH); 181 tcsetattr(fd, TCSANOW, &tio); 182 ret = ga_channel_client_add(c, fd); 183 if (ret) { 184 g_error("error adding channel to main loop"); 185 } 186 break; 187 } 188 case GA_CHANNEL_UNIX_LISTEN: { 189 Error *local_err = NULL; 190 int fd = unix_listen(path, NULL, strlen(path), &local_err); 191 if (local_err != NULL) { 192 g_critical("%s", error_get_pretty(local_err)); 193 error_free(local_err); 194 return false; 195 } 196 ga_channel_listen_add(c, fd, true); 197 break; 198 } 199 default: 200 g_critical("error binding/listening to specified socket"); 201 return false; 202 } 203 204 return true; 205 } 206 207 GIOStatus ga_channel_write_all(GAChannel *c, const gchar *buf, gsize size) 208 { 209 GError *err = NULL; 210 gsize written = 0; 211 GIOStatus status = G_IO_STATUS_NORMAL; 212 213 while (size) { 214 status = g_io_channel_write_chars(c->client_channel, buf, size, 215 &written, &err); 216 g_debug("sending data, count: %d", (int)size); 217 if (err != NULL) { 218 g_warning("error writing to channel: %s", err->message); 219 return G_IO_STATUS_ERROR; 220 } 221 if (status != G_IO_STATUS_NORMAL) { 222 break; 223 } 224 size -= written; 225 } 226 227 if (status == G_IO_STATUS_NORMAL) { 228 status = g_io_channel_flush(c->client_channel, &err); 229 if (err != NULL) { 230 g_warning("error flushing channel: %s", err->message); 231 return G_IO_STATUS_ERROR; 232 } 233 } 234 235 return status; 236 } 237 238 GIOStatus ga_channel_read(GAChannel *c, gchar *buf, gsize size, gsize *count) 239 { 240 return g_io_channel_read_chars(c->client_channel, buf, size, count, NULL); 241 } 242 243 GAChannel *ga_channel_new(GAChannelMethod method, const gchar *path, 244 GAChannelCallback cb, gpointer opaque) 245 { 246 GAChannel *c = g_malloc0(sizeof(GAChannel)); 247 c->event_cb = cb; 248 c->user_data = opaque; 249 250 if (!ga_channel_open(c, path, method)) { 251 g_critical("error opening channel"); 252 ga_channel_free(c); 253 return NULL; 254 } 255 256 return c; 257 } 258 259 void ga_channel_free(GAChannel *c) 260 { 261 if (c->method == GA_CHANNEL_UNIX_LISTEN 262 && c->listen_channel) { 263 ga_channel_listen_close(c); 264 } 265 if (c->client_channel) { 266 ga_channel_client_close(c); 267 } 268 g_free(c); 269 } 270