A: The Problem
A.1: Introdution
A.2: The Real Problem
B: The Solution
C: How to reproduce the Problem and track down stuff


A: The Problem

A.1: Introdution

The problem occurs when you are using any of the
XFree 4.* versions and try to make xdm put out the
line "willing, 3 users, load: 1.00 1.01 1.02" in the
chooser-line.
Therefore you have to use
"DisplayManager.willing:         /usr/X11R6/lib/X11/xdm/Xwilling"
in your /etc/X11/xdm/xdm-config's file.

Now let's have a look at the Xwilling-Shellscript:
The current version looks like:

#!/bin/sh
#
# $XFree86$

# The output of this script is displayed in the chooser window.
# (instead of "Willing to manage")

load="^Uptime|sed -e 's/^.*load[^0-9]*//'"
nrusers="^Who|cut -c 1-8|sort -u|wc -l|sed 's/^[        ]*//'"
s=""; [ "$nrusers" != 1 ] && s=s

echo "${nrusers} user${s}, load: ${load}"

Looks quite fine and system-independent as every
$SYSTEM can do its own line with a simple and
clean shell-script.

Now let's see what xdm does with the script and what
is send to a remote chooser-server and what it displays:

A.2: The Real Problem

The remote chooser-server displays:
"Willing, but /etc/X11/xdm/Xwilling failed" - *SHRUG*
Let's have a look at xc/programs/xdm/policy.c which
generates this chooser-line:
line 134 is coming up with:

if ((fd = popen(willing, "r")) && fgets(statusBuf, 256, fd))

ok, there is no error-checking but so far there is no
need for error-checking.
IS THERE ? Yes. there is. see Section C. How to to reproduce.

Now guess, does popen fail or fgets ? Right. Fgets fails.

As far as I have reproduced the error (See section C)
popen runs the Xwilling-script and puts the output
in a buffered pipe (like man 2 popen tells us)
fgets tries to to read on the filedescriptor as you can
easly(:-) see in the glibc-2.2.5 sources.
What comes now is a bit strange:
the read get's interrupted by SIGCHLD and thats why
fget's returns NULL and fails.
"willing but /.../Xwilling failed" is displayed.
read() sets EINTR but we don't care about because
we are not sure if fgets() does provide us with the
essential errno and we come back to fgets is returning
NULL. An error has occured.(linux)

As far as I can see
- Xwilling runs writing into the pipe
- fgets reads the pipe
- while reading: SIGCHLD comes from a terminating
  Xwilling-script and read in fgets()'s deep structure
  fails due to SIGCHLD.



B: The solution

As I can see blocking the SIGCHLD before popen
and unblocking it before pclose, would fix this behaviour.
"Programming For the Real World, POSIX.4" from O'Reilly tells us
on chapter 3: "The Basics of Real-Time: Multiple Tasks" on
page 65:
"When you have blocked a signal, and that signal is sent to your
process, it remains pending for you until you unblock the signal.
When you do unblock a signal that is pending, you should immediately
expect to receive the signal."

and here comes the unified diff -u policy.c.orig policy.c:

--- xc/programs/xdm/policy.c.orig       Tue Apr  2 23:56:04 2002
+++ xc/programs/xdm/policy.c    Wed Apr  3 00:37:36 2002
@@ -33,7 +33,7 @@

 # include "dm.h"
 # include "dm_auth.h"
-
+# include <signal.h>
 #ifdef XDMCP

 # include <X11/X.h>
@@ -131,12 +131,15 @@
     {
         if (*willing)
        {   FILE *fd;
+       int mask = siggetmask();
+       sigsetmask(mask|sigmask(SIGCHLD));
            if ((fd = popen(willing, "r")) && fgets(statusBuf, 256, fd))

            {
                statusBuf[strlen(statusBuf)-1] = 0; /* chop newline */
            }
            else
                sprintf (statusBuf, "Willing, but %s failed",willing);
+               sigsetmask(mask);
            if (fd) pclose(fd);
        }
        else

(You can get the diff at
http://plantage.dynodns.net/~thomas/xdm.diff)



C: How to reproduce the Problem and track down stuff

http://plantage.dynodns.net/~thomas/xdm-trackdown.diff
comes up with a read() and a usable ERRNO
and stores all signals in a file in /tmp
You can play around with it a bit.

_______________________________________________
Xpert mailing list
[EMAIL PROTECTED]
http://XFree86.Org/mailman/listinfo/xpert

Reply via email to