mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	rootston: Double fork for keyboard bindings
This avoids leaving around zombies, without having to setup SIGCHLD handler (which interferes with other fork/waitpid calls).
This commit is contained in:
		
							parent
							
								
									d2814c1795
								
							
						
					
					
						commit
						11d440972d
					
				
					 1 changed files with 35 additions and 7 deletions
				
			
		| 
						 | 
					@ -2,6 +2,7 @@
 | 
				
			||||||
#include <stdbool.h>
 | 
					#include <stdbool.h>
 | 
				
			||||||
#include <stdint.h>
 | 
					#include <stdint.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <sys/wait.h>
 | 
				
			||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
#include <wayland-server.h>
 | 
					#include <wayland-server.h>
 | 
				
			||||||
#include <wlr/backend/multi.h>
 | 
					#include <wlr/backend/multi.h>
 | 
				
			||||||
| 
						 | 
					@ -84,6 +85,39 @@ static void pressed_keysyms_update(xkb_keysym_t *pressed_keysyms,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void double_fork_shell_cmd(const char *shell_cmd) {
 | 
				
			||||||
 | 
						pid_t pid = fork();
 | 
				
			||||||
 | 
						if (pid < 0) {
 | 
				
			||||||
 | 
							wlr_log(WLR_ERROR, "cannot execute binding command: fork() failed");
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (pid == 0) {
 | 
				
			||||||
 | 
							pid = fork();
 | 
				
			||||||
 | 
							if (pid == 0) {
 | 
				
			||||||
 | 
								execl("/bin/sh", "/bin/sh", "-c", shell_cmd, NULL);
 | 
				
			||||||
 | 
								_exit(EXIT_FAILURE);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								_exit(pid == -1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int status;
 | 
				
			||||||
 | 
						while (waitpid(pid, &status, 0) < 0) {
 | 
				
			||||||
 | 
							if (errno == EINTR) {
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							wlr_log_errno(WLR_ERROR, "waitpid() on first child failed");
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wlr_log(WLR_ERROR, "first child failed to fork command");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char *exec_prefix = "exec ";
 | 
					static const char *exec_prefix = "exec ";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool outputs_enabled = true;
 | 
					static bool outputs_enabled = true;
 | 
				
			||||||
| 
						 | 
					@ -113,13 +147,7 @@ static void keyboard_binding_execute(struct roots_keyboard *keyboard,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else if (strncmp(exec_prefix, command, strlen(exec_prefix)) == 0) {
 | 
						} else if (strncmp(exec_prefix, command, strlen(exec_prefix)) == 0) {
 | 
				
			||||||
		const char *shell_cmd = command + strlen(exec_prefix);
 | 
							const char *shell_cmd = command + strlen(exec_prefix);
 | 
				
			||||||
		pid_t pid = fork();
 | 
							double_fork_shell_cmd(shell_cmd);
 | 
				
			||||||
		if (pid < 0) {
 | 
					 | 
				
			||||||
			wlr_log(WLR_ERROR, "cannot execute binding command: fork() failed");
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
		} else if (pid == 0) {
 | 
					 | 
				
			||||||
			execl("/bin/sh", "/bin/sh", "-c", shell_cmd, (void *)NULL);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	} else if (strcmp(command, "maximize") == 0) {
 | 
						} else if (strcmp(command, "maximize") == 0) {
 | 
				
			||||||
		struct roots_view *focus = roots_seat_get_focus(seat);
 | 
							struct roots_view *focus = roots_seat_get_focus(seat);
 | 
				
			||||||
		if (focus != NULL) {
 | 
							if (focus != NULL) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue