-
Notifications
You must be signed in to change notification settings - Fork 8
/
detach.c
132 lines (118 loc) · 3.03 KB
/
detach.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
* Detach a daemon process from whoever/whatever started it.
* Mostly lifted from an article in the July/August 1987 ;login:,
* by Dave Lennert (hplabs!hpda!davel). Blame bugs on me.
*/
/*
| [[email protected]] Lifted this from Rayan Zachariassens
| ZMailer support library. Handy.
*/
#include "prototypes.h"
#include <signal.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#if defined(sun) || defined(BSD) || defined(__svr4__)
#define USE_BSDSETPGRP
#endif
void
detach()
{
/*
* If launched by init (process 1), there's no need to detach.
*
* Note: this test is unreliable due to an unavoidable race
* condition if the process is orphaned.
*/
if (getppid() == 1)
goto out;
/* Ignore terminal stop signals */
#ifdef SIGTTOU
(void) signal(SIGTTOU, SIG_IGN);
#endif /* SIGTTOU */
#ifdef SIGTTIN
(void) signal(SIGTTIN, SIG_IGN);
#endif /* SIGTTIN */
#ifdef SIGTSTP
(void) signal(SIGTSTP, SIG_IGN);
#endif /* SIGTSTP */
/*
* Allow parent shell to continue.
* Ensure the process is not a process group leader.
*/
if (fork() != 0)
exit(0); /* parent */
/* child */
/*
* Disassociate from controlling terminal and process group.
*
* Ensure the process can't reacquire a new controlling terminal.
* This is done differently on BSD vs. AT&T:
*
* BSD won't assign a new controlling terminal
* because process group is non-zero.
*
* AT&T won't assign a new controlling terminal
* because process is not a process group leader.
* (Must not do a subsequent setpgrp()!)
*/
#ifdef _POSIX_SOURCE
(void) setsid();
{
int fd; /* file descriptor */
if ((fd = open("/dev/tty", O_RDWR, 0)) >= 0) {
ioctl(fd, TIOCNOTTY, 0); /* lose controlling terminal */
close(fd);
}
}
#else /* !_POSIX_SOURCE */
#ifdef USE_BSDSETPGRP
#if defined(__svr4__) || defined(__DARWIN_UNIX03)
setpgrp();
#else /* not __svr4__ */
(void) setpgrp(0, getpid()); /* change process group */
{
int fd; /* file descriptor */
if ((fd = open("/dev/tty", O_RDWR, 0)) >= 0) {
ioctl(fd, TIOCNOTTY, 0); /* lose controlling terminal */
close(fd);
}
}
#endif /* not __svr4__ */
#else /* !USE_BSDSETPGRP */
/* lose controlling terminal and change process group */
setpgrp();
signal(SIGHUP, SIG_IGN); /* immunge from pgrp leader death */
if (fork() != 0) /* become non-pgrp-leader */
exit(0); /* first child */
/* second child */
#endif /* USE_BSDSETPGRP */
#endif /* !_POSIX_SOURCE */
out:
(void) close(0);
(void) close(1);
(void) close(2);
(void) umask(022); /* clear any inherited file mode creation mask */
/* Clean out our environment from personal contamination */
/* cleanenv(); */
#if defined(USE_RLIMIT) || defined(sun) || defined(__svr4__)
/* In case this place runs with cpu limits, remove them */
{
struct rlimit rl;
rl.rlim_cur = RLIM_INFINITY;
rl.rlim_max = RLIM_INFINITY;
setrlimit(RLIMIT_CPU, &rl);
}
#endif /* USE_RLIMIT */
return;
}
#ifdef USE_NOFILE
#ifndef NOFILE
#define NOFILE 20
#endif /* NOFILE */
int
getdtablesize()
{
return NOFILE;
}
#endif /* USE_NOFILE */