char-stdio: Restore blocking mode of stdout on exit
qemu_chr_open_fd() sets stdout into non-blocking mode. Restore the old
fd flags on exit to avoid breaking unsuspecting applications that run on
the same terminal after qemu and don't expect to get EAGAIN.
While at at, also ensure term_exit is called once (at the moment it's
called both from char_stdio_finalize() and as the atexit() hook.
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2423
Signed-off-by: Maxim Mikityanskiy <maxtram95@gmail.com>
Link: https://lore.kernel.org/r/20240703190812.3459514-1-maxtram95@gmail.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit a0124e333e)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
			
			
This commit is contained in:
		
				
					committed by
					
						
						Michael Tokarev
					
				
			
			
				
	
			
			
			
						parent
						
							b932f9fbd4
						
					
				
				
					commit
					8f7bb1266f
				
			@@ -41,6 +41,7 @@
 | 
			
		||||
/* init terminal so that we can grab keys */
 | 
			
		||||
static struct termios oldtty;
 | 
			
		||||
static int old_fd0_flags;
 | 
			
		||||
static int old_fd1_flags;
 | 
			
		||||
static bool stdio_in_use;
 | 
			
		||||
static bool stdio_allow_signal;
 | 
			
		||||
static bool stdio_echo_state;
 | 
			
		||||
@@ -50,6 +51,8 @@ static void term_exit(void)
 | 
			
		||||
    if (stdio_in_use) {
 | 
			
		||||
        tcsetattr(0, TCSANOW, &oldtty);
 | 
			
		||||
        fcntl(0, F_SETFL, old_fd0_flags);
 | 
			
		||||
        fcntl(1, F_SETFL, old_fd1_flags);
 | 
			
		||||
        stdio_in_use = false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -102,6 +105,7 @@ static void qemu_chr_open_stdio(Chardev *chr,
 | 
			
		||||
 | 
			
		||||
    stdio_in_use = true;
 | 
			
		||||
    old_fd0_flags = fcntl(0, F_GETFL);
 | 
			
		||||
    old_fd1_flags = fcntl(1, F_GETFL);
 | 
			
		||||
    tcgetattr(0, &oldtty);
 | 
			
		||||
    if (!g_unix_set_fd_nonblocking(0, true, NULL)) {
 | 
			
		||||
        error_setg_errno(errp, errno, "Failed to set FD nonblocking");
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user