This is the mail archive of the cygwin-xfree@cygwin.com mailing list for the Cygwin XFree86 project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: need xterm to log to a file


On Fri, 10 Dec 2004, Christopher Faylor wrote:

On Fri, Dec 10, 2004 at 06:50:11AM -0500, Thomas Dickey wrote:
I see it's a (usually minor) error in xterm, which runs into a cygwin bug.
The function creat_as() does a fork/wait, assuming that it has to strip
off the setuid/setgid privilges.  That's not needed in cygwin, but the
fork/wait doesn't work (looks like a cygwin bug).  I'll add a fix in #198
so it will work for cygwin.

How about saying "cygwin bug" a few more times? I love it when people sling that term around while providing no details.

hmm - saying it twice was redundant.


I did point to the particular function which is hanging (creat_as, in xterm's misc.c). It does a fork, setuid/getuid and then an open. (The
imake configuration doesn't give enough detail to ensure that I can determine at that point if the setuid is needed, and it hasn't been an issue before now).


Now bear in mind that xterm normally runs as two processes.  This fork
is a third process, used to ensure that a file is created as the original
user (just in case xterm was running setuid).

If fork/wait didsn't work it would be a serious problem with repercussions
for every package in the cygwin distribution and it would certainly be
one that we'd want to fix.

;-)


Can you be more precise in detailing this problem?

Not much. gdb's of no use here, so I added some traces to see which lines are executed. It doesn't appear to return from the waitpid, but on the child side is last seen heading into the _exit(0). Here's the relevant section of code (with the unused ifdef's removed):

int
creat_as(int uid, int gid, Boolean append, char *pathname, int mode)
{
    int fd;
    int pid;
    int retval = 0;
    int childstat = 0;

    pid = fork();
    switch (pid) {
    case 0:			/* child */
	setgid(gid);
	setuid(uid);
	fd = open(pathname,
		  O_WRONLY | O_CREAT | (append ? O_APPEND : O_EXCL),
		  mode);
	if (fd >= 0) {
	    close(fd);
	    _exit(0);		<==== child gets here
	} else
	    _exit(1);
	/* NOTREACHED */
    case -1:			/* error */
	return retval;
    default:			/* parent */
				<==== parent gets here
	while (waitpid(pid, &childstat, 0) < 0) {
	    if (errno == EINTR)
		continue;
	    break;
	}
	if (WIFEXITED(childstat))
	    retval = 1;
	return retval;
    }
}

As for why it's hanging, I suppose your guess might be better than mine.

--
Thomas E. Dickey
http://invisible-island.net
ftp://invisible-island.net


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]