Submitted By: Alexander E. Patrakov Date: 2004-11-03 Initial Package Version: 6.8.1 Origin: Alexander E. Patrakov Upstream Status: Accepted into xterm, http://bugs.xfree86.org/show_bug.cgi?id=1093 Description: prevents the race condition and deadlock in luit. Should apply both to XOrg and XFree86. Testcase: (preferrably in Xnest - this will open 100 xterm windows) for a in `seq 1 100` ; do ( xterm -lc -e info & ) ; sleep 0.2 done Half of xterms will be blank without this patch. "killall luit" to close all xterms. --- xc/programs/luit/luit.c 2004-09-21 08:05:44.000000000 +0600 +++ xc/programs/luit/luit.c.fixed 2004-10-27 12:46:24.092624776 +0600 @@ -434,6 +434,16 @@ return 0; } +static void +sigwinchHandler(int sig) { + sigwinch_queued = 1; +} + +static void +sigchldHandler(int sig) +{ + sigchld_queued = 1; +} static int condom(int argc, char **argv) @@ -444,6 +454,7 @@ char *path; char **child_argv; int rc; + int val; rc = parseArgs(argc, argv, child_argv0, &path, &child_argv); @@ -461,6 +472,29 @@ perror("Couldn't drop priviledges"); exit(1); } +#ifdef SIGWINCH + installHandler(SIGWINCH, sigwinchHandler); +#endif + installHandler(SIGCHLD, sigchldHandler); + + rc = copyTermios(0, pty); + if(rc < 0) + FatalError("Couldn't copy terminal settings\n"); + + rc = setRawTermios(); + if(rc < 0) + FatalError("Couldn't set terminal to raw\n"); + + val = fcntl(0, F_GETFL, 0); + if(val >= 0) { + fcntl(0, F_SETFL, val | O_NONBLOCK); + } + val = fcntl(pty, F_GETFL, 0); + if(val >= 0) { + fcntl(pty, F_SETFL, val | O_NONBLOCK); + } + + setWindowSize(0, pty); pid = fork(); if(pid < 0) { @@ -470,6 +504,10 @@ if(pid == 0) { close(pty); +#ifdef SIGWINCH + installHandler(SIGWINCH, SIG_DFL); +#endif + installHandler(SIGCHLD, SIG_DFL); child(line, path, child_argv); } else { free(child_argv); @@ -490,6 +528,7 @@ close(0); close(1); close(2); + pgrp = setsid(); if(pgrp < 0) { kill(getppid(), SIGABRT); @@ -517,53 +556,17 @@ exit(1); } -static void -sigwinchHandler(int sig) { - sigwinch_queued = 1; -} - -static void -sigchldHandler(int sig) -{ - sigchld_queued = 1; -} - void parent(int pid, int pty) { unsigned char buf[BUFFER_SIZE]; int i; - int val; int rc; if(verbose) { reportIso2022(outputState); } -#ifdef SIGWINCH - installHandler(SIGWINCH, sigwinchHandler); -#endif - installHandler(SIGCHLD, sigchldHandler); - - rc = copyTermios(0, pty); - if(rc < 0) - FatalError("Couldn't copy terminal settings\n"); - - rc = setRawTermios(); - if(rc < 0) - FatalError("Couldn't set terminal to raw\n"); - - val = fcntl(0, F_GETFL, 0); - if(val >= 0) { - fcntl(0, F_SETFL, val | O_NONBLOCK); - } - val = fcntl(pty, F_GETFL, 0); - if(val >= 0) { - fcntl(pty, F_SETFL, val | O_NONBLOCK); - } - - setWindowSize(0, pty); - for(;;) { rc = waitForInput(0, pty);