Skip to content

Commit 5ad9bcf

Browse files
authored
Merge pull request #589 from Nikokrock/support_tty_in_rlimit
Improve linux implemenation of rlimit to support tty
2 parents ed02d0d + 8225cfc commit 5ad9bcf

File tree

4 files changed

+39
-0
lines changed

4 files changed

+39
-0
lines changed

src/e3/os/data/rlimit-aarch64-linux

136 Bytes
Binary file not shown.

src/e3/os/data/rlimit-x86-linux

4.12 KB
Binary file not shown.

src/e3/os/data/rlimit-x86_64-linux

6.61 KB
Binary file not shown.

tools/rlimit/rlimit.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,21 @@ main (int argc, char **argv)
153153
sigaddset(&block_cld, SIGCHLD);
154154
sigprocmask(SIG_BLOCK, &block_cld, NULL);
155155

156+
/* In some cases rlimit might be launched with stdin and/or stdout being
157+
* a terminal. In that case at process startup, the rlimit process is
158+
* the foreground process group. This means that the following actions
159+
* will cause the child process to block:
160+
* - read input from the terminal (SIGTTIN signal)
161+
* - write output to the terminal
162+
* (SIGTTOU signal if terminal mode TOSTOP enabled)
163+
* - change terminal settings (SIGTTOU signal)
164+
*
165+
* As rlimit is not supposed to read input the following is done:
166+
*
167+
* 1- make the child process the foreground process group
168+
* 2- allow the parent process to write in parallel to the terminal
169+
*/
170+
156171
pid = fork ();
157172
switch (pid) {
158173
case -1:
@@ -184,6 +199,23 @@ main (int argc, char **argv)
184199
}
185200
#endif /* __APPLE__ */
186201

202+
/* ignore SIGTTOU so that tcsetpgrp call does not block. */
203+
signal (SIGTTOU, SIG_IGN);
204+
205+
/* Set child process as foreground process group so that
206+
* children can read from the terminal if needed. Note that
207+
* we ignore any error here because stdin might not be a terminal.
208+
* If only stdout is a terminal there are no issues with not
209+
* being the foreground process as most terminals are configured
210+
* with TOSTOP off (so SIGTTOU is only emited in case of terminal
211+
* settings change.
212+
*/
213+
tcsetpgrp(0, getpgid(getpid()));
214+
215+
/* Restore SIGTTIN and SIGTTOU signal to their original value
216+
* in order not to impact children processes behaviour. */
217+
signal (SIGTTIN, SIG_DFL);
218+
signal (SIGTTOU, SIG_DFL);
187219
execvp ((const char *) argv[2], (char *const *) &argv[2]);
188220
fprintf (stderr, "rlimit: could not run \"%s\": ", argv[2]);
189221
perror ("execvp");
@@ -196,6 +228,13 @@ main (int argc, char **argv)
196228
int timeout = atoi (argv[1]);
197229
int seconds = timeout;
198230

231+
/* At this stage rlimit might not be anymore the foreground process.
232+
* Ignore SIGTTOU in order to able to write and SIGTTIN for safety
233+
* (though no input is attempted from the rlimit itself).
234+
*/
235+
signal (SIGTTOU, SIG_IGN);
236+
signal (SIGTTIN, SIG_IGN);
237+
199238
/* pid variable is now set correctly so unblock SIGCHLD */
200239
sigprocmask(SIG_UNBLOCK, &block_cld, NULL);
201240

0 commit comments

Comments
 (0)