about summary refs log tree commit diff
path: root/sysdeps
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2023-11-20 19:19:50 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2023-11-20 23:28:16 +0100
commit49b308a26e2a9e02ef396f67f59c462ad4171ea4 (patch)
treee4705638a64da583bbe578896dbb5f8b5fa70333 /sysdeps
parent3cbaacdfd2c11cb726011ef6464dce00c186a2bf (diff)
downloadglibc-49b308a26e2a9e02ef396f67f59c462ad4171ea4.tar.gz
glibc-49b308a26e2a9e02ef396f67f59c462ad4171ea4.tar.xz
glibc-49b308a26e2a9e02ef396f67f59c462ad4171ea4.zip
hurd: Prevent the final file_exec_paths call from signals
Otherwise if the exec server started thrashing the old task,
we won't be able to restart the exec.

This notably fixes building ghc.
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/mach/hurd/spawni.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/sysdeps/mach/hurd/spawni.c b/sysdeps/mach/hurd/spawni.c
index 9516001817..58a89b45f3 100644
--- a/sysdeps/mach/hurd/spawni.c
+++ b/sysdeps/mach/hurd/spawni.c
@@ -812,6 +812,18 @@ retry:
 
     inline error_t exec (file_t file)
       {
+	sigset_t old, new;
+
+	/* Avoid getting interrupted while exec(), notably not after the exec
+	   server has committed to the exec and started thrashing the task.
+
+	   Various issues otherwise show up when building e.g. ghc.
+
+	   TODO Rather add proper interrupt support to the exec server, that
+	   avoids interrupts in that period.  */
+	__sigfillset(&new);
+	__sigprocmask (SIG_SETMASK, &new, &old);
+
 	error_t err = __file_exec_paths
 	  (file, task,
 	   __sigismember (&_hurdsig_traced, SIGKILL) ? EXEC_SIGTRAP : 0,
@@ -824,7 +836,7 @@ retry:
 	/* Fallback for backwards compatibility.  This can just be removed
 	   when __file_exec goes away.  */
 	if (err == MIG_BAD_ID)
-	  return __file_exec (file, task,
+	  err = __file_exec (file, task,
 			      (__sigismember (&_hurdsig_traced, SIGKILL)
 			      ? EXEC_SIGTRAP : 0),
 			      args, argslen, env, envlen,
@@ -833,6 +845,8 @@ retry:
 			      ints, INIT_INT_MAX,
 			      NULL, 0, NULL, 0);
 
+	__sigprocmask (SIG_SETMASK, &old, NULL);
+
 	return err;
       }