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 |
|
---|
8 | int
|
---|
9 | main(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 | }
|
---|