"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "chardev/char-socket.c" between
qemu-6.0.0-rc1.tar.xz and qemu-6.0.0-rc2.tar.xz

About: QEMU is a generic machine/processor emulator and virtualizer. Release candidate.

char-socket.c  (qemu-6.0.0-rc1.tar.xz):char-socket.c  (qemu-6.0.0-rc2.tar.xz)
skipping to change at line 405 skipping to change at line 405
static void remove_hup_source(SocketChardev *s) static void remove_hup_source(SocketChardev *s)
{ {
if (s->hup_source != NULL) { if (s->hup_source != NULL) {
g_source_destroy(s->hup_source); g_source_destroy(s->hup_source);
g_source_unref(s->hup_source); g_source_unref(s->hup_source);
s->hup_source = NULL; s->hup_source = NULL;
} }
} }
static void char_socket_yank_iochannel(void *opaque)
{
QIOChannel *ioc = QIO_CHANNEL(opaque);
qio_channel_shutdown(ioc, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
}
static void tcp_chr_free_connection(Chardev *chr) static void tcp_chr_free_connection(Chardev *chr)
{ {
SocketChardev *s = SOCKET_CHARDEV(chr); SocketChardev *s = SOCKET_CHARDEV(chr);
int i; int i;
if (s->read_msgfds_num) { if (s->read_msgfds_num) {
for (i = 0; i < s->read_msgfds_num; i++) { for (i = 0; i < s->read_msgfds_num; i++) {
close(s->read_msgfds[i]); close(s->read_msgfds[i]);
} }
g_free(s->read_msgfds); g_free(s->read_msgfds);
skipping to change at line 427 skipping to change at line 434
} }
remove_hup_source(s); remove_hup_source(s);
tcp_set_msgfds(chr, NULL, 0); tcp_set_msgfds(chr, NULL, 0);
remove_fd_in_watch(chr); remove_fd_in_watch(chr);
if (s->registered_yank && if (s->registered_yank &&
(s->state == TCP_CHARDEV_STATE_CONNECTING (s->state == TCP_CHARDEV_STATE_CONNECTING
|| s->state == TCP_CHARDEV_STATE_CONNECTED)) { || s->state == TCP_CHARDEV_STATE_CONNECTED)) {
yank_unregister_function(CHARDEV_YANK_INSTANCE(chr->label), yank_unregister_function(CHARDEV_YANK_INSTANCE(chr->label),
yank_generic_iochannel, char_socket_yank_iochannel,
QIO_CHANNEL(s->sioc)); QIO_CHANNEL(s->sioc));
} }
object_unref(OBJECT(s->sioc)); object_unref(OBJECT(s->sioc));
s->sioc = NULL; s->sioc = NULL;
object_unref(OBJECT(s->ioc)); object_unref(OBJECT(s->ioc));
s->ioc = NULL; s->ioc = NULL;
g_free(chr->filename); g_free(chr->filename);
chr->filename = NULL; chr->filename = NULL;
tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED); tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED);
} }
skipping to change at line 943 skipping to change at line 950
} }
sioc = qio_channel_socket_new_fd(fd, NULL); sioc = qio_channel_socket_new_fd(fd, NULL);
if (!sioc) { if (!sioc) {
return -1; return -1;
} }
tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING); tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
tcp_chr_set_client_ioc_name(chr, sioc); tcp_chr_set_client_ioc_name(chr, sioc);
if (s->registered_yank) { if (s->registered_yank) {
yank_register_function(CHARDEV_YANK_INSTANCE(chr->label), yank_register_function(CHARDEV_YANK_INSTANCE(chr->label),
yank_generic_iochannel, char_socket_yank_iochannel,
QIO_CHANNEL(sioc)); QIO_CHANNEL(sioc));
} }
ret = tcp_chr_new_client(chr, sioc); ret = tcp_chr_new_client(chr, sioc);
object_unref(OBJECT(sioc)); object_unref(OBJECT(sioc));
return ret; return ret;
} }
static void tcp_chr_accept(QIONetListener *listener, static void tcp_chr_accept(QIONetListener *listener,
QIOChannelSocket *cioc, QIOChannelSocket *cioc,
void *opaque) void *opaque)
{ {
Chardev *chr = CHARDEV(opaque); Chardev *chr = CHARDEV(opaque);
SocketChardev *s = SOCKET_CHARDEV(chr); SocketChardev *s = SOCKET_CHARDEV(chr);
tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING); tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
tcp_chr_set_client_ioc_name(chr, cioc); tcp_chr_set_client_ioc_name(chr, cioc);
if (s->registered_yank) { if (s->registered_yank) {
yank_register_function(CHARDEV_YANK_INSTANCE(chr->label), yank_register_function(CHARDEV_YANK_INSTANCE(chr->label),
yank_generic_iochannel, char_socket_yank_iochannel,
QIO_CHANNEL(cioc)); QIO_CHANNEL(cioc));
} }
tcp_chr_new_client(chr, cioc); tcp_chr_new_client(chr, cioc);
} }
static int tcp_chr_connect_client_sync(Chardev *chr, Error **errp) static int tcp_chr_connect_client_sync(Chardev *chr, Error **errp)
{ {
SocketChardev *s = SOCKET_CHARDEV(chr); SocketChardev *s = SOCKET_CHARDEV(chr);
QIOChannelSocket *sioc = qio_channel_socket_new(); QIOChannelSocket *sioc = qio_channel_socket_new();
tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING); tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
tcp_chr_set_client_ioc_name(chr, sioc); tcp_chr_set_client_ioc_name(chr, sioc);
if (qio_channel_socket_connect_sync(sioc, s->addr, errp) < 0) { if (qio_channel_socket_connect_sync(sioc, s->addr, errp) < 0) {
tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED); tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED);
object_unref(OBJECT(sioc)); object_unref(OBJECT(sioc));
return -1; return -1;
} }
if (s->registered_yank) { if (s->registered_yank) {
yank_register_function(CHARDEV_YANK_INSTANCE(chr->label), yank_register_function(CHARDEV_YANK_INSTANCE(chr->label),
yank_generic_iochannel, char_socket_yank_iochannel,
QIO_CHANNEL(sioc)); QIO_CHANNEL(sioc));
} }
tcp_chr_new_client(chr, sioc); tcp_chr_new_client(chr, sioc);
object_unref(OBJECT(sioc)); object_unref(OBJECT(sioc));
return 0; return 0;
} }
static void tcp_chr_accept_server_sync(Chardev *chr) static void tcp_chr_accept_server_sync(Chardev *chr)
{ {
SocketChardev *s = SOCKET_CHARDEV(chr); SocketChardev *s = SOCKET_CHARDEV(chr);
QIOChannelSocket *sioc; QIOChannelSocket *sioc;
info_report("QEMU waiting for connection on: %s", info_report("QEMU waiting for connection on: %s",
chr->filename); chr->filename);
tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING); tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
sioc = qio_net_listener_wait_client(s->listener); sioc = qio_net_listener_wait_client(s->listener);
tcp_chr_set_client_ioc_name(chr, sioc); tcp_chr_set_client_ioc_name(chr, sioc);
if (s->registered_yank) { if (s->registered_yank) {
yank_register_function(CHARDEV_YANK_INSTANCE(chr->label), yank_register_function(CHARDEV_YANK_INSTANCE(chr->label),
yank_generic_iochannel, char_socket_yank_iochannel,
QIO_CHANNEL(sioc)); QIO_CHANNEL(sioc));
} }
tcp_chr_new_client(chr, sioc); tcp_chr_new_client(chr, sioc);
object_unref(OBJECT(sioc)); object_unref(OBJECT(sioc));
} }
static int tcp_chr_wait_connected(Chardev *chr, Error **errp) static int tcp_chr_wait_connected(Chardev *chr, Error **errp)
{ {
SocketChardev *s = SOCKET_CHARDEV(chr); SocketChardev *s = SOCKET_CHARDEV(chr);
const char *opts[] = { "telnet", "tn3270", "websock", "tls-creds" }; const char *opts[] = { "telnet", "tn3270", "websock", "tls-creds" };
skipping to change at line 1113 skipping to change at line 1120
if (s->listener) { if (s->listener) {
qio_net_listener_set_client_func_full(s->listener, NULL, NULL, qio_net_listener_set_client_func_full(s->listener, NULL, NULL,
NULL, chr->gcontext); NULL, chr->gcontext);
object_unref(OBJECT(s->listener)); object_unref(OBJECT(s->listener));
} }
if (s->tls_creds) { if (s->tls_creds) {
object_unref(OBJECT(s->tls_creds)); object_unref(OBJECT(s->tls_creds));
} }
g_free(s->tls_authz); g_free(s->tls_authz);
if (s->registered_yank) { if (s->registered_yank) {
yank_unregister_instance(CHARDEV_YANK_INSTANCE(chr->label)); /*
* In the chardev-change special-case, we shouldn't unregister the yank
* instance, as it still may be needed.
*/
if (!chr->handover_yank_instance) {
yank_unregister_instance(CHARDEV_YANK_INSTANCE(chr->label));
}
} }
qemu_chr_be_event(chr, CHR_EVENT_CLOSED); qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
} }
static void qemu_chr_socket_connected(QIOTask *task, void *opaque) static void qemu_chr_socket_connected(QIOTask *task, void *opaque)
{ {
QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task)); QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task));
Chardev *chr = CHARDEV(opaque); Chardev *chr = CHARDEV(opaque);
SocketChardev *s = SOCKET_CHARDEV(chr); SocketChardev *s = SOCKET_CHARDEV(chr);
Error *err = NULL; Error *err = NULL;
s->connect_task = NULL; s->connect_task = NULL;
if (qio_task_propagate_error(task, &err)) { if (qio_task_propagate_error(task, &err)) {
tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED); tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED);
if (s->registered_yank) { if (s->registered_yank) {
yank_unregister_function(CHARDEV_YANK_INSTANCE(chr->label), yank_unregister_function(CHARDEV_YANK_INSTANCE(chr->label),
yank_generic_iochannel, char_socket_yank_iochannel,
QIO_CHANNEL(sioc)); QIO_CHANNEL(sioc));
} }
check_report_connect_error(chr, err); check_report_connect_error(chr, err);
goto cleanup; goto cleanup;
} }
s->connect_err_reported = false; s->connect_err_reported = false;
tcp_chr_new_client(chr, sioc); tcp_chr_new_client(chr, sioc);
cleanup: cleanup:
skipping to change at line 1168 skipping to change at line 1181
static void tcp_chr_connect_client_async(Chardev *chr) static void tcp_chr_connect_client_async(Chardev *chr)
{ {
SocketChardev *s = SOCKET_CHARDEV(chr); SocketChardev *s = SOCKET_CHARDEV(chr);
QIOChannelSocket *sioc; QIOChannelSocket *sioc;
tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING); tcp_chr_change_state(s, TCP_CHARDEV_STATE_CONNECTING);
sioc = qio_channel_socket_new(); sioc = qio_channel_socket_new();
tcp_chr_set_client_ioc_name(chr, sioc); tcp_chr_set_client_ioc_name(chr, sioc);
if (s->registered_yank) { if (s->registered_yank) {
yank_register_function(CHARDEV_YANK_INSTANCE(chr->label), yank_register_function(CHARDEV_YANK_INSTANCE(chr->label),
yank_generic_iochannel, char_socket_yank_iochannel,
QIO_CHANNEL(sioc)); QIO_CHANNEL(sioc));
} }
/* /*
* Normally code would use the qio_channel_socket_connect_async * Normally code would use the qio_channel_socket_connect_async
* method which uses a QIOTask + qio_task_set_error internally * method which uses a QIOTask + qio_task_set_error internally
* to avoid blocking. The tcp_chr_wait_connected method, however, * to avoid blocking. The tcp_chr_wait_connected method, however,
* needs a way to synchronize with completion of the background * needs a way to synchronize with completion of the background
* connect task which can't be done with the QIOChannelSocket * connect task which can't be done with the QIOChannelSocket
* async APIs. Thus we must use QIOTask directly to implement * async APIs. Thus we must use QIOTask directly to implement
* the non-blocking concept locally. * the non-blocking concept locally.
skipping to change at line 1405 skipping to change at line 1418
if (!qmp_chardev_validate_socket(sock, addr, errp)) { if (!qmp_chardev_validate_socket(sock, addr, errp)) {
return; return;
} }
qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_RECONNECTABLE); qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_RECONNECTABLE);
/* TODO SOCKET_ADDRESS_FD where fd has AF_UNIX */ /* TODO SOCKET_ADDRESS_FD where fd has AF_UNIX */
if (addr->type == SOCKET_ADDRESS_TYPE_UNIX) { if (addr->type == SOCKET_ADDRESS_TYPE_UNIX) {
qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_FD_PASS); qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_FD_PASS);
} }
if (!yank_register_instance(CHARDEV_YANK_INSTANCE(chr->label), errp)) { /*
return; * In the chardev-change special-case, we shouldn't register a new yank
* instance, as there already may be one.
*/
if (!chr->handover_yank_instance) {
if (!yank_register_instance(CHARDEV_YANK_INSTANCE(chr->label), errp)) {
return;
}
} }
s->registered_yank = true; s->registered_yank = true;
/* be isn't opened until we get a connection */ /* be isn't opened until we get a connection */
*be_opened = false; *be_opened = false;
update_disconnected_filename(s); update_disconnected_filename(s);
if (s->is_listen) { if (s->is_listen) {
if (qmp_chardev_open_socket_server(chr, is_telnet || is_tn3270, if (qmp_chardev_open_socket_server(chr, is_telnet || is_tn3270,
skipping to change at line 1548 skipping to change at line 1567
{ {
SocketChardev *s = SOCKET_CHARDEV(obj); SocketChardev *s = SOCKET_CHARDEV(obj);
return s->state == TCP_CHARDEV_STATE_CONNECTED; return s->state == TCP_CHARDEV_STATE_CONNECTED;
} }
static void char_socket_class_init(ObjectClass *oc, void *data) static void char_socket_class_init(ObjectClass *oc, void *data)
{ {
ChardevClass *cc = CHARDEV_CLASS(oc); ChardevClass *cc = CHARDEV_CLASS(oc);
cc->supports_yank = true;
cc->parse = qemu_chr_parse_socket; cc->parse = qemu_chr_parse_socket;
cc->open = qmp_chardev_open_socket; cc->open = qmp_chardev_open_socket;
cc->chr_wait_connected = tcp_chr_wait_connected; cc->chr_wait_connected = tcp_chr_wait_connected;
cc->chr_write = tcp_chr_write; cc->chr_write = tcp_chr_write;
cc->chr_sync_read = tcp_chr_sync_read; cc->chr_sync_read = tcp_chr_sync_read;
cc->chr_disconnect = tcp_chr_disconnect; cc->chr_disconnect = tcp_chr_disconnect;
cc->get_msgfds = tcp_get_msgfds; cc->get_msgfds = tcp_get_msgfds;
cc->set_msgfds = tcp_set_msgfds; cc->set_msgfds = tcp_set_msgfds;
cc->chr_add_client = tcp_chr_add_client; cc->chr_add_client = tcp_chr_add_client;
cc->chr_add_watch = tcp_chr_add_watch; cc->chr_add_watch = tcp_chr_add_watch;
 End of changes. 11 change blocks. 
10 lines changed or deleted 31 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)