runSudoChown runs sudo chown with proper terminal handling. It resets the terminal to sane mode before running sudo to ensure password input works correctly.
(ctx context.Context, username string, recursive bool, path string)
| 272 | // runSudoChown runs sudo chown with proper terminal handling. |
| 273 | // It resets the terminal to sane mode before running sudo to ensure password input works correctly. |
| 274 | func runSudoChown(ctx context.Context, username string, recursive bool, path string) error { |
| 275 | // Open /dev/tty for direct terminal access |
| 276 | tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0) |
| 277 | if err != nil { |
| 278 | return fmt.Errorf("failed to open /dev/tty: %w", err) |
| 279 | } |
| 280 | defer func() { |
| 281 | _ = tty.Close() // Ignore close error - tty is for terminal I/O, not data persistence |
| 282 | }() |
| 283 | |
| 284 | // Reset terminal to sane mode before running sudo |
| 285 | // This ensures the terminal is in canonical mode with echo properly controlled |
| 286 | sttyCmd := exec.CommandContext(ctx, "stty", "sane", "-F", "/dev/tty") |
| 287 | _ = sttyCmd.Run() // Ignore errors, best effort |
| 288 | |
| 289 | // Build the chown command |
| 290 | args := []string{"chown"} |
| 291 | if recursive { |
| 292 | args = append(args, "-R") |
| 293 | } |
| 294 | args = append(args, username, path) |
| 295 | |
| 296 | cmd := exec.CommandContext(ctx, "sudo", args...) |
| 297 | cmd.Stdin = tty |
| 298 | cmd.Stdout = tty |
| 299 | cmd.Stderr = tty |
| 300 | |
| 301 | return cmd.Run() |
| 302 | } |
| 303 | |
| 304 | // FixFilePermission attempts to fix permission issues on a specific file by changing ownership. |
| 305 | // This is called when a file operation (read or write) fails due to permission issues, |
no test coverage detected