> It is possible to demonstrate this with some effort using > a small C program.
For completeness this is an example of a program to reproduce the issue: DIE("tcgetpgrp"). The failure window is small, so many iterations and a diverse host workload is required to demonstrate the issue. Alternatively, deliberately introducing a short delay at maybe_give_terminal_to() should reduce the time to detection. #include <errno.h> #include <fcntl.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <time.h> #include <unistd.h> #include <sys/wait.h> #define DIE(...) die(__LINE__, __VA_ARGS__) void die(unsigned lineno, const char *fmt, ...) { va_list argp; va_start(argp, fmt); vfprintf(stderr, fmt, argp); fputc('\n', stderr); exit(1); } int main() { const char *ttyname = ctermid(0); if (!ttyname) DIE("ctermid"); int ttyfd = open(ttyname, O_RDONLY); if (-1 == ttyfd) DIE(ttyname); pid_t child = fork(); if (-1 == child) DIE("fork"); if (!child) { if (setpgid(0, 0)) DIE("setpgid"); kill(getpid(), SIGSTOP); exit(0); } if (setpgid(child, child)) DIE("setpgid"); if (tcsetpgrp(ttyfd, child)) DIE("tcsetpgrp"); int status; pid_t waited; waited = waitpid(child, &status, WUNTRACED); if (waited != child || !WIFSTOPPED(status)) DIE("waitpid"); struct timespec delay = { .tv_nsec = 10000000 }; nanosleep(&delay, 0); if (child != tcgetpgrp(ttyfd)) DIE("tcgetpgrp"); return 0; } Earl