diff options
author | tsi <tsi> | 2008-04-24 19:41:05 +0000 |
---|---|---|
committer | tsi <tsi> | 2008-04-24 19:41:05 +0000 |
commit | d7e47959401c9fc772e7d31c37adc2afc5716818 (patch) | |
tree | d02c9af7ad49ad8a5b07c0e76a4eec5e76cd7746 | |
parent | 1a5f4760c3641e66923b333eebb909512629a3f3 (diff) |
38. Avoid screen corruption that occurs upon /dev/console output while the
X server is running on SunOS, by redirecting this output into a file.
The file is copied back to /dev/console on server exit. Note that screen
corruption still occurs on output to /dev/wscons because wscons cannot be
redirected in this fashion. (Marc La France).
-rw-r--r-- | programs/Xserver/hw/xfree86/CHANGELOG | 7 | ||||
-rw-r--r-- | programs/Xserver/hw/xfree86/os-support/sunos/sun_init.c | 141 |
2 files changed, 146 insertions, 2 deletions
diff --git a/programs/Xserver/hw/xfree86/CHANGELOG b/programs/Xserver/hw/xfree86/CHANGELOG index 97a53905e..3dc9ecef1 100644 --- a/programs/Xserver/hw/xfree86/CHANGELOG +++ b/programs/Xserver/hw/xfree86/CHANGELOG @@ -1,4 +1,9 @@ XFree86 4.7.99.17 (xx May 2008) + 38. Avoid screen corruption that occurs upon /dev/console output while the + X server is running on SunOS, by redirecting this output into a file. + The file is copied back to /dev/console on server exit. Note that screen + corruption still occurs on output to /dev/wscons because wscons cannot be + redirected in this fashion. (Marc La France). XFree86 4.7.99.16 (23 April 2008) @@ -20715,4 +20720,4 @@ XFree86 3.0a (28 April 1994) XFree86 3.0 (26 April 1994) -$XFree86: xc/programs/Xserver/hw/xfree86/CHANGELOG,v 3.3947 2008/04/09 11:03:40 dawes Exp $ +$XFree86: xc/programs/Xserver/hw/xfree86/CHANGELOG,v 3.3948 2008/04/23 11:04:03 dawes Exp $ diff --git a/programs/Xserver/hw/xfree86/os-support/sunos/sun_init.c b/programs/Xserver/hw/xfree86/os-support/sunos/sun_init.c index 13019db10..533a592d8 100644 --- a/programs/Xserver/hw/xfree86/os-support/sunos/sun_init.c +++ b/programs/Xserver/hw/xfree86/os-support/sunos/sun_init.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_init.c,v 1.11 2008/03/26 19:04:52 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_init.c,v 1.12tsi Exp $ */ /* * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany * Copyright 1993 by David Wexelblat <dwex@goblin.org> @@ -27,6 +27,9 @@ #include "xf86Priv.h" #include "xf86_OSlib.h" +#include <sys/stropts.h> +#include <sys/strredir.h> + static Bool KeepTty = FALSE; static Bool Protect0 = FALSE; #ifdef HAS_USL_VTS @@ -36,6 +39,97 @@ static int xf86StartVT = -1; static char fb_dev[PATH_MAX] = "/dev/console"; +#ifdef NOREDIRECT +#undef SRIOCSREDIR +#endif + +#ifdef SRIOCSREDIR +static char *redirfn = NULL; +static FILE *redirfd = NULL; +static Bool redired = FALSE; +static int pipe_fds[2] = {-1, -1}; + +static void +xf86CopyRedirectedConsole(void) +{ + long length; + char buffer[16]; /* Increase size for efficiency */ + + while ((length = read(pipe_fds[1], buffer, sizeof(buffer))) > 0) { + redired = TRUE; + fwrite(buffer, 1, length, redirfd); + } +} + +static void +xf86ReadRedirectedConsole(pointer pData, int error, pointer pMask) +{ + if ((error >= 0) && pMask && FD_ISSET(pipe_fds[1], (fd_set *)pMask)) + xf86CopyRedirectedConsole(); + + fflush(redirfd); +} + +static void +xf86RedirectConsole(void) +{ + int consolefd; + + /* fb_dev can be overridden */ + if ((consolefd = open("/dev/console", O_RDWR | O_NDELAY)) < 0) + return; + + xasprintf(&redirfn, "%s.console", xf86FilePaths->logFile); + if (!redirfn) { + xf86Msg(X_WARNING, "xf86RedirectConsole: could not allocate console" + " redirection file name (%s)\n", strerror(errno)); + goto done; + } + + if (!(redirfd = fopen(redirfn, "w"))) { + xf86Msg(X_WARNING, "xf86RedirectConsole: could not open \"%s\"" + " (%s)\n", redirfn, strerror(errno)); + goto openfail; + } + + if (pipe(pipe_fds) < 0) { + xf86Msg(X_WARNING, "xf86RedirectConsole: could not create pipe for" + " console redirection (%s)\n", strerror(errno)); + goto pipefail; + } + + if (fcntl(pipe_fds[1], F_SETFL, O_NDELAY) < 0) { + xf86Msg(X_WARNING, "xf86RedirectConsole: fcntl /dev/console O_NDELAY" + " failure (%s)\n", strerror(errno)); + goto cntlfail; + } + + if (ioctl(consolefd, SRIOCSREDIR, pipe_fds[0]) < 0) { + xf86Msg(X_WARNING, "xf86RedirectConsole: ioctl /dev/console" + " SRIOCSREDIR failure (%s)\n", strerror(errno)); + goto cntlfail; + } + + AddEnabledDevice(pipe_fds[1]); + RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, + xf86ReadRedirectedConsole, NULL); + goto done; + +cntlfail: + close(pipe_fds[0]); + close(pipe_fds[1]); + pipe_fds[0] = pipe_fds[1] = -1; +pipefail: + fclose(redirfd); + redirfd = NULL; +openfail: + xfree(redirfn); + redirfn = NULL; +done: + close(consolefd); +} +#endif /* SRIOCSREDIR */ + void xf86OpenConsole(void) { @@ -179,6 +273,9 @@ xf86OpenConsole(void) ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS); #endif #endif +#ifdef SRIOCSREDIR + xf86RedirectConsole(); +#endif } #ifdef HAS_USL_VTS else /* serverGeneration != 1 */ @@ -301,6 +398,48 @@ xf86CloseConsole(void) #endif /* HAS_USL_VTS */ +#ifdef SRIOCSREDIR + if (pipe_fds[1] >= 0) { + /* Catch the last little bit, if any */ + xf86CopyRedirectedConsole(); + + close(pipe_fds[0]); + close(pipe_fds[1]); + pipe_fds[0] = -1; + + fclose(redirfd); + + if (redired) { + /* Copy data back to /dev/console */ + if ((pipe_fds[1] = open(redirfn, O_RDONLY)) < 0) { + xf86Msg(X_WARNING, "xf86CloseConsole: could not reopen \"%s\"" + " (%s)\n", redirfn, strerror(errno)); + } else { + if (!(redirfd = fopen("/dev/console", "w"))) { + xf86Msg(X_WARNING, "xf86CloseConsole: could not reopen" + " \"/dev/console\" (%s)\n", strerror(errno)); + } else { + putc('\n', redirfd); + xf86CopyRedirectedConsole(); + + fclose(redirfd); + } + + close(pipe_fds[1]); + } + + redired = FALSE; + } + + pipe_fds[1] = -1; + redirfd = NULL; + + unlink(redirfn); + xfree(redirfn); + redirfn = NULL; + } +#endif + close(xf86Info.consoleFd); #if defined(__SOL8__) || defined(__sparc__) |