X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Futil.c;h=b8e73ef4bf44a4380129796bcce5c1302c3e46ba;hp=92268b69a95e4bd560102520f0d03a99842d6886;hb=a76fad090a6a1388fbaa609e8ca37e82223d2bd7;hpb=fc116c6a19877275eabb085cf03f0df23b17c0e9 diff --git a/src/util.c b/src/util.c index 92268b69a..b8e73ef4b 100644 --- a/src/util.c +++ b/src/util.c @@ -2134,8 +2134,32 @@ finish: int open_terminal(const char *name, int mode) { int fd, r; + unsigned c = 0; - if ((fd = open(name, mode)) < 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 + */ + + for (;;) { + if ((fd = open(name, mode)) >= 0) + break; + + if (errno != EIO) + return -errno; + + if (c >= 20) + return -errno; + + usleep(50 * USEC_PER_MSEC); + c++; + } + + if (fd < 0) return -errno; if ((r = isatty(fd)) < 0) {