Ticket #3417: tcsetpgrp-test.c

File tcsetpgrp-test.c, 1.3 KB (added by simonsouth, 4 years ago)

Short program that demonstrates the problem and the fix

Line 
1#include <errno.h>
2#include <fcntl.h>
3#include <signal.h>
4#include <string.h>
5#include <sys/stat.h>
6#include <unistd.h>
7
8int
9main(int argc, char **argv)
10{
11    int fd;
12    sigset_t blocked;
13
14    /* Try invoking this program first on its own, then again using either
15     * strace or the debugger. Without the patch for #3417 applied you should
16     * find it terminates normally in the first case but gets stuck in an ioctl
17     * and runs forever in the second. With the patch applied it terminates
18     * normally in both cases. */
19
20    /* Open our controlling terminal */
21    fd = open("/dev/tty", O_RDWR | O_NOCTTY);
22
23    /* If our process-group ID is not the same as our process ID (i.e. we're
24     * running with a debugger attached), move to our own (background) process
25     * group */
26    if (getpid() != tcgetpgrp(fd))
27        setpgid(0, 0);
28
29    /* Block SIGTTOU (in this thread only) */
30    sigemptyset(&blocked);
31    sigaddset(&blocked, SIGTTOU);
32    pthread_sigmask(SIG_BLOCK, &blocked, NULL);
33
34    /* Now set the terminal's foreground process group to our own.
35     *
36     * Normally this should cause a SIGTTOU signal to be sent to us if we're
37     * running in the background (within the debugger), but since we've already
38     * blocked this signal it should not be generated. */
39    tcsetpgrp(fd, getpgrp());
40
41    /* Clean up and exit */
42    close(fd);
43
44    return 0;
45}