1/* vi: set sw=4 ts=4: */ 2/* 3 * Utility routines. 4 * 5 * Copyright (C) many different people. If you wrote this, please 6 * acknowledge your work. 7 * 8 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 9 */ 10 11//#include <sys/ioctl.h> 12#include "libbb.h" 13 14 15/* From <linux/kd.h> */ 16enum { KDGKBTYPE = 0x4B33 }; /* get keyboard type */ 17 18 19static int open_a_console(const char *fnam) 20{ 21 int fd; 22 23 /* try read-write */ 24 fd = open(fnam, O_RDWR); 25 26 /* if failed, try read-only */ 27 if (fd < 0 && errno == EACCES) 28 fd = open(fnam, O_RDONLY); 29 30 /* if failed, try write-only */ 31 if (fd < 0 && errno == EACCES) 32 fd = open(fnam, O_WRONLY); 33 34 return fd; 35} 36 37/* 38 * Get an fd for use with kbd/console ioctls. 39 * We try several things because opening /dev/console will fail 40 * if someone else used X (which does a chown on /dev/console). 41 */ 42 43int get_console_fd(void) 44{ 45 static const char *const console_names[] = { 46 DEV_CONSOLE, CURRENT_VC, CURRENT_TTY 47 }; 48 49 int fd; 50 51 for (fd = 2; fd >= 0; fd--) { 52 int fd4name; 53 int choice_fd; 54 char arg; 55 56 fd4name = open_a_console(console_names[fd]); 57 chk_std: 58 choice_fd = (fd4name >= 0 ? fd4name : fd); 59 60 arg = 0; 61 if (ioctl(choice_fd, KDGKBTYPE, &arg) == 0) 62 return choice_fd; 63 if (fd4name >= 0) { 64 close(fd4name); 65 fd4name = -1; 66 goto chk_std; 67 } 68 } 69 70 bb_error_msg("cannot get file descriptor referring to console"); 71 return fd; /* total failure */ 72} 73