1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00
cde/src/lib/libast/features/sys
Johnothan King 0863a8eb29 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>
2022-02-05 13:31:31 +00:00

238 lines
6.9 KiB
Text

iff AST_SYS
ref -D_def_map_ast
header stdlib.h
header stddef.h
header sys/types.h
header stdint.h
header inttypes.h
header string.h
header unistd.h
header limits.h
header fcntl.h
header locale.h
typ dev_t,nlink_t fail{
echo "#ifndef $m"
echo "#define $m 1"
echo "typedef short $v;"
echo "#endif"
}end
typ gid_t,mode_t,uid_t fail{
echo "#ifndef $m"
echo "#define $m 1"
echo "typedef unsigned short $v;"
echo "#endif"
}end
typ wchar_t stdio.h wchar.h fail{
echo "#ifndef $m"
echo "#define $m 1"
echo "typedef unsigned short $v;"
echo "#endif"
}end
typ pid_t,ssize_t fail{
echo "#ifndef $m"
echo "#define $m 1"
echo "typedef int $v;"
echo "#endif"
}end
typ wint_t stdio.h wchar.h fail{
echo "#ifndef $m"
echo "#define $m 1"
echo "typedef int $v;"
echo "#endif"
}end
typ socklen_t sys/socket.h fail{
echo "#ifndef $m"
echo "#define $m 1"
echo "typedef int $v;"
echo "#endif"
}end
typ size_t fail{
echo "#ifndef $m"
echo "#define $m 1"
echo "typedef unsigned int $v;"
echo "#endif"
}end
typ clock_t,ino_t,off_t,ptrdiff_t fail{
echo "#ifndef $m"
echo "#define $m 1"
echo "typedef long $v;"
echo "#endif"
}end
typ time_t fail{
echo "#ifndef $m"
echo "#define $m 1"
echo "typedef unsigned long $v;"
echo "#endif"
}end
typ div_t fail{
echo "#ifndef $m"
echo "#define $m 1"
echo "typedef struct { int quot; int rem; } $v;"
echo "#endif"
}end
typ ldiv_t fail{
echo "#ifndef $m"
echo "#define $m 1"
echo "typedef struct { long quot; long rem; } $v;"
echo "#endif"
}end
tst typ_signed_size_t output{
#include <sys/types.h>
int
main()
{
unsigned long u = ~0;
size_t s = ~0;
if (s >= 0)
return 1;
printf("#if !defined(_typ_signed_size_t)\n/* ensure unsigned size_t */\ntypedef unsigned %s _ast_size_t;\n#undef\tsize_t\n#define size_t\t_ast_size_t\n#endif\n", u == (unsigned long)s ? "long" : "int");
return 0;
}
}end
define offsetof (type,member) __builtin_offsetof(type,member)
define EXIT_FAILURE 1
define EXIT_SUCCESS 0
define MB_CUR_MAX 1
define RAND_MAX 32767
define STDIN_FILENO 0
define STDOUT_FILENO 1
define STDERR_FILENO 2
define NULL 0
define SEEK_SET 0
define SEEK_CUR 1
define SEEK_END 2
define F_OK 0
define X_OK 1
define W_OK 2
define R_OK 4
print #if _BLD_ast && defined(__EXPORT__)
print #define extern __EXPORT__
print #endif
extern _exit void (int)
extern abort void (void)
extern abs int (int)
extern access int (const char*, int)
extern alarm unsigned (unsigned)
extern atexit int (void(*)(void))
extern atof double (const char*)
extern atoi int (const char*)
extern atol long (const char*)
extern bsearch void* (const void*, const void*, size_t, size_t, int(*)(const void*, const void*))
extern calloc void* (size_t, size_t)
extern cfree void (void*)
extern chdir int (const char*)
extern chown int (const char*, uid_t, gid_t)
extern close int (int)
extern confstr size_t (int, char*, size_t)
extern div div_t (int, int)
extern dup int (int)
extern dup2 int (int, int)
extern eaccess int (const char*, int)
extern execl int (const char*, const char*, ...)
extern execle int (const char*, const char*, ...)
extern execlp int (const char*, const char*, ...)
extern execv int (const char*, char* const[])
extern execve int (const char*, char* const[], char* const[])
extern execve int (const char*, char* const[], char* const[])
extern execvp int (const char*, char* const[])
extern execvpe int (const char*, char* const[], char* const[])
extern exit void (int)
extern fork pid_t (void)
extern fpathconf long (int, int)
extern free void (void*)
extern fsync int (int)
extern ftruncate int (int, off_t)
extern getcwd char* (char*, size_t)
extern getegid gid_t (void)
extern getenv char* (const char*)
extern geteuid uid_t (void)
extern getgid gid_t (void)
extern getgroups int (int, gid_t[])
extern getlogin char* (void)
extern getpgrp pid_t (void)
extern getpid pid_t (void)
extern getppid pid_t (void)
extern gettxt char* (const char*, const char*)
extern getuid uid_t (void)
extern isatty int (int)
extern labs long (long)
extern ldiv ldiv_t (long, long)
extern link int (const char*, const char*)
extern lseek off_t (int, off_t, int)
extern malloc void* (size_t)
extern mblen int (const char*, size_t)
extern mbstowcs size_t (wchar_t*, const char*, size_t)
extern mbtowc int (wchar_t*, const char*, size_t)
extern memalign void* (size_t, size_t)
extern memccpy void* (void*, const void*, int, size_t)
extern memchr void* (const void*, int, size_t)
extern memcmp int (const void*, const void*, size_t)
extern memcpy void* (void*, const void*, size_t)
extern memmove void* (void*, const void*, size_t)
extern memset void* (void*, int, size_t)
extern pathconf long (const char*, int)
extern pause int (void)
extern pipe int (int[])
extern pvalloc void* (size_t)
extern qsort void (void*, size_t, size_t, int(*)(const void*, const void*))
extern rand int (void)
extern read ssize_t (int, void*, size_t)
extern realloc void* (void*, size_t)
extern realpath char* (const char*, char*)
extern resolvepath char* (const char*, char*, size_t)
extern rmdir int (const char*)
extern setgid int (gid_t)
extern setpgid int (pid_t, pid_t)
extern setsid pid_t (void)
extern setuid int (uid_t)
extern sleep unsigned (unsigned int)
extern spawnveg pid_t (const char*, char* const[], char* const[], pid_t, int)
extern srand void (unsigned int)
extern strcasecmp int (const char*, const char*)
extern strcat char* (char*, const char*)
extern strchr char* (const char*, int)
extern strcmp int (const char*, const char*)
extern strcoll int (const char*, const char*)
extern strcpy char* (char*, const char*)
extern strcspn size_t (const char*, const char*)
extern strdup char* (const char*)
extern strlcat size_t (char*, const char*, size_t)
extern strlcpy size_t (char*, const char*, size_t)
extern strlen size_t (const char*)
extern strncasecmp int (const char*, const char*, size_t)
extern strncat char* (char*, const char*, size_t)
extern strncmp int (const char*, const char*, size_t)
extern strncpy char* (char*, const char*, size_t)
extern strpbrk char* (const char*, const char*)
extern strrchr char* (const char*, int)
extern strspn size_t (const char*, const char*)
extern strstr char* (const char*, const char*)
extern strtok char* (char*, const char*)
extern strxfrm size_t (char*, const char*, size_t)
extern swab void (const void*, void*, ssize_t)
extern sysconf long (int)
extern system int (const char*)
extern tcgetpgrp pid_t (int)
extern tcsetpgrp int (int, pid_t)
extern truncate int (const char*, off_t)
extern ttyname char* (int)
extern unlink int (const char*)
extern valloc void* (size_t)
extern wcstombs size_t (char*, const wchar_t*, size_t)
extern wctomb int (char*, wchar_t)
extern write ssize_t (int, const void*, size_t)
print #undef extern
# <stdarg.h> is handled by proto so this must be after the last test
print #include <stdarg.h>