diff options
author | Ronny Chevalier <chevalier.ronny@gmail.com> | 2015-04-15 16:05:41 -0400 |
---|---|---|
committer | Anthony G. Basile <blueness@gentoo.org> | 2015-04-15 16:05:41 -0400 |
commit | 38a4db66e7e166f3b92f15e1c66d6707fcbab69d (patch) | |
tree | a7b8de09a5c532d97c73598860000eddb7216a4e /src/shared/terminal-util.c | |
parent | 5ad9610b49875b6d65c56600d5b98d1afc11a4bd (diff) |
Ronny Chevalier <chevalier.ronny@gmail.com>shared: add terminal-util.[ch]
Signed-off-by: Anthony G. Basile <blueness@gentoo.org>
Diffstat (limited to 'src/shared/terminal-util.c')
-rw-r--r-- | src/shared/terminal-util.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/src/shared/terminal-util.c b/src/shared/terminal-util.c new file mode 100644 index 0000000000..04c871a3f7 --- /dev/null +++ b/src/shared/terminal-util.c @@ -0,0 +1,87 @@ +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <termios.h> +#include <unistd.h> +#include <fcntl.h> +#include <signal.h> +#include <time.h> +#include <assert.h> +#include <poll.h> +#include <linux/vt.h> +#include <linux/tiocl.h> +#include <linux/kd.h> + +#include "terminal-util.h" +#include "time-util.h" +#include "process-util.h" +#include "util.h" +#include "fileio.h" +#include "path-util.h" + +static volatile unsigned cached_columns = 0; +static volatile unsigned cached_lines = 0; + +int open_terminal(const char *name, int mode) { + int fd, r; + unsigned c = 0; + + /* + * If a TTY is in the process of being closed opening it might + * cause EIO. This is horribly awful, but unlikely to be + * changed in the kernel. Hence we work around this problem by + * retrying a couple of times. + * + * https://bugs.launchpad.net/ubuntu/+source/linux/+bug/554172/comments/245 + */ + + assert(!(mode & O_CREAT)); + + for (;;) { + fd = open(name, mode, 0); + if (fd >= 0) + break; + + if (errno != EIO) + return -errno; + + /* Max 1s in total */ + if (c >= 20) + return -errno; + + usleep(50 * USEC_PER_MSEC); + c++; + } + + r = isatty(fd); + if (r < 0) { + safe_close(fd); + return -errno; + } + + if (!r) { + safe_close(fd); + return -ENOTTY; + } + + return fd; +} |