| 1 |
https://bugs.gentoo.org/show_bug.cgi?id=197104 |
| 2 |
|
| 3 |
commit a5b8053606d6e786cdcf6734f271acc05f9cc588 |
| 4 |
Author: Adam Jackson <ajax@benzedrine.nwnk.net> |
| 5 |
Date: Tue Sep 11 11:37:06 2007 -0400 |
| 6 |
|
| 7 |
Ignore - not just block - SIGALRM around Popen()/Pclose(). |
| 8 |
|
| 9 |
Because our "popen" implementation uses stdio, and because nobody's stdio |
| 10 |
library is capable of surviving signals, we need to make absolutely sure |
| 11 |
that we hide the SIGALRM from the smart scheduler. Otherwise, when you |
| 12 |
open a menu in openoffice, and it recompiles XKB to deal with the |
| 13 |
accelerators, and you popen xkbcomp because we suck, then the scheduler |
| 14 |
will tell you you're taking forever doing something stupid, and the |
| 15 |
wait() code will get confused, and input will hang and your CPU usage |
| 16 |
slams to 100%. Down, not across. |
| 17 |
|
| 18 |
diff --git a/os/utils.c b/os/utils.c |
| 19 |
index 3bb7dbe..afcaae4 100644 |
| 20 |
--- a/os/utils.c |
| 21 |
+++ b/os/utils.c |
| 22 |
@@ -1720,6 +1720,8 @@ static struct pid { |
| 23 |
int pid; |
| 24 |
} *pidlist; |
| 25 |
|
| 26 |
+static sighandler_t old_alarm = NULL; /* XXX horrible awful hack */ |
| 27 |
+ |
| 28 |
pointer |
| 29 |
Popen(char *command, char *type) |
| 30 |
{ |
| 31 |
@@ -1741,11 +1743,15 @@ Popen(char *command, char *type) |
| 32 |
return NULL; |
| 33 |
} |
| 34 |
|
| 35 |
+ /* Ignore the smart scheduler while this is going on */ |
| 36 |
+ old_alarm = signal(SIGALRM, SIG_IGN); |
| 37 |
+ |
| 38 |
switch (pid = fork()) { |
| 39 |
case -1: /* error */ |
| 40 |
close(pdes[0]); |
| 41 |
close(pdes[1]); |
| 42 |
xfree(cur); |
| 43 |
+ signal(SIGALRM, old_alarm); |
| 44 |
return NULL; |
| 45 |
case 0: /* child */ |
| 46 |
if (setgid(getgid()) == -1) |
| 47 |
@@ -1921,6 +1927,8 @@ Pclose(pointer iop) |
| 48 |
/* allow EINTR again */ |
| 49 |
OsReleaseSignals (); |
| 50 |
|
| 51 |
+ signal(SIGALRM, old_alarm); |
| 52 |
+ |
| 53 |
return pid == -1 ? -1 : pstat; |
| 54 |
} |
| 55 |
|