Commit fb687773 authored by Olga Krishtal's avatar Olga Krishtal Committed by Michael Roth
Browse files

qga: set file descriptor in qmp_guest_file_open non-blocking on Win32



Set fd non-blocking to avoid common use cases (like reading from a
named pipe) from hanging the agent. This was missed in the original
code.

The patch introduces qemu_set_handle_nonoblocking, the local analog
of qemu_set_nonblock for HANDLES.
The usage of handles in qemu_set_non/block is impossible, because for
win32 there is a difference between file discriptors and file handles,
and all file ops are made via Win32 api.

Signed-off-by: default avatarOlga Krishtal <okrishtal@parallels.com>
Signed-off-by: default avatarDenis V. Lunev <den@openvz.org>
CC: Michael Roth <mdroth@linux.vnet.ibm.com>
CC: Stefan Weil <sw@weilnetz.de>
Signed-off-by: default avatarMichael Roth <mdroth@linux.vnet.ibm.com>
parent c87d0964
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -128,6 +128,28 @@ static GuestFileHandle *guest_file_handle_find(int64_t id, Error **errp)
    return NULL;
}

static void handle_set_nonblocking(HANDLE fh)
{
    DWORD file_type, pipe_state;
    file_type = GetFileType(fh);
    if (file_type != FILE_TYPE_PIPE) {
        return;
    }
    /* If file_type == FILE_TYPE_PIPE, according to MSDN
     * the specified file is socket or named pipe */
    if (!GetNamedPipeHandleState(fh, &pipe_state, NULL,
                                 NULL, NULL, NULL, 0)) {
        return;
    }
    /* The fd is named pipe fd */
    if (pipe_state & PIPE_NOWAIT) {
        return;
    }

    pipe_state |= PIPE_NOWAIT;
    SetNamedPipeHandleState(fh, &pipe_state, NULL, NULL);
}

int64_t qmp_guest_file_open(const char *path, bool has_mode,
                            const char *mode, Error **errp)
{
@@ -158,6 +180,11 @@ int64_t qmp_guest_file_open(const char *path, bool has_mode,
        return -1;
    }

    /* set fd non-blocking to avoid common use cases (like reading from a
     * named pipe) from hanging the agent
     */
    handle_set_nonblocking(fh);

    fd = guest_file_handle_add(fh, errp);
    if (fd < 0) {
        CloseHandle(fh);