mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
Support glibc 2.35's posix_spawn_file_actions_addtcsetpgrp_np(3)
This commit implements support for the glibc 2.35
posix_spawn_file_actions_addtcsetpgrp_np(3) extension[2][3],
updating spawnveg(3) to use the new function for setting the
terminal group. This was done with the intention of improving
performance in interactive shells without reintroducing previous
race conditions[4][5].
[1]: https://sourceware.org/pipermail/libc-alpha/2022-February/136040.html
[2]: https://sourceware.org/git/?p=glibc.git;a=commit;h=342cc934
[3]: https://sourceware.org/git/?p=glibc.git;a=commit;h=6289d28d
[4]: https://github.com/ksh93/ksh/issues/79
[5]: https://www.mail-archive.com/ast-developers@research.att.com/msg00717.html
src/cmd/ksh93/sh/path.c:
- Tell spawnveg(3) to set the terminal process group when launching
a child process in an interactive shell.
src/cmd/ksh93/sh/xec.c:
- If posix_spawn_file_actions_addtcsetpgrp_np(3) is available,
allow use of spawnveg(3) (via sh_ntfork()) even with job control
active.
- sh_ntfork(): Reimplement most of the SIGTSTP handling code
removed in commit 66c37202.
src/lib/libast/comp/spawnveg.c,
src/lib/libast/misc/procopen.c,
src/lib/libast/features/sys:
- Add support for posix_spawn_file_actions_addtcsetpgrp_np(3).
- Allow spawnveg to set the terminal process group when pgid == 0.
This was necessary to avoid race conditions when using the new
function.
src/lib/libast/features/lib:
- Detect posix_spawn_file_actions_addtcsetpgrp_np(3).
- Do not detect an OS spawnveg(3). With the API changes to spawnveg
in this pull request ksh probably can't use the OS's spawnveg
function anymore. (That's assuming anything else even provides a
spawnveg function to begin with, which is unlikely.)
src/lib/libast/features/api,
src/cmd/ksh93/include/defs.h:
- Bump libast version (20220101 => 20220201) due to the spawnveg(3)
API change.
src/lib/libast/man/spawnveg.3:
- Document the changes to spawnveg(3) in the corresponding man
page. Currently, it will only use the new tcfd argument if
posix_spawn_file_actions_addtcsetpgrp_np(3) is supported. This
could also be implemented for the fork(2) fallback, but for now
I've avoided changing that since actually using it in the fork
code would likely require a lot of hackery to avoid attempting
tcsetpgrp with vfork (the behavior of tcsetpgrp after vfork is
not portable) and would only benefit systems that don't have
posix_spawn and vfork (I can't recall any off the top of my head
that would fall under that category).
- Updated the man page to account for spawnveg's change in
behavior.
Co-authored-by: Martijn Dekker <martijn@inlv.org>
This commit is contained in:
parent
c7a774d9df
commit
0863a8eb29
9 changed files with 101 additions and 35 deletions
|
|
@ -29,8 +29,8 @@
|
|||
#define defs_h_defined
|
||||
|
||||
#include <ast.h>
|
||||
#if !defined(AST_VERSION) || AST_VERSION < 20220101
|
||||
#error libast version 20220101 or later is required
|
||||
#if !defined(AST_VERSION) || AST_VERSION < 20220201
|
||||
#error libast version 20220201 or later is required
|
||||
#endif
|
||||
#if !_lib_fork
|
||||
#error In 2021, ksh joined the 21st century and started requiring fork(2).
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ static pid_t _spawnveg(const char *path, char* const argv[], char* const envp[],
|
|||
while(1)
|
||||
{
|
||||
sh_stats(STAT_SPAWN);
|
||||
pid = spawnveg(path,argv,envp,pgid);
|
||||
pid = spawnveg(path,argv,envp,pgid,job.jobcontrol?job.fd:-1);
|
||||
if(pid>=0 || errno!=EAGAIN)
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,10 @@
|
|||
# include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
#if _lib_posix_spawn > 1 && _lib_posix_spawn_file_actions_addtcsetpgrp_np
|
||||
#define _use_ntfork_tcpgrp 1
|
||||
#endif
|
||||
|
||||
#define SH_NTFORK SH_TIMING
|
||||
#define NV_BLTPFSH NV_ARRAY
|
||||
|
||||
|
|
@ -1613,7 +1617,11 @@ int sh_exec(register const Shnode_t *t, int flags)
|
|||
fifo_save_ppid = sh.current_pid;
|
||||
#endif
|
||||
#if SHOPT_SPAWN
|
||||
#if _use_ntfork_tcpgrp
|
||||
if(com)
|
||||
#else
|
||||
if(com && !job.jobcontrol)
|
||||
#endif /* _use_ntfork_tcpgrp */
|
||||
{
|
||||
parent = sh_ntfork(t,com,&jobid,ntflag);
|
||||
if(parent<0)
|
||||
|
|
@ -3449,7 +3457,8 @@ static void sigreset(int mode)
|
|||
|
||||
/*
|
||||
* A combined fork/exec for systems with slow fork().
|
||||
* Incompatible with job control on interactive shells (job.jobcontrol).
|
||||
* Incompatible with job control on interactive shells (job.jobcontrol) if
|
||||
* the system does not support posix_spawn_file_actions_addtcsetpgrp_np().
|
||||
*/
|
||||
static pid_t sh_ntfork(const Shnode_t *t,char *argv[],int *jobid,int flag)
|
||||
{
|
||||
|
|
@ -3461,6 +3470,9 @@ static pid_t sh_ntfork(const Shnode_t *t,char *argv[],int *jobid,int flag)
|
|||
char **arge, *path;
|
||||
volatile pid_t grp = 0;
|
||||
Pathcomp_t *pp;
|
||||
#if _use_ntfork_tcpgrp
|
||||
volatile int jobwasset=0;
|
||||
#endif /* _use_ntfork_tcpgrp */
|
||||
if(flag)
|
||||
{
|
||||
otype = savetype;
|
||||
|
|
@ -3525,8 +3537,21 @@ static pid_t sh_ntfork(const Shnode_t *t,char *argv[],int *jobid,int flag)
|
|||
}
|
||||
arge = sh_envgen();
|
||||
sh.exitval = 0;
|
||||
#if _use_ntfork_tcpgrp
|
||||
if(job.jobcontrol)
|
||||
{
|
||||
signal(SIGTTIN,SIG_DFL);
|
||||
signal(SIGTTOU,SIG_DFL);
|
||||
signal(SIGTSTP,SIG_DFL);
|
||||
jobwasset++;
|
||||
}
|
||||
#endif /* _use_ntfork_tcpgrp */
|
||||
#ifdef JOBS
|
||||
#if _use_ntfork_tcpgrp
|
||||
if(sh_isstate(SH_MONITOR) && (job.jobcontrol || (otype&FAMP)))
|
||||
#else
|
||||
if(sh_isstate(SH_MONITOR) && (otype&FAMP))
|
||||
#endif /* _use_ntfork_tcpgrp */
|
||||
{
|
||||
if((otype&FAMP) || job.curpgid==0)
|
||||
grp = 1;
|
||||
|
|
@ -3587,6 +3612,17 @@ static pid_t sh_ntfork(const Shnode_t *t,char *argv[],int *jobid,int flag)
|
|||
sh_popcontext(buffp);
|
||||
if(buffp->olist)
|
||||
free_list(buffp->olist);
|
||||
#if _use_ntfork_tcpgrp
|
||||
if(jobwasset)
|
||||
{
|
||||
signal(SIGTTIN,SIG_IGN);
|
||||
signal(SIGTTOU,SIG_IGN);
|
||||
if(sh_isstate(SH_INTERACTIVE))
|
||||
signal(SIGTSTP,SIG_IGN);
|
||||
else
|
||||
signal(SIGTSTP,SIG_DFL);
|
||||
}
|
||||
#endif /* _use_ntfork_tcpgrp */
|
||||
if(sigwasset)
|
||||
sigreset(1); /* restore ignored signals */
|
||||
if(scope)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue