Ticket #3417: tcsetpgrp-test.c

File tcsetpgrp-test.c, 1.3 KB (added by simonsouth, 9 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}