On Thu, 28 Aug 2008, Prof Brian Ripley wrote:

> This is an Xt error, whereas the first one is an Xlib error.  It is easy
> to trap it.
>
> You do realize that this will never work?  In the current setup all open
> X11 devices must be on the same display, and 'display' is ignored if a
> device is already open.  (I don't know if that is documented: I did not
> write the Xlib device nor the help page.)

I have a different problem with the x11() bringing
down R when $DISPLAY does not refer to a valid X
server.  I typically sit at a Windows laptop running
a Cygwin X server and use the ssh client/terminal
emulator program 'putty' to run a shell on on Linux,
where I run R.  Putty tunnels X protocol and sets
DISPLAY (to something like localhost:11.0) whether or
not the PC's X server is running.  If I have forgotten
to start the PC's X server R currently shuts down when
I try to start x11() or the tcl/tk stuff that
available.packages() runs.  E.g.,
  > x11()
  X connection to localhost:11.0 broken (explicit kill or server shutdown).
  linuxPrompt%

If I call the XIOErrorHandler(R_X11IOErr) before calling XOpenDisplay()
(in src/modules/X11/devX11.c) then I can trap that error
and have x11() throw an ordinary R error:
  > x11()
  Error in x11() : X11 I/O error while opening device "localhost:11.0"
  >

The following patch sets the IOErrorHandler before XOpenDisplay
and changes the handler a bit so it doesn't assume that some
global variables have been set yet.

It doesn't help the problem in available.packages().  That must
make its own unprotected call to XOpenDisplay().

Index: src/modules/X11/devX11.c
===================================================================
--- src/modules/X11/devX11.c    (revision 46454)
+++ src/modules/X11/devX11.c    (working copy)
@@ -1080,19 +1080,30 @@

 static int R_X11IOErr(Display *dsp)
 {
-    int fd = ConnectionNumber(display);
-    /*
-    while (nfonts--)  R_XFreeFont(display, fontcache[nfonts].font);
-    nfonts = 0;
-    */
-    removeInputHandler(&R_InputHandlers,
-                      getInputHandler(R_InputHandlers,fd));
-    /*
-    XCloseDisplay(display);
-    displayOpen = FALSE;
-    strcpy(dspname, "");
-    */
-    error(_("X11 fatal IO error: please save work and shut down R"));
+    int fd ;
+    /* display is only set after successful call to XOpenDisplay.
+     * If it is non-null I think it should be the same as dsp, but
+     * display==NULL & dsp!=NULL means that we have run into a problem
+     * while executing XOpenDisplay.
+     */
+    if (display && displayOpen) {
+       fd = ConnectionNumber(display);
+       /*
+       while (nfonts--)  R_XFreeFont(display, fontcache[nfonts].font);
+       nfonts = 0;
+       */
+       removeInputHandler(&R_InputHandlers,
+                         getInputHandler(R_InputHandlers,fd));
+       /*
+       XCloseDisplay(display);
+       displayOpen = FALSE;
+       strcpy(dspname, "");
+       */
+       error(_("X11 fatal IO error: please save work and shut down R"));
+    } else if (dsp) { /* In XOpenDisplay() is the intent */
+       char *devname =  XDisplayName(dspname) ;
+       error(_("X11 I/O error while opening device \"%s\""), devname);
+    }
     return 0; /* but should never get here */
 }

@@ -1247,15 +1258,21 @@
     /* initialize the X11 device driver data structures. */

     if (!displayOpen) {
+        /* Set IOErrorHandler before trying to open the display
+         * just in case DISPLAY is putty tunnelling X11 protocol
+         * to a machine that is not runing an X server.  Set dspname
+         * now so R_X11IOErr can show it to user. */
+       XSetIOErrorHandler(R_X11IOErr);
+       strncpy(dspname, p, 101);
+       dspname[100] = '\0';
        if ((display = XOpenDisplay(p)) == NULL) {
+            dspname[0] = '\0' ;
            warning(_("unable to open connection to X11 display '%s'"), p);
            return FALSE;
        }
        DisplayOpened = TRUE;
        Rf_setX11Display(display, gamma_fac, colormodel, maxcube, TRUE);
        displayOpen = TRUE;
-       strncpy(dspname, p, 101);
-       dspname[100] = '\0';
        if(xd->handleOwnEvents == FALSE)
            addInputHandler(R_InputHandlers, ConnectionNumber(display),
                            R_ProcessX11Events, XActivity);

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to