summaryrefslogtreecommitdiff
path: root/src
AgeCommit message (Collapse)AuthorFilesLines
2020-03-09udscs-server: split initializationJakub Janků3-78/+38
Divide creation of udscs_server into 2 steps: 1) udscs_server_new() - allocates new udscs_server struct and inits it 2) udscs_server_listen_to_fd(), udscs_server_listen_to_address() - starts accepting new connections Remove udscs_create_server() and udscs_create_server_for_fd(). This makes the code a bit shorter and nicer. Signed-off-by: Jakub Janků <jjanku@redhat.com> Acked-by: Victor Toso <victortoso@redhat.com>
2020-03-09virtio: use GObject macroJakub Janků3-40/+25
Use G_DECLARE_FINAL_TYPE(). Rename struct vdagent_virtio_port --> VirtioPort Signed-off-by: Jakub Janků <jjanku@redhat.com> Acked-by: Victor Toso <victortoso@redhat.com>
2020-03-09udscs: use GObject macroJakub Janků11-54/+36
Use G_DECLARE_FINAL_TYPE(). Rename struct udscs_connection --> UdscsConnection Signed-off-by: Jakub Janků <jjanku@redhat.com> Acked-by: Victor Toso <victortoso@redhat.com>
2020-03-09introduce VDAgentConnectionJakub Janků8-937/+912
1) VDAgentConnection Add vdagent-connection.{c,h} files, define a new derivable class VDAgentConnection. VDAgentConnection uses GIO and therefore integrates well with GMainLoop. Read messages must begin with a header of a fixed size. Message body size can vary. Note: vdagent_connection_destroy() cancels ongoing I/O-ops and closes the underlying FD. However, the I/O-ops do not finish immediately, but asynchronously in the next iteration of the main loop. At the beginning of each op, VDAgentConnection is referenced, so the object isn't finalized until the ops themselves finish. To solve this, call g_main_context_iteration() before the agent exits. 2) udscs Make udscs_connection a subclass of VDAgentConnection. Rewrite udscs_server using GSocketService. Use GList to store server's connections. Drop support for select(), remove: * udscs_server_fill_fds() * udscs_server_handle_fds() Remove udscs_{set,get}_user_data(). Custom data can be associated with the GObject using g_object_set_data(). 3) virtio_port Make vdagent_virtio_port a subclass of VDAgentConnection. Drop support for select(), remove: * vdagent_virtio_port_fill_fds() * vdagent_virtio_port_handle_fds() 4) vdagentd Replace the main_loop() with a GMainLoop. Use g_unix_signal_add() to handle SIGINT, SIGHUP, SIGTERM. SIGQUIT handling is not supported by GLib. Integrate the session_info into the loop using GIOChannel and g_io_add_watch(). Signed-off-by: Jakub Janků <jjanku@redhat.com> Acked-by: Victor Toso <victortoso@redhat.com>
2020-03-06clipboard: implement CAP_CLIPBOARD_GRAB_SERIALMarc-André Lureau1-1/+39
Implement the behaviour described in protocol "vdagent: introduce VD_AGENT_CAP_CLIPBOARD_GRAB_SERIAL". Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Acked-by: Victor Toso <victortoso@redhat.com>
2020-03-06clipboard: only send release when no immediate grabMarc-André Lureau3-10/+10
Do not send a release event between two grabs, this helps with window manager interaction issues on peer side. Advertise this behaviour via a capability introduced in spice-protocol 0.12.16, so the client doesn't need to do some time-based filtering. (the capability shouldn't need to be negotiated, a client shouldn't expect a release between two grabs) Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Acked-by: Victor Toso <victortoso@redhat.com>
2020-03-06clipboard: filter out only our own eventsMarc-André Lureau1-4/+6
Do not rely on internal state when receiving clipboard events, as this may race with external events. Use gtk_clipboard_set_with_owner() Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Acked-by: Victor Toso <victortoso@redhat.com>
2020-03-06clipboard: gobject-ify VDAgentClipboardsMarc-André Lureau3-30/+56
This will allow easier lifecycle management, and usage of gtk_clipboard_set_with_owner() Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Acked-by: Victor Toso <victortoso@redhat.com>
2020-03-06vdagent: use G_OPTION_FLAG_NONEMarc-André Lureau1-15/+22
Improve readability a bit, reindent slightly. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Acked-by: Victor Toso <victortoso@redhat.com>
2020-03-06clipboard: remove vdagent-selection-id usageMarc-André Lureau1-9/+20
Modernize a bit the code, using gtk_clipboard_get_selection(). Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Acked-by: Victor Toso <victortoso@redhat.com>
2019-10-17vdagentd: Fix session lookup for new GNOME versionsBenjamin Berg1-4/+55
New GNOME versions have started to manage the session using the systemd user instance. The effect of this is that the spice-vdagent running in the user session is forked off (indirectly) from the systemd user instance and does technically not belong to any session. The correct way of handling this situation is to simply assume that the process belongs to the users graphical session. Add a heuristic to find the graphical session based on the UID, fixing spice-vdagent running on GNOME 3.34 with systemd integration. Acked-by: Victor Toso <victortoso@redhat.com>
2019-08-31virtio-port: handle_fds: make read and write code consistentUri Lublin1-5/+5
A comment and curly brackets for style were added. Signed-off-by: Uri Lublin <uril@redhat.com> Acked-by: Frediano Ziglio <fziglio@redhat.com>
2019-08-28covscan: add comment on false-positive on g_memdup()Victor Toso1-4/+2
Previous commit set last element of orig_argv array to NULL. That's redundant as g_memdup() uses memcpy() and it would do just that. Add a comment that the reason for this change is to workaround clang's warning. Suggested by Uri. Signed-off-by: Victor Toso <victortoso@redhat.com> Acked-by: Uri Lublin <uril@redhat.com>
2019-08-27covscan: initialize argv's copyVictor Toso1-1/+4
Otherwise we get a CLANG_WARNING due accessing garbage. Covscan report: > spice-vdagent-0.19.0/src/vdagent/vdagent.c:471:9: warning: 1st function call argument is an uninitialized value > # execvp(orig_argv[0], orig_argv); > # ^ ~~~~~~~~~~~~ > spice-vdagent-0.19.0/src/vdagent/vdagent.c:421:24: note: Storing uninitialized value > # char **orig_argv = g_memdup(argv, sizeof(char*) * (argc+1)); > # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > spice-vdagent-0.19.0/src/vdagent/vdagent.c:434:9: note: Assuming 'error' is equal to NULL > # if (error != NULL) { > # ^~~~~~~~~~~~~ > spice-vdagent-0.19.0/src/vdagent/vdagent.c:434:5: note: Taking false branch > # if (error != NULL) { > # ^ > spice-vdagent-0.19.0/src/vdagent/vdagent.c:442:9: note: Assuming 'portdev' is not equal to NULL > # if (portdev == NULL) > # ^~~~~~~~~~~~~~~ > spice-vdagent-0.19.0/src/vdagent/vdagent.c:442:5: note: Taking false branch > # if (portdev == NULL) > # ^ > spice-vdagent-0.19.0/src/vdagent/vdagent.c:445:9: note: Assuming 'vdagentd_socket' is not equal to NULL > # if (vdagentd_socket == NULL) > # ^~~~~~~~~~~~~~~~~~~~~~~ > spice-vdagent-0.19.0/src/vdagent/vdagent.c:445:5: note: Taking false branch > # if (vdagentd_socket == NULL) > # ^ > spice-vdagent-0.19.0/src/vdagent/vdagent.c:448:30: note: Assuming 'do_daemonize' is 0 > # openlog("spice-vdagent", do_daemonize ? LOG_PID : (LOG_PID | LOG_PERROR), > # ^~~~~~~~~~~~ > spice-vdagent-0.19.0/src/vdagent/vdagent.c:448:30: note: '?' condition is false > spice-vdagent-0.19.0/src/vdagent/vdagent.c:451:9: note: Assuming the condition is false > # if (!g_file_test(portdev, G_FILE_TEST_EXISTS)) { > # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > spice-vdagent-0.19.0/src/vdagent/vdagent.c:451:5: note: Taking false branch > # if (!g_file_test(portdev, G_FILE_TEST_EXISTS)) { > # ^ > spice-vdagent-0.19.0/src/vdagent/vdagent.c:457:9: note: Assuming 'do_daemonize' is 0 > # if (do_daemonize) > # ^~~~~~~~~~~~ > spice-vdagent-0.19.0/src/vdagent/vdagent.c:457:5: note: Taking false branch > # if (do_daemonize) > # ^ > spice-vdagent-0.19.0/src/vdagent/vdagent.c:468:9: note: Assuming 'version_mismatch' is not equal to 0 > # if (version_mismatch) { > # ^~~~~~~~~~~~~~~~ > spice-vdagent-0.19.0/src/vdagent/vdagent.c:468:5: note: Taking true branch > # if (version_mismatch) { > # ^ > spice-vdagent-0.19.0/src/vdagent/vdagent.c:471:9: note: 1st function call argument is an uninitialized value > # execvp(orig_argv[0], orig_argv); > # ^ ~~~~~~~~~~~~ > # 469| syslog(LOG_INFO, "Version mismatch, restarting"); > # 470| sleep(1); > # 471|-> execvp(orig_argv[0], orig_argv); > # 472| } > # 473| Signed-off-by: Victor Toso <victortoso@redhat.com> Acked-by: Uri Lublin <uril@redhat.com>
2019-08-27covscan: avoid false positive on g_clear_pointer()Victor Toso1-1/+2
This is a CLANG_WARNING found by covscan. It is a false positive as g_clear_pointer() does set vportp to NULL, meaning that the situation described by covscan below should not be reached. Moving away from g_clear_pointer() in this specific case just to make our tool happy. Covscan report: > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:458:9: warning: Use of memory after it is freed > # if (wbuf->write_pos != wbuf->size) { > # ^ > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:268:12: note: Assuming the condition is true > # while (*vportp && (*vportp)->write_buf) > # ^~~~~~~ > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:268:12: note: Left side of '&&' is true > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:268:5: note: Loop condition is true. Entering loop body > # while (*vportp && (*vportp)->write_buf) > # ^ > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:269:9: note: Calling 'vdagent_virtio_port_do_write' > # vdagent_virtio_port_do_write(vportp); > # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:453:5: note: Taking false branch > # if (!wbuf) { > # ^ > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:458:9: note: Assuming the condition is false > # if (wbuf->write_pos != wbuf->size) { > # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:458:5: note: Taking false branch > # if (wbuf->write_pos != wbuf->size) { > # ^ > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:465:9: note: Assuming 'n' is < 0 > # if (n < 0) { > # ^~~~~ > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:465:5: note: Taking true branch > # if (n < 0) { > # ^ > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:466:13: note: Assuming the condition is false > # if (errno == EINTR) > # ^~~~~~~~~~~~~~ > /usr/include/errno.h:38:16: note: expanded from macro 'errno' > ## define errno (*__errno_location ()) > # ^ > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:466:9: note: Taking false branch > # if (errno == EINTR) > # ^ > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:469:9: note: Calling 'vdagent_virtio_port_destroy' > # vdagent_virtio_port_destroy(vportp); > # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:130:5: note: Taking false branch > # if (!vport) > # ^ > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:133:9: note: Assuming the condition is false > # if (vport->disconnect_callback) > # ^~~~~~~~~~~~~~~~~~~~~~~~~~ > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:133:5: note: Taking false branch > # if (vport->disconnect_callback) > # ^ > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:137:5: note: Loop condition is true. Entering loop body > # while (wbuf) { > # ^ > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:140:9: note: Memory is released > # g_free(wbuf); > # ^~~~~~~~~~~~ > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:137:5: note: Loop condition is false. Execution continues on line 144 > # while (wbuf) { > # ^ > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:144:5: note: Loop condition is true. Entering loop body > # for (i = 0; i < VDP_END_PORT; i++) { > # ^ > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:144:5: note: Loop condition is true. Entering loop body > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:144:5: note: Loop condition is true. Entering loop body > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:144:5: note: Loop condition is false. Execution continues on line 148 > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:149:5: note: Assuming '_p' is null > # g_clear_pointer(vportp, g_free); > # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > /usr/include/glib-2.0/glib/gmem.h:124:9: note: expanded from macro 'g_clear_pointer' > # if (_p) \ > # ^~ > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:149:5: note: Taking false branch > /usr/include/glib-2.0/glib/gmem.h:124:5: note: expanded from macro 'g_clear_pointer' > # if (_p) \ > # ^ > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:149:5: note: Loop condition is false. Exiting loop > /usr/include/glib-2.0/glib/gmem.h:114:3: note: expanded from macro 'g_clear_pointer' > # G_STMT_START { \ > # ^ > /usr/include/glib-2.0/glib/gmacros.h:346:23: note: expanded from macro 'G_STMT_START' > ##define G_STMT_START do > # ^ > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:469:9: note: Returning; memory was released > # vdagent_virtio_port_destroy(vportp); > # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:269:9: note: Returning; memory was released > # vdagent_virtio_port_do_write(vportp); > # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:268:12: note: Left side of '&&' is true > # while (*vportp && (*vportp)->write_buf) > # ^ > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:268:5: note: Loop condition is true. Entering loop body > # while (*vportp && (*vportp)->write_buf) > # ^ > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:269:9: note: Calling 'vdagent_virtio_port_do_write' > # vdagent_virtio_port_do_write(vportp); > # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:453:5: note: Taking false branch > # if (!wbuf) { > # ^ > spice-vdagent-0.19.0/src/vdagentd/virtio-port.c:458:9: note: Use of memory after it is freed > # if (wbuf->write_pos != wbuf->size) { > # ^~~~~~~~~~~~~~~ > # 456| } > # 457| > # 458|-> if (wbuf->write_pos != wbuf->size) { > # 459| syslog(LOG_ERR, "do_write: buffer is incomplete!!"); > # 460| return; Signed-off-by: Victor Toso <victortoso@redhat.com> Acked-by: Frediano Ziglio <fziglio@redhat.com>
2019-07-24x11: Change check to make code scanners not giving warningFrediano Ziglio1-4/+2
Some code scanners (both Coverity and clang one) report that prev_sel/prev_cond could be unreferenced while NULL. Change condition to make clear a NULL pointer is not used. Signed-off-by: Frediano Ziglio <fziglio@redhat.com> Acked-by: Victor Toso <victortoso@redhat.com>
2019-07-24device-info: remove g_list_length() on compare_addresses()Victor Toso1-5/+7
The g_list_length() function does iterate over both lists to compare its length. Considering that we use this to check for true/false and we will iterate again on both lists, we can do so once. This also avoids covscan/clang warnings: | spice-vdagent-0.19.0/src/vdagent/device-info.c:216:27: warning: Access to field 'data' results in a dereference of a null pointer (loaded from variable 'lb') | # PciDevice *devb = lb->data; | # ^ | spice-vdagent-0.19.0/src/vdagent/device-info.c:397:5: note: Taking false branch | # if (!user_pci_addr) { | # ^ | spice-vdagent-0.19.0/src/vdagent/device-info.c:407:22: note: Calling 'find_device_at_pci_address' | # char *dev_path = find_device_at_pci_address(user_pci_addr, &vendor_id, &device_id); | # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | spice-vdagent-0.19.0/src/vdagent/device-info.c:329:5: note: Taking true branch | # g_return_val_if_fail(pci_addr != NULL, NULL); | # ^ | /usr/include/glib-2.0/glib/gmessages.h:594:9: note: expanded from macro 'g_return_val_if_fail' | # if G_LIKELY(expr) { } else \ | # ^ | /usr/include/glib-2.0/glib/gmacros.h:385:43: note: expanded from macro 'G_LIKELY' | ##define G_LIKELY(expr) (__builtin_expect (_G_BOOLEAN_EXPR((expr)), 1)) | # ^ | /usr/include/glib-2.0/glib/gmacros.h:379:4: note: expanded from macro '_G_BOOLEAN_EXPR' | # if (expr) \ | # ^ | spice-vdagent-0.19.0/src/vdagent/device-info.c:329:5: note: Taking true branch | /usr/include/glib-2.0/glib/gmessages.h:594:6: note: expanded from macro 'g_return_val_if_fail' | # if G_LIKELY(expr) { } else \ | # ^ | spice-vdagent-0.19.0/src/vdagent/device-info.c:329:5: note: Loop condition is false. Exiting loop | /usr/include/glib-2.0/glib/gmessages.h:593:40: note: expanded from macro 'g_return_val_if_fail' | ##define g_return_val_if_fail(expr,val) G_STMT_START{ \ | # ^ | /usr/include/glib-2.0/glib/gmacros.h:346:23: note: expanded from macro 'G_STMT_START' | ##define G_STMT_START do | # ^ | spice-vdagent-0.19.0/src/vdagent/device-info.c:330:5: note: Taking true branch | # g_return_val_if_fail(device_id != NULL, NULL); | # ^ | /usr/include/glib-2.0/glib/gmessages.h:594:9: note: expanded from macro 'g_return_val_if_fail' | # if G_LIKELY(expr) { } else \ | # ^ | /usr/include/glib-2.0/glib/gmacros.h:385:43: note: expanded from macro 'G_LIKELY' | ##define G_LIKELY(expr) (__builtin_expect (_G_BOOLEAN_EXPR((expr)), 1)) | # ^ | /usr/include/glib-2.0/glib/gmacros.h:379:4: note: expanded from macro '_G_BOOLEAN_EXPR' | # if (expr) \ | # ^ | spice-vdagent-0.19.0/src/vdagent/device-info.c:330:5: note: Taking true branch | /usr/include/glib-2.0/glib/gmessages.h:594:6: note: expanded from macro 'g_return_val_if_fail' | # if G_LIKELY(expr) { } else \ | # ^ | spice-vdagent-0.19.0/src/vdagent/device-info.c:330:5: note: Loop condition is false. Exiting loop | /usr/include/glib-2.0/glib/gmessages.h:593:40: note: expanded from macro 'g_return_val_if_fail' | ##define g_return_val_if_fail(expr,val) G_STMT_START{ \ | # ^ | /usr/include/glib-2.0/glib/gmacros.h:346:23: note: expanded from macro 'G_STMT_START' | ##define G_STMT_START do | # ^ | spice-vdagent-0.19.0/src/vdagent/device-info.c:331:5: note: Taking true branch | # g_return_val_if_fail(vendor_id != NULL, NULL); | # ^ | /usr/include/glib-2.0/glib/gmessages.h:594:9: note: expanded from macro 'g_return_val_if_fail' | # if G_LIKELY(expr) { } else \ | # ^ | /usr/include/glib-2.0/glib/gmacros.h:385:43: note: expanded from macro 'G_LIKELY' | ##define G_LIKELY(expr) (__builtin_expect (_G_BOOLEAN_EXPR((expr)), 1)) | # ^ | /usr/include/glib-2.0/glib/gmacros.h:379:4: note: expanded from macro '_G_BOOLEAN_EXPR' | # if (expr) \ | # ^ | spice-vdagent-0.19.0/src/vdagent/device-info.c:331:5: note: Taking true branch | /usr/include/glib-2.0/glib/gmessages.h:594:6: note: expanded from macro 'g_return_val_if_fail' | # if G_LIKELY(expr) { } else \ | # ^ | spice-vdagent-0.19.0/src/vdagent/device-info.c:331:5: note: Loop condition is false. Exiting loop | /usr/include/glib-2.0/glib/gmessages.h:593:40: note: expanded from macro 'g_return_val_if_fail' | ##define g_return_val_if_fail(expr,val) G_STMT_START{ \ | # ^ | /usr/include/glib-2.0/glib/gmacros.h:346:23: note: expanded from macro 'G_STMT_START' | ##define G_STMT_START do | # ^ | spice-vdagent-0.19.0/src/vdagent/device-info.c:334:5: note: Loop condition is true. Entering loop body | # for (int i = 0; i < 10; ++i) { | # ^ | spice-vdagent-0.19.0/src/vdagent/device-info.c:340:13: note: Assuming the condition is false | # if (stat(dev_path, &buf) != 0) { | # ^~~~~~~~~~~~~~~~~~~~~~~~~ | spice-vdagent-0.19.0/src/vdagent/device-info.c:340:9: note: Taking false branch | # if (stat(dev_path, &buf) != 0) { | # ^ | spice-vdagent-0.19.0/src/vdagent/device-info.c:355:13: note: Assuming the condition is false | # if (realpath(sys_path, device_link) == NULL) { | # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | spice-vdagent-0.19.0/src/vdagent/device-info.c:355:9: note: Taking false branch | # if (realpath(sys_path, device_link) == NULL) { | # ^ | spice-vdagent-0.19.0/src/vdagent/device-info.c:361:36: note: Calling 'parse_pci_address_from_sysfs_path' | # PciAddress *drm_pci_addr = parse_pci_address_from_sysfs_path(device_link); | # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | spice-vdagent-0.19.0/src/vdagent/device-info.c:129:9: note: Assuming 'pos' is non-null | # if (!pos) { | # ^~~~ | spice-vdagent-0.19.0/src/vdagent/device-info.c:129:5: note: Taking false branch | # if (!pos) { | # ^ | spice-vdagent-0.19.0/src/vdagent/device-info.c:136:9: note: Assuming 'pos' is non-null | # if (!pos) { | # ^~~~ | spice-vdagent-0.19.0/src/vdagent/device-info.c:136:5: note: Taking false branch | # if (!pos) { | # ^ | spice-vdagent-0.19.0/src/vdagent/device-info.c:142:9: note: Assuming 'pos' is non-null | # if (!pos) { | # ^~~~ | spice-vdagent-0.19.0/src/vdagent/device-info.c:142:5: note: Taking false branch | # if (!pos) { | # ^ | spice-vdagent-0.19.0/src/vdagent/device-info.c:146:27: note: Calling 'pci_address_new' | # PciAddress *address = pci_address_new(); | # ^~~~~~~~~~~~~~~~~ | spice-vdagent-0.19.0/src/vdagent/device-info.c:61:12: note: Taking false branch | # return g_new0(PciAddress, 1); | # ^ | /usr/include/glib-2.0/glib/gmem.h:279:42: note: expanded from macro 'g_new0' | ##define g_new0(struct_type, n_structs) _G_NEW (struct_type, n_structs, malloc0) | # ^ | /usr/include/glib-2.0/glib/gmem.h:211:4: note: expanded from macro '_G_NEW' | # if (__s == 1) \ | # ^ | spice-vdagent-0.19.0/src/vdagent/device-info.c:61:12: note: Left side of '&&' is false | /usr/include/glib-2.0/glib/gmem.h:279:42: note: expanded from macro 'g_new0' | ##define g_new0(struct_type, n_structs) _G_NEW (struct_type, n_structs, malloc0) | # ^ | /usr/include/glib-2.0/glib/gmem.h:213:40: note: expanded from macro '_G_NEW' | # else if (__builtin_constant_p (__n) && \ | # ^ | spice-vdagent-0.19.0/src/vdagent/device-info.c:61:12: note: Null pointer value stored to field 'devices' | # return g_new0(PciAddress, 1); | # ^~~~~~~~~~~~~~~~~~~~~ | /usr/include/glib-2.0/glib/gmem.h:279:42: note: expanded from macro 'g_new0' | ##define g_new0(struct_type, n_structs) _G_NEW (struct_type, n_structs, malloc0) | # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | /usr/include/glib-2.0/glib/gmem.h:217:12: note: expanded from macro '_G_NEW' | # __p = g_##func##_n (__n, __s); \ | # ^~~~~~~~~~~~~~~~~~~~~~~ | <scratch space>:76:1: note: expanded from here | #g_malloc0_n | #^ | spice-vdagent-0.19.0/src/vdagent/device-info.c:146:27: note: Returning from 'pci_address_new' | # PciAddress *address = pci_address_new(); | # ^~~~~~~~~~~~~~~~~ | spice-vdagent-0.19.0/src/vdagent/device-info.c:149:5: note: Loop condition is true. Entering loop body | # while (pos) { | # ^ | spice-vdagent-0.19.0/src/vdagent/device-info.c:150:26: note: Taking false branch | # PciDevice *dev = g_new0(PciDevice, 1); | # ^ | /usr/include/glib-2.0/glib/gmem.h:279:42: note: expanded from macro 'g_new0' | ##define g_new0(struct_type, n_structs) _G_NEW (struct_type, n_structs, malloc0) | # ^ | /usr/include/glib-2.0/glib/gmem.h:211:4: note: expanded from macro '_G_NEW' | # if (__s == 1) \ | # ^ | spice-vdagent-0.19.0/src/vdagent/device-info.c:150:26: note: Left side of '&&' is false | /usr/include/glib-2.0/glib/gmem.h:279:42: note: expanded from macro 'g_new0' | ##define g_new0(struct_type, n_structs) _G_NEW (struct_type, n_structs, malloc0) | # ^ | /usr/include/glib-2.0/glib/gmem.h:213:40: note: expanded from macro '_G_NEW' | # else if (__builtin_constant_p (__n) && \ | # ^ | spice-vdagent-0.19.0/src/vdagent/device-info.c:152:9: note: Taking true branch | # if (!parse_pci_device(pos + 1, next, dev)) { | # ^ | spice-vdagent-0.19.0/src/vdagent/device-info.c:154:13: note: Execution continues on line 159 | # break; | # ^ | spice-vdagent-0.19.0/src/vdagent/device-info.c:361:36: note: Returning from 'parse_pci_address_from_sysfs_path' | # PciAddress *drm_pci_addr = parse_pci_address_from_sysfs_path(device_link); | # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | spice-vdagent-0.19.0/src/vdagent/device-info.c:362:9: note: Taking false branch | # if (!drm_pci_addr) { | # ^ | spice-vdagent-0.19.0/src/vdagent/device-info.c:367:14: note: Calling 'compare_addresses' | # if (!compare_addresses(pci_addr, drm_pci_addr)) { | # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | spice-vdagent-0.19.0/src/vdagent/device-info.c:207:11: note: Assuming the condition is true | # if (!(a->domain == b->domain | # ^~~~~~~~~~~~~~~~~~~~~~ | spice-vdagent-0.19.0/src/vdagent/device-info.c:207:11: note: Left side of '&&' is true | spice-vdagent-0.19.0/src/vdagent/device-info.c:208:12: note: Assuming the condition is true | # && g_list_length(a->devices) == g_list_length(b->devices))) { | # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | spice-vdagent-0.19.0/src/vdagent/device-info.c:207:5: note: Taking false branch | # if (!(a->domain == b->domain | # ^ | spice-vdagent-0.19.0/src/vdagent/device-info.c:212:35: note: 'lb' initialized to a null pointer value | # for (GList *la = a->devices, *lb = b->devices; | # ^~ | spice-vdagent-0.19.0/src/vdagent/device-info.c:213:10: note: Assuming 'la' is not equal to NULL | # la != NULL; | # ^~~~~~~~~~ | spice-vdagent-0.19.0/src/vdagent/device-info.c:212:5: note: Loop condition is true. Entering loop body | # for (GList *la = a->devices, *lb = b->devices; | # ^ | spice-vdagent-0.19.0/src/vdagent/device-info.c:216:27: note: Access to field 'data' results in a dereference of a null pointer (loaded from variable 'lb') | # PciDevice *devb = lb->data; | # ^~ | # 214| la = la->next, lb = lb->next) { | # 215| PciDevice *deva = la->data; | # 216|-> PciDevice *devb = lb->data; | # 217| | # 218| if (deva->slot != devb->slot Signed-off-by: Victor Toso <victortoso@redhat.com> Acked-by: Frediano Ziglio <fziglio@redhat.com>
2019-07-24x11: Constify XEvent argumentFrediano Ziglio1-11/+12
No reasons to have it mutable. Signed-off-by: Frediano Ziglio <fziglio@redhat.com> Acked-by: Victor Toso <victortoso@redhat.com>
2019-07-24x11: Avoid passing XEvent as valueFrediano Ziglio1-21/+21
The structure is not that small and is not necessary to copy the value. This also removed a Coverity warning. Signed-off-by: Frediano Ziglio <fziglio@redhat.com> Acked-by: Victor Toso <victortoso@redhat.com>
2019-07-24x11-randr: Avoid passing XEvent as valueFrediano Ziglio3-6/+6
The structure is not that small and is not necessary to copy the value. This also removed a Coverity warning. Signed-off-by: Frediano Ziglio <fziglio@redhat.com> Acked-by: Victor Toso <victortoso@redhat.com>
2019-07-19vdagent: simple fix for address-of-packed-memberVictor Toso1-2/+5
Seems to be a false positive but as this message only happens when user client connects, we can copy this array to make compiling warn free. > src/vdagent/vdagent.c: In function ‘daemon_read_complete’: > src/vdagent/vdagent.c:226:71: error: taking address of packed member of > ‘struct VDAgentAudioVolumeSync’ may result in an unaligned pointer > value [-Werror=address-of-packed-member] > 226 | vdagent_audio_playback_sync(avs->mute, avs->nchannels, avs->volume); > | ~~~^~~~~~~~ > src/vdagent/vdagent.c:228:69: error: taking address of packed member of > ‘struct VDAgentAudioVolumeSync’ may result in an unaligned pointer > value [-Werror=address-of-packed-member] > 228 | vdagent_audio_record_sync(avs->mute, avs->nchannels, avs->volume); > | ~~~^~~~~~~~ Signed-off-by: Victor Toso <victortoso@redhat.com> Acked-by: Frediano Ziglio <fziglio@redhat.com>
2019-07-19x11-randr: simplest fix for address-of-packed-memberVictor Toso1-7/+11
The struct type for width/height is uint32_t while we are trying to access and change it with int* - code can be improved a bit in following patches but this one fixes the warning by copying the value from the struct and copying back new value afterwards. Also: - Moved variables to internal scope; - Added braces to inner if; > src/vdagent/x11-randr.c: In function ‘zero_base_monitors’: > src/vdagent/x11-randr.c:621:28: error: taking address of packed member of > ‘struct VDAgentMonConfig’ may result in an unaligned pointer value > [-Werror=address-of-packed-member] > 621 | mon_width = (int *)&mon_config->monitors[i].width; > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > src/vdagent/x11-randr.c:622:29: error: taking address of packed member of > ‘struct VDAgentMonConfig’ may result in an unaligned pointer value > [-Werror=address-of-packed-member] > 622 | mon_height = (int *)&mon_config->monitors[i].height; > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Signed-off-by: Victor Toso <victortoso@redhat.com> Acked-by: Frediano Ziglio <fziglio@redhat.com>
2019-07-19x11-randr: use glib's MAX and MINVictor Toso1-14/+4
Since 2861868 "randr: remove monitors.xml on auto-configuration" in 2015-04-10 by Marc-Andre Lureau <marcandre.lureau@redhat.com> this file includes glib.h and can remove those helpers. Signed-off-by: Victor Toso <victortoso@redhat.com> Acked-by: Frediano Ziglio <fziglio@redhat.com>
2019-07-19vdagent: fix memory leak of g_memdup()Victor Toso1-0/+2
Found by covscan: | spice-vdagent-0.19.0/src/vdagent/vdagent.c:432:9: warning: Potential leak of memory pointed to by 'orig_argv' | # g_printerr("Invalid arguments, %s\n", error->message); | # ^ | spice-vdagent-0.19.0/src/vdagent/vdagent.c:418:24: note: Memory is allocated | # char **orig_argv = g_memdup(argv, sizeof(char*) * (argc+1)); | # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | spice-vdagent-0.19.0/src/vdagent/vdagent.c:431:9: note: Assuming 'error' is not equal to NULL | # if (error != NULL) { | # ^~~~~~~~~~~~~ | spice-vdagent-0.19.0/src/vdagent/vdagent.c:431:5: note: Taking true branch | # if (error != NULL) { | # ^ | spice-vdagent-0.19.0/src/vdagent/vdagent.c:432:9: note: Potential leak of memory pointed to by 'orig_argv' | # g_printerr("Invalid arguments, %s\n", error->message); | # ^ | # 430| | # 431| if (error != NULL) { | # 432|-> g_printerr("Invalid arguments, %s\n", error->message); | # 433| g_clear_error(&error); | # 434| return -1; Signed-off-by: Victor Toso <victortoso@redhat.com> Acked-by: Frediano Ziglio <fziglio@redhat.com>
2019-03-01Advertise VD_AGENT_CAP_GRAPHICS_DEVICE_INFOJonathon Jongsma1-0/+1
Since we now support the graphics device info message, advertise this fact when sending capabilities to the server. Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> Acked-by: Frediano Ziglio <fziglio@redhat.com>
2019-02-25x11: invalidate requests for targets on grab from clientJakub Janků2-0/+12
If XSetSelectionOwner() is invoked during the time we are waiting for the requested clipboard targets, the targets we eventually receive are no longer valid. To solve this, ignore the same count of target notifications as we expected at the time we received grab from the client. Otherwise we end up in a situation when vdagent holds the clipboard grab in the guest but cannot provide data to the apps that request it - this can be observed in the log: clipboard: received selection request event for target *, while not owning client clipboard Signed-off-by: Jakub Janků <jjanku@redhat.com> Acked-by: Victor Toso <victortoso@redhat.com>
2019-02-22clipboard: cancel request for targets on grab from clientJakub Janků1-1/+8
If gtk_clipboard_set_with_data() is invoked between gtk_clipboard_request_targets() and the GtkClipboardTargetsReceivedFunc callback, the targets we eventually receive are no longer valid. To solve this, cancel the request in vdagent_clipboard_grab(). Otherwise we end up in a situation when vdagent holds clipboard grab in the guest but cannot provide data to the apps that request it - this can be observed in the log: CRITICAL **: 20:48:55.782: clipboard_get_cb: assertion 'c->selections[sel_id].owner == OWNER_CLIENT' failed Signed-off-by: Jakub Janků <jjanku@redhat.com> Acked-by: Victor Toso <victortoso@redhat.com>
2019-01-31vdagent: Use g_file_test() instead of direct stat callChristophe Fergeau1-10/+1
vdagent.c has a 'file_test' function which tests for the existence of the /dev entry for the spicevmc channel. glib already provides such a g_file_test() function, so we can use it instead. Signed-off-by: Christophe Fergeau <cfergeau@redhat.com> Acked-by: Jakub Janků <jjanku@redhat.com>
2019-01-31vdagent: Silently ignore missing spicevmc deviceChristophe Fergeau1-2/+2
On most distros, spice-vdagent will be autostarted as part of the startup of the desktop environment session. This is done by spice-vdagent.desktop, which has no way of checking if we are in a virt environment with the needed devices present. Currently, if /dev/virtio-ports/com.redhat.spice.0 is missing, we log an error in syslog, and exit with an error exit code. This is too noisy when autostarting it on a bare metal machine which have no use for spice-vdagent. This reverts 0159111b to get rid of these warnings in the session's logs https://gitlab.freedesktop.org/spice/linux/vd_agent/issues/12 Signed-off-by: Christophe Fergeau <cfergeau@redhat.com> Acked-by: Frediano Ziglio <fziglio@redhat.com>
2019-01-30Fix coding styleJonathon Jongsma1-9/+19
Use brackets everywhere. Acked-by: Frediano Ziglio <fziglio@redhat.com>
2019-01-29Send device info to agent when it connectsJonathon Jongsma1-0/+15
Previously, the device info was only sent from the daemon to the session agent when we receive the device info message from the host. That means that if the session agent exits and reconnects, the session agent will not have the device info necessary to translate spice display IDs to guest device outputs. This patch saves the last device info message that was received from the host, and re-sends it to the session agent when it reconnects. NOTE: this may not be necessary if the server simply re-sends a device info message when it detects that the agent has connected... Acked-by: Lukáš Hrázký <lhrazky@redhat.com> Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
2019-01-29Send display_id down to the vdagentd daemonJonathon Jongsma3-30/+76
Add a display_id field to the structure that we use to send down the list of guest display resolutions to the vdagentd daemon. This allows us to map the spice display id to the proper X display for determining mouse locations, etc. In the case where we have an mjpeg plugin running in the streaming agent, we have two spice displays representing the same guest display. In that scenario, the session agent may maintain the following guest output mapping: spice channel 0 (QXL) => X output 0 spice channel 1 (streaming-agent) => X output 0 While this is not necessarily a supported scenario, it would be nice if the cursor input worked properly in this case. The root problem is that when the session agent sends down the guest xorg resolutions to the system daemon, it simply loops through the list of xorg displays, and for each X display it looks up the first spice display ID associated with it and sends that down to the daemon. In the scenario mentioned above, since there is only a single X display configured (albeit represented by two different spice displays), we would send down a single display resolution to the system daemon: - { width=1280, height=1024, x=0, y=0, display_id=0 } Notice that there is no entry for display_id=1. When the agent receives a cursor input message for display channel 1, that message will get passed to the systemn daemon, which will attempt to look up display_id 1 in order to convert the event coordinates to global coordinates. Finding no entry for display_id=1, the mouse events do not work. In this patch, when we want to send the guest resolutions down to the system daemon, we still loop through the list of X outputs, but for each output we also loop through the guest output mapping table and send a resolution structure down to the daemon for each registered output mapping. This means that in the previously mentioned scenario, we would send down the following information: - { width=1280, height=1024, x=0, y=0, display_id=0 } - { width=1280, height=1024, x=0, y=0, display_id=1 } This means that when the client sends a mouse event for display_id=1, the system daemon knows the coordinates of the guest display associated with that ID and can process the mouse event properly. Acked-by: Lukáš Hrázký <lhrazky@redhat.com> Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
2019-01-29Use new function in vdagent_x11_send_daemon_guest_xorg_res()Jonathon Jongsma1-12/+7
Rather than getting the current guest resolution in a VDAgentMonitorsConfig struct and then translating it to a new struct type for sending down to the daemon, simply use the new function that was factored out in a previous commit and populate the message struct directly. Acked-by: Lukáš Hrázký <lhrazky@redhat.com> Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
2019-01-29Factor a function out of get_current_mon_config()Jonathon Jongsma1-21/+53
When sending the guest xorg resolution to the vdagentd daemon, we get the current resolution with this function, which returns a VDAgentMonitorsConfig structure that must then be converted to the structure that we send to the daemon. Rather than re-using this function that returns the wrong type, factor out most of the functionality into a separate function. This function can be used by a new function to return a type appropriate for sending the xorg resolution to the daemon. This is necessary because in the next few commits I'll be changing the vdagentd protocol to send an additional display_id parameter to the daemon. Acked-by: Lukáš Hrázký <lhrazky@redhat.com> Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
2019-01-29Use guest output map to determine xrandr outputJonathon Jongsma1-9/+72
instead of using the spice display id directly as the xrandr output, look it up using our new guest output map Acked-by: Lukáš Hrázký <lhrazky@redhat.com> Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
2019-01-29Make clearer distinctions between output idsJonathon Jongsma1-25/+25
There are basically three ways to refer to an output within vdagent: - The index of the array of MonitorConfig message. This is essentially a "spice display id" - the index of the array of xrandr outputs. This is the "output index" - the xrandr output id. This is the "output ID" Previously, the "spice display id" and the "output index" were treated as synonymous. But in order to support more complciated setups with multiple display devices, etc, we need to differentiate these ideas more clearly. This patch simply renames some variables and a function so that we can tell more easily which one of these concepts we are dealing with. Acked-by: Lukáš Hrázký <lhrazky@redhat.com> Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
2019-01-29Look up and store xrandr output in display mapJonathon Jongsma3-45/+35
Instead of storing each device address and device display ID in the hash table, simply use the lookup_xrandr_output_for_device_info() function to look up the ID of the xrandr output and store that in the hash table. Acked-by: Lukáš Hrázký <lhrazky@redhat.com> Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
2019-01-29Add lookup_xrand_output_for_device_info()Jonathon Jongsma2-0/+536
Add a function to look up an xrandr output for a given device display id. This uses sysfs and the drm subsystem to lookup information about a graphics device output. It then compares the drm output name to xrandr output names to try to match that device output to an xrandr output. This is necesary for guests that have multiple graphics devices. Acked-by: Lukáš Hrázký <lhrazky@redhat.com> Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
2019-01-28Receive the graphics_device_info messageLukáš Hrázký8-0/+101
The graphics_device_info message contains the device display ID information (device address and device display ID). Stores the data in a hash table in vdagent. Signed-off-by: Lukáš Hrázký <lhrazky@redhat.com> Acked-by: Jonathon Jongsma <jjongsma@redhat.com>
2019-01-17Update all paths /var/run -> /runChristian Hesse3-4/+4
Commit 098268a33c7c8008ccec9050aea8f0763f1c06d5 (systemd: Update path in unit file) was a really incomplete change. Let's change every occurrence of /var/run to /run. Signed-off-by: Christian Hesse <mail@eworm.de> Acked-by: Frediano Ziglio <fziglio@redhat.com>
2019-01-16file-xfer: Do not strip filename if file part has no extensionFrediano Ziglio1-1/+2
Signed-off-by: Frediano Ziglio <fziglio@redhat.com> Acked-by: Victor Toso <victortoso@redhat.com>
2019-01-16Fix race condition creating fileFrediano Ziglio1-14/+14
Avoid race condition creating file between checking file existence with stat() and opening with open(). Directly create the file passing the O_EXCL flag. Signed-off-by: Frediano Ziglio <fziglio@redhat.com> Acked-by: Victor Toso <victortoso@redhat.com>
2019-01-16Factor out function to create fileFrediano Ziglio2-36/+53
Make easier to test file creation Signed-off-by: Frediano Ziglio <fziglio@redhat.com> Acked-by: Victor Toso <victortoso@redhat.com>
2019-01-16file-xfers: Allocate file_path after disk space checkFrediano Ziglio1-2/+1
Variable is not used. Keep code to create file together. Signed-off-by: Frediano Ziglio <fziglio@redhat.com> Acked-by: Victor Toso <victortoso@redhat.com>
2019-01-16file-xfers: Reuse cleanup codeFrediano Ziglio1-4/+2
Signed-off-by: Frediano Ziglio <fziglio@redhat.com> Acked-by: Victor Toso <victortoso@redhat.com>
2019-01-16file-xfers: Initialise correctly AgentFileXferTask::file_fd fieldFrediano Ziglio1-0/+1
Correct invalid value for a file descriptor is -1, not 0. Signed-off-by: Frediano Ziglio <fziglio@redhat.com> Acked-by: Victor Toso <victortoso@redhat.com>
2019-01-07Check errors setting standard file descriptorsFrediano Ziglio2-8/+24
Signed-off-by: Frediano Ziglio <fziglio@redhat.com> Acked-by: Christophe Fergeau <cfergeau@redhat.com>
2019-01-07Ignore some Coverity reportsFrediano Ziglio3-0/+5
Signed-off-by: Frediano Ziglio <fziglio@redhat.com> Acked-by: Christophe Fergeau <cfergeau@redhat.com>
2019-01-04Add missing config.h includesFrediano Ziglio4-0/+4
Make sure all module files include config.h Signed-off-by: Frediano Ziglio <fziglio@redhat.com> Acked-by: Christophe Fergeau <cfergeau@redhat.com>
2019-01-04Unify config.h inclusion styleFrediano Ziglio10-27/+5
Remove HAVE_CONFIG_H check, it is always defined. Remove indentation of includes, now the include is not in a condition and also some were indented some not. Signed-off-by: Frediano Ziglio <fziglio@redhat.com> Acked-by: Christophe Fergeau <cfergeau@redhat.com>