s->chr_event(s->handler_opaque, event);
}
-static void qemu_chr_generic_open_bh(void *opaque)
+static void qemu_chr_fire_open_event(void *opaque)
{
CharDriverState *s = opaque;
qemu_chr_be_event(s, CHR_EVENT_OPENED);
- qemu_bh_delete(s->bh);
- s->bh = NULL;
+ qemu_free_timer(s->open_timer);
+ s->open_timer = NULL;
}
void qemu_chr_generic_open(CharDriverState *s)
{
- if (s->bh == NULL) {
- s->bh = qemu_bh_new(qemu_chr_generic_open_bh, s);
- qemu_bh_schedule(s->bh);
+ if (s->open_timer == NULL) {
+ s->open_timer = qemu_new_timer_ms(vm_clock,
+ qemu_chr_fire_open_event, s);
+ qemu_mod_timer(s->open_timer, qemu_get_clock_ms(vm_clock) - 1);
}
}
{
CharDriverState *chr = NULL;
NetCharDriver *s = NULL;
+ Error *local_err = NULL;
int fd = -1;
chr = g_malloc0(sizeof(CharDriverState));
s = g_malloc0(sizeof(NetCharDriver));
- fd = inet_dgram_opts(opts);
+ fd = inet_dgram_opts(opts, &local_err);
if (fd < 0) {
- fprintf(stderr, "inet_dgram_opts failed\n");
goto return_err;
}
return chr;
return_err:
+ if (local_err) {
+ qerror_report_err(local_err);
+ error_free(local_err);
+ }
g_free(chr);
g_free(s);
if (fd >= 0) {
if (fd < 0)
continue;
+#ifndef MSG_CMSG_CLOEXEC
+ qemu_set_cloexec(fd);
+#endif
if (s->msgfd != -1)
close(s->msgfd);
s->msgfd = fd;
struct cmsghdr cmsg;
char control[CMSG_SPACE(sizeof(int))];
} msg_control;
+ int flags = 0;
ssize_t ret;
iov[0].iov_base = buf;
msg.msg_control = &msg_control;
msg.msg_controllen = sizeof(msg_control);
- ret = recvmsg(s->fd, &msg, 0);
- if (ret > 0 && s->is_unix)
+#ifdef MSG_CMSG_CLOEXEC
+ flags |= MSG_CMSG_CLOEXEC;
+#endif
+ ret = recvmsg(s->fd, &msg, flags);
+ if (ret > 0 && s->is_unix) {
unix_process_msgfd(chr, &msg);
+ }
return ret;
}
TCPCharDriver *s = chr->opaque;
s->connected = 1;
- qemu_set_fd_handler2(s->fd, tcp_chr_read_poll,
- tcp_chr_read, NULL, chr);
+ if (s->fd >= 0) {
+ qemu_set_fd_handler2(s->fd, tcp_chr_read_poll,
+ tcp_chr_read, NULL, chr);
+ }
qemu_chr_generic_open(chr);
}
{
CharDriverState *chr = NULL;
TCPCharDriver *s = NULL;
+ Error *local_err = NULL;
int fd = -1;
int is_listen;
int is_waitconnect;
if (is_unix) {
if (is_listen) {
- fd = unix_listen_opts(opts);
+ fd = unix_listen_opts(opts, &local_err);
} else {
- fd = unix_connect_opts(opts);
+ fd = unix_connect_opts(opts, &local_err, NULL, NULL);
}
} else {
if (is_listen) {
- fd = inet_listen_opts(opts, 0, NULL);
+ fd = inet_listen_opts(opts, 0, &local_err);
} else {
- fd = inet_connect_opts(opts, NULL);
+ fd = inet_connect_opts(opts, &local_err, NULL, NULL);
}
}
if (fd < 0) {
return chr;
fail:
- if (fd >= 0)
+ if (local_err) {
+ qerror_report_err(local_err);
+ error_free(local_err);
+ }
+ if (fd >= 0) {
closesocket(fd);
+ }
g_free(s);
g_free(chr);
return NULL;